Simulating SDEs with shared noise in `DifferentialEquations.jl`

I have a problem with two processes X_{1, t}, X_{2, t} \in \mathbb{R} which satisfy the SDEs

\begin{align} dX_{1, t} = f_1(t, X_{1, t}) \; dt + \sigma \; dW_t, \\ dX_{2, t} = f_2(t, X_{1, t}) \; dt + \sigma \; dW_t. \end{align}

The functions f_i are nonlinear. The two processes share the noise \sigma \; dW_t. I would like to simulate paths of X_{1, t} and X_{2, t} with the same noise realisations. I tried to do this with DifferentialEquations.jl and DiffEqNoiseProcess.jl, by defining W = WienerProcess(0., 0.), passing it as noise to SDEProblem and solving with the same seed. But when I check the noise realisation, I get different values.

See this MWE for f_1(t, x) = \sqrt{x} and f_2(t, x) = x, and \sigma = 1.

using DifferentialEquations

f₁(x, p, t) = sqrt(x)
f₂(x, p, t) = x

g(x, p, t) = 1.

W = WienerProcess(0., 0.)
x₀ = 10.
tspan = (0., 1.)

prob₁ = SDEProblem(f₁, g, x₀, tspan, noise = W)
prob₂ = SDEProblem(f₂, g, x₀, tspan, noise = W)

seed = 42

sol₁ = solve(prob₁; seed = seed, save_noise = true)
sol₂ = solve(prob₂; seed = seed, save_noise = true)

error = [sol₁.W(t)[1] - sol₂.W(t)[1] for t in 0:0.01:1]

Am I misunderstanding how the seed works? Is there a better way to achieve this?

I have thought of an inefficient way of doing this. I can simulate the two variables X_1 and X_2 as a vector SDE with noise matrix \Sigma = \begin{pmatrix} 1 & 0 \\ 1 & 0\\\end{pmatrix}. This leads to

using DifferentialEquations
using SparseArrays

f₁(x, p, t) = sqrt(x)
f₂(x, p, t) = x

function fjoint!(dx, x, p, t)
    dx[1] = f₁(x[1], p, t)
    dx[2] = f₂(x[2], p, t)

    return 
end

function g!(Σ, x, p, t)
    Σ[1, 1] = 1.
    Σ[2, 1] = 1.

    return
end

x₀ = 2ones(2);
tspan = (0.0, 1.0);

A = spzeros(2, 2)
A[1, 1] = 1.0
A[2, 1] = 1.0

prob = SDEProblem(fjoint!, g!, x₀, tspan; noise_rate_prototype = A);

If somebody can think of a simpler way, please let me know.

This is scalar noise and is discussed here:

1 Like