# Improving performance in solving SDEProblem

**URL:** <https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396>\
**Category:** Performance\
**Tags:** diffeq, sde\
**Created:** [June 4, 2021, 5:04pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396 "2021-06-04T17:04:23Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Frazze](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frazze/32/25142_2.png) [@Frazze](https://discourse.julialang.org/u/Frazze)\
**Post date:** [June 4, 2021, 5:04pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/1 "2021-06-04T17:04:23Z")

</div>

Hi everyone,  
I’m studying part of the 2D Swift Hohenberg model with an additive noise term, but I’m really new to the SDEProblems so I don’t know if my way to build the model is the best way to solve it.  
I’ve take a look to the tutorial [Stochastic Differential Equations · DifferentialEquations.jl](https://diffeq.sciml.ai/stable/tutorials/sde_example/) and I’ve defined

```julia
function Add_noise(u,p,t)
     
    return fill(0.5,Nx*Ny)
end

```

As the noise. Then

```julia
#Definition of the problem
u0= rand(Nx,Ny) |> vec
tspan = (0.0,35.0)
prob =@time SDEProblem(F_sh,Add_noise,u0,tspan,p);

```

Where F\_sh is

```julia
#Definition of the equation
function F_sh(u, p, t)
    @unpack l , L1 = p
    
    return -L1 * u .+ (l .* u)
end

```

And L1 is the SH operator.  
Then I try to solve the problem using

```julia
#Solution of the problem

sol =@time solve(prob,alg_hints=[:additive,:stiff],SRIW1(), save_everystep=false, save_start=false, saveat=[5,35])

```

But it seems not working very well because is slow, in particular increasing the resolution of the grid (Nx\*Ny).  
What kind of error I’m doing?  
Thank you so much for the help, every comment is welcome!

---

<div class="post-metadata">

**Author:** ![frankschae](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankschae/32/8382_2.png) [@frankschae](https://discourse.julialang.org/u/frankschae)\
**Post date:** [June 4, 2021, 9:37pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/2 "2021-06-04T21:37:59Z")

</div>

Allocating large vectors as the output is probably the biggest performance hit (and for vectors of small size you should use `StaticArrays`). There is a nice tutorial for optimizing DiffEq code:

[https://tutorials.sciml.ai/html/introduction/03-optimizing\_diffeq\_code.html](https://tutorials.sciml.ai/html/introduction/03-optimizing_diffeq_code.html)

So I think, writing your functions inplace to remove allocations is a good idea:

```julia
function Add_noise(du,u,p,t)
  fill!(du,1//2*one(eltype(u)))
  return nothing
end

function F_sh(du, u, p, t)
    @unpack l , L1 = p

    @. du = -L1 * u + (l * u) # if L1 and l are numbers ..
    return nothing
end

```

Since your noise is additive, I think using a specialized solver will result in a speed up. Likely, `SOSRA()` is a good choice (you’ll find the available solvers at [SDE Solvers · DifferentialEquations.jl](https://diffeq.sciml.ai/latest/solvers/sde_solve/)).

---

<div class="post-metadata">

**Author:** ![Frazze](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frazze/32/25142_2.png) [@Frazze](https://discourse.julialang.org/u/Frazze)\
**Post date:** [June 7, 2021, 5:31pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/3 "2021-06-07T17:31:30Z")

</div>

Thank you so much Frank, but still something goes wrong. I think that the problem is because L1 is not a number but `L1=(I+Δ)^2` where Δ is the laplacian operator that I wrote as

```julia
#Domain and grid 
Nx = 90
Ny = 90
lx = 30
ly = 30

# the Laplacian operator
function Laplacian2D(Nx, Ny, lx, ly)
	hx = lx/Nx
	hy = ly/Ny
	D2x = CenteredDifference(2, 2, hx, Nx)
	D2y = CenteredDifference(2, 2, hy, Ny)
	Qx = PeriodicBC(hx |> typeof)
	Qy = PeriodicBC(hy |> typeof)
	
	A = kron(sparse(I, Ny, Ny), sparse(D2x * Qx)[1]) + kron(sparse(D2y * Qy)[1], sparse(I, Nx, Nx))
	return A
end

```

I tried to write F\_sh like

```julia
function F_sh(du,u, p, t)
    @unpack l , d = p
    
    du .= -(I + Δ)^2 * u .+ (l .* u)
    return nothing
end

```

Putting d=Δ. But this not seems to be the good way to solve my problem. Maybe I have to writing different the Laplacian function?

---

<div class="post-metadata">

**Author:** ![frankschae](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frankschae/32/8382_2.png) [@frankschae](https://discourse.julialang.org/u/frankschae)\
**Post date:** [June 7, 2021, 8:25pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/4 "2021-06-07T20:25:31Z")

</div>

I see. Δ seems to be defined in global scope now and you don’t want to compute the square in each function call. So, you’ll have to localize `L1` within the function by either adding it to the parameter vector (Why did you change that?) or by using a functor.

---

<div class="post-metadata">

**Author:** ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)\
**Post date:** [June 7, 2021, 8:39pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/5 "2021-06-07T20:39:27Z")

</div>

Just a remark in passing: `I̶f̶ ̶y̶o̶u̶ ̶b̶r̶o̶a̶d̶c̶a̶s̶t̶ ̶w̶i̶t̶h̶ ̶`̶@̶.̶`̶ ̶a̶t̶ ̶t̶h̶e̶ ̶s̶t̶a̶r̶t̶ ̶o̶f̶ ̶t̶h̶e̶ ̶l̶i̶n̶e̶,̶ ̶y̶o̶u̶ ̶d̶o̶n̶'̶t̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶w̶o̶r̶r̶y̶ ̶a̶b̶o̶u̶t̶ ̶w̶h̶e̶r̶e̶ ̶e̶x̶a̶c̶t̶l̶y̶ ̶t̶o̶ ̶p̶l̶a̶c̶e̶ ̶d̶o̶t̶s̶`:

```julia
@̶.̶ ̶d̶u̶ ̶=̶ ̶-̶(̶I̶ ̶+̶ ̶Δ̶)̶^̶2̶ ̶*̶ ̶u̶ ̶+̶ ̶(̶l̶ ̶*̶ ̶u̶)̶

```

No, don’t do that! See Chris’s remark below.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [June 7, 2021, 8:40pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/6 "2021-06-07T20:40:37Z")

</div>

Watch out with broadcasting `I` though: it doesn’t mean what you think it means.

---

<div class="post-metadata">

**Author:** ![ptoche](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ptoche/32/23554_2.png) [@ptoche](https://discourse.julialang.org/u/ptoche)\
**Post date:** [June 7, 2021, 8:56pm UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/7 "2021-06-07T20:56:55Z")

</div>

Ah I missed that. Good point. So here you would avoid `@.` and just pay more attention to where to place dots. Thanks!

---

<div class="post-metadata">

**Author:** ![Frazze](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frazze/32/25142_2.png) [@Frazze](https://discourse.julialang.org/u/Frazze)\
**Post date:** [June 9, 2021, 8:58am UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/8 "2021-06-09T08:58:57Z")

</div>

Ok thank you, using your hints i reach the solution in

> 619.053820 seconds (7.22 M allocations: 1.374 TiB, 6.78% gc time)

Then, it’s quite good now.

---

<div class="post-metadata">

**Author:** ![Frazze](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/frazze/32/25142_2.png) [@Frazze](https://discourse.julialang.org/u/Frazze)\
**Post date:** [June 9, 2021, 9:00am UTC](https://discourse.julialang.org/t/improving-performance-in-solving-sdeproblem/62396/9 "2021-06-09T09:00:56Z")

</div>

Yes, and also write (I + Δ)^2 is different from (I + Δ).^2
