# ModelingToolKit: Cannot \`convert\` an object of type SymbolicUtils.BasicSymbolic{Float64}

**URL:** <https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213>\
**Category:** Modelling & Simulations\
**Created:** [July 19, 2024, 5:58am UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213 "2024-07-19T05:58:22Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 19, 2024, 5:58am UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213/1 "2024-07-19T05:58:22Z")

</div>

```julia
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as D
using DifferentialEquations: solve

f(t) = t
@register_symbolic f(t)

@mtkmodel FOL begin
    @variables begin
        y(t)
        z(t)
    end
    @equations begin
        y ~ f(t)
        D(z) ~ D(y)
    end
end

@mtkbuild fol = FOL()
prob = ODEProblem(fol, [fol.z => 1], (0.0, 18.0), []);
sol = solve(prob);

```

yields

```julia
MethodError: Cannot `convert` an object of type SymbolicUtils.BasicSymbolic{Float64} to an object of type Float64
Stacktrace:
  [1] setindex!(A::Vector{Float64}, x::SymbolicUtils.BasicSymbolic{Float64}, i1::Int64)
    @ Base .\array.jl:1021
  [2] macro expansion
    @ C:\Users\a1058035\.julia\packages\SymbolicUtils\EGhOJ\src\code.jl:418 [inlined]
  [3] macro expansion
    @ C:\Users\a1058035\.julia\packages\Symbolics\Nk48t\src\build_function.jl:546 [inlined]
  [4] macro expansion
    @ C:\Users\a1058035\.julia\packages\SymbolicUtils\EGhOJ\src\code.jl:375 [inlined]
  [5] macro expansion
    @ C:\Users\a1058035\.julia\packages\RuntimeGeneratedFunctions\M9ZX8\src\RuntimeGeneratedFunctions.jl:163 [inlined]
  [6] macro expansion
    @ .\none:0 [inlined]
  [7] generated_callfunc
    @ .\none:0 [inlined]
  [8] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{…})(::Vector{…}, ::Vector{…}, ::Vector{…}, ::Float64)
    @ RuntimeGeneratedFunctions C:\Users\a1058035\.julia\packages\RuntimeGeneratedFunctions\M9ZX8\src\RuntimeGeneratedFunctions.jl:150
  [9] (::ModelingToolkit.var"#f#717"{…})(du::Vector{…}, u::Vector{…}, p::ModelingToolkit.MTKParameters{…}, t::Float64)
    @ ModelingToolkit C:\Users\a1058035\.julia\packages\ModelingToolkit\U2JaS\src\systems\diffeqs\abstractodesystem.jl:342
 [10] (::SciMLBase.Void{ModelingToolkit.var"#f#717"{…}})(::Vector{Float64}, ::Vararg{Any})
    @ SciMLBase C:\Users\a1058035\.julia\packages\SciMLBase\rR75x\src\utils.jl:482
 [11] (::FunctionWrappers.CallWrapper{…})(f::SciMLBase.Void{…}, arg1::Vector{…}, arg2::Vector{…}, arg3::ModelingToolkit.MTKParameters{…}, arg4::Float64)
    @ FunctionWrappers C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:65
 [12] macro expansion
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:137 [inlined]
 [13] do_ccall
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:125 [inlined]
 [14] FunctionWrapper
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:144 [inlined]
 [15] _call
    @ C:\Users\a1058035\.julia\packages\FunctionWrappersWrappers\9XR0m\src\FunctionWrappersWrappers.jl:12 [inlined]
 [16] FunctionWrappersWrapper
    @ C:\Users\a1058035\.julia\packages\FunctionWrappersWrappers\9XR0m\src\FunctionWrappersWrappers.jl:10 [inlined]
 [17] Void
    @ C:\Users\a1058035\.julia\packages\SciMLBase\rR75x\src\utils.jl:482 [inlined]
 [18] (::FunctionWrappers.CallWrapper{…})(f::SciMLBase.Void{…}, arg1::Vector{…}, arg2::Vector{…}, arg3::ModelingToolkit.MTKParameters{…}, arg4::Float64)
    @ FunctionWrappers C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:65
 [19] macro expansion
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:137 [inlined]
 [20] do_ccall
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:125 [inlined]
 [21] FunctionWrapper
    @ C:\Users\a1058035\.julia\packages\FunctionWrappers\Q5cBx\src\FunctionWrappers.jl:144 [inlined]
 [22] _call
    @ C:\Users\a1058035\.julia\packages\FunctionWrappersWrappers\9XR0m\src\FunctionWrappersWrappers.jl:12 [inlined]
 [23] FunctionWrappersWrapper
    @ C:\Users\a1058035\.julia\packages\FunctionWrappersWrappers\9XR0m\src\FunctionWrappersWrappers.jl:10 [inlined]
 [24] ODEFunction
    @ C:\Users\a1058035\.julia\packages\SciMLBase\rR75x\src\scimlfunctions.jl:2297 [inlined]
 [25] initialize!(integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.Tsit5Cache{…})
    @ OrdinaryDiffEq C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\perform_step\low_order_rk_perform_step.jl:799
 [26] initialize!(integrator::OrdinaryDiffEq.ODEIntegrator{…}, cache::OrdinaryDiffEq.DefaultCache{…})
    @ OrdinaryDiffEq C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\perform_step\composite_perform_step.jl:34
 [27] __init(prob::ODEProblem{…}, alg::OrdinaryDiffEq.CompositeAlgorithm{…}, timeseries_init::Tuple{}, ts_init::Tuple{}, ks_init::Tuple{}, recompile::Type{…}; saveat::Tuple{}, tstops::Tuple{}, d_discontinuities::Tuple{}, save_idxs::Nothing, save_everystep::Bool, save_on::Bool, save_start::Bool, save_end::Nothing, callback::Nothing, dense::Bool, calck::Bool, dt::Float64, dtmin::Float64, dtmax::Float64, force_dtmin::Bool, adaptive::Bool, gamma::Rational{…}, abstol::Nothing, reltol::Nothing, qmin::Rational{…}, qmax::Int64, qsteady_min::Int64, qsteady_max::Int64, beta1::Nothing, beta2::Nothing, qoldinit::Rational{…}, controller::Nothing, fullnormalize::Bool, failfactor::Int64, maxiters::Int64, internalnorm::typeof(DiffEqBase.ODE_DEFAULT_NORM), internalopnorm::typeof(LinearAlgebra.opnorm), isoutofdomain::typeof(DiffEqBase.ODE_DEFAULT_ISOUTOFDOMAIN), unstable_check::typeof(DiffEqBase.ODE_DEFAULT_UNSTABLE_CHECK), verbose::Bool, timeseries_errors::Bool, dense_errors::Bool, advance_to_tstop::Bool, stop_at_next_tstop::Bool, initialize_save::Bool, progress::Bool, progress_steps::Int64, progress_name::String, progress_message::typeof(DiffEqBase.ODE_DEFAULT_PROG_MESSAGE), progress_id::Symbol, userdata::Nothing, allow_extrapolation::Bool, initialize_integrator::Bool, alias_u0::Bool, alias_du0::Bool, initializealg::OrdinaryDiffEq.DefaultInit, kwargs::@Kwargs{…})
    @ OrdinaryDiffEq C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\solve.jl:524
 [28] __init (repeats 4 times)
    @ C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\solve.jl:11 [inlined]
 [29] #__solve#500
    @ C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\solve.jl:6 [inlined]
 [30] __solve
    @ C:\Users\a1058035\.julia\packages\OrdinaryDiffEq\kMujN\src\solve.jl:1 [inlined]
 [31] solve_call(_prob::ODEProblem{…}, args::OrdinaryDiffEq.CompositeAlgorithm{…}; merge_callbacks::Bool, kwargshandle::Nothing, kwargs::@Kwargs{…})
    @ DiffEqBase C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:612
 [32] solve_call
    @ C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:569 [inlined]
 [33] solve_up(prob::ODEProblem{…}, sensealg::Nothing, u0::Vector{…}, p::ModelingToolkit.MTKParameters{…}, args::OrdinaryDiffEq.CompositeAlgorithm{…}; kwargs::@Kwargs{…})
    @ DiffEqBase C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:1080
 [34] solve_up
    @ C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:1066 [inlined]
 [35] #solve#51
    @ C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:1003 [inlined]
 [36] solve
    @ C:\Users\a1058035\.julia\packages\DiffEqBase\c8MAQ\src\solve.jl:993 [inlined]

```

Did I do anything wrong? If I change `f(t)` to `sin(t)`, it works.

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [July 19, 2024, 6:46am UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213/2 "2024-07-19T06:46:16Z")

</div>

I’m not an expert here, but do you _need_ to register `f(t)` as symbolic? I think it is necessary to use `@register_symbolic f(t)` if you define your own function, typically one that Julia does not know how to differentiate [e.g., an interpolation function of experimental data, a step input with if statements, etc.]. But not if you use built-in functions such as `sin(t)`, `t`, etc.

Again, I’m not an expert.

I also notice that you _differentiate_ your input function `f(t)` in your model. It may be that by registering the function via `@register_symbolic` that you tell MTK that it should not attempt to differentiate the function, and then you explicitly differentiate it in the equations part.

Again, I’m just guessing here.

---

<div class="post-metadata">

**Author:** ![cstjean](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cstjean/32/1444_2.png) [@cstjean](https://discourse.julialang.org/u/cstjean)\
**Post date:** [July 22, 2024, 5:54am UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213/3 "2024-07-22T05:54:06Z")

</div>

> [@BLI](#):
>
> I also notice that you _differentiate_ your input function `f(t)` in your model. It may be that by registering the function via `@register_symbolic` that you tell MTK that it should not attempt to differentiate the function, and then you explicitly differentiate it in the equations part.

That seems to be true… But in this system taking the derivative isn’t necessary. The solution is just `z = 1 + f(t)`. I guess if I write `z = initial_z + y`, and make `initial_z` a parameter, I can achieve the same affect, but it’s not elegant.

To be more concrete, the engineers I work with have an equation of the form  
`(z2 - z1) = 54.213(y2 - y1)` (1 and 2 are different time points). I figured that the `D(z) ~ 54.213D(y)` was the natural way to write that in differential equation form. Since `y` contains input data, I followed [Getting Started with ModelingToolkit.jl · ModelingToolkit.jl (sciml.ai)](https://docs.sciml.ai/ModelingToolkit/dev/tutorials/ode_modeling/#Specifying-a-time-variable-forcing-function) and hit the problem in this post. Am I missing something?

---

<div class="post-metadata">

**Author:** ![BLI](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bli/32/37206_2.png) [@BLI](https://discourse.julialang.org/u/BLI)\
**Post date:** [July 22, 2024, 12:05pm UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213/4 "2024-07-22T12:05:27Z")

</div>

Hm. So how do the engineers that you work with _use_ this equation:  
z\_2 - z\_1 = 54.213(y\_2 - y\_1)  
Specifically,

- are y\_1 and y\_2 known?
- is z\_1 known?
- is the constant always 54.213?

A similar problem could be the relationship between position s and velocity v:

v = \frac{\mathrm{d}s}{\mathrm{d}t}

If velocity v is constant, the solution is (of course):

s\_2 - s\_1 = v\cdot (t\_2 - t\_1)

Here, the solution is simple, so one would not pose this as a differential equation.  
I probably miss something in your problem.

---

<div class="post-metadata">

**Author:** ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)\
**Post date:** [July 22, 2024, 1:50pm UTC](https://discourse.julialang.org/t/modelingtoolkit-cannot-convert-an-object-of-type-symbolicutils-basicsymbolic-float64/117213/5 "2024-07-22T13:50:23Z")

</div>

> [@cstjean](#):
>
> That seems to be true… But in this system taking the derivative isn’t necessary. The solution is just `z = 1 + f(t)`. I guess if I write `z = initial_z + y`, and make `initial_z` a parameter, I can achieve the same affect, but it’s not elegant.

As written the model starts as index 2 IIRC, so you do need to differentiate it in order to get an index 1 in order to run the standard processes. That’s a limitation of Pantelides.

But the error (which we should improve BTW, I wouldn’t say it’s a good error message) is then saying the derivative is not defined on the registered function.
