Skip to content

Commit 1b7c1f7

Browse files
committed
revised docs after v0.3 release
1 parent 3955e56 commit 1b7c1f7

10 files changed

+116
-83
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
11
# Changelog for `CriticalTransitions.jl`
22

3+
## v0.3.0
4+
Major overhaul introducing `CoupledSDEs`
5+
6+
This release replaces the `StochSystem` struct with the new `CoupledSDEs` struct to define a stochastic dynamical system. To see how the new version works, check out the [documentation](https://juliadynamics.github.io/CriticalTransitions.jl/dev/).
7+
8+
The update is a breaking change for almost all functions, because the interface is now built around `CoupledSDEs`. The benefit is that the package now integrates much more seamlessly with DynamicalSystems.jl and DifferentialEquations.jl. To use the package with the old `StochSystem` struct, choose version v0.2.1 or lower.
9+
10+
Full changelog [here](https://github.com/JuliaDynamics/CriticalTransitions.jl/compare/v0.2.1...v0.3.0)
11+
312
## v0.2.1
413
Freeze before major overhaul `v0.3.0`
514

docs/pages.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ pages = [
44
"Quickstart" => "quickstart.md",
55
"Tutorial" => "tutorial.md",
66
"Manual" => Any[
7-
"Define a CoupledSDE" => "man/CoupledSDEs.md",
7+
"Define a CoupledSDEs system" => "man/CoupledSDEs.md",
88
"Stability analysis" => "man/systemanalysis.md",
99
"Simulating the system" => "man/simulation.md",
1010
"Sampling transitions" => "man/sampling.md",

docs/src/figs/CTjl_structure_v0.3.jpg

370 KB
Loading
273 KB
Loading

docs/src/index.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
Building on [DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSystems.jl/stable/) and [DifferentialEquations.jl](https://diffeq.sciml.ai/stable/), this package aims to provide a toolbox for dynamical systems under time-dependent forcing, with a focus on tipping phenomena and metastability.
66

7-
![CT.jl infographic](./figs/CTjl_structure.png)
7+
![CT.jl infographic](./figs/CTjl_structure_v0.3_small.jpeg)
88

99
!!! info "Current features"
1010
* **Stability analysis**: Fixed points, linear stability, basins of attraction, edge tracking
@@ -16,6 +16,7 @@ Building on [DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSyste
1616
* **Rare event simulation**: importance sampling, AMS
1717
* **Quasipotentials**: Ordered line integral method (OLIM)
1818
* **Rate-induced tipping** tools
19+
* **Symbolic** differentiation of action functionals
1920
* ...?
2021

2122

docs/src/man/CoupledSDEs.md

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,39 @@
1-
# Define a CoupledSDE
1+
# Define a CoupledSDEs system
22

33
A `CoupledSDEs` defines a stochastic dynamical system of the form
44

55
```math
6-
\text{d}\vec x = f(\vec x(t); \ p) \text{d}t + g(\vec x(t); \ p) \text{d}\mathcal{W} \ ,
6+
\text{d}\vec x = f(\vec x(t); \ p) \text{d}t + \sigma (\vec x(t); \ p) \, \text{d}\mathcal{W} \ ,
77
```
8-
where $\text{d}\mathcal{W}=\Gamma \cdot \text{d}\mathcal{N}$, $\vec x \in \mathbb{R}^\text{dim}$ and $\mathcal N$ denotes a stochastic process. The (positive definite) noise covariance matrix is $\Sigma = \Gamma \Gamma^\top \in \mathbb R^{N\times N}$.
8+
where $\vec x \in \mathbb{R}^\text{D}$, $\sigma > 0$ is the noise strength, $\text{d}\mathcal{W}=\Gamma \cdot \text{d}\mathcal{N}$, and $\mathcal N$ denotes a stochastic process. The (positive definite) noise covariance matrix is $\Sigma = \Gamma \Gamma^\top \in \mathbb R^{N\times N}$.
99

10-
The function $f$ is the deterministic part of the system and is assumed to be of similar form as is accepted in [DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSystems.jl/latest/tutorial/), i.e., `f(u, p, t)` for out-of-place (oop) and `f(du, u, p, t)` for in-place (iip).
10+
The function $f$ is the deterministic part of the system and follows the syntax of a `ContinuousTimeDynamicalSystem` in [DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSystems.jl/latest/tutorial/), i.e., `f(u, p, t)` for out-of-place (oop) and `f!(du, u, p, t)` for in-place (iip). The function $g$ allows to specify the stochastic dynamics of the system along with the [noise process](#noise-process) $\mathcal{W}$. It should be of the same type (iip or oop) as $f$.
1111

12-
The function $g$ represent the stochastics dynamics of the system and should be the of the same type (iip or oop) as $f$.
13-
14-
The keyword `noise` defines the system [noise process](#noise-process). In combination with `g` one can define different type of stochastic systems. Examples of different type of stochastics systems can be found on the [StochasticDiffEq.jl tutorial page](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/sde_example/). A quick overview of the different types of stochastic systems can be found [here](#Type-of-stochastic-system).
12+
By combining $\sigma$, $g$ and $\mathcal{W}$, you can define different type of stochastic systems. Examples of different types of stochastic systems can be found on the [StochasticDiffEq.jl tutorial page](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/sde_example/). A quick overview of common types of stochastic systems can be found [below](#Type-of-stochastic-system).
1513

1614
!!! info
17-
Note that nonlinear mixings of the Noise Process $\mathcal{W}$ are not Stochasitic Differential Equations but are a different class of differential equations of random ordinary differential equations (RODEs) which have a separate set of solvers. See [this example](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/rode_example/) of DifferentialEquations.jl.
18-
19-
15+
Note that nonlinear mixings of the Noise Process $\mathcal{W}$ fall into the class of random ordinary differential equations (RODEs) which have a separate set of solvers. See [this example](https://docs.sciml.ai/DiffEqDocs/stable/tutorials/rode_example/) of DifferentialEquations.jl.
2016

2117
```@docs
2218
CoupledSDEs
2319
```
24-
## Type of stochastic system
25-
Let us make some examples of the different types of stochastic systems that can be defined.
20+
21+
## Defining stochastic dynamics
22+
Let's look at some examples of the different types of stochastic systems that can be defined.
23+
24+
For simplicity, we choose a slow exponential growth in 2 dimensions as the deterministic dynamics `f`:
2625
```@example type
2726
using CriticalTransitions, Plots
2827
import Random # hide
2928
Random.seed!(10) # hide
30-
f!(du, u, p, t) = du .= 1.01u
31-
σ = 0.25
29+
f!(du, u, p, t) = du .= 1.01u # deterministic part
30+
σ = 0.25 # noise strength
3231
```
3332
### Additive noise
34-
When `g` is independent of the state variables `u`, the noise is called additive.
33+
When `g \, \text{d}\mathcal{W}` is independent of the state variables `u`, the noise is called additive.
3534

3635
#### Diagonal noise
37-
A system of diagional noise is the most common type of noise. It is defined by a vector of random numbers `dW` whose size matches the output of `g` where the noise is applied element-wise, i.e. `g.*dW`.
36+
A system of diagonal noise is the most common type of noise. It is defined by a vector of random numbers `dW` whose size matches the output of `g` where the noise is applied element-wise, i.e. `g.*dW`.
3837
```@example type
3938
t0 = 0.0; W0 = zeros(2);
4039
W = WienerProcess(t0, W0, 0.0)
@@ -100,9 +99,9 @@ plot(sol)
10099
```
101100

102101
!!! warning
103-
Non-diagonal problem need specific type of solvers. See the [SciML recommendations](https://docs.sciml.ai/DiffEqDocs/stable/solvers/sde_solve/#sde_solve).
102+
Non-diagonal problems need specific type of solvers. See the [SciML recommendations](https://docs.sciml.ai/DiffEqDocs/stable/solvers/sde_solve/#sde_solve).
104103

105-
### Corelated noise
104+
### Correlated noise
106105
```@example type
107106
ρ = 0.3
108107
Σ = [1 ρ; ρ 1]
@@ -113,11 +112,53 @@ sol = simulate(sde, 1.0, dt=0.01, alg=SOSRA())
113112
plot(sol)
114113
```
115114

116-
## Noise process
117-
We provide the noise processes $\text{d}\mathcal{W}$ that can be used in the stochastic simulations through the [DiffEqNoiseProcess.jl](https://docs.sciml.ai/DiffEqNoiseProcess/stable) package. A complete list of the available processes can be found [here](https://docs.sciml.ai/DiffEqNoiseProcess/stable/noise_processes/). We list some of the most common ones below:
115+
## Available noise processes
116+
We provide the noise processes $\mathcal{W}$ that can be used in the stochastic simulations through the [DiffEqNoiseProcess.jl](https://docs.sciml.ai/DiffEqNoiseProcess/stable) package. A complete list of the available processes can be found [here](https://docs.sciml.ai/DiffEqNoiseProcess/stable/noise_processes/). We list some of the most common ones below:
118117
```@docs
119118
WienerProcess
120119
SimpleWienerProcess
121120
OrnsteinUhlenbeckProcess
122121
CorrelatedWienerProcess
122+
```
123+
124+
## Interface to `DynamicalSystems.jl`
125+
126+
!!! tip "Analyzing deterministic dynamics with DynamicalSystems.jl"
127+
The deterministic part of a [`CoupledSDEs`](@ref) system can easily be extracted as a
128+
[`CoupledODEs`](https://juliadynamics.github.io/DynamicalSystems.jl/dev/tutorial/#DynamicalSystemsBase.CoupledODEs), a common subtype of a `ContinuousTimeDynamicalSystem` in DynamicalSystems.jl.
129+
130+
131+
-
132+
type of `DynamicalSystems.jl` using the function [`CoupledODEs`](@ref). Vice vera,
133+
a `CoupledODEs` system can be converted into a `CoupledSDEs` via `CoupledSDEs(ds::CoupledODEs, g)` with g the noise function.
134+
135+
#### Converting between `CoupledSDEs` and `CoupledODEs`
136+
137+
- `CoupledODEs(sde::CoupledSDEs)` extracts the deterministic part of `sde` as a `CoupledODEs`
138+
- `CoupledSDEs(ode::CoupledODEs, g)`, with `g` the noise function, turns `ode` into a `CoupledSDEs`
139+
140+
For example, the
141+
Lyapunov spectrum of a `CoupledSDEs` in the absence of noise, here exemplified by the
142+
FitzHugh-Nagumo model, can be computed by typing:
143+
144+
```@example type
145+
using CriticalTransitions
146+
using DynamicalSystems: lyapunovspectrum
147+
148+
function fitzhugh_nagumo(u, p, t)
149+
x, y = u
150+
ϵ, β, α, γ, κ, I = p
151+
152+
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
153+
dy = -β * y + x
154+
155+
return SA[dx, dy]
156+
end
157+
158+
sys = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), [1.,3.,1.,1.,1.,0.], 0.1)
159+
ls = lyapunovspectrum(CoupledODEs(sys), 10000)
160+
```
161+
162+
```@docs
163+
CoupledODEs
123164
```

docs/src/man/utils.md

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,4 @@
1-
# Convenience functions and types
2-
3-
## Interface to `DynamicalSystems.jl`
4-
5-
!!! tip "Using the functionality of DynamicalSystems.jl"
6-
A [`CoupledSDEs`](@ref) can easily be turned into a
7-
[`CoupledODEs`](https://juliadynamics.github.io/DynamicalSystems.jl/dev/tutorial/#DynamicalSystemsBase.CoupledODEs)
8-
instance of `DynamicalSystems.jl` using the function [`CoupledODEs`](@ref). Vice vera,
9-
a `CoupledODEs` system can be converted into a `CoupledSDEs` via `CoupledSDEs(ds::CoupledODEs, g)` with g the noise function.
10-
11-
This way, many of the methods in `DynamicalSystems.jl` can be used directly, even if we have
12-
not written an analogue method that takes `CoupledSDEs` as input. For example, the
13-
Lyapunov spectrum of a `CoupledSDEs`, here exemplified by the FitzHugh-Nagumo model, can be
14-
computed by typing:
15-
16-
```julia
17-
using CriticalTransitions
18-
using DynamicalSystems: lyapunovspectrum
19-
20-
function fitzhugh_nagumo(u, p, t)
21-
x, y = u
22-
ϵ, β, α, γ, κ, I = p
23-
24-
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
25-
dy = -β * y + x
26-
27-
return SA[dx, dy]
28-
end
29-
30-
sys = CoupledSDEs(fitzhugh_nagumo, id_func, zeros(2), σ, [1.,3.,1.,1.,1.,0.])
31-
ls = lyapunovspectrum(CoupledODEs(sys), 10000)
32-
```
33-
34-
```@docs
35-
CoupledODEs(sys::CoupledSDEs; diffeq, t0=0.0)
36-
```
1+
# Utility functions
372

383
## `CoupledSDEs` utility functions
394

@@ -56,4 +21,4 @@ make_h5(text::String, relpath::String="")
5621

5722
```@docs
5823
intervals_to_box(bmin::Vector, bmax::Vector)
59-
```
24+
```

docs/src/quickstart.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,11 @@ As this module is not published yet, there are two ways to access it:
1414
## Basic usage
1515
The general workflow of `CriticalTransitions` essentially follows two steps:
1616

17-
1. Define your system (see [Define a CoupledSDE](@ref))
17+
1. Define your system (see [Define a CoupledSDEs system](@ref))
1818
2. Investigate the system by calling methods (see [Methods](@ref))
1919

20-
!!! info "Extension to RateSystem and TippingSystem"
21-
We are currently working on extending the types of dynamical systems that can be studied with CriticalTransitions.jl. Particularly, we are planning to introduce the overarching structure `TippingSystem`, which has two subtypes: `CoupledSDEs` (as it already exists) and `RateSystem`, a new dynamical system type in which the system parameters may evolve in time.
20+
!!! info "New system type: RateSystem"
21+
We are planning to introduce the the struct `RateSystem` along `CoupledSDEs`. In a `RateSystem`, the time dependence of parameters can conveniently be specified, laying the foundation for a toolbox to study rate-induced tipping, or R-tipping.
2222

2323
## Methods
2424

docs/src/tutorial.md

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
To give you an idea of how our package works, this tutorial provides some example code with explanations.
44

55
## Example: FitzHugh-Nagumo model
6-
Consider the FitzHugh-Nagumo model,
6+
Let's consider a simple 2-dimensional dynamical system - the *FitzHugh-Nagumo* model:
77

88
```math
99
\begin{aligned}
@@ -19,7 +19,7 @@ Let's investigate this system under stochastic forcing.
1919
### System definition
2020
First, we need to translate the system equations above into Julia code.
2121

22-
This works by defining a function `f(u,p,t)` which takes as input a vector `u` of state variables (``u``,``v``), a vector `p` of parameters, and time `t`. The function must return an array of flow increments ($\text{d}u$, $\text{d}v$). For performance reasons, it is advisable to return a StaticArray `SA[du, dv]` rather than just a Vector `[du, dv]`. This is why we need the `StaticArrays` package.
22+
This works exactly as in [DynamicalSystems.jl](https://juliadynamics.github.io/DynamicalSystemsBase.jl/dev/) by defining a function `f(u,p,t)` which takes as input a vector `u` of state variables (``u``,``v``), a vector `p` of parameters, and time `t`. The function must return an array of flow increments ($\text{d}u$, $\text{d}v$). For performance reasons, it is advisable to return a StaticArray `SA[du, dv]` rather than just a Vector `[du, dv]`.
2323

2424
```@example MAIN
2525
using CriticalTransitions
@@ -37,14 +37,12 @@ function fitzhugh_nagumo(u,p,t)
3737
end
3838
```
3939

40-
Note that the system parameters `ϵ, β, α, γ, κ, I = p[1]` are unpacked as the first component of `p`. This is necessary because in CriticalTransitions.jl one can also define a separate set of parameters for the stochastic component of the system, which would then make up the second component `p[2]` ( see [Define a CoupledSDE](@ref)).
41-
4240
!!! tip "In-place vs. out-of-place"
4341
The function `fitzhugh_nagumo(u,p,t)` is defined *out-of-place*. It is also possible to define the system *in-place* as `fitzhugh_nagumo!(du,u,p,t)`. For more info, see [here](https://diffeq.sciml.ai/stable/types/ode_types/).
4442

4543
### CoupledSDE
4644

47-
Next, we turn the `fitzhugh_nagumo` system into a stochastic dynamical system. Suppose we would like to force both state variables ``u`` and ``v`` with additive, uncorrelated Gaussian noise of intensity ``\sigma``. This is the default case. We simply write
45+
Next, we construct a stochastic system with the `fitzhugh_nagumo` equation as the deterministic part. Suppose we would like to force both state variables ``u`` and ``v`` with additive, uncorrelated Gaussian noise of intensity ``\sigma``. This is the default case. We simply write
4846

4947
```@example MAIN
5048
p = [1., 3., 1., 1., 1., 0.] # Parameters (ϵ, β, α, γ, κ, I)
@@ -53,15 +51,15 @@ p = [1., 3., 1., 1., 1., 0.] # Parameters (ϵ, β, α, γ, κ, I)
5351
# CoupledSDE
5452
sys = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), p, σ)
5553
```
56-
Here we have chosen `zeros(2)` as the initial state of the system. The length of this vector must correspond to the system's dimensionality, but for now the state is just a placeholder that aligns our syntax with that of DifferentialEquations.jl and DynamicalSystems.jl.
54+
Here the first field `fitzhugh_nagumo` specifies the deterministic dynamics `f` (see [Define a CoupledSDEs system](@ref)), and the second field `idfunc` specifies the noise function `g`. The `idfunc` identity function is predefined for convenience. We have chosen `zeros(2)` as the initial state of the system, which is the third field. The length of this vector must match the system's dimensionality. In the fourth field, we specify the parameter vector, which includes the parameters of `f` followed by the parameters of `g` (in this case, there are no parameters for `g`). Lastly, `σ` sets the noise strength. Since we have not specified a noise process, the default case of an uncorrelated Wiener process is used.
5755

5856
!!! note "Multiplicative and/or correlated noise"
59-
Of course, it is also possible to define more complicated noise processes than simple additive white noise. This is done by specifying a custom *noise function* and *covariance matrix* in the `CoupledSDEs` definition. For more info, see [Define a CoupledSDE](@ref).
57+
Of course, it is also possible to define more complicated noise processes than simple additive white noise. This is done by specifying a custom *noise function* and *covariance matrix* in the `CoupledSDEs` definition. For more info, see [Define a CoupledSDEs system](@ref).
6058

61-
That's it! Now we can throw the toolbox of `CriticalTransitions` at our stochastic FitzHugh-Nagumo system `sys`.
59+
That's it! Now we can apply the toolbox of `CriticalTransitions` to our stochastic FitzHugh-Nagumo system `sys`.
6260

6361
### Find stable equilibria
64-
For the parameters chosen above, the FitzHugh-Nagumo system is bistable. Let's compute the fixed points using the [`fixedpoints`](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/chaostools/stable/periodicity/#ChaosTools.fixedpoints) function from ChaosTools.jl. As this function is from the `DynamicalSystems` ecosystem, it takes a system of type `CoupledODEs` as input. We can simply convert the CoupledSDEs `sys` via the [`CoupledODEs`](@ref) function:
62+
For the parameters chosen above, the FitzHugh-Nagumo system is bistable. Let's compute the fixed points using the [`fixedpoints`](https://juliadynamics.github.io/CriticalTransitions.jl/dev/man/systemanalysis/#ChaosTools.fixedpoints) function. This function is borrowed from ChaosTools.jl and is loaded as an extension when we write `using ChaosTools`.
6563

6664
```@example MAIN
6765
using ChaosTools
@@ -74,21 +72,21 @@ fp1, fp2 = eqs[stab]
7472
```
7573

7674
### Stochastic simulation
77-
Using the `simulate` function, we now run a simulation of our system starting out from the fixed point `fp1`:
75+
Using the [`simulate`](@ref) function, we now run a simulation of our system for `1e3` time units starting out from the fixed point `fp1`:
7876

7977
```@example MAIN
80-
sim = simulate(sys, 1e3, fp1, saveat=0.1)
78+
sim = simulate(sys, 1e3, fp1; saveat=0.1)
8179
```
8280

83-
In the keyword arguments, we have specified the time step `dt` and total duration `tmax` of the numerical time integration.
81+
In the keyword arguments, we have specified at which interval the solution is saved. Further keyword arguments can be used to change the solver (the default is `SOSRA()` for stochastic integration) and other settings.
8482

85-
The simulated trajectory is stored in `sim` as a matrix with 2 rows corresponding to the state variables ``u``, ``v``, and 10,000 columns corresponding to the time steps.
83+
The simulated trajectory is stored in `sim` in the usual output format of the [`solve`](https://docs.sciml.ai/DiffEqDocs/stable/basics/common_solver_opts/#CommonSolve.solve-Tuple%7BSciMLBase.AbstractDEProblem,%20Vararg%7BAny%7D%7D) method of DifferentialEquations.jl, including the solution `sim.u` and the vector of time points `sim.t`. The solution can also be accessed as a matrix `sim[i, t]`, where `i` is the `i`-th component of `u` and `t` the time index.
8684

8785
Let's plot the result. Did the trajectory transition to the other attractor?
8886

8987
```@example MAIN
9088
using Plots
91-
plt = plot(sim[1, :], sim[2, :], xlabel="u", ylabel="v", legend=false)
89+
plt = plot(sim[1, :], sim[2, :]; xlabel="u", ylabel="v", legend=false)
9290
scatter!([fp1[1], fp2[1]], [fp1[2], fp2[2]], color=:red, markersize=4)
9391
xlims!(-1.2, 1.2)
9492
ylims!(-0.6, 0.6)

0 commit comments

Comments
 (0)