Skip to content

Commit

Permalink
Merge pull request #67 from JuliaDiffEq/double_implicit
Browse files Browse the repository at this point in the history
Noise implicit methods
  • Loading branch information
ChrisRackauckas committed Apr 1, 2018
2 parents 1ef7813 + 68433d7 commit b7579ea
Show file tree
Hide file tree
Showing 10 changed files with 620 additions and 7 deletions.
5 changes: 4 additions & 1 deletion src/StochasticDiffEq.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ module StochasticDiffEq
include("caches/lamba_caches.jl")
include("caches/iif_caches.jl")
include("caches/sdirk_caches.jl")
include("caches/split_step_caches.jl")
include("caches/sra_caches.jl")
include("caches/rossler_caches.jl")
include("caches/kencarp_caches.jl")
Expand All @@ -68,6 +69,7 @@ module StochasticDiffEq
include("perform_step/sri.jl")
include("perform_step/sra.jl")
include("perform_step/sdirk.jl")
include("perform_step/split_step.jl")
include("perform_step/kencarp.jl")
include("perform_step/predcorr.jl")
include("perform_step/split.jl")
Expand All @@ -86,7 +88,8 @@ module StochasticDiffEq

export SplitEM, IIF1M, IIF2M, IIF1Mil

export ImplicitEM, ImplicitEulerHeun, ImplicitRKMil
export ImplicitEM, ImplicitEulerHeun, ISSEM, ISSEulerHeun,
ImplicitRKMil

export StochasticDiffEqRODEAlgorithm, StochasticDiffEqRODEAdaptiveAlgorithm,
StochasticDiffEqRODECompositeAlgorithm
Expand Down
4 changes: 4 additions & 0 deletions src/alg_utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ alg_order(alg::LambaEM) = 1//2
alg_order(alg::ImplicitEM) = 1//2
alg_order(alg::ImplicitEulerHeun) = 1//2
alg_order(alg::ImplicitRKMil) = 1//1
alg_order(alg::ISSEM) = 1//2
alg_order(alg::ISSEulerHeun) = 1//2
alg_order(alg::SplitEM) = 1//2
alg_order(alg::PCEuler) = 1//2
alg_order(alg::IIF1M) = 1//2
Expand Down Expand Up @@ -69,6 +71,8 @@ alg_compatible(prob,alg::SplitEM) = true
alg_compatible(prob,alg::PCEuler) = true
alg_compatible(prob,alg::ImplicitEM) = true
alg_compatible(prob,alg::ImplicitEulerHeun) = true
alg_compatible(prob,alg::ISSEM) = true
alg_compatible(prob,alg::ISSEulerHeun) = true
alg_compatible(prob,alg::RKMil) = is_diagonal_noise(prob)
alg_compatible(prob,alg::ImplicitRKMil) = is_diagonal_noise(prob)
alg_compatible(prob,alg::RKMilCommute) = true # No good check for commutative noise
Expand Down
70 changes: 65 additions & 5 deletions src/algorithms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,10 @@ Base.@pure ImplicitEM(;chunk_size=0,autodiff=true,diff_type=Val{:central},
theta = 1/2,symplectic=false,
max_newton_iter=7,new_jac_conv_bound = 1e-3,
controller = :Predictive) =
ImplicitEM{chunk_size,autodiff,typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),typeof(new_jac_conv_bound),controller}(
ImplicitEM{chunk_size,autodiff,
typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),
typeof(new_jac_conv_bound),controller}(
linsolve,diff_type,κ,tol,
symplectic ? 1/2 : theta,
extrapolant,
Expand All @@ -141,8 +143,10 @@ Base.@pure ImplicitEulerHeun(;chunk_size=0,autodiff=true,diff_type=Val{:central}
theta = 1/2,symplectic = false,
max_newton_iter=7,new_jac_conv_bound = 1e-3,
controller = :Predictive) =
ImplicitEulerHeun{chunk_size,autodiff,typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),typeof(new_jac_conv_bound),controller}(
ImplicitEulerHeun{chunk_size,autodiff,
typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),
typeof(new_jac_conv_bound),controller}(
linsolve,diff_type,κ,tol,
symplectic ? 1/2 : theta,
extrapolant,min_newton_iter,
Expand All @@ -166,14 +170,70 @@ Base.@pure ImplicitRKMil(;chunk_size=0,autodiff=true,diff_type=Val{:central},
theta = 1/2,symplectic = false,
max_newton_iter=7,new_jac_conv_bound = 1e-3,
controller = :Predictive,interpretation=:Ito) =
ImplicitRKMil{chunk_size,autodiff,typeof(linsolve),typeof(diff_type),
ImplicitRKMil{chunk_size,autodiff,
typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),typeof(new_jac_conv_bound),
controller,interpretation}(
linsolve,diff_type,κ,tol,
symplectic ? 1/2 : theta,
extrapolant,min_newton_iter,
max_newton_iter,new_jac_conv_bound,symplectic)

struct ISSEM{CS,AD,F,S,K,T,T2,Controller} <: StochasticDiffEqNewtonAdaptiveAlgorithm{CS,AD,Controller}
linsolve::F
diff_type::S
κ::K
tol::T
theta::T2
extrapolant::Symbol
min_newton_iter::Int
max_newton_iter::Int
new_jac_conv_bound::T2
symplectic::Bool
end
Base.@pure ISSEM(;chunk_size=0,autodiff=true,diff_type=Val{:central},
linsolve=DEFAULT_LINSOLVE,κ=nothing,tol=nothing,
extrapolant=:constant,min_newton_iter=1,
theta = 1,symplectic=false,
max_newton_iter=7,new_jac_conv_bound = 1e-3,
controller = :Predictive) =
ISSEM{chunk_size,autodiff,
typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),
typeof(new_jac_conv_bound),controller}(
linsolve,diff_type,κ,tol,
symplectic ? 1/2 : theta,
extrapolant,
min_newton_iter,
max_newton_iter,new_jac_conv_bound,symplectic)

