Skip to content

Commit

Permalink
[WIP] Update fsdocs and move tutorials into docs
Browse files Browse the repository at this point in the history
  • Loading branch information
AndrewIOM committed Apr 15, 2024
1 parent 465fb9b commit b5f70ae
Show file tree
Hide file tree
Showing 27 changed files with 1,222 additions and 974 deletions.
12 changes: 6 additions & 6 deletions .config/dotnet-tools.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
"paket"
]
},
"fsharp.formatting.commandtool": {
"version": "11.4.3",
"commands": [
"fsdocs"
]
},
"fantomas": {
"version": "6.3.1",
"commands": [
"fantomas"
]
},
"fsdocs-tool": {
"version": "20.0.0",
"commands": [
"fsdocs"
]
}
}
}
8 changes: 4 additions & 4 deletions build.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,9 @@ Target.create "DocsMeta" (fun _ ->
sprintf "<PackageIconUrl>%s/master/docs/content/logo.png</PackageIconUrl>" repositoryContentUrl
sprintf "<PackageTags>%s</PackageTags>" tags
sprintf "<Version>%s</Version>" release.NugetVersion
sprintf "<FsDocsLogoSource>%s/master/docs/img/logo.png</FsDocsLogoSource>" repositoryContentUrl
sprintf "<FsDocsLicenseLink>%s/blob/master/LICENSE.md</FsDocsLicenseLink>" repositoryUrl
sprintf "<FsDocsReleaseNotesLink>%s/blob/master/RELEASE_NOTES.md</FsDocsReleaseNotesLink>" repositoryUrl
sprintf "<FsDocsLogoSource>/img/logo.png</FsDocsLogoSource>"
sprintf "<FsDocsLicenseLink>%s/blob/master/LICENSE</FsDocsLicenseLink>" repositoryUrl
sprintf "<FsDocsReleaseNotesLink>%s/blob/master/RELEASE_NOTES.MD</FsDocsReleaseNotesLink>" repositoryUrl
"<FsDocsWarnOnMissingDocs>true</FsDocsWarnOnMissingDocs>"
"<FsDocsTheme>default</FsDocsTheme>"
"</PropertyGroup>"
Expand All @@ -169,7 +169,7 @@ Target.create "DocsMeta" (fun _ ->

Target.create "GenerateDocs" (fun _ ->
Fake.IO.Shell.cleanDir ".fsdocs"
DotNet.exec id "fsdocs" "build --clean" |> ignore
DotNet.exec id "fsdocs" "build --clean --eval --strict" |> ignore
)

// --------------------------------------------------------------------------------------
Expand Down
File renamed without changes.
Empty file added docs/_template.ipynb
Empty file.
30 changes: 15 additions & 15 deletions docs/confidence-intervals.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ index: 5
#r "../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
Expand All @@ -37,20 +37,20 @@ open Bristlecone
open Bristlecone.Optimisation
open Bristlecone.Data

// fitFn =
fun engine dataset hypothesis result ->
// // fitFn =
// fun engine dataset hypothesis result ->

// The function used to fit the model, which unless an
// advanced scenario is usually Bristlecone.fit
let fitFn = Bristlecone.fit
// // The function used to fit the model, which unless an
// // advanced scenario is usually Bristlecone.fit
// let fitFn = Bristlecone.fit

// The number of jumps to perform in parameter space
let n = 10000
// // The number of jumps to perform in parameter space
// let n = 10000

let ci = ConfidenceInterval.ProfileLikelihood.profile fitFn engine dataset hypothesis n result
// let ci = ConfidenceInterval.ProfileLikelihood.profile fitFn engine dataset hypothesis n result

// Optionally, save the result
let saveDir = "/some/save/dir"
let subjectName = "some subject"
let modelId = "some model hypothesis"
Confidence.save saveDir subjectName modelId result.ResultId ci
// // Optionally, save the result
// let saveDir = "/some/save/dir"
// let subjectName = "some subject"
// let modelId = "some model hypothesis"
// Confidence.save saveDir subjectName modelId result.ResultId ci
4 changes: 2 additions & 2 deletions docs/data.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ index: 1
#r "../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
Expand Down
4 changes: 2 additions & 2 deletions docs/dendro.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ index: 1
#r "../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
Expand Down
10 changes: 5 additions & 5 deletions docs/diagnostics.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ index: 5
#r "../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
Expand Down Expand Up @@ -69,9 +69,9 @@ of the `IComponentLogger<float>)` type:
[ NB TODO: This function must be refactored to work with the new Bristlecone Language ]
*)

open Bristlecone
open Bristlecone.Language
open Bristlecone.Diagnostics.ModelComponents
// open Bristlecone
// open Bristlecone.Language
// open Bristlecone.Diagnostics.ModelComponents

// let hypothesis (cLog:IComponentLogger<ModelExpression>) =

Expand Down
51 changes: 48 additions & 3 deletions docs/estimation-engine.fsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ index: 3
#r "../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{package-version}}"
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
Expand All @@ -31,4 +31,49 @@ will suffice for all model hypotheses.
Forthcoming
*)
*)


