Skip to content

Commit 36911f9

Browse files
Merge pull request #14 from wi11dey/master
SecondOrderDDEProblem (and underlying DynamicalDDEProblem)
2 parents 983cc77 + c555ead commit 36911f9

File tree

3 files changed

+222
-11
lines changed

3 files changed

+222
-11
lines changed

src/SciMLBase.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,8 @@ export SplitSDEProblem
546546
export RODEProblem, RODESolution, SDEProblem
547547
export DAEProblem, DAESolution
548548
export DDEProblem
549+
export DynamicalDDEFunction, DynamicalDDEProblem,
550+
SecondOrderDDEProblem
549551
export SDDEProblem
550552
export PDEProblem
551553
export IncrementingODEProblem

src/problems/dde_problems.jl

Lines changed: 119 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
"""
22
$(TYPEDEF)
33
"""
4-
struct DDEProblem{uType,tType,lType,lType2,isinplace,P,F,H,K} <:
4+
struct StandardDDEProblem end
5+
6+
"""
7+
$(TYPEDEF)
8+
"""
9+
struct DDEProblem{uType,tType,lType,lType2,isinplace,P,F,H,K,PT} <:
510
AbstractDDEProblem{uType,tType,lType,isinplace}
611
f::F
712
u0::uType
@@ -13,18 +18,20 @@ struct DDEProblem{uType,tType,lType,lType2,isinplace,P,F,H,K} <:
1318
kwargs::K
1419
neutral::Bool
1520
order_discontinuity_t0::Int
21+
problem_type::PT
1622

1723
@add_kwonly function DDEProblem{iip}(f::AbstractDDEFunction{iip}, u0, h, tspan, p=NullParameters();
1824
constant_lags = (),
1925
dependent_lags = (),
2026
neutral = f.mass_matrix !== I && det(f.mass_matrix) != 1,
2127
order_discontinuity_t0 = 0,
28+
problem_type = StandardDDEProblem(),
2229
kwargs...) where {iip}
2330
_tspan = promote_tspan(tspan)
2431
new{typeof(u0),typeof(_tspan),typeof(constant_lags),typeof(dependent_lags),isinplace(f),
25-
typeof(p),typeof(f),typeof(h),typeof(kwargs)}(
32+
typeof(p),typeof(f),typeof(h),typeof(kwargs),typeof(problem_type)}(
2633
f, u0, h, _tspan, p, constant_lags, dependent_lags, kwargs, neutral,
27-
order_discontinuity_t0)
34+
order_discontinuity_t0, problem_type)
2835
end
2936

