Skip to content

Commit e3d1374

Browse files
Merge pull request #779 from hurak/master
SDE Examples: minor rewording of explanation of "diagonal vs non-diagonal noise"
2 parents 36a6ba1 + 0de11d4 commit e3d1374

File tree

2 files changed

+33
-35
lines changed

2 files changed

+33
-35
lines changed

docs/make.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ makedocs(
3939
"https://www.wolframalpha.com/input/?i=u%27%3D-sqrt%28u%29",
4040
"https://www.mathworks.com/help/simulink/gui/absolutetolerance.html",
4141
"https://www.mathworks.com/help/matlab/math/choose-an-ode-solver.html",
42-
"https://journals.ametsoc.org/view/journals/atsc/20/2/1520-0469_1963_020_0130_dnf_2_0_co_2.xml"
42+
"https://journals.ametsoc.org/view/journals/atsc/20/2/1520-0469_1963_020_0130_dnf_2_0_co_2.xml",
43+
"https://mathematica.stackexchange.com/questions/40122/help-to-plot-poincar%C3%A9-section-for-double-pendulum",
44+
"https://github.com/SciML/DiffEqProblemLibrary.jl/blob/master/lib/SDEProblemLibrary/src/SDEProblemLibrary.jl",
4345
],
4446
doctest = false, clean = true,
4547
warnonly = [:missing_docs],

docs/src/tutorials/sde_example.md

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -142,49 +142,45 @@ In general, a system of SDEs
142142
du = f(u,p,t)dt + g(u,p,t)dW,
143143
```
144144

145-
where `g` is now a matrix of values, is numerically integrated in the
146-
same way as ODEs. A common scenario is when we have diagonal noise, which
147-
is the default for DifferentialEquations.jl. Physically this means that
148-
every variable in the system gets a different random kick. Consequently, `g` is a
149-
diagonal matrix and we can handle this in a simple manner by defining
150-
the deterministic part `f(du,u,p,t)` and the stochastic part
151-
`g(du2,u,p,t)` as in-place functions.
152-
153-
Consider for example a stochastic variant of the Lorenz equations, where we introduce a
154-
simple additive noise to each of `x,y,z`, which is simply `3*N(0,dt)`. Here, `N` is the normal
155-
distribution and `dt` is the time step. This is done as follows:
145+
where `u` is now a vector of variables, `f` is a vector, and `g` is a matrix, is numerically integrated in the same way as ODEs. A common scenario, which is the default for DifferentialEquations.jl, is that every variable in the system gets a different random kick. This is the case when `g` is a diagonal matrix. Correspondingly, we say that we have a diagonal noise.
146+
147+
We handle this in a simple manner by defining the deterministic part `f!(du,u,p,t)` and the stochastic part
148+
`g!(du2,u,p,t)` as in-place functions, but note that our convention is that the function `g!` only defines and modifies the diagonal entries of `g` matrix.
149+
150+
As an example, we consider a stochastic variant of the Lorenz equations, where we add to each of `u₁, u₂, u₃` their own simple noise `3*N(0,dt)`. Here, `N` is the normal distribution and `dt` is the time step. This is done as follows:
156151

157152
```@example sde2
158153
using DifferentialEquations
159154
using Plots
160-
function lorenz!(du, u, p, t)
155+
156+
function f!(du, u, p, t)
161157
du[1] = 10.0 * (u[2] - u[1])
162158
du[2] = u[1] * (28.0 - u[3]) - u[2]
163159
du[3] = u[1] * u[2] - (8 / 3) * u[3]
164160
end
165161
166-
function σ_lorenz!(du, u, p, t)
162+
function g!(du, u, p, t) # It actually represents a diagonal matrix [3.0 0 0; 0 3.0 0; 0 0 3.0]
167163
du[1] = 3.0
168164
du[2] = 3.0
169165
du[3] = 3.0
170166
end
171167
172-
prob_sde_lorenz = SDEProblem(lorenz!, σ_lorenz!, [1.0, 0.0, 0.0], (0.0, 10.0))
168+
prob_sde_lorenz = SDEProblem(f!, g!, [1.0, 0.0, 0.0], (0.0, 10.0))
173169
sol = solve(prob_sde_lorenz)
174170
plot(sol, idxs = (1, 2, 3))
175171
```
176172

177173
Note that it's okay for the noise function to mix terms. For example
178174

179175
```@example sde2
180-
function σ_lorenz!(du, u, p, t)
176+
function g!(du, u, p, t)
181177
du[1] = sin(u[3]) * 3.0
182178
du[2] = u[2] * u[1] * 3.0
183179
du[3] = 3.0
184180
end
185181
```
186182

187-
is a valid noise function, which will once again give diagonal noise by `du2.*W`.
183+
is a valid noise function.
188184

189185
## Example 3: Systems of SDEs with Scalar Noise
190186

@@ -200,12 +196,12 @@ let's solve a linear SDE with scalar noise using a high order algorithm:
200196
```@example sde3
201197
using DifferentialEquations
202198
using Plots
203-
f(du, u, p, t) = (du .= u)
204-
g(du, u, p, t) = (du .= u)
199+
f!(du, u, p, t) = (du .= u)
200+
g!(du, u, p, t) = (du .= u)
205201
u0 = rand(4, 2)
206202
207203
W = WienerProcess(0.0, 0.0, 0.0)
208-
prob = SDEProblem(f, g, u0, (0.0, 1.0), noise = W)
204+
prob = SDEProblem(f!, g!, u0, (0.0, 1.0), noise = W)
209205
sol = solve(prob, SRIW1())
210206
plot(sol)
211207
```
@@ -216,7 +212,7 @@ In the previous examples we had diagonal noise, that is a vector of random numbe
216212
`dW` whose size matches the output of `g` where the noise is applied element-wise,
217213
and scalar noise where a single random variable is applied to all dependent variables.
218214
However, a more general type of noise allows for the terms to linearly mixed via `g`
219-
being a matrix.
215+
being a general nondiagonal matrix.
220216

221217
Note that nonlinear mixings are not SDEs but fall under the more general class of
222218
random ordinary differential equations (RODEs) which have a
@@ -228,8 +224,8 @@ is `g(u,p,t)*dW`, the matrix multiplication. For example, we can do the followin
228224

229225
```@example sde4
230226
using DifferentialEquations
231-
f(du, u, p, t) = du .= 1.01u
232-
function g(du, u, p, t)
227+
f!(du, u, p, t) = du .= 1.01u
228+
function g!(du, u, p, t)
233229
du[1, 1] = 0.3u[1]
234230
du[1, 2] = 0.6u[1]
235231
du[1, 3] = 0.9u[1]
@@ -239,10 +235,10 @@ function g(du, u, p, t)
239235
du[2, 3] = 0.3u[2]
240236
du[2, 4] = 1.8u[2]
241237
end
242-
prob = SDEProblem(f, g, ones(2), (0.0, 1.0), noise_rate_prototype = zeros(2, 4))
238+
prob = SDEProblem(f!, g!, ones(2), (0.0, 1.0), noise_rate_prototype = zeros(2, 4))
243239
```
244240

245-
In our `g` we define the functions for computing the values of the matrix.
241+
In our `g!` we define the functions for computing the values of the matrix.
246242
We can now think of the SDE that this solves as the system of equations
247243

248244
```math
@@ -259,7 +255,7 @@ the same random number in the first and second SDEs.
259255
noise. This is discussed [in the SDE solvers page](@ref sde_solve).
260256

