Hi All,
I’m trying to put together a DataDrivenDiffEq.jl
example for my demo system of an SIR epidemiological model.
using OrdinaryDiffEq
using DataDrivenDiffEq
using ModelingToolkit
function sir_ode(u,p,t)
(s,i,r) = u
(β,γ) = p
ds = -β*s*i
di = β*s*i - γ*i
dr = γ*i
[ds,di,dr]
end
p = [0.5,0.25]
u0 = [0.99, 0.01, 0.0]
tspan = (0.0, 40.0)
solver = ExplicitRK()
sir_prob = ODEProblem(sir_ode, u0, tspan, p)
sir_sol = solve(sir_prob, solver)
I use a sufficient basis to capture the above dynamics.
dd_prob = ContinuousDataDrivenProblem(sir_sol)
@parameters t
@variables u[1:3](t)
Ψ = Basis([u; u[1]*u[2]], u, independent_variable = t)
Koopman inference generates the correct set of equations, but the parameter values are incorrect.
res_koopman = solve(dd_prob, Ψ, DMDPINV(), digits = 1)
sys_koopman = result(res_koopman)
julia> equations(sys_koopman)
3-element Vector{Equation}:
Differential(t)(u[1](t)) ~ p₁*u[1](t)*u[2](t)
Differential(t)(u[2](t)) ~ p₂*u[2](t) + p₃*u[1](t)*u[2](t)
Differential(t)(u[3](t)) ~ p₄*u[2](t)
julia> parameter_map(res_koopman)
4-element Vector{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Float64}}:
p₁ => -0.5
p₂ => -0.2
p₃ => 0.5
p₄ => 0.2
p₂ and p₄ should be -0.25 and 0.25, while the rest of the solution is correct. The true values of all parameters are correctly identified using SINDy.
res_sindy = solve(dd_prob, Ψ, STLSQ(), digits = 1)
sys_sindy = result(res_sindy)
julia> parameter_map(res_sindy)
4-element Vector{Pair{Sym{Real, Base.ImmutableDict{DataType, Any}}, Float64}}:
p₁ => -0.5
p₂ => -0.25
p₃ => 0.5
p₄ => 0.25
Does anyone have an idea why Koopman inference comes so close, but doesn’t get it correct?