Skip to content

add coupledSDEs type #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 42 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
30d0970
add coupledSDEs type
oameye Jul 24, 2024
a11ba2c
add CoupledSDEs docs
oameye Jul 28, 2024
62c5e7e
apply suggested format changes
oameye Jul 28, 2024
89225a4
add idfunc
oameye Jul 28, 2024
f169386
Fix docs?
oameye Jul 28, 2024
43ad5e9
change coupled sde example to use trajectory
oameye Jul 28, 2024
8de87b8
specify which CoupledODEs docstring
oameye Jul 28, 2024
023ff0c
change to SciML default tolerances
oameye Jul 28, 2024
f6a400e
classify noise
oameye Jul 29, 2024
5c5e6dc
correct spelling of invertible
oameye Jul 29, 2024
ce7a03e
make noisetype field a namedtuple
oameye Jul 30, 2024
573f18f
Merge branch 'main' into CoupledSDEs
Datseris Jul 31, 2024
fba7327
make coupledSDEs an extention
oameye Jul 31, 2024
e01bce6
Merge branch 'CoupledSDEs' of https://github.com/oameye/DynamicalSyst…
oameye Jul 31, 2024
c875b5e
export pretty print
oameye Jul 31, 2024
b3ccb26
export CoupledODEs
oameye Jul 31, 2024
b08fd7c
add CoupledODEs <-> CoupledSDEs tests
oameye Aug 1, 2024
dfc3053
add extention to modules in makedocs
oameye Aug 1, 2024
daca4a7
define dynamics rule sde specific
oameye Aug 1, 2024
73af990
port docs into the docstring
Datseris Aug 1, 2024
92e3369
delete ported documentation
Datseris Aug 1, 2024
548130d
fix small typos in docstring
oameye Aug 1, 2024
1a0c884
add CoupledSDEs examples to docs
oameye Aug 1, 2024
413a25a
remove noise strength
oameye Aug 3, 2024
381820f
update docs with no noise strength
oameye Aug 4, 2024
cb956e8
add covariance kwarg and change g to kwarg
oameye Aug 5, 2024
17cf5cb
update docs
oameye Aug 5, 2024
ba148d9
diffusion <-> covariance matrix
oameye Aug 7, 2024
eb8544b
add noise_strength kwarg
oameye Aug 7, 2024
e28b4dd
estimate invertiability with a tolerance
oameye Aug 7, 2024
39057fb
move to SOSRA with non-adaptive timesteps
oameye Sep 10, 2024
400ac12
Merge branch 'main' into CoupledSDEs
oameye Sep 20, 2024
41c900b
Reyk's comments
oameye Sep 23, 2024
e5bc61a
implemented review comments - part 1
reykboerner Sep 24, 2024
f907929
revised CoupledSDEs docstring
reykboerner Sep 26, 2024
75996be
remove broken docs link
reykboerner Sep 26, 2024
7189029
implemented review comments - part 2
reykboerner Sep 26, 2024
109e7b4
proofread and revised CoupledSDEs docs
reykboerner Sep 26, 2024
5df534a
fixed bug that made tests fail
reykboerner Sep 26, 2024
78f25ee
Update CHANGELOG.md
Datseris Sep 30, 2024
9368e7d
Merge branch 'main' into CoupledSDEs
Datseris Sep 30, 2024
de8258e
Update Project.toml
Datseris Sep 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ deps/build.log
Manifest.toml
*style.jl
*.scss
*.css
*.css
.vscode
7 changes: 7 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,12 @@ Roots = "1, 2"
SciMLBase = "1.19.5, 2"
StateSpaceSets = "1"
Statistics = "1"
StochasticDiffEq = "6.66.0"
SymbolicIndexingInterface = "0.3.4"
julia = "1.9"

[weakdeps]
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"