struct ISSEulerHeun{CS,AD,F,S,K,T,T2,Controller} <: StochasticDiffEqNewtonAdaptiveAlgorithm{CS,AD,Controller}
linsolve::F
diff_type::S
κ::K
tol::T
theta::T2
extrapolant::Symbol
min_newton_iter::Int
max_newton_iter::Int
new_jac_conv_bound::T2
symplectic::Bool
end
Base.@pure ISSEulerHeun(;chunk_size=0,autodiff=true,diff_type=Val{:central},
linsolve=DEFAULT_LINSOLVE,κ=nothing,tol=nothing,
extrapolant=:constant,min_newton_iter=1,
theta = 1,symplectic=false,
max_newton_iter=7,new_jac_conv_bound = 1e-3,
controller = :Predictive) =
ISSEulerHeun{chunk_size,autodiff,
typeof(linsolve),typeof(diff_type),
typeof(κ),typeof(tol),typeof(new_jac_conv_bound),controller}(
linsolve,diff_type,κ,tol,
symplectic ? 1/2 : theta,
extrapolant,
min_newton_iter,
max_newton_iter,new_jac_conv_bound,symplectic)

struct SKenCarp{CS,AD,F,FDT,K,T,T2,Controller} <: StochasticDiffEqNewtonAdaptiveAlgorithm{CS,AD,Controller}
linsolve::F
diff_type::FDT
Expand Down
182 changes: 182 additions & 0 deletions src/caches/split_step_caches.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
mutable struct ISSEMCache{uType,rateType,J,JC,UF,uEltypeNoUnits,noiseRateType,F} <: StochasticDiffEqMutableCache
u::uType
uprev::uType
du1::rateType
fsalfirst::rateType
k::rateType
z::uType
dz::uType
tmp::uType
gtmp::noiseRateType
gtmp2::rateType
J::J
W::J
jac_config::JC
linsolve::F
uf::UF
ηold::uEltypeNoUnits
κ::uEltypeNoUnits
tol::uEltypeNoUnits
newton_iters::Int
end

u_cache(c::ISSEMCache) = (c.uprev2,c.z,c.dz)
du_cache(c::ISSEMCache) = (c.k,c.fsalfirst)

function alg_cache(alg::ISSEM,prob,u,ΔW,ΔZ,p,rate_prototype,noise_rate_prototype,
uEltypeNoUnits,uBottomEltype,tTypeNoUnits,uprev,f,t,::Type{Val{true}})
du1 = zeros(rate_prototype)
J = zeros(uEltypeNoUnits,length(u),length(u)) # uEltype?
W = similar(J)
z = similar(u)
dz = similar(u); tmp = similar(u); gtmp = similar(noise_rate_prototype)
fsalfirst = zeros(rate_prototype)
k = zeros(rate_prototype)

uf = DiffEqDiffTools.UJacobianWrapper(f,t,p)
linsolve = alg.linsolve(Val{:init},uf,u)
jac_config = build_jac_config(alg,f,uf,du1,uprev,u,tmp,dz)
ηold = one(uEltypeNoUnits)

