-
Notifications
You must be signed in to change notification settings - Fork 30
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
add coupledSDEs type #212
add coupledSDEs type #212
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking like a really good base, but there are two key things missing:
- You need to port over here in this PR the docs from CrtiicalTransitions.jl. Just copy the
CoupledSDEs.md
here and add it as one more doc page. Given that this is a rather complex new type, it is fine for it to have its own doc page. - We need to try this out also with another downstream package, just to make sure that there isn't some assumption we haven't thought of but we "bake in" this new type. What I would recommend is to find attractors using featurizing: if you can apply this simple code snippet https://juliadynamics.github.io/DynamicalSystemsDocs.jl/attractors/stable/examples/#Trivial-featurizing-and-grouping-for-basins-fractions to any sort of stochastic bistable system, and see that there are two attractors, tjhat would be absolutely fantastic. You can just provide the final script jere as a comment, and when this PR is merged I'll add it to Attractors.jl as an example. cc @reykboerner
A bit off topic but https://github.com/JuliaDynamics/CriticalTransitions.jl/blob/ce6d1b19e95eab772b71b158f35f64ee976484d9/src/utils.jl#L12-L14 needs to be reworked to return a static vector. If this is added here I will show you how with a comment.
Why do we have to care about this? Is there any algorithm that cares about this information and would need to access it? |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #212 +/- ##
==========================================
+ Coverage 82.00% 87.59% +5.58%
==========================================
Files 15 18 +3
Lines 717 927 +210
==========================================
+ Hits 588 812 +224
+ Misses 129 115 -14 ☔ View full report in Codecov by Sentry. |
Yes, for example, the large deviation algorithms implemented in CT.jl are not applicable to all types of stochastic differentials. For further details, I would rather have @reykboerner, who possesses much more expertise on this topic than I do. |
The documentation does not build because of this error:
Not sure why? |
Hi both, yes, as @oameye said, the information on the noise term is important for determining which methods can be applied to a I think the most important criterion to classify a Alternatively, we could add warnings and leave it to the user to ensure that they are using an appropriate method. @raphael-roemer and @ryandeeley might have input, too |
There are two options I see: option 1: request the user to specify the noise type by in addition providing a symbol that indicates the noise type such as The noise type would be one more field of the struct that can be examined by other functions. |
You can't expand a docstring twice @oameye , because then when you refer to it documenter.jl doesn't know where to hyperlink. Sinmply remove the Alternatively, if you really want this docstring to be tehre as well, put |
Here is the example with attractors.jl. using Attractors, StaticArrays
using DynamicalSystemsBase
using DynamicalSystemsBase: idfunc
function fitzhugh_nagumo(u, p, t)
x, y = u
ϵ, β, α, γ, κ, I = p
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
dy = -β * y + x
return SA[dx, dy]
end
sde = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), [1.,3.,1.,1.,1.,0.], 0.1)
ode = CoupledODEs(sde)
function featurizer(X, t)
return X[end]
end
mapper = AttractorsViaFeaturizing(ode, featurizer; Ttr = 200, T = 1)
xg = yg = range(-4, 4; length = 101)
region = HRectangle([-4, 4], [1, 1])
sampler, _ = statespace_sampler(region)
fs = basins_fractions(mapper, sampler) However, should the |
No I want to see the SDE system being given to |
This code snippet works, but takes a long time to complete (~1 min). Lowering the default tolerances to 1e-3 helps. using Attractors, StaticArrays
using DynamicalSystemsBase
using DynamicalSystemsBase: idfunc
function fitzhugh_nagumo(u, p, t)
x, y = u
ϵ, β, α, γ, κ, I = p
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
dy = -β * y + x
return SA[dx, dy]
end
sde = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), [1.,3.,1.,1.,1.,0.], 0.01)
function featurizer(X, t)
return X[end]
end
mapper = AttractorsViaFeaturizing(sde, featurizer; Ttr = 10, T = 1)
xg = yg = range(-1, 1; length = 51)
region = HRectangle([-1, 1], [1, 1])
sampler, _ = statespace_sampler(region)
fs = basins_fractions(mapper, sampler) |
Regarding the Attractors example. I looked up the default tolerances by StochasticDiffEq. Apperently they only use 1e-2, see here. So that's why it took so long. Will change the default |
That's surprising. Which tolerance are you referring to? There is no tolerance in the code snippet you pasted. By default basin fractions will integrate 1,000 initial conditions, and then cluster them. I assume 99.9% of the time here is spent on integrating the initial conditions. Is solving a 2D SDE really so costly that you need about 1 milisecond per initial condition? |
Can you try changing this to |
In any case, it is absolutely fantastic that this just works out of the box with Attractors.jl. |
This is what solved it. SDE solvers require much lower tolerances. using Attractors, StaticArrays
using DynamicalSystemsBase
using DynamicalSystemsBase: idfunc
function fitzhugh_nagumo(u, p, t)
x, y = u
ϵ, β, α, γ, κ, I = p
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
dy = -β * y + x
return SA[dx, dy]
end
sde = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), [1.,3.,1.,1.,1.,0.], 0.01)
function featurizer(X, t)
return X[end]
end
mapper = AttractorsViaFeaturizing(sde, featurizer; Ttr = 200, T = 1)
xg = yg = range(-1, 1; length = 101)
region = HRectangle([-1, 1], [1, 1])
sampler, _ = statespace_sampler(region)
fs = basins_fractions(mapper, sampler)
It doesn't make a difference. It is the same.
Yeah, I agree. You laid out a really good foundation :) |
Just to be clear as I haven't run the code block: |
Yes :) Output is:
I think option 2 is feasible. I will give it a go. Also having option 1, so that the user can override it, is probably favorable. |
Great. I think that's the only thing remaining from the code side. I will have a final review of the docs though. and then we can merge! |
I'll ask @reykboerner if he is planning to review through another channel. The implementation of |
Ha but StochasticDiffEq is still an main dependency in the project.toml. we should change this (on phone atm) |
A split is planned, but it will take time. |
I will finish and submit my review today. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @oameye, thanks a lot for all the work so far and sorry for the delay in reviewing!
There are a few minor changes I would implement, plus a question about the robustness of testing the noise function for time-independence, state-independence etc.
Let me know if I can help with making any of these changes!
I also have only skimmed the docs text and the tests so far.
I assume this is good to go @reykboerner and @oameye ? |
Not yet. Let me take a quick look later today |
I need to finish the remaining edits tomorrow morning, we'll let you know! |
@reykboerner Thanks a lot Reyk for carrying it to finish line! @Datseris We are also good to go for me! :D |
mucho successo ! |
So we merge? |
Fantastic job @oameye @reykboerner . I am merging and tagging now. @oameye can you paste me again please the example you used to show that |
I assume it was this one: using Attractors, StaticArrays
using DynamicalSystemsBase
using DynamicalSystemsBase: idfunc
function fitzhugh_nagumo(u, p, t)
x, y = u
ϵ, β, α, γ, κ, I = p
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
dy = -β * y + x
return SA[dx, dy]
end
sde = CoupledSDEs(fitzhugh_nagumo, idfunc, zeros(2), [1.,3.,1.,1.,1.,0.], 0.01)
function featurizer(X, t)
return X[end]
end
mapper = AttractorsViaFeaturizing(sde, featurizer; Ttr = 200, T = 1)
xg = yg = range(-1, 1; length = 101)
region = HRectangle([-1, 1], [1, 1])
sampler, _ = statespace_sampler(region)
fs = basins_fractions(mapper, sampler) but needs updating ( |
using Attractors, StaticArrays
using DynamicalSystemsBase, StochasticDiffEq # load extention for CoupledSDEs
function fitzhugh_nagumo(u, p, t)
x, y = u
ϵ, β, α, γ, κ, I = p
dx = (-α * x^3 + γ * x - κ * y + I) / ϵ
dy = -β * y + x
return SA[dx, dy]
end
sde = CoupledSDEs(fitzhugh_nagumo, zeros(2), [1.,3.,1.,1.,1.,0.], noise_strength = 0.05)
function featurizer(X, t)
return X[end]
end
mapper = AttractorsViaFeaturizing(sde, featurizer; Ttr = 200, T = 1)
xg = yg = range(-1, 1; length = 101)
region = HRectangle([-1, 1], [1, 1])
sampler, _ = statespace_sampler(region)
fs = basins_fractions(mapper, sampler) |
We probably should write a disclaimer in the example that the attractors are found faster when using CoupledODEs. |
And we could also note that basins of attraction aren't well defined anymore theoretically in the presence of noise (essentially, noise makes any multistable system monostable); this example should simply demonstrate that existing functions work with |
resolves #202
This PR adds a new
CoupledSDEs
struct. Here, we follow closely the design ofCoupledODEs
:Feel free to look at the documentation of CT to understand the API. The type should capture equation of the form$dx = f(x, p) dt +g(x, p) dW$ . The function $\sigma$ and the covariance matrix (correlation). In general, g can be quite an exotic function, making it that we lose both the noise strength and covariance matrix. However, we need this information to use algorithms in, e.g., large deviation theory. To solve this, I have opted for two design choses:
g
both captures the noise strengthg
wil also be rescaled with the noise strength. The parameterS
inCoupledSDEs{IIP,D,I,P,S}
indicated if this has happened or not.DiffEqNoiseProcess.jl
that adds a covariance field to the noise processdW
. This allows the user to add a correlated noise process like CorrelatedWienerProcess where the covariance matrix is automatically saved in the Integrator.This solved the problem of not having acces to this information after the construction. Nevertheless, there is still some ambiguity as the user can always choose the
g
function freely. We can put the responsibility with the user and make tests that try to guess the type of noise. Or we will have to make subtypes such that we can easily distinguish scalar, multiplicative, additive, etc.TODO