ParameterizedFunctions.jl @ode_def programmatically generate model

Is there a way to pass variables into @ode_def that would be treated as constants in the ODE problem?

For example, something like

function create_model_def(male)
    h = male ? 2.0 : 7.0

    f = @ode_def begin
        dy₁ = -k₁*y₁+k₃*y₂*y₃
        dy₂ =  k₁*y₁-k₂*y₂^2-k₃*y₂*y₃
        dy₃ =  k₂*y₂^2 + h
    end k₁ k₂ k₃

end

This results in LoadError: UndefVarError: h not defined because h is not defined at the time the macro is expanded.

In my application, h would be a function with different constants that depend on if the model is for a male or female. I don’t want to pass in a bool as a model parameter so I can keep all parameters continuous to use the sensitivity analysis functions easily. Instead, I would like to generate separate ODE models programmatically. I also want to avoid re-writing the entire model for males and females because the vast majority of the model is identical.

Since macros act at parse time and @ode_def is a macro, you’d have to write a macro yourself to do this. It’s not too difficult, since it would just be:

using ParameterizedFunctions

macro create_model_def(male)
    val = male ? 2.0 : 7.0
    quote
        f = @ode_def begin
            dy₁ = -k₁*y₁+k₃*y₂*y₃
            dy₂ =  k₁*y₁-k₂*y₂^2-k₃*y₂*y₃
            dy₃ =  k₂*y₂^2 + $val
        end k₁ k₂ k₃
    end
end

@create_model_def true
@create_model_def false

However, this can get complicated fast, which is why we recommend the newer ModelingToolkit.jl for this kind of staged programming.

In ModelingToolkit, this looks like:

using ModelingToolkit

function create_model_def(male)
    @variables t y₁(t) y₂(t) y₃(t)
    @parameters k₁ k₂ k₃
    @derivatives D'~t
    val = male ? 2.0 : 7.0
    eqs = [D(y₁) ~ -k₁*y₁+k₃*y₂*y₃
           D(y₂) ~  k₁*y₁-k₂*y₂^2-k₃*y₂*y₃
           D(y₃) ~  k₂*y₂^2 + val]
    ODEFunction(ODESystem(eqs))
end
create_model_def(true)
create_model_def(false)

Thank you! Is ModelingToolkit.jl stable?

It just got to this point a few days ago, so it’s not like ParameterizedFunctions.jl which hasn’t changed syntax in 3 years and has no intention of ever changing again, but the current ModelingToolkit is the interface we plan on keeping and what we plan on generally pointing to as the symbolic front end for DifferentialEquations.jl and the SciML ecosystem as whole. At this point ParameterizedFunctions.jl is actually just converting that syntax to ModelingToolkit under the hood.