Driftless Stochastic differential equation

Hi everybody,

I’m using the GREAT StochasticDiffEq.jl package to define a multidimensional driftless SDE as follows:

using StochasticDiffEq

function f!(du, u, p, t)
    du .= p[1]
    return nothing
end

function g!(du, u, p, t)
    du[1] = p[3] * exp(-p[2] * t) 
    du[2] = p[5] * exp(-p[4] * t) 

    return nothing
end

u0 = [1.0, 0.3]
tspan = (0.0, 1.0)
params = ([0.0, 0.0], 0.2, 0.2, 0.2, 0.1)

sde = SDEProblem(f!, g!, u0, tspan, params)


Is there a way of defining the SDE in order to avoid the unnecessary drift computations?

Thanks in advance for your help!

That looks right, just making it zero. Did you profile it? I would suspect that f calls are negligible

Thank you very much for your quick answer, Chris :slight_smile:

Yes, I timed it. By doing:

du = zeros(eltype(u0), 2)
u = zeros(eltype(u0), 2)
t = 0.1

@btime f!($du, $u, $params, $t)
@btime g!($du, $u, $params, $t)

I obtained:

 6.458 ns (0 allocations: 0 bytes)

for f!, and:

 7.375 ns (0 allocations: 0 bytes)

for g!.

I’m asking about completely removing f! computations because my complete setup (which involves simulating 1E6 trajectories) is:

using StochasticDiffEq

function f!(du, u, p, t)
    du .= p[1]
    return nothing
end

function g!(du, u, p, t)
    du[1] = p[3] * exp(-p[2] * t) 
    du[2] = p[5] * exp(-p[4] * t) 

    return nothing
end

u0 = [1.0, 0.3]
tspan = (0.0, 1.0)
params = ([0.0, 0.0], 0.2, 0.2, 0.2, 0.1)

sde = EnsembleProblem(SDEProblem(f!, g!, u0, tspan, params))

solve(sde, EM(), dt=1 / 200, trajectories=1E6)  

and in this case having more than 1E6 evaluations of the zero drift function is not negligible anymore.

FWIW, on my laptop replacing du .= p[1] by fill!(du,0.0) or du .= 0.0 gives a noticeable speedup from ~8ns to ~5ns. The latter two seem the same speed.

If your problem is really only two dimensional though you might do better using out of place and static arrays. That gets the call to the analogous f(u,p,t) = @SVector [0.0,0.0] down to just over 1ns on my laptop.

edit: And I would guess that if you have a large number of components in your real problem the relative time spent in f! relative to g! is likely lower.

That’s fantastic. Thanks for elaborating, @isaacsas :slight_smile:

You’re welcome!