You can use, e.g.,
using DifferentialEquations, Plots
h(p, t) = zeros(3)
function pkiv(du, u, h, p, t)
hist2 = h(p, t - 2)[2]
hist3 = h(p, t - 10)[3]
k₁, k₂, k₃ = p
A, B, C = u
du[1] = - k₁ * A * B + k₃ * hist3
du[2] = k₁ * A * B - k₂ * hist2
du[3] = k₂ * hist2 - k₃ * hist3
nothing
end
u0 = [10.0, 1.0, 0]
p = [0.1, 0.15, 0.1]
tspan = (0.0, 60.0)
prob = DDEProblem(pkiv, u0, h, tspan, p; constant_lags=(2, 10))
alg = MethodOfSteps(Tsit5())
sol = solve(prob, alg)
plot(sol)
I removed hist1
since it was not used. Moreover, h(p, t)
will be equal to u
as that is the “history” at the current time with the given parameters.
constant_lags
should be a collection (i.e., tuple, array, etc.) of the constant delays (if you want to specify them). The documentation also contains a list of other problem-specific options.
By the way, if you only use the DDE solvers, you can reduce loading and compilation times by only loading DelayDiffEq
instead of DifferentialEquations
.
In this case you can also speed up the evaluation of the history function by extracting the desired indices directly:
using DifferentialEquations, Plots
function h_idxs(p, t; idxs::Union{Int,Nothing}=nothing)
if idxs === nothing
zeros(3)
else
0.0
end
end
function pkiv_idxs(du, u, h, p, t)
hist2 = h(p, t - 2; idxs=2)
hist3 = h(p, t - 10; idxs=3)
k₁, k₂, k₃ = p
A, B, C = u
du[1] = - k₁ * A * B + k₃ * hist3
du[2] = k₁ * A * B - k₂ * hist2
du[3] = k₂ * hist2 - k₃ * hist3
nothing
end
u0 = [10.0, 1.0, 0]
p = [0.1, 0.15, 0.1]
tspan = (0.0, 60.0)
prob_idxs = DDEProblem(pkiv_idxs, u0, h_idxs, tspan, p; constant_lags=(2, 10))
alg = MethodOfSteps(Tsit5())
sol = solve(prob_idxs, alg)
plot(sol)
A quick timing with @time
confirms that this reduces allocations (but does not seem to have a significant impact on computation time in this example):
julia> @time solve(prob, alg);
0.000178 seconds (2.72 k allocations: 232.328 KiB)
julia> @time solve(prob_idxs, alg);
0.000176 seconds (1.55 k allocations: 141.078 KiB)