# SDE Lokta-Volterra Work-Precision Diagrams

##### Chris Rackauckas
using StochasticDiffEq, DiffEqDevTools, ParameterizedFunctions
using Plots; gr()
const N = 100

f = @ode_def LotkaVolterraTest begin
dx = a*x - b*x*y
dy = -c*y + d*x*y
end a b c d

p = [1.5,1.0,3.0,1.0]

function g(du,u,p,t)
du .= 0.1u
end
u0 = [1.0;1.0]
tspan = (0.0,10.0)
prob = SDEProblem(f,g,u0,tspan,p);

sol = solve(prob,SRIW1(),abstol=1e-4,reltol=1e-4)
plot(sol)


## Strong Error

The starting dts was chosen as the largest in the 1/4^i which were stable. All larger dts contained trajectories which would veer off to infinity.

reltols = 1.0 ./ 4.0 .^ (2:4)
abstols = reltols#[0.0 for i in eachindex(reltols)]
setups = [Dict(:alg=>SRIW1())
Dict(:alg=>EM(),:dts=>1.0./12.0.^((1:length(reltols)) .+ 1.5))
Dict(:alg=>SRIW2())
Dict(:alg=>SOSRI())
Dict(:alg=>SOSRI2())
]
test_dt = 1/10^2
appxsol_setup = Dict(:alg=>SRIW1(),:abstol=>1e-4,:reltol=>1e-4)
wp = WorkPrecisionSet(prob,abstols,reltols,setups,test_dt;
maxiters = 1e7,
verbose=false,save_everystep=false,
appxsol_setup = appxsol_setup,
numruns_error=N,error_estimate=:final)
plot(wp)


## Weak Error

reltols = 1.0 ./ 4.0 .^ (2:4)
abstols = reltols#[0.0 for i in eachindex(reltols)]
setups = [Dict(:alg=>SRIW1())
Dict(:alg=>EM(),:dts=>1.0./12.0.^((1:length(reltols)) .+ 1.5))
Dict(:alg=>SRIW2())
Dict(:alg=>SOSRI())
Dict(:alg=>SOSRI2())
]
test_dt = 1e-2
appxsol_setup = Dict(:alg=>SRIW1(),:abstol=>1e-4,:reltol=>1e-4)
wp = WorkPrecisionSet(prob,abstols,reltols,setups,test_dt;
maxiters = 1e7,
verbose=false,save_everystep=false,
parallel_type = :none,
appxsol_setup = appxsol_setup,
numruns_error=N,error_estimate=:weak_final)
plot(wp;legend=:topleft)

sample_size = Int[10;1e2;1e3]
se = get_sample_errors(prob,setups[6],test_dt,numruns=sample_size,
appxsol_setup = appxsol_setup,
sample_error_runs = 100_000,solution_runs=20)

3-element Array{Float64,1}:
0.14352419049611304
0.014828503068766121
0.0014783618938791503

plot(wp;legend=:topleft)
times = [wp[i].times for i in 1:length(wp)]
times = [minimum(minimum(t) for t in times),maximum(maximum(t) for t in times)]
plot!([se[end];se[end]],times,color=:orange,linestyle=:dash,label="Sample Error: 1000",lw=3)


## Conclusion

These results show that in both strong and weak error, the high order method is more efficient. The strong and the weak are track each other well for the methods tested on this problem, with the strong error slightly higher than the weak error. To reach the sample error for a 100 trajectories, the higher order method is around 5x faster. To reach the sampling error for 10000 trajectories, the higher order method is nearly 100x faster.

using DiffEqBenchmarks
DiffEqBenchmarks.bench_footer(WEAVE_ARGS[:folder],WEAVE_ARGS[:file])


## Appendix

These benchmarks are a part of the DiffEqBenchmarks.jl repository, found at: https://github.com/JuliaDiffEq/DiffEqBenchmarks.jl

To locally run this tutorial, do the following commands:

using DiffEqBenchmarks
DiffEqBenchmarks.weave_file("NonStiffSDE","LotkaVolterraSDE.jmd")

Computer Information:

Julia Version 1.1.0
Commit 80516ca202 (2019-01-21 21:24 UTC)
Platform Info:
OS: Linux (x86_64-pc-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2680 v4 @ 2.40GHz
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-6.0.1 (ORCJIT, haswell)


Package Information:

Status: /home/crackauckas/.julia/environments/v1.1/Project.toml
[c52e3926-4ff0-5f6e-af25-54175e0327b1] Atom 0.8.8
[bcd4f6db-9728-5f36-b5f7-82caef46ccdb] DelayDiffEq 5.9.1
[bb2cbb15-79fc-5d1e-9bf1-8ae49c7c1650] DiffEqBenchmarks 0.1.0
[459566f4-90b8-5000-8ac3-15dfb0a30def] DiffEqCallbacks 2.5.2
[f3b72e0c-5b89-59e1-b016-84e28bfd966d] DiffEqDevTools 2.13.0
[aae7a2af-3d4f-5e19-a356-7da93b79d9d0] DiffEqFlux 0.6.1
[78ddff82-25fc-5f2b-89aa-309469cbf16f] DiffEqMonteCarlo 0.15.1
[77a26b50-5914-5dd7-bc55-306e6241c503] DiffEqNoiseProcess 3.3.1
[055956cb-9e8b-5191-98cc-73ae4a59e68a] DiffEqPhysics 3.2.0
[a077e3f3-b75c-5d7f-a0c6-6bc4c8ec64a9] DiffEqProblemLibrary 4.5.0
[ef61062a-5684-51dc-bb67-a0fcdec5c97d] DiffEqUncertainty 1.1.0
[0c46a032-eb83-5123-abaf-570d42b7fbaa] DifferentialEquations 6.6.0
[35a29f4d-8980-5a13-9543-d66fff28ecb8] DocumenterTools 0.1.1
[b305315f-e792-5b7a-8f41-49f472929428] Elliptic 0.5.0
[7f56f5a3-f504-529b-bc02-0b1fe5e64312] LSODA 0.4.0
[c030b06c-0b6d-57c2-b091-7029874bd033] ODE 2.4.0
[54ca160b-1b9f-5127-a996-1867f4bc2a2c] ODEInterface 0.4.6
[09606e27-ecf5-54fc-bb29-004bd9f985bf] ODEInterfaceDiffEq 3.3.1
[1dea7af3-3e70-54e6-95c3-0bf5283fa5ed] OrdinaryDiffEq 5.12.0
[2dcacdae-9679-587a-88bb-8b444fb7085b] ParallelDataTransfer 0.5.0
[65888b18-ceab-5e60-b2b9-181511a3b968] ParameterizedFunctions 4.2.0
[91a5bcdd-55d7-5caf-9e0b-520d859cae80] Plots 0.26.0
[9cded84f-2146-5f9f-b71f-7cd68310d1ff] PumasDocs 0.0.0
[d330b81b-6aea-500a-939a-2ce795aea3ee] PyPlot 2.8.1
[731186ca-8d62-57ce-b412-fbd966d074cd] RecursiveArrayTools 0.20.0
[e88e6eb3-aa80-5325-afca-941959d7151f] Zygote 0.3.2