Skip to content

Commit 7231222

Browse files
committed
add ability to reorder states in linearized model
1 parent a9e9d11 commit 7231222

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

src/systems/abstractsystem.jl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1208,6 +1208,57 @@ function linearize(sys, inputs, outputs; op = Dict(), allow_input_derivatives =
12081208
linearize(ssys, lin_fun; op, allow_input_derivatives), ssys
12091209
end
12101210

1211+
"""
1212+
(; Ã, B̃, C̃, D̃) = similarity_transform(sys, T; unitary=false)
1213+
1214+
Perform a similarity transform `T : Tx̃ = x` on linear system represented by matrices in NamedTuple `sys` such that
1215+
```
1216+
à = T⁻¹AT
1217+
B̃ = T⁻¹ B
1218+
C̃ = CT
1219+
D̃ = D
1220+
```
1221+
1222+
If `unitary=true`, `T` is assumed unitary and the matrix adjoint is used instead of the inverse.
1223+
"""
1224+
function similarity_transform(sys::NamedTuple, T; unitary = false)
1225+
if unitary
1226+
A = T'sys.A * T
1227+
B = T'sys.B
1228+
else
1229+
Tf = lu(T)
1230+
A = Tf \ sys.A * T
1231+
B = Tf \ sys.B
1232+
end
1233+
C = sys.C * T
1234+
D = sys.D
1235+
(; A, B, C, D)
1236+
end
1237+
1238+
"""
1239+
reorder_states(sys::NamedTuple, old, new)
1240+
1241+
Permute the state representation of `sys` obtained from [`linearize`](@ref) so that the state order is changed from `old` to `new`
1242+
Example:
1243+
```
1244+
lsys, ssys = linearize(pid, [reference.u, measurement.u], [ctr_output.u])
1245+
desired_order = [int.x, der.x] # States that are present in states(ssys)
1246+
lsys = ModelingToolkit.reorder_states(lsys, states(ssys), desired_order)
1247+
```
1248+
See also [`ModelingToolkit.similarity_transform`](@ref)
1249+
"""
1250+
function reorder_states(sys::NamedTuple, old, new)
1251+
nx = length(old)
1252+
length(new) == nx || error("old and new must have the same length")
1253+
perm = [findfirst(isequal(n), old) for n in new]
1254+
issorted(perm) && return sys # shortcut return, no reordering
1255+
P = zeros(Int, nx, nx)
1256+
for i in 1:nx # Build permutation matrix
1257+
P[i, perm[i]] = 1
1258+
end
1259+
similarity_transform(sys, P; unitary = true)
1260+
end
1261+
12111262
@latexrecipe function f(sys::AbstractSystem)
12121263
return latexify(equations(sys))
12131264
end

0 commit comments

Comments
 (0)