3037
function DDEProblem{iip}(f::AbstractDDEFunction{iip}, h, tspan::Tuple, p=NullParameters();
@@ -43,3 +50,112 @@ DDEProblem(f, args...; kwargs...) =
4350

4451
DDEProblem(f::AbstractDDEFunction, args...; kwargs...) =
4552
DDEProblem{isinplace(f)}(f, args...; kwargs...)
53+
54+
"""
55+
$(TYPEDEF)
56+
"""
57+
abstract type AbstractDynamicalDDEProblem end
58+
59+
"""
60+
$(TYPEDEF)
61+
"""
62+
struct DynamicalDDEProblem{iip} <: AbstractDynamicalDDEProblem end
63+
64+
# u' = f1(v,h)
65+
# v' = f2(t,u,h)
66+
"""
67+
DynamicalDDEProblem(f::DynamicalDDEFunction,v0,u0,tspan,p=NullParameters(),callback=CallbackSet())
68+
69+
Define a dynamical DDE problem from a [`DynamicalDDEFunction`](@ref).
70+
"""
71+
function DynamicalDDEProblem(f::DynamicalDDEFunction,v0,u0,h,tspan,p=NullParameters();dependent_lags=(),kwargs...)
72+
DDEProblem(f,ArrayPartition(v0,u0),h,tspan,p;
73+
problem_type=DynamicalDDEProblem{isinplace(f)}(),
74+
dependent_lags=ntuple(i->(u,p,t)->dependent_lags[i](u[1],u[2],p,t),length(dependent_lags)),
75+
kwargs...)
76+
end
77+
function DynamicalDDEProblem(f::DynamicalDDEFunction,h,tspan,p=NullParameters();kwargs...)
78+
DynamicalDDEProblem(f,h(p,first(tspan))...,h,tspan,p;kwargs...)
79+
end
80+
function DynamicalDDEProblem(f1::Function,f2::Function,args...;kwargs...)
81+
DynamicalDDEProblem(DynamicalDDEFunction(f1,f2),args...;kwargs...)
82+
end
83+
84+
"""
85+
DynamicalDDEProblem{isinplace}(f1,f2,v0,u0,h,tspan,p=NullParameters(),callback=CallbackSet())
86+
87+
Define a dynamical DDE problem from the two functions `f1` and `f2`.
88+
89+
# Arguments
90+
* `f1` and `f2`: The functions in the DDE.
91+
* `v0` and `u0`: The initial conditions.
92+
* `h`: The initial history function.
93+
* `tspan`: The timespan for the problem.
94+
* `p`: Parameter values for `f1` and `f2`.
95+
* `callback`: A callback to be applied to every solver which uses the problem. Defaults to nothing.
96+
97+
`isinplace` optionally sets whether the function is inplace or not.
98+
This is determined automatically, but not inferred.
99+
"""
100+
function DynamicalDDEProblem{iip}(f1::Function,f2::Function,args...;kwargs...) where iip
101+
DynamicalDDEProblem(DynamicalDDEFunction{iip}(f1,f2),args...;kwargs...)
102+
end
103+
104+
# u'' = f(du,u,h,p,t)
105+
"""
106+
$(TYPEDEF)
107+
"""
108+
struct SecondOrderDDEProblem{iip} <: AbstractDynamicalDDEProblem end
109+
function SecondOrderDDEProblem(f,args...;kwargs...)
110+
iip = isinplace(f,6)
111+
SecondOrderDDEProblem{iip}(f,args...;kwargs...)
112+
end
113+
114+
"""
115+
SecondOrderDDEProblem{isinplace}(f,du0,u0,h,tspan,p=NullParameters(),callback=CallbackSet())
116+
117+
Define a second order DDE problem with the specified function.
118+
119+
# Arguments
120+
* `f`: The function for the second derivative.
121+
* `du0`: The initial derivative.
122+
* `u0`: The initial condition.
123+
* `h`: The initial history function.
124+
* `tspan`: The timespan for the problem.
125+
* `p`: Parameter values for `f`.
126+
* `callback`: A callback to be applied to every solver which uses the problem. Defaults to nothing.
127+
128+
`isinplace` optionally sets whether the function is inplace or not.
129+
This is determined automatically, but not inferred.
130+
"""
131+
function SecondOrderDDEProblem{iip}(f,args...;kwargs...) where iip
132+
if iip
133+
f2 = function (du,v,u,h,p,t)
134+
du .= v
135+
end
136+
else
137+
f2 = function (v,u,h,p,t)
138+
v
139+
end
140+
end
141+
DynamicalDDEProblem{iip}(f,f2,args...;problem_type=SecondOrderDDEProblem{iip}(),kwargs...)
142+
end
143+
function SecondOrderDDEProblem(f::DynamicalDDEFunction,args...;kwargs...)
144+
iip = isinplace(f.f1, 6)
145+
if f.f2.f === nothing
146+
if iip
147+
f2 = function (du,v,u,h,p,t)
148+
du .= v
149+
end
150+
else
151+
f2 = function (v,u,h,p,t)
152+
v
153+
end
154+
end
155+
return DynamicalDDEProblem(DynamicalDDEFunction{iip}(f.f1,f2;mass_matrix=f.mass_matrix,analytic=f.analytic),
156+
args...;problem_type=SecondOrderDDEProblem{iip}(),kwargs...)
157+
else
158+
return DynamicalDDEProblem(DynamicalDDEFunction{iip}(f.f1,f.f2;mass_matrix=f.mass_matrix,analytic=f.analytic),
159+
args...;problem_type=SecondOrderDDEProblem{iip}(),kwargs...)
160+
end
161+
end

src/scimlfunctions.jl

Lines changed: 101 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,27 @@ struct DDEFunction{iip,F,TMM,Ta,Tt,TJ,JVP,VJP,JP,SP,TW,TWt,TPJ,S,TCV} <: Abstrac
109109
colorvec::TCV
110110
end
111111

112+
"""
113+
$(TYPEDEF)
114+
"""
115+
struct DynamicalDDEFunction{iip,F1,F2,TMM,Ta,Tt,TJ,JVP,VJP,JP,SP,TW,TWt,TPJ,S,TCV} <: AbstractDDEFunction{iip}
116+
f1::F1
117+
f2::F2
118+
mass_matrix::TMM
119+
analytic::Ta
120+
tgrad::Tt
121+
jac::TJ
122+
jvp::JVP
123+
vjp::VJP
124+
jac_prototype::JP
125+
sparsity::SP
126+
Wfact::TW
127+
Wfact_t::TWt
128+
paramjac::TPJ
129+
syms::S
130+
colorvec::TCV
131+
end
132+
112133
"""
113134
$(TYPEDEF)
114135
"""
@@ -322,6 +343,21 @@ end
322343
(f::DDEFunction)(args...) = f.f(args...)
323344
(f::DDEFunction)(::Type{Val{:analytic}},args...) = f.analytic(args...)
324345

346+
function (f::DynamicalDDEFunction)(u,h,p,t)
347+
ArrayPartition(f.f1(u.x[1],u.x[2],h,p,t),f.f2(u.x[1],u.x[2],h,p,t))
348+
end
349+
function (f::DynamicalDDEFunction)(du,u,h,p,t)
350+
f.f1(du.x[1],u.x[1],u.x[2],h,p,t)
351+
f.f2(du.x[2],u.x[1],u.x[2],h,p,t)
352+
end
353+
function Base.getproperty(f::DynamicalDDEFunction, name::Symbol)
354+
if name === :f
355+
# Use the f property as an alias for calling the function itself, so DynamicalDDEFunction fits the same interface as DDEFunction as expected by the ODEFunctionWrapper in DelayDiffEq.jl.
356+
return f
357+
end
358+
return getfield(f, name)
359+
end
360+
325361
(f::SDEFunction)(args...) = f.f(args...)
326362
(f::SDEFunction)(::Type{Val{:analytic}},args...) = f.analytic(args...)
327363
(f::SDEFunction)(::Type{Val{:tgrad}},args...) = f.tgrad(args...)
@@ -933,6 +969,63 @@ DDEFunction{iip}(f::DDEFunction; kwargs...) where iip = f
933969
DDEFunction(f; kwargs...) = DDEFunction{isinplace(f, 5),RECOMPILE_BY_DEFAULT}(f; kwargs...)
934970
DDEFunction(f::DDEFunction; kwargs...) = f
935971

972+
@add_kwonly function DynamicalDDEFunction{iip}(f1,f2,mass_matrix,analytic,tgrad,jac,jvp,vjp,
973+
jac_prototype,sparsity,Wfact,Wfact_t,paramjac,
974+
syms,colorvec) where iip
975+
f1 = typeof(f1) <: AbstractDiffEqOperator ? f1 : DDEFunction(f1)
976+
f2 = DDEFunction(f2)
977+
DynamicalDDEFunction{isinplace(f2),typeof(f1),typeof(f2),typeof(mass_matrix),
978+
typeof(analytic),typeof(tgrad),typeof(jac),typeof(jvp),typeof(vjp),
979+
typeof(jac_prototype),
980+
typeof(Wfact),typeof(Wfact_t),typeof(paramjac),typeof(syms),
981+
typeof(colorvec)}(f1,f2,mass_matrix,analytic,tgrad,jac,jvp,vjp,
982+
jac_prototype,sparsity,Wfact,Wfact_t,paramjac,syms,colorvec)
983+
end
984+
function DynamicalDDEFunction{iip,true}(f1,f2;mass_matrix=I,
985+
analytic=nothing,
986+
tgrad=nothing,
987+
jac=nothing,
988+
jvp=nothing,
989+
vjp=nothing,
990+
jac_prototype=nothing,
991+
sparsity=jac_prototype,
992+
Wfact=nothing,
993+
Wfact_t=nothing,
994+
paramjac = nothing,
995+
syms = nothing,
996+
colorvec = nothing) where iip
997+
DynamicalDDEFunction{iip,typeof(f1),typeof(f2),typeof(mass_matrix),
998+
typeof(analytic),
999+
typeof(tgrad),typeof(jac),typeof(jvp),typeof(vjp),typeof(jac_prototype),typeof(sparsity),
1000+
typeof(Wfact),typeof(Wfact_t),typeof(paramjac),typeof(syms),
1001+
typeof(colorvec)}(
1002+
f1,f2,mass_matrix,analytic,tgrad,jac,jvp,vjp,jac_prototype,sparsity,
1003+
Wfact,Wfact_t,paramjac,syms,colorvec)
1004+
end
1005+
function DynamicalDDEFunction{iip,false}(f1,f2;mass_matrix=I,
1006+
analytic=nothing,
1007+
tgrad=nothing,
1008+
jac=nothing,
1009+
jvp=nothing,
1010+
vjp=nothing,
1011+
jac_prototype=nothing,
1012+
sparsity=jac_prototype,
1013+
Wfact=nothing,
1014+
Wfact_t=nothing,
1015+
paramjac = nothing,
1016+
syms = nothing,
1017+
colorvec = nothing) where iip
1018+
DynamicalDDEFunction{iip,Any,Any,Any,Any,Any,Any,Any,
1019+
Any,Any,Any,Any,Any}(
1020+
f1,f2,mass_matrix,analytic,tgrad,
1021+
jac,jvp,vjp,jac_prototype,sparsity,
1022+
Wfact,Wfact_t,paramjac,syms,colorvec)
1023+
end
1024+
DynamicalDDEFunction(f1,f2=nothing; kwargs...) = DynamicalDDEFunction{isinplace(f1, 6)}(f1, f2; kwargs...)
1025+
DynamicalDDEFunction{iip}(f1,f2; kwargs...) where iip =
1026+
DynamicalDDEFunction{iip,RECOMPILE_BY_DEFAULT}(DDEFunction{iip}(f1), DDEFunction{iip}(f2); kwargs...)
1027+
DynamicalDDEFunction(f::DynamicalDDEFunction; kwargs...) = f
1028+
9361029
function SDDEFunction{iip,true}(f,g;
9371030
mass_matrix=I,
9381031
analytic=nothing,
@@ -1135,14 +1228,14 @@ has_Wfact_t(f::Union{SplitFunction,SplitSDEFunction}) = has_Wfact_t(f.f1)
11351228
has_paramjac(f::Union{SplitFunction,SplitSDEFunction}) = has_paramjac(f.f1)
11361229
has_colorvec(f::Union{SplitFunction,SplitSDEFunction}) = has_colorvec(f.f1)
11371230

1138-
has_jac(f::DynamicalODEFunction) = has_jac(f.f1)
1139-
has_jvp(f::DynamicalODEFunction) = has_jvp(f.f1)
1140-
has_vjp(f::DynamicalODEFunction) = has_vjp(f.f1)
1141-
has_tgrad(f::DynamicalODEFunction) = has_tgrad(f.f1)
1142-
has_Wfact(f::DynamicalODEFunction) = has_Wfact(f.f1)
1143-
has_Wfact_t(f::DynamicalODEFunction) = has_Wfact_t(f.f1)
1144-
has_paramjac(f::DynamicalODEFunction) = has_paramjac(f.f1)
1145-
has_colorvec(f::DynamicalODEFunction) = has_colorvec(f.f1)
1231+
has_jac(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_jac(f.f1)
1232+
has_jvp(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_jvp(f.f1)
1233+
has_vjp(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_vjp(f.f1)
1234+
has_tgrad(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_tgrad(f.f1)
1235+
has_Wfact(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_Wfact(f.f1)
1236+
has_Wfact_t(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_Wfact_t(f.f1)
1237+
has_paramjac(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_paramjac(f.f1)
1238+
has_colorvec(f::Union{DynamicalODEFunction,DynamicalDDEFunction}) = has_colorvec(f.f1)
11461239

11471240
has_jac(f::Union{UDerivativeWrapper,UJacobianWrapper}) = has_jac(f.f)
11481241
has_jvp(f::Union{UDerivativeWrapper,UJacobianWrapper}) = has_jvp(f.f)

0 commit comments

Comments
 (0)