if alg.κ != nothing
κ = alg.κ
else
κ = uEltypeNoUnits(1//100)
end
if alg.tol != nothing
tol = alg.tol
else
reltol = 1e-1 # TODO: generalize
tol = min(0.03,first(reltol)^(0.5))
end

if is_diagonal_noise(prob)
gtmp2 = gtmp
else
gtmp2 = similar(rate_prototype)
end

ISSEMCache(u,uprev,du1,fsalfirst,k,z,dz,tmp,gtmp,gtmp2,J,W,jac_config,linsolve,uf,
ηold,κ,tol,10000)
end

mutable struct ISSEMConstantCache{F,uEltypeNoUnits} <: StochasticDiffEqConstantCache
uf::F
ηold::uEltypeNoUnits
κ::uEltypeNoUnits
tol::uEltypeNoUnits
newton_iters::Int
end

function alg_cache(alg::ISSEM,prob,u,ΔW,ΔZ,p,rate_prototype,noise_rate_prototype,
uEltypeNoUnits,uBottomEltype,tTypeNoUnits,uprev,f,t,::Type{Val{false}})
uf = DiffEqDiffTools.UDerivativeWrapper(f,t,p)
ηold = one(uEltypeNoUnits)

if alg.κ != nothing
κ = alg.κ
else
κ = uEltypeNoUnits(1//100)
end
if alg.tol != nothing
tol = alg.tol
else
reltol = 1e-1 # TODO: generalize
tol = min(0.03,first(reltol)^(0.5))
end

ISSEMConstantCache(uf,ηold,κ,tol,100000)
end

mutable struct ISSEulerHeunCache{uType,rateType,J,JC,UF,uEltypeNoUnits,noiseRateType,F} <: StochasticDiffEqMutableCache
u::uType
uprev::uType
du1::rateType
fsalfirst::rateType
k::rateType
z::uType
dz::uType
tmp::uType
gtmp::noiseRateType
gtmp2::rateType
gtmp3::noiseRateType
J::J
W::J
jac_config::JC
linsolve::F
uf::UF
ηold::uEltypeNoUnits
κ::uEltypeNoUnits
tol::uEltypeNoUnits
newton_iters::Int
end

u_cache(c::ISSEulerHeunCache) = (c.uprev2,c.z,c.dz)
du_cache(c::ISSEulerHeunCache) = (c.k,c.fsalfirst)

function alg_cache(alg::ISSEulerHeun,prob,u,ΔW,ΔZ,p,rate_prototype,noise_rate_prototype,
uEltypeNoUnits,uBottomEltype,tTypeNoUnits,uprev,f,t,::Type{Val{true}})
du1 = zeros(rate_prototype)
J = zeros(uEltypeNoUnits,length(u),length(u)) # uEltype?
W = similar(J)
z = similar(u)
dz = similar(u); tmp = similar(u); gtmp = similar(noise_rate_prototype)
fsalfirst = zeros(rate_prototype)
k = zeros(rate_prototype)

uf = DiffEqDiffTools.UJacobianWrapper(f,t,p)
linsolve = alg.linsolve(Val{:init},uf,u)
jac_config = build_jac_config(alg,f,uf,du1,uprev,u,tmp,dz)
ηold = one(uEltypeNoUnits)

if alg.κ != nothing
κ = alg.κ
else
κ = uEltypeNoUnits(1//100)
end
if alg.tol != nothing
tol = alg.tol
else
reltol = 1e-1 # TODO: generalize
tol = min(0.03,first(reltol)^(0.5))
end

gtmp2 = similar(rate_prototype)

if is_diagonal_noise(prob)
gtmp3 = gtmp2
else
gtmp3 = similar(noise_rate_prototype)
end

ISSEulerHeunCache(u,uprev,du1,fsalfirst,k,z,dz,tmp,gtmp,gtmp2,gtmp3,
J,W,jac_config,linsolve,uf,ηold,κ,tol,10000)
end

mutable struct ISSEulerHeunConstantCache{F,uEltypeNoUnits} <: StochasticDiffEqConstantCache
uf::F
ηold::uEltypeNoUnits
κ::uEltypeNoUnits
tol::uEltypeNoUnits
newton_iters::Int
end

function alg_cache(alg::ISSEulerHeun,prob,u,ΔW,ΔZ,p,rate_prototype,noise_rate_prototype,
uEltypeNoUnits,uBottomEltype,tTypeNoUnits,uprev,f,t,::Type{Val{false}})
uf = DiffEqDiffTools.UDerivativeWrapper(f,t,p)
ηold = one(uEltypeNoUnits)

if alg.κ != nothing
κ = alg.κ
else
κ = uEltypeNoUnits(1//100)
end
if alg.tol != nothing
tol = alg.tol
else
reltol = 1e-1 # TODO: generalize
tol = min(0.03,first(reltol)^(0.5))
end

ISSEulerHeunConstantCache(uf,ηold,κ,tol,100000)
end
1 change: 0 additions & 1 deletion src/perform_step/sdirk.jl
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@

cache.ηold = η
cache.newton_iters = iter
u = uprev + dt*(1-theta)*ftmp + theta*z + gtmp

if integrator.opts.adaptive

Expand Down
Loading

0 comments on commit b7579ea

Please sign in to comment.