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: docs/src/basics/Linearization.md
+70-1
Original file line number
Diff line number
Diff line change
@@ -22,7 +22,7 @@ The `linearize` function expects the user to specify the inputs ``u`` and the ou
22
22
```@example LINEARIZE
23
23
using ModelingToolkit
24
24
using ModelingToolkit: t_nounits as t, D_nounits as D
25
-
@variables x(t)=0 y(t)=0 u(t)=0 r(t)=0
25
+
@variables x(t)=0 y(t) u(t) r(t)=0
26
26
@parameters kp = 1
27
27
28
28
eqs = [u ~ kp * (r - y) # P controller
@@ -57,6 +57,74 @@ The operating point to linearize around can be specified with the keyword argume
57
57
58
58
If linearization is to be performed around multiple operating points, the simplification of the system has to be carried out a single time only. To facilitate this, the lower-level function [`ModelingToolkit.linearization_function`](@ref) is available. This function further allows you to obtain separate Jacobians for the differential and algebraic parts of the model. For ODE models without algebraic equations, the statespace representation above is available from the output of `linearization_function` as `A, B, C, D = f_x, f_u, h_x, h_u`.
59
59
60
+
All variables that will be fixed by an operating point _must_ be provided in the operating point to `linearization_function`. For example, if the operating points fix the value of
61
+
`x`, `y` and `z` then an operating point with constant values for these variables (e.g. `Dict(x => 1.0, y => 1.0, z => 1.0)`) must be provided. The constant values themselves
62
+
do not matter and can be changed by subsequent operating points.
63
+
64
+
One approach to batch linearization would be to call `linearize` in a loop, providing a different operating point each time. For example:
println(linearize(simplified_sys, linfun; op = Dict(x => 1.0)))
87
+
println(linearize(simplified_sys, linfun; op = Dict(x => 0.0)))
88
+
89
+
@time linearize(simplified_sys, linfun; op = Dict(x => 0.0))
90
+
91
+
nothing # hide
92
+
```
93
+
94
+
However, this route is still expensive since it has to repeatedly process the symbolic map provided to `op`. `linearize` is simply a wrapper for creating and solving a
95
+
[`ModelingToolkit.LinearizationProblem`](@ref). This object is symbolically indexable, and can thus integrate with SymbolicIndexingInterface.jl for fast updates.
96
+
97
+
```@example LINEARIZE
98
+
using SymbolicIndexingInterface
99
+
100
+
# The second argument is the value of the independent variable `t`.
101
+
linprob = LinearizationProblem(linfun, 1.0)
102
+
# It can be mutated
103
+
linprob.t = 0.0
104
+
# create a setter function to update `x` efficiently
105
+
setter! = setu(linprob, x)
106
+
107
+
function fast_linearize!(problem, setter!, value)
108
+
setter!(problem, value)
109
+
solve(problem)
110
+
end
111
+
112
+
println(fast_linearize!(linprob, setter!, 1.0))
113
+
println(fast_linearize!(linprob, setter!, 0.0))
114
+
115
+
@time fast_linearize!(linprob, setter!, 1.0)
116
+
117
+
nothing # hide
118
+
```
119
+
120
+
Note that `linprob` above can be interacted with similar to a normal `ODEProblem`.
121
+
122
+
```@repl LINEARIZE
123
+
prob[x]
124
+
prob[x] = 1.5
125
+
prob[x]
126
+
```
127
+
60
128
## Symbolic linearization
61
129
62
130
The function [`ModelingToolkit.linearize_symbolic`](@ref) works similar to [`ModelingToolkit.linearize`](@ref) but returns symbolic rather than numeric Jacobians. Symbolic linearization have several limitations and no all systems that can be linearized numerically can be linearized symbolically.
0 commit comments