Putting linear ODESystem in matrix-vector form

Hi, sorry to bother you again. I have noticed that the matrices returned by linearize_symbolic don’t follow the order of the output variables specified as:

ss_matrices, ssys = ModelingToolkit.linearize_symbolic(model, [Ta.V.u, Φhp_c.I.u, Φcv_c.I.u], [Ce.v, Ci.v, Ch.v])

Will give the exact same ss_matrices.A as for example:

ss_matrices, ssys = ModelingToolkit.linearize_symbolic(model, [Ta.V.u, Φhp_c.I.u, Φcv_c.I.u], [Ci.v, Ch.v, Ce.v])

Where I changed the order of [Ce.v, Ci.v, Ch.v] to [Ci.v, Ch.v, Ce.v].

Interestingly the matrix ss_matrices.B does follow the order of the input vector [Ta.V.u, Φhp_c.I.u, Φcv_c.I.u].

Is there a way to figure out what order of variables it used? (by matching some parameters to the analytical result I know what order it used but that’s not super convenient for larger equations)

It’s expected that the A matrix remains the same, what you expect will change is the C matrix that gives the output, recall

\begin{aligned} \dot x &= Ax + Bu\\ y &= Cx + Du \end{aligned}

where x is the state and y are the outputs.

I expect the two C matrices will differ by a permutation.

That’s not what I would expect. If I change the order of [x_1, x_2, x_3] to [x_2, x_1, x_3] then A should have column 1 swapped for column 2.

I checked the matrix C and it was the identity matrix for both options (or any option x really).

You are not specifying the state x when you call linearize, you are specifying the outputs y. The state x is picked by the MTK model compiler and its size is independent on the number of outputs you pick. Try picking zero outputs ([]) and you’ll still get the same A matrix, but a C matrix of size 0 \times 3

I just tried swapping the output order and I get this

julia> ss_matrices.C
3×3 Matrix{Num}:
 1  0  0
 0  1  0
 0  0  1

# swap order

julia> ss_matrices.C
3×3 Matrix{Num}:
 1  0  0
 0  0  1
 0  1  0

Ah okay that makes sense, thanks. But then my question would be, is there a way to figure out what x the compiler picked?

There is, that’s why simplified_sys is returned :slight_smile: :

julia> unknowns(ssys)
3-element Vector{SymbolicUtils.BasicSymbolic{Real}}:
 Ci₊v(t)
 Ce₊v(t)
 Ch₊v(t)
1 Like

Ah and ofcourse I realize now I could have also gotten that from C. Thanks again…