[extensions]
StochasticSystemsBase = "StochasticDiffEq"
2 changes: 2 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
[deps]
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
DiffEqNoiseProcess = "77a26b50-5914-5dd7-bc55-306e6241c503"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8"
DynamicalSystemsBase = "6e36e845-645a-534a-86f2-f5d4aa5a06b4"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StateSpaceSets = "40b095a5-5852-4c12-98c7-d43bf788e795"
StochasticDiffEq = "789caeaf-c7a9-5a7d-9973-96adeb23e2a0"
51 changes: 35 additions & 16 deletions docs/juliadynamics-dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ $code-background: $codebg; // for inline code
$pre-background: $codebg; // for code blocks
$documenter-docstring-header-background: lighten-color($body-background-color, 0.5);


// Sidebar
$documenter-sidebar-background: darken-color($maincolor, 1.2); //background color for sidebar
$documenter-sidebar-color: $text; //font color for sidebar
Expand All @@ -86,22 +87,8 @@ $input-focus-border-color: $mainwhite;

$documenter-docstring-shadow: 3px 3px 4px invert($shadow-color);



// Admonition stuff
$admbg: lighten-color($body-background-color, 0.5);
$admonition-background: (
'default': $admbg, 'info': $admbg, 'success': $admbg, 'warning': $admbg,
'danger': $admbg, 'compat': $admbg
);
$admonition-header-background: (
'default': #ba3f1f, 'warning': #a88b17, 'danger': #c7524c,
'success': #42ac68, 'info': #28c);

// Deprecations
$admonition-body-color: null;
$admonition-body-color: null;
$admonition-header-color: null;
// This line is required after https://github.com/JuliaDocs/Documenter.jl/pull/2499
$admonition-default: $darkbg;

// All secondary themes have to be nested in a theme--$(themename) class. When Documenter
// switches themes, it applies this class to <html> and then disables the primary
Expand Down Expand Up @@ -157,4 +144,36 @@ html.theme--#{$themename} {
.hljs-subst {
color: #f8f8f2;
}



// fix for the settings/modal panel
.modal-card-head {
background-color: darken($darkbg,5);
}
.modal-card-body {
background-color: darken($darkbg,5);
}
.modal-card-foot {
background-color: darken($darkbg,5);
}
.select {
> select {
background-color: darken($darkbg,5);
}
}

// fix for the search panel
.input {
background-color: darken($darkbg,5);
}
.search-result-title {
color: white
}

// match the size of the light theme (additional rule
// that is dark-theme specific and messing around
// with the size of elements, making the size be 0,75em
// only for the dark theme, no idea why)
font-size: unset !important;
}
51 changes: 35 additions & 16 deletions docs/juliadynamics-darkdefs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ $code-background: $codebg; // for inline code
$pre-background: $codebg; // for code blocks
$documenter-docstring-header-background: lighten-color($body-background-color, 0.5);


// Sidebar
$documenter-sidebar-background: darken-color($maincolor, 1.2); //background color for sidebar
$documenter-sidebar-color: $text; //font color for sidebar
Expand All @@ -40,22 +41,8 @@ $input-focus-border-color: $mainwhite;

$documenter-docstring-shadow: 3px 3px 4px invert($shadow-color);



// Admonition stuff
$admbg: lighten-color($body-background-color, 0.5);
$admonition-background: (
'default': $admbg, 'info': $admbg, 'success': $admbg, 'warning': $admbg,
'danger': $admbg, 'compat': $admbg
);
$admonition-header-background: (
'default': #ba3f1f, 'warning': #a88b17, 'danger': #c7524c,
'success': #42ac68, 'info': #28c);

// Deprecations
$admonition-body-color: null;
$admonition-body-color: null;
$admonition-header-color: null;
// This line is required after https://github.com/JuliaDocs/Documenter.jl/pull/2499
$admonition-default: $darkbg;

// All secondary themes have to be nested in a theme--$(themename) class. When Documenter
// switches themes, it applies this class to <html> and then disables the primary
Expand Down Expand Up @@ -111,4 +98,36 @@ html.theme--#{$themename} {
.hljs-subst {
color: #f8f8f2;
}



// fix for the settings/modal panel
.modal-card-head {
background-color: darken($darkbg,5);
}
.modal-card-body {
background-color: darken($darkbg,5);
}
.modal-card-foot {
background-color: darken($darkbg,5);
}
.select {
> select {
background-color: darken($darkbg,5);
}
}

// fix for the search panel
.input {
background-color: darken($darkbg,5);
}
.search-result-title {
color: white
}

// match the size of the light theme (additional rule
// that is dark-theme specific and messing around
// with the size of elements, making the size be 0,75em
// only for the dark theme, no idea why)
font-size: unset !important;
}
6 changes: 5 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
cd(@__DIR__)