(**## Time Modes
Bristlecone can run models in either discrete time, or continuous time. When running models in continuous time, an integration function is required:
*)

(**
Currently only fixed timesteps are supported, but variable timestep support (e.g. for sediment core data) is planned.
Two integration functions are included:
| Solver | Function | Description |
| - | - | - |
| Runge-Kutta 4 (MathNet Numerics) | ``Integration.MathNet.integrate`` | A fourth-order Runge Kutta method to provide approximate solutions to ODE systems. |
| Runge-Kutta 547M (Open Solving Library for ODEs - Microsoft Research) | ``Integration.MsftOslo.integrate`` | A method based on classic Runge-Kutta, but with automatic error and step size control. [See the documentation](https://www.microsoft.com/en-us/research/wp-content/uploads/2014/07/osloUserGuide.pdf).|
## Optimisation
Bristlecone supports optimisation functions that have the following type signature:
```fsharp
type Optimise<'data> = int -> int -> Domain -> ('data[] -> 'data) -> ('data * 'data []) list
```
There are two optimsation techniques currently built-in:
| Method | Function | Description |
| - | - | - |
| Amoeba (Nelder-Mead) | ``Optimisation.Amoeba.solve`` | A gradient-descent method. |
| MCMC Random Walk | ``Optimisation.MonteCarlo.randomWalk`` | A method based on classic Runge-Kutta, but with automatic error and step size control. [See the documentation](https://www.microsoft.com/en-us/research/wp-content/uploads/2014/07/osloUserGuide.pdf).|
## Estimation Engines
To use Bristlecone functions requires a configured ``EstimationEngine``. The easiest way is with the helper functions within the ``Bristlecone`` module:
| Function | Type | Description |
| - | - | - |
| ``mkContinuous`` | EstimationEngine | Default continuous engine |
| ``mkDiscrete`` | EstimationEngine | Default discrete model engine |
| ``withContinuousTime`` | t : Integrate<'a,'b> -> engine: EstimationEngine<'a,'b> -> EstimationEngine<'a,'b> | Transforms engine to continuous time mode, using the given integrator function. |
| ``withConditioning`` | c: Conditioning -> engine: EstimationEngine<'a,'b> -> EstimationEngine<'a,'b> | Choose how the start point is chosen when solving the model system. |
**)
File renamed without changes.
173 changes: 173 additions & 0 deletions docs/examples/plant-temperature.fsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
(**
---
title: Plant response to temperature
category: Examples
categoryindex: 2
index: 1
---
*)

(*** condition: prepare ***)
#nowarn "211"
#r "../../src/Bristlecone/bin/Release/netstandard2.0/Bristlecone.dll"
#r "nuget: MathNet.Numerics.FSharp,5.0.0"
(*** condition: fsx ***)
#if FSX
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // FSX
(*** condition: ipynb ***)
#if IPYNB
#r "nuget: Bristlecone,{{fsdocs-package-version}}"
#endif // IPYNB

(**
# Growth of tree rings in response to temperature
This Bristlecone example demonstrates model-fitting
using high-resolution monthly temperature data with
annual ring width increments.
First, we must reference Bristlecone and open it:
*)
open Bristlecone // Opens Bristlecone core library and estimation engine
open Bristlecone.Language // Open the language for writing Bristlecone models
open Bristlecone.Time

(**
### Step 1. Defining the ecological model
Here, we
*)


// 1. Model System
// ----------------------------

let hypothesis =

/// The universal gas constant in J mol−1 K−1
let gasConstant = Constant 8.314

/// An Arrhenius function to represent temperature limitation on growth.
/// Form of equation: https://pubag.nal.usda.gov/download/13565/PDF
let temperatureLimitation =
Constant System.Math.E
** ((Constant 1000. * Parameter "Ea" * (Environment "temperature" - Constant 298.))
/ (Constant 298. * gasConstant * Environment "temperature"))

/// Plant growth is a function of net photosynthesis minus environmental losses.
/// Photosynthesis is limited by light and temperature.
let ``db/dt`` = This * Parameter "r" * temperatureLimitation - Parameter "γB" * This

Model.empty
|> Model.addEquation "stem radius" ``db/dt``
|> Model.estimateParameter "Ea" noConstraints 40.0 50.0
|> Model.estimateParameter "γB" noConstraints 0.01 0.40
|> Model.estimateParameter "r" notNegative 0.01 1.00
|> Model.useLikelihoodFunction (ModelLibrary.Likelihood.sumOfSquares [ "stem radius" ])
|> Model.compile


// 2. Setup Bristlecone Engine
// ----------------------------
// A bristlecone engine provides a fixed setup for estimating parameters from data.
// Use the same engine for all model fits within a single study.

let engine =
Bristlecone.mkContinuous
|> Bristlecone.withContinuousTime Integration.MathNet.integrate
|> Bristlecone.withConditioning Conditioning.RepeatFirstDataPoint
|> Bristlecone.withTunedMCMC
[ Optimisation.MonteCarlo.TuneMethod.CovarianceWithScale 0.200,
250,
Optimisation.EndConditions.afterIteration 20000 ]


// 3. Test Engine and Model
// ----------------------------
// Running a full test is strongly recommended. The test will demonstrate if the current
// configuration can find known parameters for a model. If this step fails, there is an
// issue with either your model, or the Bristlecone configuration.

// 0. Configure Options
// ----------------------------

module Settings =

/// Bristlecone can use latitude and longitude to compute day length.
let latitude, longitude = 63.2, 15.2
let endWhen = Optimisation.EndConditions.afterIteration 1


// let startValues =
// [ ShortCode.create "lynx", 30.09; ShortCode.create "hare", 19.58 ] |> Map.ofList

// // TODO Test settings new format

// hypothesis
// |> Bristlecone.testModel engine Options.testSeriesLength startValues Options.iterations []


// // 4. Load Real Data
// // ----------------------------
// // Here, we are using the FSharp.Data type provider to read in .csv datasets.
// // We prepare the monthly temperature dataset for the analysis by:
// // a) Loading the daily dataset using the FSharp.Data library;
// // b) Replacing NaN values with the F# 'None' option type;
// // c) Converting the dataset into a Bristlecone time series type;
// // d) Interpolate the 'None' values by linear interpolation to fill in missing measurements;
// // e) Generalise the time series from daily to monthly by applying an average function.

// open FSharp.Data

// // TODO Is there a way to streamline this?
// [<Literal>]
// let DailyTemperatureUrl = __SOURCE_DIRECTORY__ + "/data/mean-temperature-daily.csv"

// let meanTemperatureMonthly =
// let maxTemperatures = CsvProvider<DailyTemperatureUrl>.Load DailyTemperatureUrl

// maxTemperatures.Rows
// |> Seq.map (fun r ->
// ((if System.Double.IsNaN r.``T[avg]`` then
// None
// else
// Some(r.``T[avg]`` + 273.15)),
// r.Date))
// |> TimeSeries.fromObservations
// |> TimeSeries.interpolate
// |> TimeSeries.generalise (FixedTemporalResolution.Months(PositiveInt.create 1)) (fun x -> x |> Seq.averageBy fst)


// module Test =

// open Bristlecone.Test

// let settings = TestSettings.Default

// let testSettings =
// { Resolution = Years 1
// TimeSeriesLength = 30
// StartValues = [ code "b", 5.; code "t", 255. ] |> Map.ofList
// EndCondition = Settings.endWhen
// GenerationRules =
// [ "b" |> GenerationRules.alwaysLessThan 1000000.
// "b" |> GenerationRules.alwaysMoreThan 0.
// code "b", (fun data -> (data |> Seq.max) - (data |> Seq.min) > 100.) ]
// NoiseGeneration = fun p data -> data
// EnvironmentalData = [ code "t", TemperatureData.monthly ] |> Map.ofList
// Random = MathNet.Numerics.Random.MersenneTwister()
// StartDate = System.DateTime(1970, 01, 01)
// Attempts = 50000 }

// let run () =
// hypothesis |> Bristlecone.testModel Settings.engine testSettings


// let testResult = Test.run ()

// // 4. Fit Model to Real Data
// // -----------------------------------
// let result =
// hypothesis
// |> Bristlecone.fit engine (Optimisation.EndConditions.afterIteration Options.iterations) data
Loading

0 comments on commit b5f70ae

Please sign in to comment.