I have an MTK model (ported from the epidemics
R package where I build the model using a loop. How are symbolic arrays dealt with in the @mtkmodel
DSL? I’ve tried a few things, but I can’t find what I need to port this model over.
using Symbolics
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using LinearAlgebra
using OrdinaryDiffEq
using Plots
K = 3 # Number of age groups
@parameters σ γ N[1:K] B[1:K, 1:K] # exposure, recovery, population sizes, and contact matrix
@variables S(t)[1:K] E(t)[1:K] I(t)[1:K] R(t)[1:K] λ(t)[1:K] # SEIR and force of infection
eqs = Vector{ModelingToolkit.Equation}()
for k in 1:K
push!(eqs, λ[k] ~ sum([B[i,k]*I[i]/N[i] for i in 1:K]))
push!(eqs, D(S[k]) ~ -λ[k] * S[k])
push!(eqs, D(E[k]) ~ λ[k] * S[k] - σ*E[k])
push!(eqs, D(I[k]) ~ σ*E[k] - γ*I[k])
push!(eqs, D(R[k]) ~ γ*I[k])
end
@mtkbuild sys = ODESystem(eqs, t)
#sys = structural_simplify(sys) # This fails
uktotal = [14799290, 16526302, 28961159]
i₀ = 1e-6
inits = [1.0-i₀, 0.0, i₀, 0.0]
ukpop = hcat(repeat([uktotal], 4)...)
u0_vector = vec(hcat(repeat([inits], K)...)' .* ukpop)
cm_orig = hcat([[7.883663, 2.794154, 1.565665],
[3.120220, 4.854839, 2.624868],
[3.063895, 4.599893, 5.005571]]...)'
cm_norm = cm_orig/maximum(eigvals(cm_orig))
p = [sys.B => 1.3/7 * cm_norm,
sys.σ => 1.0/2,
sys.γ => 1.0/7,
sys.N => [14799290.0, 16526302.0, 28961159.0]]
u0 = [sys.S => u0_vector[1:K],
sys.E => u0_vector[K+1:2K],
sys.I => u0_vector[2K+1:3K],
sys.R => u0_vector[3K+1:4K]]
prob = ODEProblem(sys, u0, (0.0, 600.0), p)
sol = solve(prob, Tsit5(), saveat=1.0)
u = sol.u
S_out = permutedims(hcat([[u[i][j] for j in [1, 5, 9]] for i in 1:length(u)]...))
E_out = permutedims(hcat([[u[i][j] for j in [2, 6, 10]] for i in 1:length(u)]...))
I_out = permutedims(hcat([[u[i][j] for j in [3, 7, 11]] for i in 1:length(u)]...))
R_out = permutedims(hcat([[u[i][j] for j in [4, 8, 12]] for i in 1:length(u)]...))
plot(sol.t, I_out, label="Infectious", ylim=(0,500000))
plot!(sol.t, E_out, label="Exposed")
In addition, structural_simplify
throws an error on the system, which I found unexpected.
julia> structural_simplify(sys)
ERROR: ExtraVariablesSystemException: The system is unbalanced. There are 15 highest order derivative variables and 12 equations.
More variables than equations, here are the potential extra variable(s):
(S(t))[1]
(E(t))[1]
(I(t))[1]
(R(t))[1]
(S(t))[2]
(E(t))[2]
(I(t))[2]
(R(t))[2]
(S(t))[3]
(E(t))[3]
(I(t))[3]
(R(t))[3]
(λ(t))[1]
(λ(t))[2]
(λ(t))[3]
Stacktrace:
[1] error_reporting(state::TearingState{…}, bad_idxs::Vector{…}, n_highest_vars::Int64, iseqs::Bool, orig_inputs::Set{…})
@ ModelingToolkit.StructuralTransformations ~/.julia/packages/ModelingToolkit/cAhZr/src/structural_transformation/utils.jl:50
[2] check_consistency(state::TearingState{ODESystem}, orig_inputs::Set{Any})
@ ModelingToolkit.StructuralTransformations ~/.julia/packages/ModelingToolkit/cAhZr/src/structural_transformation/utils.jl:85
[3] _structural_simplify!(state::TearingState{…}, io::Nothing; simplify::Bool, check_consistency::Bool, fully_determined::Bool, warn_initialize_determined::Bool, dummy_derivative::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systemstructure.jl:689
[4] structural_simplify!(state::TearingState{…}, io::Nothing; simplify::Bool, check_consistency::Bool, fully_determined::Bool, warn_initialize_determined::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systemstructure.jl:635
[5] __structural_simplify(sys::ODESystem, io::Nothing; simplify::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systems.jl:0
[6] __structural_simplify
@ ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systems.jl:55 [inlined]
[7] structural_simplify(sys::ODESystem, io::Nothing; simplify::Bool, split::Bool, kwargs::@Kwargs{})
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systems.jl:22
[8] structural_simplify
@ ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systems.jl:19 [inlined]
[9] structural_simplify(sys::ODESystem)
@ ModelingToolkit ~/.julia/packages/ModelingToolkit/cAhZr/src/systems/systems.jl:19
[10] top-level scope
@ REPL[1]:1