DDE parameter estimation with unknown constant delay using DiffEqFlux

I am trying to estimate the parameters for a delay differential equation. One of the parameters that I try to estimate is the (constant) delay itself. Following the tutorial documentation, I wrote the following code:

prob = DDEProblem(model, u0, h, tspan, p0[1:15], constant_lags=[p0[15]])
alg = MethodOfSteps(Tsit5())
sol = solve(prob,alg,saveat=time_points,abstol=1e-5,reltol=1e-5)

function problem_gen(prob,p)
    u0 = [p[16]; 0.0; 0.0; data[1,1]; data[2,1]; (p[5] + p[6]*p[9])*p[8]]
    h(p,t; idxs=nothing) = typeof(idxs) <: Number ? 0.0 : u0
    new_prob = remake(prob;u0=u0,h=h,p=p[1:15],constant_lags=[p[15]])
end

function predict_dde(p)
    prob_ = problem_gen(prob,p)
    sol = solve(prob_,alg,saveat=1.0,abstol=1e-5,reltol=1e-5,
                cb=PositiveDomain(zeros(6)))
    Array(sol)
end

function loss_dde(p)
    error = sum(abs2,data-predict_dde(p)[4:5,:])
end

cb = function (p,l...)
    display(loss_dde(p))
    return false
end

p_start = param_space[120,:]

cb(p_start,loss_dde(p_start))
result_dde = DiffEqFlux.sciml_train(loss_dde, p_start, ADAM(),
                                    cb = cb, maxiters = 100)

When I run the code, I get the following error:

ERROR: MethodError: no method matching model(::Array{ReverseDiff.TrackedReal{Float64,Float64,ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}}},1}, ::ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}}, ::ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}}, ::ReverseDiff.TrackedReal{Float64,Float64,ReverseDiff.TrackedArray{Float64,Float64,1,Array{Float64,1},Array{Float64,1}}})

I was wondering if it is possible to do this estimation using DiffEqFlux at all.

Many thanks in advance for any input!

The DDE lag parameter has massive issues with discontinuities (it changes the number and points of discontinuity) which in turn means it has very big issues with local minima behavior. You’d be better served by using a global optimizer here. The ones I usually use for this kind of case are:

https://galacticoptim.sciml.ai/dev/global_optimizers/global/

1 Like

Thanks a lot @ChrisRackauckas! I was already using BlackBoxOptim, but I thought maybe training would work better (more smooth solutions) if I used collocation which is included in DiffEqFlux. It is also good that I learned about GalacticOptim!