ModelingToolkit.jl icon indicating copy to clipboard operation
ModelingToolkit.jl copied to clipboard

Array variable not recognized in registered function call

Open baggepinnen opened this issue 2 weeks ago • 1 comments

I was experimenting with a replacement for the SampledData component from MTKstdlib that leverages array variables. The idea is to call

f ~ interpolate(int_type, int_data, int_time, t)

where int_data, int_time are symbolic arrays, such that they can be replaced by replacing the parameters. I can't get @register_symbolic to handle this signature, so I registered manually using

interpolate(int, d::Symbolics.Arr, time, t::Num, args...) = SymbolicUtils.term(interpolate, int, d, time, t, type = Real)

However, the symbolic array variables do not appear to be recognized as present in the system, because the generated code does not unpack them from the parameter object:

julia> prob.f.f.f_oop
RuntimeGeneratedFunction(#=in ModelingToolkit=#, #=using ModelingToolkit=#, :((ˍ₋arg1, ˍ₋arg2, t)->begin
          #= /home/fredrikb/.julia/packages/SymbolicUtils/0opve/src/code.jl:373 =#
          #= /home/fredrikb/.julia/packages/SymbolicUtils/0opve/src/code.jl:374 =#
          #= /home/fredrikb/.julia/packages/SymbolicUtils/0opve/src/code.jl:375 =#
          begin
              begin
                  begin
                      var"f(t)" = (interpolate)(Linear(), int_data, int_time, t)
                      var"ddx(t)" = (*)(1//10, (+)((+)(var"f(t)", (*)(ˍ₋arg2[2], ˍ₋arg1[2])), (*)(ˍ₋arg2[8], ˍ₋arg1[1])))
                      begin
                          #= /home/fredrikb/.julia/packages/SymbolicUtils/0opve/src/code.jl:468 =#
                          (SymbolicUtils.Code.create_array)(typeof(ˍ₋arg1), nothing, Val{1}(), Val{(2,)}(), ˍ₋arg1[2], var"ddx(t)")
                      end
                  end
              end
          end
      end))

and calling solve thus fails with

julia> sol = solve(prob, Tsit5())
ERROR: UndefVarError: `int_data` not defined

Here's the current implementation of the new SampledData that reproduces the error

using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using DataInterpolations
using DataInterpolations: AbstractInterpolation
using OrdinaryDiffEq

interpolate(::Type{T}, data::AbstractArray, time, t::AbstractFloat) where T = T(data, time)(t)

# @register_symbolic interpolate(int_type, data, time, t)
# interpolate(int::SymbolicUtils.BasicSymbolic{Interpolation}, args...) = SymbolicUtils.term(interpolate, int, args..., type = Real)
interpolate(int, d::Symbolics.Arr, time, t::Num, args...) = SymbolicUtils.term(interpolate, int, d, time, t, type = Real)
# Base.delete_method.(methods(interpolate))

@mtkmodel SystemWithInput begin
    @parameters begin
        m=10
        k=1000
        d=1
        int_time[1:11]
        int_data[1:11]
        # int::AbstractInterpolation
    end
    @structural_parameters begin
        int_type#::Interpolation
    end
    @variables begin
        f(t) = 0
        x(t) = 0
        dx(t) = 0
        ddx(t) = 0
    end
    @equations begin
        f ~ interpolate(int_type, int_data, int_time, t)
        # f ~ int(t)
        ddx * 10 ~ k * x + d * dx + f
        D(x) ~ dx
        D(dx) ~ ddx
    end
end


tv = 0:10
data = rand(length(tv))
int = LinearInterpolation(data, tv)
# @mtkbuild sys = SystemWithInput(; int)
int_time = tv
int_data = data
int_type = LinearInterpolation
@mtkbuild sys = SystemWithInput(; int_time, int_data, int_type)
prob = ODEProblem(sys, [], (0.0, 10.0))
sol = solve(prob, Tsit5())

baggepinnen avatar Jun 17 '24 05:06 baggepinnen