Header menu logo bristlecone

ScriptNotebook

Defining a Hypothesis (or Model System)

In Bristlecone, a ModelSystem represents combination of mathematical models and their estimatable parameters that can be used within model-fitting and model-selection. A ModelSystem is defined by:

To build a ModelSystem, first open the Bristlecone language:

open Bristlecone // Opens Bristlecone core library and estimation engine
open Bristlecone.Language // Open the language for writing Bristlecone models
open FSharp.Data.UnitSystems.SI.UnitSymbols // Opens SI units for use in models

Second, define the parts of your hypothesis. In this example, we will define a simple model of population growth:

Note: refer to the section on writing models for help writing Bristlecone expressions.

[<Measure>]
type individuals

let r = parameter "r" notNegative 0.01< / Time.day> 0.50< / Time.day>
let K = parameter "K" notNegative 20.<individuals> 50.<individuals>
let N = state<individuals> "N"

When making parameters, first pass an identifiable short code that you will see in output files. Next, you must pass the constraint mode. In Bristlecone, although the optimisation algorithms are unconstrained, it is possible to constrain parameters to specific values using transformations. These are applied automatically within the model-fitting process. Two available options are noConstaints, which is unconstrained, and positiveOnly, which prevents the value of that parameter dropping below zero. The last arguments are two numbers representing a lower and upper bound from which to draw an initial starting value for the parameter. The starting value is drawn from a continuous uniform distribution, using a Random that you define in the EstimationEngine (see estimating).

let ``dN/dt``: ModelExpression<individuals / Time.day> =
    P r * This * (Constant 1. - (This / P K))

From the above code, our model is compiled into the following internal representation:

ME
  (Multiply
     [Multiply [Parameter "r"; This];
      Subtract (Constant 1.0, Divide (This, Parameter "K"))])

Our model of the change in N (population count) over time has two estimatable parameters defined using the Parameter term, which are r (the intrinsic growth rate of the population) and K (the carrying capacity of the population). The type system verifies that all required parameters are in place, and conducts unit arithmetic to ensure that specified units make sense at compile-time.

Next, we need to create our ModelSystem by using the helper functions that can be found under Model.*.

In this example, we will use a sum-of-squares measure to determine the goodness-of-fit rather than a likelihood function. A selection of likelihood functions, including sum-of-squares functions, are included in Bristlecone within the ModelLibrary module.

The ModelSystem can be created with forward pipes (|>) as follows:

let hypothesis =
    Model.empty
    |> Model.addRateEquation N ``dN/dt``
    |> Model.estimateParameter r
    |> Model.estimateParameter K
    |> Model.useLikelihoodFunction (ModelLibrary.Likelihood.sumOfSquares [ Require.state N ])
    |> Model.compile

In the above code, we first start with an empty model system, Model.empty. We then add each component with a short code to represent it, and finally call Model.compile. The Model.compile function checks the validity of the model in terms of duplicate short codes, making sure all parameters are set to be estimated, and that all the required parts are in place.

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>
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Data
namespace Microsoft.FSharp.Data.UnitSystems
namespace Microsoft.FSharp.Data.UnitSystems.SI
namespace Microsoft.FSharp.Data.UnitSystems.SI.UnitSymbols
Multiple items
val Measure: sId: MeasureId<'u> -> ModelExpression<'u>

--------------------
type MeasureAttribute = inherit Attribute new: unit -> MeasureAttribute

--------------------
new: unit -> MeasureAttribute
[<Measure>] type individuals
val r: IncludedParameter</Time.day>
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 notNegative: Parameter.Constraint
Multiple items
val Time<'t> : ModelExpression<'t>

--------------------
module Time from Bristlecone
[<Measure>] type day
val K: IncludedParameter<individuals>
val N: StateId<individuals>
val state: name: string -> StateId<'u>
type ModelExpression<'u> = private | ME of ModelExpressionUntyped static member (%) : ModelExpression<'u> * ModelExpression<'u> -> ModelExpression<'u> static member ( * ) : ModelExpression<'u1> * ModelExpression<'u2> -> ModelExpression<'u1 'u2> static member (+) : ModelExpression<'u> * ModelExpression<'u> -> ModelExpression<'u> static member (-) : ModelExpression<'u> * ModelExpression<'u> -> ModelExpression<'u> static member (.<) : ModelExpression<'u> * ModelExpression<'u> -> BoolExpression static member (.>) : ModelExpression<'u> * ModelExpression<'u> -> BoolExpression static member (/) : ModelExpression<'u1> * ModelExpression<'u2> -> ModelExpression<'u1/'u2> static member (=.) : ModelExpression<'u> * ModelExpression<'u> -> BoolExpression static member Environment: sid: StateId<'u> -> ModelExpression<'u> static member Exp: ModelExpression<1> -> ModelExpression<1> ...
val P: name: IncludedParameter<'u> -> ModelExpression<'u>
val This<'u> : ModelExpression<'u>
val Constant: x: float<'u> -> ModelExpression<'u>
val hypothesis: ModelSystem.ModelSystem<Time.day>
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>
namespace Bristlecone.ModelLibrary
module Likelihood from Bristlecone.ModelLibrary
<summary>Likelihood functions to represent a variety of distributions and data types.</summary>
<namespacedoc><summary>Pre-built model parts for use in Bristlecone</summary></namespacedoc>
val sumOfSquares: keys: ModelSystem.LikelihoodRequirement list -> ModelSystem.Likelihood<'u>
<summary> Residual sum of squares. Provides a simple metric of distance between observed data and model predictions. </summary>
module Require from Bristlecone.Language
val state: s: StateId<'u> -> ModelSystem.LikelihoodRequirement
val compile: (ModelBuilder.ModelBuilder<'u> -> ModelSystem.ModelSystem<'u>)

Type something to start searching.