Hello, my question is both related to building functions from expressions and DiffEq domain.
I am working on a simulation engine based on ODE solver and the input problems for the solver are provided as JSON files, which includes initial values and all the expressions to build ODE system and other related functions. I can easily parse this file, replace simbols in Expr with p[i]
, u[i]
and have an Expr blocks to build, for example, ode_func
- ODE system and saving_func
- the output function for ODEProblem
:
ode_expr = quote
A = u[1]
B = u[2]
k1 = p[1]
comp1 = p[2]
v1 = k1 * A * comp1
du[1] = -v1
du[2] = v1
end
saving_expr = quote
A = u[1]
B = u[2]
k1 = integrator.p[1]
comp1 = integrator.p[2]
v1 = k1 * A * comp1
[A, B, k1, v1]
end
Those exprs are runtime data but initially I know the arguments and output types for functions, so I can build ode_func
and saving_func
and form ODEProblem
:
@eval ode_func(du,u,p,t) = $ode_expr
@eval saving_func(u,t,integrator) = $saving_expr
out = SavedValues(Float64, Vector{Float64})
scb = SavingCallback(saving_func, out)
prob = ODEProblem(ode_func, u0, tspan, p0, callback=scb)
However when I try to solve the prob
: solve(prob,Tsit5())
I encounter world age error
:
The applicable method may be too new: running in world age 27808, while current world is 27811.
I know that it can be solved with invokelatest
but here saving_func
is not called directly but provided to another function solve
…
I’ll be grateful if someone helps me solve this issue. Is “parse |> eval” the only (correct?) way to build functions here (or macros can do it in a nicer way) and how to solve world age error
in this case?