261257
The matrix itself is determined by the keyword argument `noise_rate_prototype` in the `SDEProblem`
262-
constructor. This is a prototype for the type that `du` will be in `g`. This can
258+
constructor. This is a prototype for the type that `du` will be in `g!`. This can
263259
be any `AbstractMatrix` type. Thus, we can define the problem as
264260

265261
```@example sde4
@@ -271,18 +267,18 @@ A[1, 4] = 1
271267
A[2, 4] = 1
272268
A = sparse(A)
273269
274-
# Make `g` write the sparse matrix values
275-
function g(du, u, p, t)
270+
# Make `g!` write the sparse matrix values
271+
function g!(du, u, p, t)
276272
du[1, 1] = 0.3u[1]
277273
du[1, 4] = 0.12u[2]
278274
du[2, 4] = 1.8u[2]
279275
end
280276
281-
# Make `g` use the sparse matrix
282-
prob = SDEProblem(f, g, ones(2), (0.0, 1.0), noise_rate_prototype = A)
277+
# Make `g!` use the sparse matrix
278+
prob = SDEProblem(f!, g!, ones(2), (0.0, 1.0), noise_rate_prototype = A)
283279
```
284280

285-
and now `g(u,p,t)` writes into a sparse matrix, and `g(u,p,t)*dW` is sparse matrix
281+
and now `g!(u,p,t)` writes into a sparse matrix, and `g!(u,p,t)*dW` is sparse matrix
286282
multiplication.
287283

288284
## Example 4: Colored Noise
@@ -292,7 +288,7 @@ In that portion of the docs, it is shown how to define your own noise process
292288
`my_noise`, which can be passed to the SDEProblem
293289

294290
```julia
295-
SDEProblem(f, g, u0, tspan, noise = my_noise)
291+
SDEProblem(f!, g!, u0, tspan, noise = my_noise)
296292
```
297293

298294
Note that general colored noise problems are only compatible with the `EM` and `EulerHeun` methods.
@@ -311,11 +307,11 @@ dW_1 dW_2 = ρ dt
311307
In this problem, we have a diagonal noise problem given by:
312308

313309
```@example sde4
314-
function f(du, u, p, t)
310+
function f!(du, u, p, t)
315311
du[1] = μ * u[1]
316312
du[2] = κ * (Θ - u[2])
317313
end
318-
function g(du, u, p, t)
314+
function g!(du, u, p, t)
319315
du[1] = √u[2] * u[1]
320316
du[2] = σ * √u[2]
321317
end
@@ -339,7 +335,7 @@ heston_noise = CorrelatedWienerProcess!(Γ, tspan[1], zeros(2), zeros(2))
339335
This is then used to build the SDE:
340336

341337
```@example sde4
342-
SDEProblem(f, g, ones(2), tspan, noise = heston_noise)
338+
SDEProblem(f!, g!, ones(2), tspan, noise = heston_noise)
343339
```
344340

345341
Of course, to fully define this problem, we need to define our constants. Constructors

0 commit comments

Comments
 (0)