JuliaSymbolics / Symbolics.jl

Symbolic programming for the next generation of numerical software
https://docs.sciml.ai/Symbolics/stable/
Other
1.37k stars 153 forks source link

How to @register_symbolic a function by a non-interactive way #1097

Closed chooron closed 7 months ago

chooron commented 8 months ago

I want to build a function that can automatically perform interpolation based on input data and register the interpolation function for each variable using @register_symbolic. Then, I want to construct an ODESystem and concatenate it with other ODESystem. The code is as follows:

function build_interpolation_system(
    input::ComponentVector{T},
    time::Vector{T};
    name::Symbol=:interpolator
) where {T<:Number}
    eqs = []
    for nm in keys(input)
        func_nm = Symbol(nm, "_itp")
        tmp_itp = data_itp(t, time, input[nm])
        eval(:($(func_nm)(t) = $tmp_itp))
        eval(:(@register_symbolic $(func_nm)(t)))
        push!(eqs, eval(:($nm ~ $(func_nm)(t))))
    end
    ODESystem(eqs, t; name=name)
end

However, after reading the documentation, I found that only @variables can define variables using Symbols in a "non-interactive way", while @register_symbolic does not support this. Therefore, I used eval(:(@register_symbolic $(func_nm)(t))) to register my function. But this approach also has problems. When testing, this method raises an error:


WARNING: replacing module DeepFlex.
ERROR: MethodError: no method matching pet_itp(::Float64)
The applicable method may be too new: running in world age 41654, while current world is 41666.

Closest candidates are:
  pet_itp(::Any) (method too new to be called from this world context.)
   @ Main.DeepFlex e:\JlCode\DeepFlex.jl\src\framework\mtk.jl:120
  pet_itp(::Num) (method too new to be called from this world context.)
   @ Main.DeepFlex D:\Julia\Julia-1.10.0\packages\packages\Symbolics\5oRzS\src\wrapper-types.jl:142
  pet_itp(::SymbolicUtils.Symbolic{<:Real}) (method too new to be called from this world context.)
   @ Main.DeepFlex D:\Julia\Julia-1.10.0\packages\packages\Symbolics\5oRzS\src\wrapper-types.jl:142

And when I delete line mtk.jl:120, i.e., not registering this function, the error doesn't occur, but the equations' result is not aesthetic.

I would like to ask if there is any way to optimize my code and solve this problem.

ChrisRackauckas commented 7 months ago

Just set the interpolation to be a callable function that is registered. DataInterpolations.jl already does this for its interpolators, so you can just use or copy that: https://github.com/SciML/DataInterpolations.jl/blob/master/ext/DataInterpolationsSymbolicsExt.jl