You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/systems/abstractsystem.jl
+62-9Lines changed: 62 additions & 9 deletions
Original file line number
Diff line number
Diff line change
@@ -1225,7 +1225,7 @@ y &= h(x, z, u)
1225
1225
\\end{aligned}
1226
1226
```
1227
1227
1228
-
where `x` are differential states, `z` algebraic states, `u` inputs and `y` outputs. To obtain a linear statespace representation, see [`linearize`](@ref). The input argument `variables` is a vector defining the operating point, corresponding to `states(simplified_sys)` and `p` is a vector corresponding to the parameters of `simplified_sys`. Note: all variables in `inputs` have been converted to parameters in `simplified_sys`.
1228
+
where `x` are differential state variables, `z` algebraic variables, `u` inputs and `y` outputs. To obtain a linear statespace representation, see [`linearize`](@ref). The input argument `variables` is a vector defining the operating point, corresponding to `states(simplified_sys)` and `p` is a vector corresponding to the parameters of `simplified_sys`. Note: all variables in `inputs` have been converted to parameters in `simplified_sys`.
1229
1229
1230
1230
The `simplified_sys` has undergone [`structural_simplify`](@ref) and had any occurring input or output variables replaced with the variables provided in arguments `inputs` and `outputs`. The states of this system also indicate the order of the states that holds for the linearized matrices.
1231
1231
@@ -1288,14 +1288,25 @@ function linearization_function(sys::AbstractSystem, inputs,
Similar to [`linearize`](@ref), but returns symbolic matrices `A,B,C,D` rather than numeric. While `linearize` uses ForwardDiff to perform the linearization, this function uses `Symbolics.jacobian`.
1294
1294
1295
1295
See [`linearize`](@ref) for a description of the arguments.
1296
+
1297
+
# Extended help
1298
+
The named tuple returned as the first argument additionally contains the jacobians `f_x, f_z, g_x, g_z, f_u, g_u, h_x, h_z, h_u` of
1299
+
```math
1300
+
\\begin{aligned}
1301
+
ẋ &= f(x, z, u) \\\\
1302
+
0 &= g(x, z, u) \\\\
1303
+
y &= h(x, z, u)
1304
+
\\end{aligned}
1305
+
```
1306
+
where `x` are differential state variables, `z` algebraic variables, `u` inputs and `y` outputs.
@@ -1306,14 +1317,56 @@ function linearize_symbolic(sys::AbstractSystem, inputs,
1306
1317
fun =generate_function(sys, sts, p; expression = Val{false})[1]
1307
1318
dx =fun(sts, p, t)
1308
1319
1309
-
A = Symbolics.jacobian(dx, sts)
1310
-
B = Symbolics.jacobian(dx, inputs)
1311
-
1312
1320
h =build_explicit_observed_function(sys, outputs)
1313
1321
y =h(sts, p, t)
1314
-
C = Symbolics.jacobian(y, sts)
1315
-
D = Symbolics.jacobian(y, inputs)
1316
-
(; A, B, C, D), sys
1322
+
1323
+
fg_xz = Symbolics.jacobian(dx, sts)
1324
+
fg_u = Symbolics.jacobian(dx, inputs)
1325
+
h_xz = Symbolics.jacobian(y, sts)
1326
+
h_u = Symbolics.jacobian(y, inputs)
1327
+
f_x = fg_xz[diff_idxs, diff_idxs]
1328
+
f_z = fg_xz[diff_idxs, alge_idxs]
1329
+
g_x = fg_xz[alge_idxs, diff_idxs]
1330
+
g_z = fg_xz[alge_idxs, alge_idxs]
1331
+
f_u = fg_u[diff_idxs, :]
1332
+
g_u = fg_u[alge_idxs, :]
1333
+
h_x = h_xz[:, diff_idxs]
1334
+
h_z = h_xz[:, alge_idxs]
1335
+
1336
+
nx, nu =size(f_u)
1337
+
nz =size(f_z, 2)
1338
+
ny =size(h_x, 1)
1339
+
1340
+
D = h_u
1341
+
1342
+
ifisempty(g_z) # ODE
1343
+
A = f_x
1344
+
B = f_u
1345
+
C = h_x
1346
+
else
1347
+
gz =lu(g_z; check =false)
1348
+
issuccess(gz) ||
1349
+
error("g_z not invertible, this indicates that the DAE is of index > 1.")
1350
+
gzgx =-(gz \ g_x)
1351
+
A = [f_x f_z
1352
+
gzgx*f_x gzgx*f_z]
1353
+
B = [f_u
1354
+
gzgx * f_u] # The cited paper has zeros in the bottom block, see derivation in https://github.com/SciML/ModelingToolkit.jl/pull/1691 for the correct formula
1355
+
1356
+
C = [h_x h_z]
1357
+
Bs =-(gz \ g_u) # This equation differ from the cited paper, the paper is likely wrong since their equaiton leads to a dimension mismatch.
1358
+
if!iszero(Bs)
1359
+
if!allow_input_derivatives
1360
+
der_inds =findall(vec(any(!iszero, Bs, dims =1)))
1361
+
@showtypeof(der_inds)
1362
+
error("Input derivatives appeared in expressions (-g_z\\g_u != 0), the following inputs appeared differentiated: $(ModelingToolkit.inputs(sys)[der_inds]). Call `linear_statespace` with keyword argument `allow_input_derivatives = true` to allow this and have the returned `B` matrix be of double width ($(2nu)), where the last $nu inputs are the derivatives of the first $nu inputs.")
0 commit comments