ModelingToolkit parameter fit: keep some parameters fixed

I am trying to fit parameters in a ModelingToolkit model using DiffEqParamEstim. This works well when fitting all parameters contained in the model, but I would like to keep some of them fixed. For example, in the following example I would like to fit b but keep a fixed. I was hoping to achieve this via defaults, but it seems that all parameters in sys are passed into the fit. Does anyone know how this could be done? The idea is to be able to change which parameters are fitted without redefining the model itself.

using ModelingToolkit
using DifferentialEquations
using DiffEqParamEstim
using BlackBoxOptim

@variables t x[1:3](t)
@parameters a b
Dt = Differential(t)

x = Symbolics.scalarize(x)

eqs = Dt.(x) .~ a .* x .- b .* (x .^ 2)

@named sys = ODESystem(eqs, defaults=[a=>0.5])

u0 = vcat(x .=> [1.0, 5.0, 10.0])

time = collect(0:0.1:10)
prob = ODEProblem(sys, u0, (0.0,10.0), [b=>0.2], saveat=time)

sol = solve(prob)
# use these time traces for fit 
expt = transpose(hcat(sol.u...))

bounds = [(0,10),(0,10)]

function lossfunc(sol)
    sim = transpose(hcat(sol.u...))
    sum(abs2, sim .- expt)
end

costfunc = build_loss_objective(prob,Tsit5(),lossfunc)

resultBBO = bboptimize(costfunc; SearchRange = bounds, MaxTime=10)

2-element Vector{Float64}:
 0.2
 0.5

This is much easier in the DiffEqFlux style.

1 Like

Thanks Chris! I have looked into DiffEqFlux now, but couldn’t quite figure out how it would help with fixing some of the parameters. Do you mean using sciml_train instead of DiffEqParamEstim?

Yes.

function loss(p)
  sol = solve(prob, Tsit5(), p=[p[1:3];1.0], saveat = tsteps)
  loss = sum(abs2, sol.-1)
  return loss, sol
end

now it’s only training 3 out of the 4 parameters.