using DynamicalSystemsBase
using StochasticDiffEq, DiffEqNoiseProcess # to enable extention
# We need this because Documenter doesn't know where to get the docstring from otherwise
StochasticSystemsBase = Base.get_extension(DynamicalSystemsBase, :StochasticSystemsBase)

pages = [
"index.md",
"CoupledSDEs.md",
]
using DynamicalSystemsBase.SciMLBase

Expand All @@ -15,5 +19,5 @@ Downloads.download(
include("build_docs_with_style.jl")

build_docs_with_style(pages,
DynamicalSystemsBase, SciMLBase, StateSpaceSets;
DynamicalSystemsBase, SciMLBase, StateSpaceSets, StochasticSystemsBase;
)
106 changes: 106 additions & 0 deletions docs/src/CoupledSDEs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# `CoupledSDEs`

```@docs
CoupledSDEs
```

## [Examples defining stochastic dynamics](@id defining-stochastic-dynamics)

Let's look at some examples of the different types of stochastic systems that can be defined.

For simplicity, we choose a slow exponential growth in 2 dimensions as the deterministic dynamics `f`:
```@example type
using DynamicalSystemsBase, StochasticDiffEq, DiffEqNoiseProcess
using CairoMakie
import Random # hide
Random.seed!(10) # hide
f!(du, u, p, t) = du .= 1.01u # deterministic part

function plot_trajectory(Y, t)
fig = Figure()
ax = Axis(fig[1,1]; xlabel = "time", ylabel = "variable")
for var in columns(Y)
lines!(ax, t, var)
end
fig
end;
```

### Additive noise
When $g$ is independent of the state variables $u$, the noise is called additive, otherwise it is called multiplicative. The ladder is somewhat misleading, as it has come to signify the general case, despite seeming to suggest the limited case where $g(x) \propto x$. We can define a simple additive noise system as follows:
```@example type
sde = CoupledSDEs(f!, zeros(2));
```
which is equivalent to
```@example type
t0 = 0.0; W0 = zeros(2);
W = WienerProcess(t0, W0, 0.0)
sde = CoupledSDEs(f!, zeros(2); noise_process=W);
```
We defined a vector of random numbers `dW`, whose size matches the output of `g`, with the noise applied element-wise, i.e., `g.*dW`. Specifically, `dW` is a vector of Gaussian noise processes whose size matches the output of `g`. The noise is applied element-wise, i.e., `g.*dW`. By default, the noise processes are uncorrelated, meaning the covariance matrix is diagonal. This type of noise is referred to as diagonal. The vector `dW` is by default zero mean white gaussian noise $\mathcal{N}(0, \text{d}t)$ where the variance is the timestep $\text{d}t$ unit variance (Wiener Process). We can sample a trajectory from this system using the `trajectory` also used for the deterministic systems:
```@example type
tr = trajectory(sde, 1.0)
plot_trajectory(tr...)
```

#### Correlated noise
Correlated noise is where the random number generated in `dW` are correlated. This can be done by specifying the covariance matrix $\Sigma$ to the `covariance` keyword:
```@example type
ρ = 0.3
Σ = [1 ρ; ρ 1]
diffeq = (alg = LambaEM(), dt=0.1)
sde = CoupledSDEs(f!, zeros(2); covariance=Σ, diffeq=diffeq)
```
Alternativly, we can parametrise the covariance matrix by defining the diffusion function $g$ ourselves:
```@example type
g!(du, u, p, t) = (du .= [1 p[1]; p[1] 1]; return nothing)
sde = CoupledSDEs(f!, zeros(2), (ρ); g=g!, noise_prototype=zeros(2, 2))
```
Here, we had to provide a `noise_prototype` to indicate that the diffusion function `g` will output a 2x2 matrix.

#### Scalar noise
Scalar noise is where a single random variable is applied to all dependent variables. To do this, one has to give an one dimensional noise process to the `noise` keyword of the `CoupledSDEs` constructor.
```@example type
t0 = 0.0; W0 = 0.0;
noise = WienerProcess(t0, W0, 0.0)
sde = CoupledSDEs(f!, rand(2)/10; noise_process=noise)

tr = trajectory(sde, 1.0)
plot_trajectory(tr...)
```
We can see that noise applied to each variable is the same.


### Multiplicative and non-autonomous noise
Multiplicative noise in the SciML ecosystem is defined as when $g_i(t, u)=a_i u$. However, in the literature the name is sometimes used for when the noise is not-additive, including nonlinear. In general, we can make the noise time- and state-dependent in a similar fashion to the deterministic dynamics. For example, we can define a system with decreasing multiplicative noise as follows:
```@example type
function g!(du, u, p, t)
du .= u ./ (1+t)
return nothing
end
sde = CoupledSDEs(f!, rand(2)./10; g=g!)
```

#### Non-diagonal noise
Non-diagonal noise allows for the terms to linearly mixed via `g` being a matrix. Suppose we have two Wiener processes and two dependent random variables such that the output of `g` is a 2x2 matrix. Therefore, we have
```math
du_1 = f_1(u,p,t)dt + g_{11}(u,p,t)dW_1 + g_{12}(u,p,t)dW_2 \\
du_2 = f_2(u,p,t)dt + g_{21}(u,p,t)dW_1 + g_{22}(u,p,t)dW_2
```
To indicate the structure that `g` should have, we can use the `noise_prototype` keyword. Let us define a special type of non-diagonal noise called commutative noise. For this we can utilize the `RKMilCommute` algorithm which is designed to utilise the structure of commutative noise.

```@example type
σ = 0.25 # noise strength
function g!(du, u, p, t)
du[1,1] = σ*u[1]
du[2,1] = σ*u[2]
du[1,2] = σ*u[1]
du[2,2] = σ*u[2]
return nothing
end
diffeq = (alg = RKMilCommute(), reltol = 1e-3, abstol = 1e-3, dt=0.1)
sde = CoupledSDEs(f!, rand(2)./10; g=g!, noise_prototype = zeros(2, 2), diffeq = diffeq)
```

!!! warning
Non-diagonal problems need specific type of solvers. See the [SciML recommendations](https://docs.sciml.ai/DiffEqDocs/stable/solvers/sde_solve/#sde_solve).
4 changes: 2 additions & 2 deletions docs/src/assets/themes/documenter-dark.css

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/src/assets/themes/documenter-light.css

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions ext/StochasticSystemsBase.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module StochasticSystemsBase

using DynamicalSystemsBase: DynamicalSystemsBase, SciMLBase, correct_state, CoupledODEs,
CoupledSDEs, StateSpaceSets, isinplace, _delete, set_parameter!,
set_state!, dynamic_rule, isdeterministic, current_state,
DynamicalSystemsBase, _set_parameter!, u_modified!,
additional_details, referrenced_sciml_prob, DEFAULT_DIFFEQ,
SVector, SMatrix, current_parameters
using SciMLBase: SDEProblem, AbstractSDEIntegrator, __init, SDEFunction, step!
using StochasticDiffEq: SOSRA
using LinearAlgebra

include("src/CoupledSDEs.jl")
include("src/classification.jl")

export CoupledSDEs, CoupledODEs

end
Loading
Loading