Hi,
I have a delay differential equation model with 3 model parameters and a drug perturbation with one parameter (alpha). I’ve set up the simulation as:
using DifferentialEquations
using DataFrames, DataFramesMeta
using CairoMakie
# Model parameters
τ = 10.0
k1 = 0.1
k2 = 0.1
# dose
α = 2.0
D = 0.0
p = [τ, k1, k2, α, D]
# Initial conditions
x0 = [1.0, 1.0]
# DDEs
function model(dx, x, xτ, p, t)
τ, k1, k2, α, D = p
xτ1 = xτ(p, t-τ)[2]
dx[1] = 1/xτ1*(1 + α*D) - k1*x[1]
dx[2] = x[1] - k2*x[2]
end
# Define dose
dose = [0.0, 1.0, 3.0]
dose_time = 100.0
# Simulation time
t_span = (0.0, 300.0)
t_step = 1.0
# Initialise delay
xτ(p, t) = ones(2)
# Define problem
prob = DDEProblem(model, x0, xτ, t_span, p; constant_lags=[τ])
# Loop over doses
sol = DataFrame()
for i in eachindex(dose)
# Reset dose
p[5] = 0.0
# Callback
function affect!(integrator)
integrator.p[5] = dose[i]
end
cb_i = PresetTimeCallback(dose_time, affect!, save_positions=(false, false))
# Solve
sol_i = solve(prob, MethodOfSteps(Tsit5()), callback=cb_i, tstops=dose_time, saveat=t_step)
# Store
sol_i_df = @rtransform(DataFrame(sol_i), :dose = dose[i])
sol = [sol; sol_i_df]
end
# Plot
function _plt()
fig = Figure()
ax1 = Axis(fig[1, 1])
ax2 = Axis(fig[1, 2])
for i in eachindex(dose)
sol_i = @rsubset(sol, :dose == dose[i])
lines!(ax1, sol_i.timestamp, sol_i.value1)
lines!(ax2, sol_i.timestamp, sol_i.value2)
end
fig
end
_plt()
Now, I used this to generate dummy data as
# Generate dummy data
t_vec = hcat([sol[sol.dose.==i, :].timestamp for i in dose]...)'
data_mat = hcat([sol[sol.dose.==i, :].value2 .+ .5randn(size(t_vec,2)) for i in dose]...)'
Without the external forcing, I managed to estimate the parameters by writing a custom objective function along the lines of
Custom objective function
function _optim_fcn(prob, data_t, data_obs, p0)
function _cost_fcn(p, _)
# Redefine problem
new_prob = remake(prob; p=p)
# Solve DE
sol = solve(new_prob, MethodOfSteps(Tsit5()), saveat=data_t)
# Calculate sum of squares
loss = 0.0
for i in eachindex(sol_fc)
loss += (data_obs[i] - sol[i])^2
end
# Return
return loss, sol_fc
end
# Optimize for the parameters that minimize the loss
optf = OptimizationFunction(_cost_fcn, Optimization.AutoForwardDiff())
optprob = OptimizationProblem(optf, p0, lb=zeros(length(p0)), ub=300.0 * ones(length(p0)))
sol = solve(optprob, BFGS())
# return the parameters we found
return sol
end
But now, with the drug function across different doses and keeping alpha fixed, I’m struggling to implement a way to estimate the model parameters.
Any help would greatly be appreciated.