Header menu logo bristlecone

ScriptNotebook

Bristlecone

Bristlecone is a library for easily composing theoretical models into larger systems, and subsequently conducting model-fitting and model-selection analyses on time-series data. Although originally designed for the investigation of non-linear dynamics within ecological and environmental sciences, the library can be used across finance, econometrics and other fields that apply non-linear modelling techniques.

Quick Start

Bristlecone is an F# .NET library. You can easily get started by installing the latest .NET SDK. You may then simply use the Bristlecone package in a script, application, or library. The nuget package is available here.

To use in an F# script

img/example.png

Example

This example demonstrates the layout of a model when defined in Bristlecone.

open Bristlecone // Opens Bristlecone core library and estimation engine
open Bristlecone.Language // Open the language for writing Bristlecone models

let mass = state<1> "mass"

let hypothesis =

    // Model parameters:
    let η = parameter "η" NoConstraints 0.50 1.50
    let β = parameter "β" NoConstraints 0.01 1.00 // m
    let κ = parameter "κ" NoConstraints 0.01 1.00

    // Likelihood parameters:
    let sigma = parameter "σ[x]" Positive 0.01 0.10

    let vonBertalanffy = P η * This ** P β - P κ * This

    let NLL = ModelLibrary.NegLogLikelihood.Normal (Require.state mass) sigma

    Model.empty
    |> Model.addRateEquation mass vonBertalanffy
    |> Model.estimateParameter η
    |> Model.estimateParameter β
    |> Model.estimateParameter κ
    |> Model.useLikelihoodFunction NLL
    |> Model.compile

// Given some data (loaded using Bristlecone functions, FSharp.Data, etc.)...
fun data ->
  let engine = Bristlecone.mkContinuous ()
  let endCond = Optimisation.EndConditions.atIteration 10000<iteration>
  Bristlecone.fit engine endCond data hypothesis

In the above snippet, a von Bertalanffy growth model is defined as a model hypothesis. We then create an EstimationEngine, which defines the methodology for model-fitting. In Bristlecone, an EstimationEngine is created and customised using the F# forward pipe operator (for R users this may be familiar; this concept was adapted into the dplyr %>% operator).

To apply the model to data, the Bristlecone.fit function can be called with an end condition for the optimisation routine chosen in the given engine.

Samples & documentation

An API reference is automatically generated from XML comments in the library implementation.

In addition, this documentation includes step-by-step example analyses. Each analysis may be downloaded as an F# script or Jupyter notebook using the buttons at the top of each example page.

Contributing and copyright

The project is hosted on GitHub where you can report issues, fork the project and submit pull requests. If you're adding a new public API, please also consider adding samples that can be turned into documentation (using fsdocs literal scripting).

The library is available under an MIT license, which allows modification and redistribution for both commercial and non-commercial purposes. For more information see the License file in the GitHub repository.

Multiple items
module Bristlecone from Bristlecone
<namespacedoc><summary>The core library of Bristlecone, containing model-fitting functions.</summary></namespacedoc>
Main functionality of Bristlecone, including functions to scaffold `ModelSystem`s and for model-fitting (tests and real fits).


--------------------
namespace Bristlecone
module Language from Bristlecone
<summary> An F# Domain Specific Language (DSL) for scripting with Bristlecone. </summary>
val mass: StateId<1>
val state: name: string -> StateId<'u>
val hypothesis: ModelSystem.ModelSystem<Time.year>
val η: IncludedParameter<1>
Multiple items
val parameter: code: string -> con: Parameter.Constraint -> lower: float<'u> -> upper: float<'u> -> IncludedParameter<'u>
<summary> Define an estimatable parameter for a Bristlecone model. </summary>

--------------------
[<Measure>] type parameter
val NoConstraints: Parameter.Constraint
val β: IncludedParameter<1>
val κ: IncludedParameter<1>
val sigma: IncludedParameter<1>
val Positive: Parameter.Constraint
val vonBertalanffy: ModelExpression</Time.year>
val P: name: IncludedParameter<'u> -> ModelExpression<'u>
val This<'u> : ModelExpression<'u>
val NLL: ModelSystem.Likelihood<ModelSystem.state>
namespace Bristlecone.ModelLibrary
module NegLogLikelihood from Bristlecone.ModelLibrary
<summary>Negative log likelihood (-logL) functions to represent a variety of distributions and data types.</summary>
<namespacedoc><summary>Pre-built model parts for use in Bristlecone</summary></namespacedoc>
val Normal: obs: Require.ObsForLikelihood<'u> -> sigma: IncludedParameter<'u> -> ModelSystem.Likelihood<'v>
module Require from Bristlecone.Language
val state: s: StateId<'u> -> Require.ObsForLikelihood<'u>
module Model from Bristlecone.Language
<summary> Terms for scaffolding a model system for use with Bristlecone. </summary>
val empty<'time> : ModelBuilder.ModelBuilder<'time>
val addRateEquation: name: StateId<'state> -> expr: ModelExpression<'state/'time> -> mb: ModelBuilder.ModelBuilder<'time> -> ModelBuilder.ModelBuilder<'time>
val estimateParameter: p: IncludedParameter<'u> -> builder: ModelBuilder.ModelBuilder<'time> -> ModelBuilder.ModelBuilder<'time>
val useLikelihoodFunction: likelihoodFn: ModelSystem.Likelihood<ModelSystem.state> -> builder: ModelBuilder.ModelBuilder<'u> -> ModelBuilder.ModelBuilder<'u>
val compile: (ModelBuilder.ModelBuilder<'u> -> ModelSystem.ModelSystem<'u>)
val data: CodedMap<Time.TimeSeries<float<'u>,System.DateTime,'a,System.TimeSpan>>
val engine: EstimationEngine.EstimationEngine<System.DateTime,System.TimeSpan,Time.year,'u>
val mkContinuous: unit -> EstimationEngine.EstimationEngine<System.DateTime,System.TimeSpan,Time.year,'u>
<summary>A basic estimation engine for ordinary differential equations, using a Nelder-Mead optimiser.</summary>
val endCond: EstimationEngine.EndCondition
namespace Bristlecone.Optimisation
module EndConditions from Bristlecone.Optimisation
<summary>Composable end conditions to specify when optimisation routines should end.</summary>
val atIteration: iteration: int<iteration> -> EstimationEngine.Solution list -> currentIteration: int<iteration> -> EstimationEngine.OptimStopReason
<summary> End on or after a minimum number of iterations. </summary>
[<Measure>] type iteration
val fit: engine: EstimationEngine.EstimationEngine<'a,'b,'modelTimeUnit,'u> -> endCondition: EstimationEngine.EndCondition -> timeSeriesData: CodedMap<Time.TimeSeries<float<'u>,'a,'c,'b>> -> model: ModelSystem.ModelSystem<'modelTimeUnit> -> ModelSystem.EstimationResult<'a,'c,'b> (requires comparison and comparison)
<summary>Fit a time-series model to data.</summary>
<param name="engine">An estimation engine configured and tested for the given model.</param>
<param name="endCondition">The condition at which optimisation should cease.</param>
<param name="timeSeriesData">Time-series dataset that contains a series for each equation in the model system.</param>
<param name="model">A model system of equations, likelihood function, estimatible parameters, and optional measures.</param>
<returns>The result of the model-fitting procedure. If an error occurs, throws an exception.</returns>

Type something to start searching.