Skip to content

explicit handling of LabelledArrays (and NamedTuples?) #1054

@fkrauer

Description

@fkrauer

I have an example, where LabelledArrays are not accepted. I'd love to use modelingtoolkitize, but I prefer to use labelled arrays to keep track of my parameters. Would be great if this could work. The modelingtoolkitized solution also loses the names for the states and returns x1..xn, which is a bit of a pity.

This code:

using DifferentialEquations
using StatsPlots
using Turing
using Distributions
using Random
using StatsBase
using LabelledArrays
using ModelingToolkit
#using DynamicHMC

Random.seed!(42)

# ODE model: simple SIR model with seasonally forced contact rate
function SIR!(du,u,p,t)

    # states
    (S, I, R) = u[1:3]
    N = S + I + R
  
    # params
    β = p.β
    η = p.η
    φ = p.φ
    ω = 1.0/p.ω
    μ = p.μ
    σ = p.σ
      
    # FOI
    βeff = β * (1.0+η*cos(2.0*π*(t-φ)/365.0))
    λ = βeff*I/N

    # change in states
    du[1] = (μ*N - λ*S - μ*S + ω*R)
    du[2] = (λ*S - σ*I - μ*I)
    du[3] = (σ*I - μ*R - ω*R)
    du[4] = (σ*I) # cumulative incidence

end
  
# Solver settings
tmin = 0.0
tmax = 10.0*365.0
tspan = (tmin, tmax)
solvsettings = (abstol = 1.0e-6, 
                reltol = 1.0e-3, 
                saveat = 7.0,
                solver = AutoTsit5(Rosenbrock23()))

# Initiate ODE problem
theta_fix =  [1.0/(80*365)]
theta_est =  [0.28, 0.07, 1.0/365.0, 1.0 ,1.0/5.0]
p = @LArray [theta_est; theta_fix] (:β, :η, :ω, :φ, :σ, :μ)
u0 = @LArray [9998.0,1.0,1.0,1.0] (:S,:I,:R,:C)

# Initiate ODE problem
problem = ODEProblem(SIR!,u0,tspan,p)
problem_acc = ODEProblem(modelingtoolkitize(problem), u0, tspan, p, jac=true, sparse=true)

sol = solve(problem_acc, 
            solvsettings.solver, 
            abstol=solvsettings.abstol, 
            reltol=solvsettings.reltol, 
            isoutofdomain=(u,p,t)->any(x->x<0.0,u), 
            saveat=solvsettings.saveat)

throws an error:

ERROR: LoadError: type Array has no field β

But this works:

function SIR!(du,u,p,t)

    # states
    (S, I, R) = u[1:3]
    N = S + I + R
  
    # params
    β, η, ω, φ, σ, μ = p
      
    # FOI
    βeff = β * (1.0+η*cos(2.0*π*(t-φ)/365.0))
    λ = βeff*I/N

    # change in states
    du[1] = (μ*N - λ*S - μ*S + ω*R)
    du[2] = (λ*S - σ*I - μ*I)
    du[3] = (σ*I - μ*R - ω*R)
    du[4] = (σ*I) # cumulative incidence

end

p = [theta_est; theta_fix]

#--> plug p in code above

Originally posted by @fkrauer in #1009 (comment)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions