# MTK... linearization of zero dynamics

**URL:** <https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546>\
**Category:** Modelling & Simulations\
**Created:** [September 18, 2024, 11:31am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546 "2024-09-18T11:31:39Z")\
**Posts on this page:** 8\
**Page:** 1

<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:** [September 18, 2024, 11:31am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/1 "2024-09-18T11:31:39Z")

</div>

[What is the trick of hiding/folding/collapsing code blocks?]

### Consider the well-known 4-tank model by K.H. Johansson:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/0/e/0e55c0711b6f7fb66b2755f812de577aaf0078d7.png)

which has been designed to illustrate multivariable zero dynamics. The system has 2 control inputs (`v_1`, `v_2`), and two outputs (`y_1`, `y_2`); the outputs are (scaled) measures of the lower levels (`h_1`, `h_2`), while the upper levels (`h_3`, `h_4`) can be estimated. The actuators (`v_1`, `v_2`) affect all four tanks via some split-range valves.

The following code implements the model with inputs, initial states, and parameters according to Johansson’s `P-` case (i.e., with stable zero dynamics):

```julia
using ModelingToolkit
using ModelingToolkit: t_nounits as t, D_nounits as Dt
using DifferentialEquations
using ControlSystems, ControlSystemsMTK
using Plots, LaTeXStrings
#
# Input functions
# -- registering inputs
@register_symbolic u_u1(t)
@register_symbolic u_u2(t)
#
u_v_1(t) = 3.0
u_v_2(t) = 3.0
@register_symbolic u_r1(t)
@register_symbolic u_r2(t)
#
u_r_1(t) = 12.4*0.5
u_r_2(t) = 12.7*0.5
#
# -- Model
@mtkmodel FourTank begin
    # Ref: Johansson, K.H. (2000): "The Quadruple-Tank Process: A Multivariable 
    # Laboratory Process with an Adjustable Zero", 
    # IEEE Trans. Ctrl. Tech., Vol. 8, No. 3, May 2000
    # Model parameters
    @parameters begin
        # Constant 
        g = 981, [description = "Acceleration of gravity, cm/s^2"]
        # Parameters
        # -- tank parameters
        A_1 = 28, [description = "Tank 1, cross-section area, cm^2"]
        A_2 = 32, [description = "Tank 2, cross-section area, cm^2"]
        A_3 = 28, [description = "Tank 3, cross-section area, cm^2"]
        A_4 = 32, [description = "Tank 4, cross-section area, cm^2"]
        a_1 = 0.071, [description = "Tank 1, cross-section area of outlet hole, cm^2"]
        a_2 = 0.057, [description = "Tank 2, cross-section area of outlet hole, cm^2"]
        a_3 = 0.071, [description = "Tank 3, cross-section area of outlet hole, cm^2"]
        a_4 = 0.057, [description = "Tank 4, cross-section area of outlet hole, cm^2"]
        # -- valve parameters, LHP zeros
        γ_1 = 0.70, [description = "Valve 1 split setting, -"]
        γ_2 = 0.60, [description = "Valve 2 split setting, -"]
        k_1 = 3.33, [description = "Valve 1 gain, cm3/V.s"]
        k_2 = 3.35, [description = "Valve 2 gain, cm3/V.s"]
        # -- sensor parameter
        k_c = 0.5, [description = "Sensor gain, V/cm"]
    end
    #
    # Model variables, with initial values needed
    @variables begin
        # Variables
        # -- states
        h_1(t)=12.4, [description = "Tank 1 level, cm"]
        h_2(t)=12.7, [description = "Tank 2 level, cm"]
        h_3(t)=1.8, [description = "Tank 3 level, cm"]
        h_4(t)=1.4, [description = "Tank 4 level, cm"]
        # -- sensor signals
        y_1(t), [description = "Output 1: level in Tank 1, cm"]
        y_2(t), [description = "Output 2: level in Tank 2, cm"]
        # -- actuator signals
        v_1(t), [description = "Valve 1 signal, V"]
        v_2(t), [description = "Valve 2 signal, V"]
    end
    #
    # Model equations
    @equations begin
        # ODEs
        Dt(h_1) ~ -a_1/A_1*sqrt(2g*h_1) + a_3/A_1*sqrt(2g*h_3) + γ_1*k_1/A_1*v_1
        Dt(h_2) ~ -a_2/A_2*sqrt(2g*h_2) + a_4/A_2*sqrt(2g*h_4) + γ_2*k_2/A_2*v_2
        Dt(h_3) ~ -a_3/A_3*sqrt(2g*h_3) + (1-γ_2)*k_2/A_3*v_2
        Dt(h_4) ~ -a_4/A_4*sqrt(2g*h_4) + (1-γ_1)*k_1/A_4*v_1
        # Outputs
        y_1 ~ k_c*h_1
        y_2 ~ k_c*h_2
        # Inputs
        v_1 ~ u_v_1(t)
        v_2 ~ u_v_2(t)
    end
end

@mtkbuild t4 = FourTank()
tspan = (0,60*8)
prob = ODEProblem(t4, [], tspan)
sol = solve(prob, reltol=1e-4)

```

The results indicate that the specified operating points in the referenced paper are not 100% in steady state:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/6/2/62c8aac7000a437870e6327751ef55ba5bf9c6c7.png)

Next, I can do linearization of the model with the trick of creating a new model [`FourTank_noi`] where I have no inputs, achieved by commenting out the two last equations in `FourTank`. This works fine with the latest update of ModelingToolkit.

* * *

Next, I want to study the zero dynamics. To do so, I relax on specifying the inputs `v_1` and `v_2`, and instead specify the outputs `y_1` and `y_2`:

```julia
@mtkmodel FourTank_z begin
    #
    # Model parameters
    @parameters begin
        # Constant 
        g = 981, [description = "Acceleration of gravity, cm/s^2"]
        # Parameters
        # -- tank parameters
        A_1 = 28, [description = "Tank 1, cross-section area, cm^2"]
        A_2 = 32, [description = "Tank 2, cross-section area, cm^2"]
        A_3 = 28, [description = "Tank 3, cross-section area, cm^2"]
        A_4 = 32, [description = "Tank 4, cross-section area, cm^2"]
        a_1 = 0.071, [description = "Tank 1, cross-section area of outlet hole, cm^2"]
        a_2 = 0.057, [description = "Tank 2, cross-section area of outlet hole, cm^2"]
        a_3 = 0.071, [description = "Tank 3, cross-section area of outlet hole, cm^2"]
        a_4 = 0.057, [description = "Tank 4, cross-section area of outlet hole, cm^2"]
        # -- valve parameters, LHP zeros
        γ_1 = 0.70, [description = "Valve 1 split setting, -"]
        γ_2 = 0.60, [description = "Valve 2 split setting, -"]
        k_1 = 3.33, [description = "Valve 1 gain, cm3/V.s"]
        k_2 = 3.35, [description = "Valve 2 gain, cm3/V.s"]
        # -- sensor parameter
        k_c = 0.5, [description = "Sensor gain, V/cm"]
    end
    #
    # Model variables, with initial values needed
    @variables begin
        # Variables
        # -- states
        h_1(t)=12.4, [description = "Tank 1 level, cm"]
        h_2(t)=12.7, [description = "Tank 2 level, cm"]
        h_3(t)=1.8, [description = "Tank 3 level, cm"]
        h_4(t)=1.4, [description = "Tank 4 level, cm"]
        # -- sensor signals
        y_1(t), [description = "Output 1: level in Tank 1, cm"]
        y_2(t), [description = "Output 2: level in Tank 2, cm"]
        # -- actuator signals
        v_1(t), [description = "Valve 1 signal, V"]
        v_2(t), [description = "Valve 2 signal, V"]
    end
    #
    # Model equations
    @equations begin
        # ODEs
        Dt(h_1) ~ -a_1/A_1*sqrt(2g*h_1) + a_3/A_1*sqrt(2g*h_3) + γ_1*k_1/A_1*v_1
        Dt(h_2) ~ -a_2/A_2*sqrt(2g*h_2) + a_4/A_2*sqrt(2g*h_4) + γ_2*k_2/A_2*v_2
        Dt(h_3) ~ -a_3/A_3*sqrt(2g*h_3) + (1-γ_2)*k_2/A_3*v_2
        Dt(h_4) ~ -a_4/A_4*sqrt(2g*h_4) + (1-γ_1)*k_1/A_4*v_1
        # Outputs
        y_1 ~ k_c*h_1
        y_2 ~ k_c*h_2
        # Inputs
        y_1 ~ u_r_1(t)
        y_2 ~ u_r_2(t)
    end
end

@mtkbuild t4z = FourTank_z()
prob_z = ODEProblem(t4z, [], tspan)

```

This gives a warning that the system is over specified. The reason is (of course) that I have specified initial states for all four levels. If I remove the initial states for `h_1` and `h_2`, the warning disappears.

Simulating the zero dynamics gives

 ![image](https://global.discourse-cdn.com/julialang/original/3X/c/b/cb3c6863aad651e9e53d65c4ab772de99661acd1.png)

which is as expected: outputs `y_1` and `y_2` are specified to be constant (and half the value of `h_1` and `h_2`), which only leaves `h_3` and `h_4` to move. Because I chose the operating point with stable zero dynamics, the system should be stable.

Next, I want to linearize the zero dynamics so that I can find the eigenvalue(s) of the linearized model: these (this) should equal the (transmission) zeros of the system.

With the standard trick of commenting out the “input” specification (which in this case is `y_1` and `y_2`), I get:

```julia
mtkmodel FourTank_z_noi begin
    #
    # Model parameters
    @parameters begin
        # Constant 
        g = 981, [description = "Acceleration of gravity, cm/s^2"]
        # Parameters
        # -- tank parameters
        A_1 = 28, [description = "Tank 1, cross-section area, cm^2"]
        A_2 = 32, [description = "Tank 2, cross-section area, cm^2"]
        A_3 = 28, [description = "Tank 3, cross-section area, cm^2"]
        A_4 = 32, [description = "Tank 4, cross-section area, cm^2"]
        a_1 = 0.071, [description = "Tank 1, cross-section area of outlet hole, cm^2"]
        a_2 = 0.057, [description = "Tank 2, cross-section area of outlet hole, cm^2"]
        a_3 = 0.071, [description = "Tank 3, cross-section area of outlet hole, cm^2"]
        a_4 = 0.057, [description = "Tank 4, cross-section area of outlet hole, cm^2"]
        # -- valve parameters, LHP zeros
        γ_1 = 0.70, [description = "Valve 1 split setting, -"]
        γ_2 = 0.60, [description = "Valve 2 split setting, -"]
        k_1 = 3.33, [description = "Valve 1 gain, cm3/V.s"]
        k_2 = 3.35, [description = "Valve 2 gain, cm3/V.s"]
        # -- sensor parameter
        k_c = 0.5, [description = "Sensor gain, V/cm"]
    end
    #
    # Model variables, with initial values needed
    @variables begin
        # Variables
        # -- states
        h_1(t)=12.4, [description = "Tank 1 level, cm"]
        h_2(t)=12.7, [description = "Tank 2 level, cm"]
        h_3(t)=1.8, [description = "Tank 3 level, cm"]
        h_4(t)=1.4, [description = "Tank 4 level, cm"]
        # -- sensor signals
        y_1(t), [description = "Output 1: level in Tank 1, cm"]
        y_2(t), [description = "Output 2: level in Tank 2, cm"]
        # -- actuator signals
        v_1(t), [description = "Valve 1 signal, V"]
        v_2(t), [description = "Valve 2 signal, V"]
    end
    #
    # Model equations
    @equations begin
        # ODEs
        Dt(h_1) ~ -a_1/A_1*sqrt(2g*h_1) + a_3/A_1*sqrt(2g*h_3) + γ_1*k_1/A_1*v_1
        Dt(h_2) ~ -a_2/A_2*sqrt(2g*h_2) + a_4/A_2*sqrt(2g*h_4) + γ_2*k_2/A_2*v_2
        Dt(h_3) ~ -a_3/A_3*sqrt(2g*h_3) + (1-γ_2)*k_2/A_3*v_2
        Dt(h_4) ~ -a_4/A_4*sqrt(2g*h_4) + (1-γ_1)*k_1/A_4*v_1
        # Outputs
        y_1 ~ k_c*h_1
        y_2 ~ k_c*h_2
        # Inputs
        #y_1 ~ u_r_1(t)
        #y_2 ~ u_r_2(t)
    end
end

@named t4z_noi = FourTank_z_noi()
t4z_noi = complete(t4z_noi)

```

leading to

 ![image](https://global.discourse-cdn.com/julialang/original/3X/7/8/7806e071f4c58881fa40519b84facaf046b254c4.png)

OK. Now, the problems are popping up… I start with attempting symbolic linearization [this works fine for the system from valve signal inputs `v_j` to outputs `y_j`, but not for the zero dynamics]:

```julia
julia> mats,t4z_ = ModelingToolkit.linearize_symbolic(t4z_noi, [t4z_noi.y_1, t4z_noi.y_2], [t4z_noi.h_3, t4z_noi.h_4])
BoundsError: attempt to access 1-element Vector{Any} at index [2]

Stacktrace:
 [1] getindex(A::Vector{Any}, i1::Int64)
   @ Base .\essentials.jl:13
 [2] expand_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool; occurrences::SymbolicUtils.BasicSymbolic{Real}) (repeats 5 times)
   @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\diff.jl:257
 [3] expand_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool; occurrences::Nothing)
   @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\diff.jl:257
 [4] expand_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool)
   @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\diff.jl:183
 [5] jacobian(ops::Vector{SymbolicUtils.BasicSymbolic{Real}}, vars::Vector{Num}; simplify::Bool, scalarize::Bool)
   @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\diff.jl:470
 [6] jacobian(ops::Vector{SymbolicUtils.BasicSymbolic{Real}}, vars::Vector{Num})
   @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\diff.jl:465
 [7] linearize_symbolic(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num}; simplify::Bool, allow_input_derivatives::Bool, eval_expression::Bool, eval_module::Module, kwargs::@Kwargs{})
   @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\UXr3S\src\systems\abstractsystem.jl:2454
 [8] linearize_symbolic(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num})
   @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\UXr3S\src\systems\abstractsystem.jl:2434
 [9] top-level scope
   @ c:\Users\Bernt_Lie\...\jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X36sZmlsZQ==.jl:1

```

Next, I’m trying numeric/AD linearization:

```julia
julia> mats,t4z_ = ModelingToolkit.linearize(t4z_noi, [t4z_noi.y_1, t4z_noi.y_2], [t4z_noi.h_3, t4z_noi.h_4];
                op=Dict(t4z_noi.y_1 => 6.2, t4z_noi.y_2 => 6.35))
ArgumentError: Cannot convert Sym to Float64 since Sym is symbolic and Float64 is concrete. Use `substitute` to replace the symbolic unwraps.

Stacktrace:
  [1] Float64(x::SymbolicUtils.BasicSymbolic{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#815"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}})
    @ Symbolics C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\Symbolics.jl:171
  [2] convert
    @ C:\Users\Bernt_Lie\.julia\packages\ForwardDiff\PcZ48\src\dual.jl:435 [inlined]
  [3] setindex!(A::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#815"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, x::SymbolicUtils.BasicSymbolic{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#815"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, i1::Int64)
    @ Base .\array.jl:1021
  [4] macro expansion
    @ C:\Users\Bernt_Lie\.julia\packages\SymbolicUtils\5UmB7\src\code.jl:430 [inlined]
  [5] macro expansion
    @ C:\Users\Bernt_Lie\.julia\packages\Symbolics\6WqId\src\build_function.jl:546 [inlined]
  [6] macro expansion
    @ C:\Users\Bernt_Lie\.julia\packages\SymbolicUtils\5UmB7\src\code.jl:387 [inlined]
  [7] macro expansion
    @ C:\Users\Bernt_Lie\.julia\packages\RuntimeGeneratedFunctions\M9ZX8\src\RuntimeGeneratedFunctions.jl:163 [inlined]
  [8] macro expansion
    @ .\none:0 [inlined]
  [9] generated_callfunc
    @ .\none:0 [inlined]
 [10] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing})(::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#815"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var"#f#815"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var"#_RGF_ModTag", ModelingToolkit.var"#_RGF_ModTag", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, ::Vector{Float64}, ::Float64)
    @ RuntimeGeneratedFunctions C:\Users\Bernt_Lie\.julia\packages\RuntimeGeneratedFunctions\M9ZX8\src\RuntimeGeneratedFunctions.jl:150
 [11] f
    @ C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\UXr3S\src\systems\diffeqs\abstractodesystem.jl:351 [inlined]
...
    @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\UXr3S\src\systems\abstractsystem.jl:2657
 [20] linearize(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num}; op::Dict{Num, Float64}, t::Float64, allow_input_derivatives::Bool, zero_dummy_der::Bool, kwargs::@Kwargs{})
    @ ModelingToolkit C:\Users\Bernt_Lie\.julia\packages\ModelingToolkit\UXr3S\src\systems\abstractsystem.jl:2708
 [21] top-level scope
    @ c:\Users\Bernt_Lie\...\jl_notebook_cell_df34fa98e69747e1a8f8a730347b8e2f_X24sZmlsZQ==.jl:1
Output is truncated. View as a scrollable element or open in a text editor. Adjust cell output settings...

```

**Questions** :

1. Do I do something wrong?
2. Or is there a limitation in MTK?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 18, 2024, 4:31pm UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/2 "2024-09-18T16:31:49Z")

</div>

Looks like a bug in MTK, please open an issue (preferably with a single code block that reproduces the error), thanks 😃

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 19, 2024, 9:15am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/3 "2024-09-19T09:15:03Z")

</div>

Here’s an explanation and a workaround

> <https://github.com/SciML/ModelingToolkit.jl/issues/3057#issuecomment-2360417218>
>
> \*\*Describe the bug 🐞\*\*
> 
> Consider the well-known, academic "Four Tank" model. S…imulation of the input-output (valve-signal to output levels, \`case = :io\` in MRE) works. Likewise, linearization (symbolic and numeric) of the input-output model works (\`case = :lin\_io\` in MRE). Also simulation of the \*zero dynamics\* works (specifying the outputs; \`case = :zero\` in MRE). 
> 
> HOWEVER, both symbolic and numeric linearization \*fails\* for the zero dynamics case (\`case = :lin\_zero\` in MRE). 
> 
> \*\*Expected behavior\*\*
> 
> Both symbolic and numeric linearization of the zero dynamics case (\`case = :lin\_zero\`) should work. The eigenvalues of the zero dynamics system matrix should equal the transmission zeros of \`case = :lin\_io\`. 
> 
> \*\*Minimal Reproducible Example 👇\*\*
> 
> Here is my case, set up with both symbolic and numeric linearization of the zero dynamics.
> 
> \`\`\`julia
> \# Packages
> using ModelingToolkit
> using ModelingToolkit: t\_nounits as t, D\_nounits as Dt
> using DifferentialEquations
> \#
> \# Input functions
> \# -- control inputs
> @register\_symbolic u\_u1(t)
> @register\_symbolic u\_u2(t)
> \#
> u\_v\_1(t) = 3.0
> u\_v\_2(t) = 3.0
> \#
> \# -- output references
> @register\_symbolic u\_r1(t)
> @register\_symbolic u\_r2(t)
> \#
> u\_r\_1(t) = 12.4\*0.5
> u\_r\_2(t) = 12.7\*0.5
> \# 
> \# Model FourTank
> @mtkmodel FourTank begin
> # Ref: Johansson, K.H. (2000): "The Quadruple-Tank Process: A Multivariable 
> # Laboratory Process with an Adjustable Zero", 
> # IEEE Trans. Ctrl. Tech., Vol. 8, No. 3, May 2000
> # Structure parameters
> @structural\_parameters begin
> # :io = standard input-output, :zero = zero dynamics
> # :lin\_io = linearizing input-output, :lin\_zero = linearizing zero dynamics
> case = :io 
> end
> #
> # Model parameters
> @parameters begin
> # Constant 
> g = 981, \[description = "Acceleration of gravity, cm/s^2"\]
> # Parameters
> # -- tank parameters
> A\_1 = 28, \[description = "Tank 1, cross-section area, cm^2"\]
> A\_2 = 32, \[description = "Tank 2, cross-section area, cm^2"\]
> A\_3 = 28, \[description = "Tank 3, cross-section area, cm^2"\]
> A\_4 = 32, \[description = "Tank 4, cross-section area, cm^2"\]
> a\_1 = 0.071, \[description = "Tank 1, cross-section area of outlet hole, cm^2"\]
> a\_2 = 0.057, \[description = "Tank 2, cross-section area of outlet hole, cm^2"\]
> a\_3 = 0.071, \[description = "Tank 3, cross-section area of outlet hole, cm^2"\]
> a\_4 = 0.057, \[description = "Tank 4, cross-section area of outlet hole, cm^2"\]
> # -- valve parameters, case of LHP zeros/stable zero dynamics
> γ\_1 = 0.70, \[description = "Valve 1 split setting, -"\]
> γ\_2 = 0.60, \[description = "Valve 2 split setting, -"\]
> k\_1 = 3.33, \[description = "Valve 1 gain, cm3/V.s"\]
> k\_2 = 3.35, \[description = "Valve 2 gain, cm3/V.s"\]
> # -- sensor parameter
> k\_c = 0.5, \[description = "Sensor gain, V/cm"\]
> end
> #
> # Model variables, with initial values needed
> @variables begin
> # Variables
> # -- states
> h\_1(t)=12.4, \[description = "Tank 1 level, cm"\]
> h\_2(t)=12.7, \[description = "Tank 2 level, cm"\]
> h\_3(t)=1.8, \[description = "Tank 3 level, cm"\]
> h\_4(t)=1.4, \[description = "Tank 4 level, cm"\]
> # -- sensor signals
> y\_1(t), \[description = "Output 1: level in Tank 1, cm"\]
> y\_2(t), \[description = "Output 2: level in Tank 2, cm"\]
> # -- actuator signals
> v\_1(t), \[description = "Valve 1 signal, V"\]
> v\_2(t), \[description = "Valve 2 signal, V"\]
> end
> #
> # Model equations
> @equations begin
> # ODEs
> Dt(h\_1) ~ -a\_1/A\_1\*sqrt(2g\*h\_1) + a\_3/A\_1\*sqrt(2g\*h\_3) + γ\_1\*k\_1/A\_1\*v\_1
> Dt(h\_2) ~ -a\_2/A\_2\*sqrt(2g\*h\_2) + a\_4/A\_2\*sqrt(2g\*h\_4) + γ\_2\*k\_2/A\_2\*v\_2
> Dt(h\_3) ~ -a\_3/A\_3\*sqrt(2g\*h\_3) + (1-γ\_2)\*k\_2/A\_3\*v\_2
> Dt(h\_4) ~ -a\_4/A\_4\*sqrt(2g\*h\_4) + (1-γ\_1)\*k\_1/A\_4\*v\_1
> # Outputs
> y\_1 ~ k\_c\*h\_1
> y\_2 ~ k\_c\*h\_2
> # Inputs
> if case == :io
> v\_1 ~ u\_v\_1(t)
> v\_2 ~ u\_v\_2(t)
> elseif case == :lin\_io
> #v\_1 ~ u\_v\_1(t)
> #v\_2 ~ u\_v\_2(t)
> elseif case == :zero
> y\_1 ~ u\_r\_1(t)
> y\_2 ~ u\_r\_2(t)
> elseif case == :lin\_zero
> #y\_1 ~ u\_r\_1(t)
> #y\_2 ~ u\_r\_2(t)
> end
> end
> end
> \# 
> \# Instantiating case for linearizing zero dynamics
> @named t4\_LZ= FourTank(; case=:lin\_zero)
> t4\_LZ= complete(t4\_LZ)
> \# 
> \# Symbolic linearization -- gives error
> mats,t4z\_ = ModelingToolkit.linearize\_symbolic(t4\_LZ, \[t4\_LZ.y\_1, t4\_LZ.y\_2\], \[t4\_LZ.h\_3, t4\_LZ.h\_4\])
> \# 
> \# Numeric linearization -- gives error
> mats,t4z\_ = ModelingToolkit.linearize(t4\_LZ, \[t4\_LZ.y\_1, t4\_LZ.y\_2\], \[t4\_LZ.h\_3, t4\_LZ.h\_4\];
> op=Dict(t4\_LZ.y\_1 =\> 6.2, t4\_LZ.y\_2 =\> 6.35))
> \`\`\`
> 
> \*\*Error & Stacktrace ⚠️\*\*
> Case of symbolic linearization
> \`\`\`julia
> BoundsError: attempt to access 1-element Vector{Any} at index \[2\]
> 
> Stacktrace:
> \[1\] getindex(A::Vector{Any}, i1::Int64)
> @ Base .\\essentials.jl:13
> \[2\] expand\_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool; occurrences::SymbolicUtils.BasicSymbolic{Real}) (repeats 5 times)
> @ Symbolics C:\\Users\\Bernt\_Lie\\.julia\\packages\\Symbolics\\6WqId\\src\\diff.jl:257
> \[3\] expand\_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool; occurrences::Nothing)
> @ Symbolics C:\\Users\\Bernt\_Lie\\.julia\\packages\\Symbolics\\6WqId\\src\\diff.jl:257
> \[4\] expand\_derivatives(O::SymbolicUtils.BasicSymbolic{Real}, simplify::Bool)
> @ Symbolics C:\\Users\\Bernt\_Lie\\.julia\\packages\\Symbolics\\6WqId\\src\\diff.jl:183
> \[5\] jacobian(ops::Vector{SymbolicUtils.BasicSymbolic{Real}}, vars::Vector{Num}; simplify::Bool, scalarize::Bool)
> @ Symbolics C:\\Users\\Bernt\_Lie\\.julia\\packages\\Symbolics\\6WqId\\src\\diff.jl:470
> \[6\] jacobian(ops::Vector{SymbolicUtils.BasicSymbolic{Real}}, vars::Vector{Num})
> @ Symbolics C:\\Users\\Bernt\_Lie\\.julia\\packages\\Symbolics\\6WqId\\src\\diff.jl:465
> \[7\] linearize\_symbolic(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num}; simplify::Bool, allow\_input\_derivatives::Bool, eval\_expression::Bool, eval\_module::Module, kwargs::@Kwargs{})
> @ ModelingToolkit C:\\Users\\Bernt\_Lie\\.julia\\packages\\ModelingToolkit\\UXr3S\\src\\systems\\abstractsystem.jl:2454
> \[8\] linearize\_symbolic(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num})
> @ ModelingToolkit C:\\Users\\Bernt\_Lie\\.julia\\packages\\ModelingToolkit\\UXr3S\\src\\systems\\abstractsystem.jl:2434
> \[9\] top-level scope
> @ c:\\Users\\Bernt\_Lie\\OneDrive\\Documents\\researchUSN\\Supervisor\\PhD\\Kushila\_Jayamanne\\Notebooks\\jl\_notebook\_cell\_df34fa98e69747e1a8f8a730347b8e2f\_X36sZmlsZQ==.jl:1
> \`\`\`
> 
> Case of (numeric) linearization:
> \`\`\`julia
> {
> "name": "ArgumentError",
> "message": "ArgumentError: Cannot convert Sym to Float64 since Sym is symbolic and Float64 is concrete. Use \`substitute\` to replace the symbolic unwraps.",
> "stack": "ArgumentError: Cannot convert Sym to Float64 since Sym is symbolic and Float64 is concrete. Use \`substitute\` to replace the symbolic unwraps.\\n\\nStacktrace:\\n \[1\] Float64(x::SymbolicUtils.BasicSymbolic{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}})\\n @ Symbolics C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\Symbolics\\\\6WqId\\\\src\\\\Symbolics.jl:171\\n \[2\] convert\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ForwardDiff\\\\PcZ48\\\\src\\\\dual.jl:435 \[inlined\]\\n \[3\] setindex!(A::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, x::SymbolicUtils.BasicSymbolic{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, i1::Int64)\\n @ Base .\\\\array.jl:1021\\n \[4\] macro expansion\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\SymbolicUtils\\\\5UmB7\\\\src\\\\code.jl:430 \[inlined\]\\n \[5\] macro expansion\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\Symbolics\\\\6WqId\\\\src\\\\build\_function.jl:546 \[inlined\]\\n \[6\] macro expansion\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\SymbolicUtils\\\\5UmB7\\\\src\\\\code.jl:387 \[inlined\]\\n \[7\] macro expansion\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\RuntimeGeneratedFunctions\\\\M9ZX8\\\\src\\\\RuntimeGeneratedFunctions.jl:163 \[inlined\]\\n \[8\] macro expansion\\n @ .\\\\none:0 \[inlined\]\\n \[9\] generated\_callfunc\\n @ .\\\\none:0 \[inlined\]\\n \[10\] (::RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing})(::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, ::Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}, ::Vector{Float64}, ::Float64)\\n @ RuntimeGeneratedFunctions C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\RuntimeGeneratedFunctions\\\\M9ZX8\\\\src\\\\RuntimeGeneratedFunctions.jl:150\\n \[11\] f\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ModelingToolkit\\\\UXr3S\\\\src\\\\systems\\\\diffeqs\\\\abstractodesystem.jl:351 \[inlined\]\\n \[12\] ODEFunction\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\SciMLBase\\\\j8jQg\\\\src\\\\scimlfunctions.jl:2335 \[inlined\]\\n \[13\] UJacobianWrapper\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\SciMLBase\\\\j8jQg\\\\src\\\\function\_wrappers.jl:34 \[inlined\]\\n \[14\] vector\_mode\_dual\_eval!\\n @ C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ForwardDiff\\\\PcZ48\\\\src\\\\apiutils.jl:24 \[inlined\]\\n \[15\] vector\_mode\_jacobian(f::SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}})\\n @ ForwardDiff C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ForwardDiff\\\\PcZ48\\\\src\\\\jacobian.jl:125\\n \[16\] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}}, ::Val{true})\\n @ ForwardDiff C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ForwardDiff\\\\PcZ48\\\\src\\\\jacobian.jl:21\\n \[17\] jacobian(f::Function, x::Vector{Float64}, cfg::ForwardDiff.JacobianConfig{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2, Vector{ForwardDiff.Dual{ForwardDiff.Tag{SciMLBase.UJacobianWrapper{true, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, Float64, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}}, Float64}, Float64, 2}}})\\n @ ForwardDiff C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ForwardDiff\\\\PcZ48\\\\src\\\\jacobian.jl:19\\n \[18\] (::ModelingToolkit.var\\"#358#367\\"{UnitRange{Int64}, UnitRange{Int64}, Vector{ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}}, Vector{SymbolicUtils.BasicSymbolic{Real}}, ModelingToolkit.var\\"#356#364\\"{MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#10936873250485650685\\"), Symbol(\\"##arg#12853417078996959593\\"), :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0xdb453d6f, 0x8ce078e3, 0xf0a30935, 0x139cbd07, 0xbba648b8), Nothing}, SymbolicIndexingInterface.ParameterHookWrapper{SymbolicIndexingInterface.MultipleSetters{Vector{SymbolicIndexingInterface.SetParameterIndex{ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}}}}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, ModelingToolkit.var\\"#355#363\\"}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, NonlinearFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#648\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x11ce7c29, 0x6f65c7e8, 0x0fb6ac7c, 0x343656a1, 0xca307b6b), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x58b56277, 0x73127dde, 0x68c0af47, 0x517d1f4b, 0x707f7aca), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{NonlinearSystem}, Nothing, NonlinearSystem, Vector{Float64}}, ModelingToolkit.var\\"#fn#366\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#5964805160111424296\\"), Symbol(\\"##arg#9353732160355970344\\")), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x6579d8b3, 0x45aaa53d, 0xc45bd7e9, 0xae240d39, 0xf23e180a), Nothing}}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#10936873250485650685\\"), Symbol(\\"##arg#12853417078996959593\\"), :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0xbcec8039, 0xc13893b9, 0xe9fd9bf0, 0xd326ed21, 0x0dd80d24), Nothing}, ForwardDiff.Chunk{2}, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}, Bool, GeneralizedFirstOrderAlgorithm{nothing, :TrustRegion, Missing, NonlinearSolve.GenericTrustRegionScheme{NonlinearSolve.RadiusUpdateSchemes.\_\_Simple, Rational{Int64}, Rational{Int64}, Rational{Int64}, Rational{Int64}, Rational{Int64}, Nothing, Nothing, Nothing, Nothing}, Dogleg{NewtonDescent{Nothing, typeof(NonlinearSolve.DEFAULT\_PRECS)}, SteepestDescent{Nothing, typeof(NonlinearSolve.DEFAULT\_PRECS)}}, Nothing, Nothing, Nothing}, ODESystem})(u::Vector{Float64}, p::Dict{Num, Float64}, t::Float64)\\n @ ModelingToolkit C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ModelingToolkit\\\\UXr3S\\\\src\\\\systems\\\\abstractsystem.jl:2383\\n \[19\] linearize(sys::ODESystem, lin\_fun::ModelingToolkit.var\\"#358#367\\"{UnitRange{Int64}, UnitRange{Int64}, Vector{ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}}, Vector{SymbolicUtils.BasicSymbolic{Real}}, ModelingToolkit.var\\"#356#364\\"{MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#10936873250485650685\\"), Symbol(\\"##arg#12853417078996959593\\"), :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0xdb453d6f, 0x8ce078e3, 0xf0a30935, 0x139cbd07, 0xbba648b8), Nothing}, SymbolicIndexingInterface.ParameterHookWrapper{SymbolicIndexingInterface.MultipleSetters{Vector{SymbolicIndexingInterface.SetParameterIndex{ModelingToolkit.ParameterIndex{SciMLStructures.Tunable, Int64}}}}, Vector{SymbolicUtils.BasicSymbolic{Real}}}, ModelingToolkit.var\\"#355#363\\"}, ODEFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#815\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x68d7fc22, 0x9cd0330d, 0x51936f95, 0xda8a0357, 0xa6ac43de), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2, :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x077ceea2, 0x254bf500, 0x74c8eda1, 0x54c835c5, 0x5d3dd8d7), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{ODESystem}, Nothing, ODESystem, Nothing, Nothing}, NonlinearFunction{true, SciMLBase.FullSpecialize, ModelingToolkit.var\\"#f#648\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋arg1, :ˍ₋arg2), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x11ce7c29, 0x6f65c7e8, 0x0fb6ac7c, 0x343656a1, 0xca307b6b), Nothing}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(:ˍ₋out, :ˍ₋arg1, :ˍ₋arg2), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x58b56277, 0x73127dde, 0x68c0af47, 0x517d1f4b, 0x707f7aca), Nothing}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, ModelingToolkit.ObservedFunctionCache{NonlinearSystem}, Nothing, NonlinearSystem, Vector{Float64}}, ModelingToolkit.var\\"#fn#366\\"{RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#5964805160111424296\\"), Symbol(\\"##arg#9353732160355970344\\")), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0x6579d8b3, 0x45aaa53d, 0xc45bd7e9, 0xae240d39, 0xf23e180a), Nothing}}, RuntimeGeneratedFunctions.RuntimeGeneratedFunction{(Symbol(\\"##arg#10936873250485650685\\"), Symbol(\\"##arg#12853417078996959593\\"), :t), ModelingToolkit.var\\"#\_RGF\_ModTag\\", ModelingToolkit.var\\"#\_RGF\_ModTag\\", (0xbcec8039, 0xc13893b9, 0xe9fd9bf0, 0xd326ed21, 0x0dd80d24), Nothing}, ForwardDiff.Chunk{2}, MTKParameters{Vector{Float64}, Tuple{}, Tuple{}, Tuple{}}, Bool, GeneralizedFirstOrderAlgorithm{nothing, :TrustRegion, Missing, NonlinearSolve.GenericTrustRegionScheme{NonlinearSolve.RadiusUpdateSchemes.\_\_Simple, Rational{Int64}, Rational{Int64}, Rational{Int64}, Rational{Int64}, Rational{Int64}, Nothing, Nothing, Nothing, Nothing}, Dogleg{NewtonDescent{Nothing, typeof(NonlinearSolve.DEFAULT\_PRECS)}, SteepestDescent{Nothing, typeof(NonlinearSolve.DEFAULT\_PRECS)}}, Nothing, Nothing, Nothing}, ODESystem}; t::Float64, op::Dict{Num, Float64}, allow\_input\_derivatives::Bool, p::SciMLBase.NullParameters)\\n @ ModelingToolkit C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ModelingToolkit\\\\UXr3S\\\\src\\\\systems\\\\abstractsystem.jl:2657\\n \[20\] linearize(sys::ODESystem, inputs::Vector{Num}, outputs::Vector{Num}; op::Dict{Num, Float64}, t::Float64, allow\_input\_derivatives::Bool, zero\_dummy\_der::Bool, kwargs::@Kwargs{})\\n @ ModelingToolkit C:\\\\Users\\\\Bernt\_Lie\\\\.julia\\\\packages\\\\ModelingToolkit\\\\UXr3S\\\\src\\\\systems\\\\abstractsystem.jl:2708\\n \[21\] top-level scope\\n @ c:\\\\Users\\\\Bernt\_Lie\\\\OneDrive\\\\Documents\\\\researchUSN\\\\Supervisor\\\\PhD\\\\Kushila\_Jayamanne\\\\Notebooks\\\\jl\_notebook\_cell\_df34fa98e69747e1a8f8a730347b8e2f\_X24sZmlsZQ==.jl:1"
> }
> \`\`\`
> 
> \*\*Environment (please complete the following information):\*\*
> 
> - Output of \`using Pkg; Pkg.status()\`
> 
> \`\`\`julia
> Status \`C:\\Users\\Bernt\_Lie\\.julia\\environments\\v1.10\\Project.toml\`
> \[6e4b80f9\] BenchmarkTools v1.5.0
> \[336ed68f\] CSV v0.10.14
> \[a6e380b2\] ControlSystems v1.10.4
> \[687d7614\] ControlSystemsMTK v2.2.1
> \[a93c6f00\] DataFrames v1.6.1
> \[82cc6244\] DataInterpolations v6.4.0
> \[0c46a032\] DifferentialEquations v7.14.0
> \[b964fa9f\] LaTeXStrings v1.3.1
> \[23fbe1c1\] Latexify v0.16.5
> \[2fda8390\] LsqFit v0.15.0
> \[add582a8\] MLJ v0.20.7
> \[961ee093\] ModelingToolkit v9.40.0
> \[16a59e39\] ModelingToolkitStandardLibrary v2.12.0
> \[0987c9cc\] MonteCarloMeasurements v1.2.1
> \[8913a72c\] NonlinearSolve v3.14.0
> \[6fe1bfb0\] OffsetArrays v1.14.1
> \[429524aa\] Optim v1.9.4
> \[91a5bcdd\] Plots v1.40.8
> \[98d1487c\] PolyesterForwardDiff v0.1.2
> \[f27b6e38\] Polynomials v4.0.11
> \[0c5d862f\] Symbolics v6.11.0
> \[37e2e46d\] LinearAlgebra
> \`\`\`
> 
> - Output of \`using Pkg; Pkg.status(; mode = PKGMODE\_MANIFEST)\`
> 
> \`\`\`julia
> \[32m\[1mStatus\[22m\[39m \`C:\\Users\\Bernt\_Lie\\.julia\\environments\\v1.10\\Manifest.toml\`
> \[90m\[47edcb42\] \[39mADTypes v1.8.0
> \[90m\[da404889\] \[39mARFFFiles v1.4.1
> \[90m\[621f4979\] \[39mAbstractFFTs v1.5.0
> \[90m\[1520ce14\] \[39mAbstractTrees v0.4.5
> \[90m\[7d9f7c33\] \[39mAccessors v0.1.38
> \[90m\[79e6a3ab\] \[39mAdapt v4.0.4
> \[90m\[66dad0bd\] \[39mAliasTables v1.1.3
> \[90m\[dce04be8\] \[39mArgCheck v2.3.0
> \[90m\[ec485272\] \[39mArnoldiMethod v0.4.0
> \[90m\[4fba245c\] \[39mArrayInterface v7.16.0
> \[90m\[4c555306\] \[39mArrayLayouts v1.10.3
> \[90m\[a9b6321e\] \[39mAtomix v0.1.0
> \[90m\[aae01518\] \[39mBandedMatrices v1.7.5
> \[33m⌅\[39m \[90m\[198e06fe\] \[39mBangBang v0.3.40
> \[90m\[9718e550\] \[39mBaselet v0.1.1
> \[90m\[6e4b80f9\] \[39mBenchmarkTools v1.5.0
> \[90m\[e2ed5e7c\] \[39mBijections v0.1.9
> \[90m\[d1d4a3ce\] \[39mBitFlags v0.1.9
> \[90m\[62783981\] \[39mBitTwiddlingConvenienceFunctions v0.1.6
> \[90m\[8e7c35d0\] \[39mBlockArrays v1.1.1
> \[90m\[764a87c0\] \[39mBoundaryValueDiffEq v5.10.0
> \[90m\[fa961155\] \[39mCEnum v0.5.0
> \[90m\[2a0fbf3d\] \[39mCPUSummary v0.2.6
> \[90m\[00ebfdb7\] \[39mCSTParser v3.4.3
> \[90m\[336ed68f\] \[39mCSV v0.10.14
> \[90m\[324d7699\] \[39mCategoricalArrays v0.10.8
> \[90m\[af321ab8\] \[39mCategoricalDistributions v0.1.15
> \[90m\[d360d2e6\] \[39mChainRulesCore v1.25.0
> \[90m\[fb6a15b2\] \[39mCloseOpenIntervals v0.1.13
> \[90m\[944b1d66\] \[39mCodecZlib v0.7.6
> \[90m\[35d6a980\] \[39mColorSchemes v3.26.0
> \[90m\[3da002f7\] \[39mColorTypes v0.11.5
> \[90m\[c3611d14\] \[39mColorVectorSpace v0.10.0
> \[90m\[5ae59095\] \[39mColors v0.12.11
> \[90m\[861a8166\] \[39mCombinatorics v1.0.2
> \[90m\[a80b9123\] \[39mCommonMark v0.8.12
> \[90m\[38540f10\] \[39mCommonSolve v0.2.4
> \[90m\[bbf7d656\] \[39mCommonSubexpressions v0.3.1
> \[90m\[f70d9fcc\] \[39mCommonWorldInvalidations v1.0.0
> \[90m\[34da2185\] \[39mCompat v4.16.0
> \[90m\[b0b7db55\] \[39mComponentArrays v0.15.17
> \[90m\[b152e2b5\] \[39mCompositeTypes v0.1.4
> \[90m\[a33af91c\] \[39mCompositionsBase v0.1.2
> \[90m\[ed09eef8\] \[39mComputationalResources v0.3.2
> \[90m\[2569d6c7\] \[39mConcreteStructs v0.2.3
> \[90m\[f0e56b4a\] \[39mConcurrentUtilities v2.4.2
> \[90m\[187b0558\] \[39mConstructionBase v1.5.8
> \[90m\[6add18c4\] \[39mContextVariablesX v0.1.3
> \[90m\[d38c429a\] \[39mContour v0.6.3
> \[90m\[a6e380b2\] \[39mControlSystems v1.10.4
> \[90m\[aaaaaaaa\] \[39mControlSystemsBase v1.10.3
> \[90m\[687d7614\] \[39mControlSystemsMTK v2.2.1
> \[90m\[adafc99b\] \[39mCpuId v0.3.1
> \[90m\[a8cc5b0e\] \[39mCrayons v4.1.1
> \[90m\[717857b8\] \[39mDSP v0.7.9
> \[90m\[9a962f9c\] \[39mDataAPI v1.16.0
> \[90m\[a93c6f00\] \[39mDataFrames v1.6.1
> \[90m\[82cc6244\] \[39mDataInterpolations v6.4.0
> \[90m\[864edb3b\] \[39mDataStructures v0.18.20
> \[90m\[e2d170a0\] \[39mDataValueInterfaces v1.0.0
> \[90m\[244e2a9f\] \[39mDefineSingletons v0.1.2
> \[90m\[bcd4f6db\] \[39mDelayDiffEq v5.48.1
> \[90m\[8bb1440f\] \[39mDelimitedFiles v1.9.1
> \[90m\[a81e2ce2\] \[39mDescriptorSystems v1.4.4
> \[90m\[2b5f629d\] \[39mDiffEqBase v6.155.1
> \[90m\[459566f4\] \[39mDiffEqCallbacks v3.9.1
> \[90m\[77a26b50\] \[39mDiffEqNoiseProcess v5.23.0
> \[90m\[163ba53b\] \[39mDiffResults v1.1.0
> \[90m\[b552c78f\] \[39mDiffRules v1.15.1
> \[90m\[0c46a032\] \[39mDifferentialEquations v7.14.0
> \[90m\[a0c0ee7d\] \[39mDifferentiationInterface v0.5.17
> \[90m\[8d63f2c5\] \[39mDispatchDoctor v0.4.14
> \[90m\[b4f34e82\] \[39mDistances v0.10.11
> \[90m\[31c24e10\] \[39mDistributions v0.25.111
> \[90m\[ffbed154\] \[39mDocStringExtensions v0.9.3
> \[90m\[5b8099bc\] \[39mDomainSets v0.7.14
> \[90m\[7c1d4256\] \[39mDynamicPolynomials v0.6.0
> \[90m\[06fc5a27\] \[39mDynamicQuantities v1.0.0
> \[90m\[792122b4\] \[39mEarlyStopping v0.3.0
> \[90m\[4e289a0a\] \[39mEnumX v1.0.4
> \[90m\[f151be2c\] \[39mEnzymeCore v0.7.8
> \[90m\[460bff9d\] \[39mExceptionUnwrapping v0.1.10
> \[90m\[d4d017d3\] \[39mExponentialUtilities v1.26.1
> \[90m\[e2ba6199\] \[39mExprTools v0.1.10
> \[33m⌅\[39m \[90m\[6b7a57c9\] \[39mExpronicon v0.8.5
> \[90m\[c87230d0\] \[39mFFMPEG v0.4.1
> \[90m\[7a1cc6ca\] \[39mFFTW v1.8.0
> \[90m\[cc61a311\] \[39mFLoops v0.2.2
> \[90m\[b9860ae5\] \[39mFLoopsBase v0.1.1
> \[90m\[9d29842c\] \[39mFastAlmostBandedMatrices v0.1.3
> \[90m\[7034ab61\] \[39mFastBroadcast v0.3.5
> \[90m\[9aa1b823\] \[39mFastClosures v0.3.2
> \[90m\[29a986be\] \[39mFastLapackInterface v2.0.4
> \[90m\[33837fe5\] \[39mFeatureSelection v0.2.2
> \[90m\[48062228\] \[39mFilePathsBase v0.9.22
> \[90m\[1a297f60\] \[39mFillArrays v1.13.0
> \[90m\[64ca27bc\] \[39mFindFirstFunctions v1.4.1
> \[90m\[6a86dc24\] \[39mFiniteDiff v2.24.0
> \[90m\[53c48c17\] \[39mFixedPointNumbers v0.8.5
> \[90m\[1fa38f19\] \[39mFormat v1.3.7
> \[90m\[f6369f11\] \[39mForwardDiff v0.10.36
> \[90m\[069b7b12\] \[39mFunctionWrappers v1.1.3
> \[90m\[77dc65aa\] \[39mFunctionWrappersWrappers v0.1.3
> \[90m\[d9f16b24\] \[39mFunctors v0.4.12
> \[90m\[46192b85\] \[39mGPUArraysCore v0.1.6
> \[90m\[28b8d3ca\] \[39mGR v0.73.7
> \[90m\[c145ed77\] \[39mGenericSchur v0.5.4
> \[90m\[c27321d9\] \[39mGlob v1.3.1
> \[90m\[86223c79\] \[39mGraphs v1.11.2
> \[90m\[42e2da0e\] \[39mGrisu v1.0.2
> \[90m\[cd3eb016\] \[39mHTTP v1.10.8
> \[90m\[3e5b6fbb\] \[39mHostCPUFeatures v0.1.17
> \[90m\[e91730f6\] \[39mHungarian v0.7.0
> \[90m\[34004b35\] \[39mHypergeometricFunctions v0.3.24
> \[90m\[615f187c\] \[39mIfElse v0.1.1
> \[90m\[d25df0c9\] \[39mInflate v0.1.5
> \[90m\[22cec73e\] \[39mInitialValues v0.3.1
> \[90m\[842dd82b\] \[39mInlineStrings v1.4.2
> \[90m\[18e54dd8\] \[39mIntegerMathUtils v0.1.2
> \[90m\[8197267c\] \[39mIntervalSets v0.7.10
> \[90m\[3587e190\] \[39mInverseFunctions v0.1.16
> \[90m\[41ab1584\] \[39mInvertedIndices v1.3.0
> \[90m\[92d709cd\] \[39mIrrationalConstants v0.2.2
> \[90m\[c8e1da08\] \[39mIterTools v1.10.0
> \[90m\[b3c1a2ee\] \[39mIterationControl v0.5.4
> \[90m\[82899510\] \[39mIteratorInterfaceExtensions v1.0.0
> \[90m\[1019f520\] \[39mJLFzf v0.1.8
> \[90m\[692b3bcd\] \[39mJLLWrappers v1.6.0
> \[90m\[682c06a0\] \[39mJSON v0.21.4
> \[90m\[98e50ef6\] \[39mJuliaFormatter v1.0.60
> \[90m\[b14d175d\] \[39mJuliaVariables v0.2.4
> \[90m\[ccbc3e58\] \[39mJumpProcesses v9.13.7
> \[90m\[ef3ab10e\] \[39mKLU v0.6.0
> \[90m\[63c18a36\] \[39mKernelAbstractions v0.9.26
> \[90m\[ba0b0d4f\] \[39mKrylov v0.9.6
> \[90m\[929cbde3\] \[39mLLVM v9.1.2
> \[90m\[b964fa9f\] \[39mLaTeXStrings v1.3.1
> \[90m\[984bce1d\] \[39mLambertW v0.4.6
> \[90m\[23fbe1c1\] \[39mLatexify v0.16.5
> \[90m\[a5e1c1ea\] \[39mLatinHypercubeSampling v1.9.0
> \[90m\[10f19ff3\] \[39mLayoutPointers v0.1.17
> \[90m\[5078a376\] \[39mLazyArrays v2.2.1
> \[90m\[92ad9a40\] \[39mLearnAPI v0.1.0
> \[90m\[2d8b4e74\] \[39mLevyArea v1.0.0
> \[90m\[d3d80556\] \[39mLineSearches v7.3.0
> \[90m\[7a12625a\] \[39mLinearMaps v3.11.3
> \[90m\[7ed4a6bd\] \[39mLinearSolve v2.34.0
> \[90m\[2ab3a3ac\] \[39mLogExpFunctions v0.3.28
> \[90m\[e6f89c97\] \[39mLoggingExtras v1.0.3
> \[90m\[bdcacae8\] \[39mLoopVectorization v0.12.171
> \[90m\[2fda8390\] \[39mLsqFit v0.15.0
> \[90m\[64a0f543\] \[39mMLFlowClient v0.5.1
> \[90m\[add582a8\] \[39mMLJ v0.20.7
> \[90m\[45f359ea\] \[39mMLJBalancing v0.1.5
> \[90m\[a7f614a8\] \[39mMLJBase v1.7.0
> \[90m\[50ed68f4\] \[39mMLJEnsembles v0.4.3
> \[90m\[7b7b8358\] \[39mMLJFlow v0.5.0
> \[90m\[614be32b\] \[39mMLJIteration v0.6.3
> \[90m\[e80e1ace\] \[39mMLJModelInterface v1.11.0
> \[90m\[d491faf4\] \[39mMLJModels v0.17.4
> \[90m\[03970b2e\] \[39mMLJTuning v0.8.8
> \[90m\[d8e11817\] \[39mMLStyle v0.4.17
> \[90m\[f1d291b0\] \[39mMLUtils v0.4.4
> \[90m\[1914dd2f\] \[39mMacroTools v0.5.13
> \[90m\[d125e4d3\] \[39mManualMemory v0.1.8
> \[90m\[99c1a7ee\] \[39mMatrixEquations v2.4.2
> \[90m\[a3b82374\] \[39mMatrixFactorizations v3.0.1
> \[90m\[48965c70\] \[39mMatrixPencils v1.8.0
> \[90m\[bb5d69b7\] \[39mMaybeInplace v0.1.4
> \[90m\[739be429\] \[39mMbedTLS v1.1.9
> \[90m\[442fdcdd\] \[39mMeasures v0.3.2
> \[33m⌅\[39m \[90m\[128add7d\] \[39mMicroCollections v0.1.4
> \[90m\[e1d29d7a\] \[39mMissings v1.2.0
> \[90m\[961ee093\] \[39mModelingToolkit v9.40.0
> \[90m\[16a59e39\] \[39mModelingToolkitStandardLibrary v2.12.0
> \[90m\[0987c9cc\] \[39mMonteCarloMeasurements v1.2.1
> \[90m\[46d2c3a1\] \[39mMuladdMacro v0.2.4
> \[90m\[102ac46a\] \[39mMultivariatePolynomials v0.5.6
> \[90m\[d8a4904e\] \[39mMutableArithmetics v1.4.6
> \[90m\[d41bc354\] \[39mNLSolversBase v7.8.3
> \[90m\[2774e3e8\] \[39mNLsolve v4.5.1
> \[90m\[872c559c\] \[39mNNlib v0.9.23
> \[90m\[77ba4419\] \[39mNaNMath v1.0.2
> \[90m\[71a1bf82\] \[39mNameResolution v0.1.5
> \[90m\[8913a72c\] \[39mNonlinearSolve v3.14.0
> \[90m\[6fe1bfb0\] \[39mOffsetArrays v1.14.1
> \[90m\[8b6db2d4\] \[39mOpenML v0.3.1
> \[90m\[4d8831e6\] \[39mOpenSSL v1.4.3
> \[90m\[429524aa\] \[39mOptim v1.9.4
> \[90m\[bac558e1\] \[39mOrderedCollections v1.6.3
> \[90m\[1dea7af3\] \[39mOrdinaryDiffEq v6.89.0
> \[90m\[89bda076\] \[39mOrdinaryDiffEqAdamsBashforthMoulton v1.1.0
> \[90m\[6ad6398a\] \[39mOrdinaryDiffEqBDF v1.1.2
> \[90m\[bbf590c4\] \[39mOrdinaryDiffEqCore v1.6.0
> \[90m\[50262376\] \[39mOrdinaryDiffEqDefault v1.1.0
> \[90m\[4302a76b\] \[39mOrdinaryDiffEqDifferentiation v1.1.0
> \[90m\[9286f039\] \[39mOrdinaryDiffEqExplicitRK v1.1.0
> \[90m\[e0540318\] \[39mOrdinaryDiffEqExponentialRK v1.1.0
> \[90m\[becaefa8\] \[39mOrdinaryDiffEqExtrapolation v1.1.0
> \[90m\[5960d6e9\] \[39mOrdinaryDiffEqFIRK v1.1.1
> \[90m\[101fe9f7\] \[39mOrdinaryDiffEqFeagin v1.1.0
> \[90m\[d3585ca7\] \[39mOrdinaryDiffEqFunctionMap v1.1.1
> \[90m\[d28bc4f8\] \[39mOrdinaryDiffEqHighOrderRK v1.1.0
> \[90m\[9f002381\] \[39mOrdinaryDiffEqIMEXMultistep v1.1.0
> \[90m\[521117fe\] \[39mOrdinaryDiffEqLinear v1.1.0
> \[90m\[1344f307\] \[39mOrdinaryDiffEqLowOrderRK v1.2.0
> \[90m\[b0944070\] \[39mOrdinaryDiffEqLowStorageRK v1.2.1
> \[90m\[127b3ac7\] \[39mOrdinaryDiffEqNonlinearSolve v1.2.1
> \[90m\[c9986a66\] \[39mOrdinaryDiffEqNordsieck v1.1.0
> \[90m\[5dd0a6cf\] \[39mOrdinaryDiffEqPDIRK v1.1.0
> \[90m\[5b33eab2\] \[39mOrdinaryDiffEqPRK v1.1.0
> \[90m\[04162be5\] \[39mOrdinaryDiffEqQPRK v1.1.0
> \[90m\[af6ede74\] \[39mOrdinaryDiffEqRKN v1.1.0
> \[90m\[43230ef6\] \[39mOrdinaryDiffEqRosenbrock v1.2.0
> \[90m\[2d112036\] \[39mOrdinaryDiffEqSDIRK v1.1.0
> \[90m\[669c94d9\] \[39mOrdinaryDiffEqSSPRK v1.2.0
> \[90m\[e3e12d00\] \[39mOrdinaryDiffEqStabilizedIRK v1.1.0
> \[90m\[358294b1\] \[39mOrdinaryDiffEqStabilizedRK v1.1.0
> \[90m\[fa646aed\] \[39mOrdinaryDiffEqSymplecticRK v1.1.0
> \[90m\[b1df2697\] \[39mOrdinaryDiffEqTsit5 v1.1.0
> \[90m\[79d7bb75\] \[39mOrdinaryDiffEqVerner v1.1.1
> \[90m\[90014a1f\] \[39mPDMats v0.11.31
> \[90m\[65ce6f38\] \[39mPackageExtensionCompat v1.0.2
> \[90m\[d96e819e\] \[39mParameters v0.12.3
> \[90m\[69de0a69\] \[39mParsers v2.8.1
> \[90m\[b98c9c47\] \[39mPipe v1.3.0
> \[90m\[ccf2f8ad\] \[39mPlotThemes v3.2.0
> \[90m\[995b91a9\] \[39mPlotUtils v1.4.1
> \[90m\[91a5bcdd\] \[39mPlots v1.40.8
> \[90m\[e409e4f3\] \[39mPoissonRandom v0.4.4
> \[90m\[f517fe37\] \[39mPolyester v0.7.16
> \[90m\[98d1487c\] \[39mPolyesterForwardDiff v0.1.2
> \[90m\[1d0040c9\] \[39mPolyesterWeave v0.2.2
> \[90m\[f27b6e38\] \[39mPolynomials v4.0.11
> \[90m\[2dfb63ee\] \[39mPooledArrays v1.4.3
> \[90m\[85a6dd25\] \[39mPositiveFactorizations v0.2.4
> \[90m\[d236fae5\] \[39mPreallocationTools v0.4.24
> \[90m\[aea7be01\] \[39mPrecompileTools v1.2.1
> \[90m\[21216c6a\] \[39mPreferences v1.4.3
> \[90m\[8162dcfd\] \[39mPrettyPrint v0.2.0
> \[90m\[54e16d92\] \[39mPrettyPrinting v0.4.2
> \[90m\[08abe8d2\] \[39mPrettyTables v2.3.2
> \[90m\[27ebfcd6\] \[39mPrimes v0.5.6
> \[90m\[92933f4c\] \[39mProgressMeter v1.10.2
> \[90m\[43287f4e\] \[39mPtrArrays v1.2.1
> \[90m\[1fd47b50\] \[39mQuadGK v2.11.0
> \[90m\[74087812\] \[39mRandom123 v1.7.0
> \[90m\[e6cf234a\] \[39mRandomNumbers v1.6.0
> \[90m\[3cdcf5f2\] \[39mRecipesBase v1.3.4
> \[90m\[01d81517\] \[39mRecipesPipeline v0.6.12
> \[90m\[731186ca\] \[39mRecursiveArrayTools v3.27.0
> \[90m\[f2c3362d\] \[39mRecursiveFactorization v0.2.23
> \[90m\[189a3867\] \[39mReexport v1.2.2
> \[90m\[05181044\] \[39mRelocatableFolders v1.0.1
> \[90m\[ae029012\] \[39mRequires v1.3.0
> \[90m\[ae5879a3\] \[39mResettableStacks v1.1.1
> \[90m\[79098fc4\] \[39mRmath v0.8.0
> \[90m\[21fd56a4\] \[39mRobustAndOptimalControl v0.4.31
> \[90m\[7e49a35a\] \[39mRuntimeGeneratedFunctions v0.5.13
> \[90m\[94e857df\] \[39mSIMDTypes v0.1.0
> \[90m\[476501e8\] \[39mSLEEFPirates v0.6.43
> \[90m\[0bca4576\] \[39mSciMLBase v2.53.1
> \[90m\[c0aeaf25\] \[39mSciMLOperators v0.3.10
> \[90m\[53ae85a6\] \[39mSciMLStructures v1.5.0
> \[90m\[321657f4\] \[39mScientificTypes v3.0.2
> \[90m\[30f210dd\] \[39mScientificTypesBase v3.0.0
> \[90m\[6c6a2e73\] \[39mScratch v1.2.1
> \[90m\[91c51154\] \[39mSentinelArrays v1.4.5
> \[90m\[efcf1570\] \[39mSetfield v1.1.1
> \[90m\[605ecd9f\] \[39mShowCases v0.1.0
> \[90m\[992d4aef\] \[39mShowoff v1.0.3
> \[90m\[777ac1f9\] \[39mSimpleBufferStream v1.1.0
> \[90m\[727e6d20\] \[39mSimpleNonlinearSolve v1.12.1
> \[90m\[699a6c99\] \[39mSimpleTraits v0.9.4
> \[90m\[ce78b400\] \[39mSimpleUnPack v1.1.0
> \[90m\[a2af1166\] \[39mSortingAlgorithms v1.2.1
> \[90m\[47a9eef4\] \[39mSparseDiffTools v2.20.0
> \[90m\[0a514795\] \[39mSparseMatrixColorings v0.4.0
> \[90m\[e56a9233\] \[39mSparspak v0.3.9
> \[90m\[276daf66\] \[39mSpecialFunctions v2.4.0
> \[90m\[171d559e\] \[39mSplittablesBase v0.1.15
> \[90m\[860ef19b\] \[39mStableRNGs v1.0.2
> \[90m\[aedffcd0\] \[39mStatic v1.1.1
> \[90m\[0d7ed370\] \[39mStaticArrayInterface v1.8.0
> \[90m\[90137ffa\] \[39mStaticArrays v1.9.7
> \[90m\[1e83bf80\] \[39mStaticArraysCore v1.4.3
> \[90m\[a19d573c\] \[39mStatisticalMeasures v0.1.6
> \[90m\[c062fc1d\] \[39mStatisticalMeasuresBase v0.1.1
> \[90m\[64bff920\] \[39mStatisticalTraits v3.4.0
> \[90m\[82ae8749\] \[39mStatsAPI v1.7.0
> \[90m\[2913bbd2\] \[39mStatsBase v0.34.3
> \[90m\[4c63d2b9\] \[39mStatsFuns v1.3.2
> \[90m\[9672c7b4\] \[39mSteadyStateDiffEq v2.4.0
> \[90m\[789caeaf\] \[39mStochasticDiffEq v6.69.0
> \[90m\[7792a7ef\] \[39mStrideArraysCore v0.5.7
> \[90m\[892a3eda\] \[39mStringManipulation v0.3.4
> \[90m\[c3572dad\] \[39mSundials v4.25.0
> \[90m\[2efcf032\] \[39mSymbolicIndexingInterface v0.3.30
> \[90m\[19f23fe9\] \[39mSymbolicLimits v0.2.2
> \[90m\[d1185830\] \[39mSymbolicUtils v3.7.0
> \[90m\[0c5d862f\] \[39mSymbolics v6.11.0
> \[90m\[3783bdb8\] \[39mTableTraits v1.0.1
> \[90m\[bd369af6\] \[39mTables v1.12.0
> \[90m\[62fd8b95\] \[39mTensorCore v0.1.1
> \[90m\[8ea1fca8\] \[39mTermInterface v2.0.0
> \[90m\[1c621080\] \[39mTestItems v1.0.0
> \[90m\[8290d209\] \[39mThreadingUtilities v0.5.2
> \[90m\[a759f4b9\] \[39mTimerOutputs v0.5.24
> \[90m\[0796e94c\] \[39mTokenize v0.5.29
> \[90m\[3bb67fe8\] \[39mTranscodingStreams v0.11.2
> \[32m⌃\[39m \[90m\[28d57a85\] \[39mTransducers v0.4.80
> \[90m\[d5829a12\] \[39mTriangularSolve v0.2.1
> \[90m\[410a4b4d\] \[39mTricks v0.1.9
> \[90m\[781d530d\] \[39mTruncatedStacktraces v1.4.0
> \[90m\[5c2747f8\] \[39mURIs v1.5.1
> \[90m\[3a884ed6\] \[39mUnPack v1.0.2
> \[90m\[1cfade01\] \[39mUnicodeFun v0.4.1
> \[90m\[1986cc42\] \[39mUnitful v1.21.0
> \[90m\[45397f5d\] \[39mUnitfulLatexify v1.6.4
> \[90m\[a7c27f48\] \[39mUnityper v0.1.6
> \[90m\[013be700\] \[39mUnsafeAtomics v0.2.1
> \[90m\[d80eeb9a\] \[39mUnsafeAtomicsLLVM v0.2.1
> \[90m\[41fe7b60\] \[39mUnzip v0.2.0
> \[90m\[3d5dd08c\] \[39mVectorizationBase v0.21.70
> \[90m\[19fa3120\] \[39mVertexSafeGraphs v0.2.0
> \[90m\[ea10d353\] \[39mWeakRefStrings v1.4.2
> \[90m\[76eceee3\] \[39mWorkerUtilities v1.6.1
> \[90m\[6e34b625\] \[39mBzip2\_jll v1.0.8+1
> \[90m\[83423d85\] \[39mCairo\_jll v1.18.0+2
> \[90m\[ee1fde0b\] \[39mDbus\_jll v1.14.10+0
> \[90m\[2702e6a9\] \[39mEpollShim\_jll v0.0.20230411+0
> \[90m\[2e619515\] \[39mExpat\_jll v2.6.2+0
> \[33m⌅\[39m \[90m\[b22a6f82\] \[39mFFMPEG\_jll v4.4.4+1
> \[90m\[f5851436\] \[39mFFTW\_jll v3.3.10+0
> \[90m\[a3f928ae\] \[39mFontconfig\_jll v2.13.96+0
> \[90m\[d7e528f0\] \[39mFreeType2\_jll v2.13.2+0
> \[90m\[559328eb\] \[39mFriBidi\_jll v1.0.14+0
> \[90m\[0656b61e\] \[39mGLFW\_jll v3.4.0+1
> \[90m\[d2c73de3\] \[39mGR\_jll v0.73.7+0
> \[90m\[78b55507\] \[39mGettext\_jll v0.21.0+0
> \[90m\[7746bdde\] \[39mGlib\_jll v2.80.2+0
> \[90m\[3b182d85\] \[39mGraphite2\_jll v1.3.14+0
> \[90m\[2e76f6c2\] \[39mHarfBuzz\_jll v8.3.1+0
> \[90m\[1d5cc7b8\] \[39mIntelOpenMP\_jll v2024.2.1+0
> \[90m\[aacddb02\] \[39mJpegTurbo\_jll v3.0.3+0
> \[90m\[c1c5ebd0\] \[39mLAME\_jll v3.100.2+0
> \[33m⌅\[39m \[90m\[88015f11\] \[39mLERC\_jll v3.0.0+1
> \[90m\[dad2f222\] \[39mLLVMExtra\_jll v0.0.34+0
> \[90m\[1d63c593\] \[39mLLVMOpenMP\_jll v18.1.7+0
> \[90m\[dd4b983a\] \[39mLZO\_jll v2.10.2+0
> \[33m⌅\[39m \[90m\[e9f186c6\] \[39mLibffi\_jll v3.2.2+1
> \[90m\[d4300ac3\] \[39mLibgcrypt\_jll v1.8.11+0
> \[90m\[7e76a0d4\] \[39mLibglvnd\_jll v1.6.0+0
> \[90m\[7add5ba3\] \[39mLibgpg\_error\_jll v1.49.0+0
> \[90m\[94ce4f54\] \[39mLibiconv\_jll v1.17.0+0
> \[90m\[4b2f31a3\] \[39mLibmount\_jll v2.40.1+0
> \[33m⌅\[39m \[90m\[89763e89\] \[39mLibtiff\_jll v4.5.1+1
> \[90m\[38a345b3\] \[39mLibuuid\_jll v2.40.1+0
> \[90m\[856f044c\] \[39mMKL\_jll v2024.2.0+0
> \[90m\[e7412a2a\] \[39mOgg\_jll v1.3.5+1
> \[90m\[458c3c95\] \[39mOpenSSL\_jll v3.0.15+0
> \[90m\[efe28fd5\] \[39mOpenSpecFun\_jll v0.5.5+0
> \[90m\[91d4177d\] \[39mOpus\_jll v1.3.3+0
> \[90m\[36c8627f\] \[39mPango\_jll v1.54.1+0
> \[90m\[30392449\] \[39mPixman\_jll v0.43.4+0
> \[90m\[c0090381\] \[39mQt6Base\_jll v6.7.1+1
> \[90m\[629bc702\] \[39mQt6Declarative\_jll v6.7.1+2
> \[90m\[ce943373\] \[39mQt6ShaderTools\_jll v6.7.1+1
> \[90m\[e99dba38\] \[39mQt6Wayland\_jll v6.7.1+1
> \[90m\[f50d1b31\] \[39mRmath\_jll v0.5.1+0
> \[33m⌅\[39m \[90m\[fb77eaff\] \[39mSundials\_jll v5.2.2+0
> \[90m\[a44049a8\] \[39mVulkan\_Loader\_jll v1.3.243+0
> \[90m\[a2964d1f\] \[39mWayland\_jll v1.21.0+1
> \[90m\[2381bf8a\] \[39mWayland\_protocols\_jll v1.31.0+0
> \[90m\[02c8fc9c\] \[39mXML2\_jll v2.13.3+0
> \[90m\[aed1982a\] \[39mXSLT\_jll v1.1.41+0
> \[90m\[ffd25f8a\] \[39mXZ\_jll v5.4.6+0
> \[90m\[f67eecfb\] \[39mXorg\_libICE\_jll v1.1.1+0
> \[90m\[c834827a\] \[39mXorg\_libSM\_jll v1.2.4+0
> \[90m\[4f6342f7\] \[39mXorg\_libX11\_jll v1.8.6+0
> \[90m\[0c0b7dd1\] \[39mXorg\_libXau\_jll v1.0.11+0
> \[90m\[935fb764\] \[39mXorg\_libXcursor\_jll v1.2.0+4
> \[90m\[a3789734\] \[39mXorg\_libXdmcp\_jll v1.1.4+0
> \[90m\[1082639a\] \[39mXorg\_libXext\_jll v1.3.6+0
> \[90m\[d091e8ba\] \[39mXorg\_libXfixes\_jll v5.0.3+4
> \[90m\[a51aa0fd\] \[39mXorg\_libXi\_jll v1.7.10+4
> \[90m\[d1454406\] \[39mXorg\_libXinerama\_jll v1.1.4+4
> \[90m\[ec84b674\] \[39mXorg\_libXrandr\_jll v1.5.2+4
> \[90m\[ea2f1a96\] \[39mXorg\_libXrender\_jll v0.9.11+0
> \[90m\[14d82f49\] \[39mXorg\_libpthread\_stubs\_jll v0.1.1+0
> \[90m\[c7cfdc94\] \[39mXorg\_libxcb\_jll v1.17.0+0
> \[90m\[cc61e674\] \[39mXorg\_libxkbfile\_jll v1.1.2+0
> \[90m\[e920d4aa\] \[39mXorg\_xcb\_util\_cursor\_jll v0.1.4+0
> \[90m\[12413925\] \[39mXorg\_xcb\_util\_image\_jll v0.4.0+1
> \[90m\[2def613f\] \[39mXorg\_xcb\_util\_jll v0.4.0+1
> \[90m\[975044d2\] \[39mXorg\_xcb\_util\_keysyms\_jll v0.4.0+1
> \[90m\[0d47668e\] \[39mXorg\_xcb\_util\_renderutil\_jll v0.3.9+1
> \[90m\[c22f9ab0\] \[39mXorg\_xcb\_util\_wm\_jll v0.4.1+1
> \[90m\[35661453\] \[39mXorg\_xkbcomp\_jll v1.4.6+0
> \[90m\[33bec58e\] \[39mXorg\_xkeyboard\_config\_jll v2.39.0+0
> \[90m\[c5fb5394\] \[39mXorg\_xtrans\_jll v1.5.0+0
> \[90m\[3161d3a3\] \[39mZstd\_jll v1.5.6+0
> \[90m\[35ca27e7\] \[39meudev\_jll v3.2.9+0
> \[90m\[214eeab7\] \[39mfzf\_jll v0.53.0+0
> \[90m\[1a1c6b14\] \[39mgperf\_jll v3.1.1+0
> \[90m\[a4ae2306\] \[39mlibaom\_jll v3.9.0+0
> \[90m\[0ac62f75\] \[39mlibass\_jll v0.15.2+0
> \[90m\[1183f4f0\] \[39mlibdecor\_jll v0.2.2+0
> \[90m\[2db6ffa8\] \[39mlibevdev\_jll v1.11.0+0
> \[90m\[f638f0a6\] \[39mlibfdk\_aac\_jll v2.0.3+0
> \[90m\[36db933b\] \[39mlibinput\_jll v1.18.0+0
> \[90m\[b53b4c65\] \[39mlibpng\_jll v1.6.43+1
> \[90m\[f27f6e37\] \[39mlibvorbis\_jll v1.3.7+2
> \[90m\[009596ad\] \[39mmtdev\_jll v1.1.6+0
> \[90m\[1317d2d5\] \[39moneTBB\_jll v2021.12.0+0
> \[33m⌅\[39m \[90m\[1270edf5\] \[39mx264\_jll v2021.5.5+0
> \[33m⌅\[39m \[90m\[dfaa095f\] \[39mx265\_jll v3.5.0+0
> \[90m\[d8fb68d0\] \[39mxkbcommon\_jll v1.4.1+1
> \[90m\[0dad84c5\] \[39mArgTools v1.1.1
> \[90m\[56f22d72\] \[39mArtifacts
> \[90m\[2a0f44e3\] \[39mBase64
> \[90m\[ade2ca70\] \[39mDates
> \[90m\[8ba89e20\] \[39mDistributed
> \[90m\[f43a241f\] \[39mDownloads v1.6.0
> \[90m\[7b1f6079\] \[39mFileWatching
> \[90m\[9fa8497b\] \[39mFuture
> \[90m\[b77e0a4c\] \[39mInteractiveUtils
> \[90m\[4af54fe1\] \[39mLazyArtifacts
> \[90m\[b27032c2\] \[39mLibCURL v0.6.4
> \[90m\[76f85450\] \[39mLibGit2
> \[90m\[8f399da3\] \[39mLibdl
> \[90m\[37e2e46d\] \[39mLinearAlgebra
> \[90m\[56ddb016\] \[39mLogging
> \[90m\[d6f4376e\] \[39mMarkdown
> \[90m\[a63ad114\] \[39mMmap
> \[90m\[ca575930\] \[39mNetworkOptions v1.2.0
> \[90m\[44cfe95a\] \[39mPkg v1.10.0
> \[90m\[de0858da\] \[39mPrintf
> \[90m\[9abbd945\] \[39mProfile
> \[90m\[3fa0cd96\] \[39mREPL
> \[90m\[9a3f8284\] \[39mRandom
> \[90m\[ea8e919c\] \[39mSHA v0.7.0
> \[90m\[9e88b42a\] \[39mSerialization
> \[90m\[1a1011a3\] \[39mSharedArrays
> \[90m\[6462fe0b\] \[39mSockets
> \[90m\[2f01184e\] \[39mSparseArrays v1.10.0
> \[90m\[10745b16\] \[39mStatistics v1.10.0
> \[90m\[4607b0f0\] \[39mSuiteSparse
> \[90m\[fa267f1f\] \[39mTOML v1.0.3
> \[90m\[a4e569a6\] \[39mTar v1.10.0
> \[90m\[8dfed614\] \[39mTest
> \[90m\[cf7118a7\] \[39mUUIDs
> \[90m\[4ec0a83e\] \[39mUnicode
> \[90m\[e66e0078\] \[39mCompilerSupportLibraries\_jll v1.1.1+0
> \[90m\[deac9b47\] \[39mLibCURL\_jll v8.4.0+0
> \[90m\[e37daf67\] \[39mLibGit2\_jll v1.6.4+0
> \[90m\[29816b5a\] \[39mLibSSH2\_jll v1.11.0+1
> \[90m\[c8ffd9c3\] \[39mMbedTLS\_jll v2.28.2+1
> \[90m\[14a3606d\] \[39mMozillaCACerts\_jll v2023.1.10
> \[90m\[4536629a\] \[39mOpenBLAS\_jll v0.3.23+4
> \[90m\[05823500\] \[39mOpenLibm\_jll v0.8.1+2
> \[90m\[efcefdf7\] \[39mPCRE2\_jll v10.42.0+1
> \[90m\[bea87d4a\] \[39mSuiteSparse\_jll v7.2.1+1
> \[90m\[83775a58\] \[39mZlib\_jll v1.2.13+1
> \[90m\[8e850b90\] \[39mlibblastrampoline\_jll v5.11.0+0
> \[90m\[8e850ede\] \[39mnghttp2\_jll v1.52.0+1
> \[90m\[3f19e933\] \[39mp7zip\_jll v17.4.0+2
> \[36m\[1mInfo\[22m\[39m Packages marked with \[32m⌃\[39m and \[33m⌅\[39m have new versions available. Those with \[32m⌃\[39m may be upgradable, but those with \[33m⌅\[39m are restricted by compatibility constraints from upgrading. To see why use \`status --outdated -m\`
> \`\`\`
> 
> - Output of \`versioninfo()\`
> 
> \`\`\`julia
> Julia Version 1.10.5
> Commit 6f3fdf7b36 (2024-08-27 14:19 UTC)
> Build Info:
> Official https://julialang.org/ release
> Platform Info:
> OS: Windows (x86\_64-w64-mingw32)
> CPU: 16 × Intel(R) Core(TM) i9-9900K CPU @ 3.60GHz
> WORD\_SIZE: 64
> LIBM: libopenlibm
> LLVM: libLLVM-15.0.7 (ORCJIT, skylake)
> Threads: 1 default, 0 interactive, 1 GC (on 16 virtual cores)
> Environment:
> JULIA\_NUM\_THREADS = 
> \`\`\`
> 
> \*\*Additional context\*\*
> 
> Add any other context about the problem here.

> I’m not surprised that this happens, to invert a strictly proper model you will need some order of derivatives of the inputs. When simulating, this may work out if the input function is differentiable, but when linearizing there is nothing to differentiate, so the compiler has to be augmented with support for this use case, i.e., by
> 
> - Erroring with a useful error message.
> - Or better, indicate that the user must also provide the derivatives of inputs as another set of inputs
> 
> What you can do right now is to introduce new input variables `yd_1` and define `y_1` as `D(y_1) ~ yd_1`

The issue comment includes a working example

* * *

PS. being from Lund, I have endured many hours listening to the sound of those pumps 😅

---

<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:** [September 19, 2024, 9:47am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/4 "2024-09-19T09:47:59Z")

</div>

Nice!

Of course, this trick introduces two artificial integrators in the zero dynamics, but that is probably fine. Here is what I get:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/a/1ac97caec645430e5e3cb5d58b353a6badf8fa35.png)

Sorry for reminding you about the pumps 🤣

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 19, 2024, 10:33am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/5 "2024-09-19T10:33:24Z")

</div>

> [@BLI](#):
>
> Of course, this trick introduces two artificial integrators in the zero dynamics, but that is probably fine.

That’s unavoidable if you want to represent the model on statespace form 😕 The reason is the same as `inv(sys)` not working for a strictly proper system `sys`. IIRC, dymola and possibly also open-modelica has a slightly nicer error message in situations like this, indicating that input derivatives are required.

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 19, 2024, 1:28pm UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/6 "2024-09-19T13:28:37Z")

</div>

Those two extra integrator state-variables are are required to indicate the operating point of the input, since now the new “input” is the derivative of the input.

---

<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:** [September 22, 2024, 8:22am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/8 "2024-09-22T08:22:23Z")

</div>

…I more or less figured out things. But some simple questions about MTK `linearize` vs. `named_ss`…

```julia
mats, hps_ = linearize(hps_LIO, [hps_LIO.u_v], [hps_LIO.w]; op=op_pt, allow_input_derivatives=true)
sys = ss(mats...)

```

This gives a system `sys` with extra columns in the B and D matrices for input derivative.

```julia
sys_c = named_ss(hps_LIO, [hps_LIO.u_v], [hps_LIO.w]; op=op_pt, allow_input_derivatives=true)

```

`sys_c` gives matrices without input derivative. So the algorithm probably uses `linearize` as a backbone, introduces `u` as an extra state, sets up the system from input \dot{u} via states (x,u) to output y, and then removes the integrator.

In my case, `sys_c` gives the following transfer function:

```julia
julia> zpk(sys_c)
TransferFunction{Continuous, ControlSystemsBase.SisoZpk{Float64, ComplexF64}}
                               (1.0s - 2.1160129025661592e-9)(1.0s - 0.5250534353649084)
99.58081303429545-------------------------------------------------------------------------------------
                 (1.0s + 0.4409211191696938)(1.0s + 0.14243813925501536)(1.0s - 2.2168795262579917e-9)

Continuous-time transfer function model

```

So – a little bit ugly with some stray numerics – two terms which are approximately `s` that really should cancel out.

I try to do a minimal realization to see if this fixes things, and get:

```julia
julia> zpk(minrel(sys_c))
TransferFunction{Continuous, ControlSystemsBase.SisoZpk{Float64, ComplexF64}}
                            1.0
99.58081303429545-------------------------
                 1.0s + 1.1084126936887508

Continuous-time transfer function model

```

which is weirdly wrong.

- Is there a way to make `minrel` do a better job?

* * *

Finally, I also played around with the original system from `linearize`:

```julia
A_1 = [sys.A sys.B[:,1]; zeros(1,4) 0]
B_1 = [sys.B[:,2]; 1]
C_1 = [sys.C sys.D[:,1]]
D_1 = sys.D[:,2]
sys_1 = ss(A_1,B_1,C_1,D_1)

```

and then

```julia
julia> zpk(sys_1)
TransferFunction{Continuous, ControlSystemsBase.SisoZpk{Float64, ComplexF64}}
                                  (1.0s - 0.5250534374809216)(1.0s - 4.19885971173042e-16)
99.58081303429545------------------------------------------------------------------------------------------
                 (1.0s + 0.44092112239911896)(1.0s + 0.142438133808711)(1.0s)(1.0s - 2.216063822164251e-16)

Continuous-time transfer function model

```

The same types of stray numerics as from `named_ss` + the artificial pole due to using \dot{u} as input.

OK – let me try to get rid of the artificial pole by multiplying with `tf("s")`.

```julia
julia> zpk(sys_1)*tf("s")
TransferFunction{Continuous, ControlSystemsBase.SisoZpk{Float64, ComplexF64}}
                               1.0s - 0.5250534374809217
99.58081303429545------------------------------------------------------
                 (1.0s + 0.44092112239911896)(1.0s + 0.142438133808711)

Continuous-time transfer function model

```

This is interesting!! Now, the stray numerics is gone, and I have found the transfer function that I really searched for, without using `minrel` or anything…

I’m curious:

- How does `named_ss` get rid of the artificial pole? Probably not by multiplying with `tf("s")`?
- Is the idea of multiplying with `tf("s")` a good way to do it, or are there possible numeric problems with it?
- What sort of numeric fixing takes place when I do `zpk(sys_1)*tf("s")`?

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [September 23, 2024, 4:19am UTC](https://discourse.julialang.org/t/mtk-linearization-of-zero-dynamics/119546/9 "2024-09-23T04:19:50Z")

</div>

> [@BLI](#):
>
> So the algorithm probably uses `linearize` as a backbone

It does, which can be readily verified by reading [the docstring of `named_ss`](https://juliacontrol.github.io/ControlSystemsMTK.jl/dev/api/#RobustAndOptimalControl.named_ss-Tuple%7BAbstractTimeDependentSystem,%20Any,%20Any%7D) or inspecting the source.

> [@BLI](#):
>
> Is the idea of multiplying with `tf("s")` a good way to do it, or are there possible numeric problems with it?

Transfer-function representations are always a bit iffy since they use polynomials. If the system that is differentiated is strictly proper (`D` matrix is zero), you can achieve the multiplication by `s` on statespace form by postmultiplying `C` with `A`.

> [@BLI](#):
>
> What sort of numeric fixing takes place when I do `zpk(sys_1)*tf("s")`?

I don’t know what system you are using so I cannot easily figure out. You have not included any code to create `hps_LIO`.

> [@BLI](#):
>
> Is there a way to make `minrel` do a better job?

I don’t even know what system type you call `minreal` on, a statespace object, transfer function of polynomials or a ZPK model? They all have different implementations of `minreal`.

In general, many of your questions, including those from the deleted post above, can be answered by reading the docstring of the function/method your question is about. For example, the aforementioned docstring of `named_ss` will lead to to information about how the simplification is performed when input derivatives are present. The docstring for the statespace version of `minreal` contains a lot of customization of numeric tolerances etc. that can be used to tweak the result.

I would guess that your system is borderline uncontrollable, you can check this by checking the minimum singular values indicated by

```julia
julia> controllability((sminreal(sys_c)))
(iscontrollable = true, ranks = [3, 3, 3], sigma_min = [0.081129755005732, 0.018320012744819, 1.0238394749593724e-11])

```

if some of those are very small, the system has almost uncontrollable modes which may be removed by `minreal`.

If you have a poorly balanced statespace model, e.g.,

```julia
B = [
 -0.5963028955165542
 -4.793145772316456
 99.58081303429545
  1.0428129567742857e9]

C = [
 0.0 0.0 1.0 0.0]

```

you may also improve numerics by calling `balance_statespace`:

```julia
julia> sys_c
StateSpace{Continuous, Float64}
A = 
 -0.7340579610440452 0.03618086493757771 0.00020843434232478795 -0.0
 -4.793295206811445 0.0 0.0 0.0
  0.0 26.158882437925314 0.1506987048362153 0.0
  0.0 2.739365216029021e8 1.5781208968256433e6 0.0
B = 
 -0.5963028955165542
 -4.793145772316456
 99.58081303429545
  1.0428129567742857e9
C = 
 0.0 0.0 1.0 0.0
D = 
 0.0

Continuous-time state-space model

julia> balance_statespace(sys_c)[1]
StateSpace{Continuous, Float64}
A = 
 -0.7340579610440452 0.14472345975031084 0.006669898954393214 0.0
 -1.1983238017028612 0.0 0.0 0.0
  0.0 3.2698603047406642 0.1506987048362153 0.0
  0.0 4.081972265286775 0.1881266709358267 0.0
B = 
 -1.1926057910331085
 -2.396572886158228
  6.223800814643465
  7.7695619819632595
C = 
 0.0 0.0 16.0 0.0
D = 
 0.0

Continuous-time state-space model

```

`minreal` will perform much better on the latter system here. You can also try calling `sminreal` before `minreal`, if `sminreal` removes any dimensions you can also improve the numerics.
