1
- " A linearization buffer for the [`linearize`](@ref) function."
2
- struct LinearizationBuffer{
3
- NT <: Real ,
4
- JB_FUD <: JacobianBuffer ,
5
- JB_FXD <: JacobianBuffer ,
6
- JB_FXU <: JacobianBuffer ,
7
- JB_HD <: JacobianBuffer ,
8
- JB_HX <: JacobianBuffer
9
- }
10
- x:: Vector{NT}
11
- u:: Vector{NT}
12
- d:: Vector{NT}
13
- buffer_f_at_u_d:: JB_FUD
14
- buffer_f_at_x_d:: JB_FXD
15
- buffer_f_at_x_u:: JB_FXU
16
- buffer_h_at_d :: JB_HD
17
- buffer_h_at_x :: JB_HX
18
- function LinearizationBuffer (
19
- x:: Vector{NT} ,
20
- u:: Vector{NT} ,
21
- d:: Vector{NT} ,
22
- buffer_f_at_u_d:: JB_FUD ,
23
- buffer_f_at_x_d:: JB_FXD ,
24
- buffer_f_at_x_u:: JB_FXU ,
25
- buffer_h_at_d:: JB_HD ,
26
- buffer_h_at_x:: JB_HX
27
- ) where {NT<: Real , JB_FUD, JB_FXD, JB_FXU, JB_HD, JB_HX}
28
- return new {NT, JB_FUD, JB_FXD, JB_FXU, JB_HD, JB_HX} (
29
- x, u, d,
30
- buffer_f_at_u_d,
31
- buffer_f_at_x_d,
32
- buffer_f_at_x_u,
33
- buffer_h_at_d,
34
- buffer_h_at_x
35
- )
36
- end
37
-
38
- end
1
+ """
2
+ get_linearization_func(NT, f!, h!, nu, nx, ny, nd, p) -> linfunc!
39
3
40
- Base. show (io:: IO , buffer:: LinearizationBuffer ) = print (io, " LinearizationBuffer object" )
41
-
42
- function LinearizationBuffer (NT, f!, h!, nu, nx, ny, nd, p)
43
- x, u, d, f_at_u_d!, f_at_x_d!, f_at_x_u!, h_at_d!, h_at_x! = get_linearize_funcs (
44
- NT, f!, h!, nu, nx, ny, nd, p
45
- )
46
- xnext, y = Vector {NT} (undef, nx), Vector {NT} (undef, ny) # TODO : to replace ?
47
- return LinearizationBuffer (
48
- x, u, d,
49
- JacobianBuffer (f_at_u_d!, xnext, x),
50
- JacobianBuffer (f_at_x_d!, xnext, u),
51
- JacobianBuffer (f_at_x_u!, xnext, d),
52
- JacobianBuffer (h_at_d!, y, x),
53
- JacobianBuffer (h_at_x!, y, d)
54
- )
55
- end
4
+ Return the `linfunc!` function that computes the Jacobians of `f!` and `h!` functions.
56
5
57
- " Get the linearization functions for [`NonLinModel`](@ref) `f!` and `h!` functions."
58
- function get_linearize_funcs (NT, f!, h!, nu, nx, ny, nd, p)
59
- x = Vector {NT} (undef, nx)
60
- u = Vector {NT} (undef, nu)
61
- d = Vector {NT} (undef, nd)
62
- f_at_u_d! (xnext, x) = f! (xnext, x, u, d, p)
63
- f_at_x_d! (xnext, u) = f! (xnext, x, u, d, p)
64
- f_at_x_u! (xnext, d) = f! (xnext, x, u, d, p)
65
- h_at_d! (y, x) = h! (y, x, d, p)
66
- h_at_x! (y, d) = h! (y, x, d, p)
67
- return x, u, d, f_at_u_d!, f_at_x_d!, f_at_x_u!, h_at_d!, h_at_x!
6
+ The function has the following signature:
7
+ ```
8
+ linfunc!(xnext, y, A, Bu, C, Bd, Dd, x, u, d, cst_x, cst_u, cst_d) -> nothing
9
+ ```
10
+ and it should modifies in-place all the arguments before `x`. The `cst_x`, `cst_u`, `cst_d`
11
+ and are `DifferentiationInterface.Constant` objects with the linearization points.
12
+ """
13
+ function get_linearization_func (NT, f!, h!, nu, nx, ny, nd, p)
14
+ f_x! (xnext, x, u, d) = f! (xnext, x, u, d, p)
15
+ f_u! (xnext, u, x, d) = f! (xnext, x, u, d, p)
16
+ f_d! (xnext, d, x, u) = f! (xnext, x, u, d, p)
17
+ h_x! (y, x, d) = h! (y, x, d, p)
18
+ h_d! (y, d, x) = h! (y, x, d, p)
19
+ backend = AutoForwardDiff ()
20
+ strict = Val (true )
21
+ xnext = zeros (NT, nx)
22
+ y = zeros (NT, ny)
23
+ x = zeros (NT, nx)
24
+ u = zeros (NT, nu)
25
+ d = zeros (NT, nd)
26
+ cst_x = Constant (x)
27
+ cst_u = Constant (u)
28
+ cst_d = Constant (d)
29
+ A_prep = prepare_jacobian (f_x!, xnext, backend, x, cst_u, cst_d; strict)
30
+ Bu_prep = prepare_jacobian (f_u!, xnext, backend, u, cst_x, cst_d; strict)
31
+ Bd_prep = prepare_jacobian (f_d!, xnext, backend, d, cst_x, cst_u; strict)
32
+ C_prep = prepare_jacobian (h_x!, y, backend, x, cst_d ; strict)
33
+ Dd_prep = prepare_jacobian (h_d!, y, backend, d, cst_x ; strict)
34
+ function linfunc! (xnext, y, A, Bu, C, Bd, Dd, x, u, d, cst_x, cst_u, cst_d)
35
+ # all the arguments before `x` are mutated in this function
36
+ jacobian! (f_x!, xnext, A, A_prep, backend, x, cst_u, cst_d)
37
+ jacobian! (f_u!, xnext, Bu, Bu_prep, backend, u, cst_x, cst_d)
38
+ jacobian! (f_d!, xnext, Bd, Bd_prep, backend, d, cst_x, cst_u)
39
+ jacobian! (h_x!, y, C, C_prep, backend, x, cst_d)
40
+ jacobian! (h_d!, y, Dd, Dd_prep, backend, d, cst_x)
41
+ return nothing
42
+ end
43
+ return linfunc!
68
44
end
69
45
46
+
70
47
@doc raw """
71
48
linearize(model::SimModel; x=model.x0+model.xop, u=model.uop, d=model.dop) -> linmodel
72
49
@@ -181,8 +158,7 @@ function linearize!(
181
158
u0 .= u .- nonlinmodel. uop
182
159
d0 .= d .- nonlinmodel. dop
183
160
# --- compute the Jacobians at linearization points ---
184
- xnext0:: Vector{NT} , y0:: Vector{NT} = linmodel. buffer. x, linmodel. buffer. y
185
- get_jacobians! (linmodel, xnext0, y0, nonlinmodel, x0, u0, d0)
161
+ linearize_core! (linmodel, nonlinmodel, x0, u0, d0)
186
162
# --- compute the nonlinear model output at operating points ---
187
163
xnext0, y0 = linmodel. buffer. x, linmodel. buffer. y
188
164
h! (y0, nonlinmodel, x0, d0, model. p)
@@ -203,22 +179,19 @@ function linearize!(
203
179
return linmodel
204
180
end
205
181
206
- " Compute the 5 Jacobians of `model` at the linearization point and write them in `linmodel`."
207
- function get_jacobians! (linmodel:: LinModel , xnext0, y0, model:: SimModel , x0, u0, d0)
208
- linbuffer = model. linbuffer # a LinearizationBuffer object
209
- linbuffer. x .= x0
210
- linbuffer. u .= u0
211
- linbuffer. d .= d0
212
- get_jacobian! (linmodel. A, linbuffer. buffer_f_at_u_d, xnext0, x0)
213
- get_jacobian! (linmodel. Bu, linbuffer. buffer_f_at_x_d, xnext0, u0)
214
- get_jacobian! (linmodel. Bd, linbuffer. buffer_f_at_x_u, xnext0, d0)
215
- get_jacobian! (linmodel. C, linbuffer. buffer_h_at_d, y0, x0)
216
- get_jacobian! (linmodel. Dd, linbuffer. buffer_h_at_x, y0, d0)
182
+ " Call `linfunc!` function to compute the Jacobians of `model` at the linearization point."
183
+ function linearize_core! (linmodel:: LinModel , model:: SimModel , x0, u0, d0)
184
+ xnext0, y0 = linmodel. buffer. x, linmodel. buffer. y
185
+ A, Bu, C, Bd, Dd = linmodel. A, linmodel. Bu, linmodel. C, linmodel. Bd, linmodel. Dd
186
+ cx = Constant (x0)
187
+ cu = Constant (u0)
188
+ cd = Constant (d0)
189
+ model. linfunc! (xnext0, y0, A, Bu, C, Bd, Dd, x0, u0, d0, cx, cu, cd)
217
190
return nothing
218
191
end
219
192
220
193
" Copy the state-space matrices of `model` to `linmodel` if `model` is already linear."
221
- function get_jacobians ! (linmodel:: LinModel , _ , _ , model:: LinModel , _ , _ , _)
194
+ function linearize_core ! (linmodel:: LinModel , model:: LinModel , _ , _ , _ )
222
195
linmodel. A .= model. A
223
196
linmodel. Bu .= model. Bu
224
197
linmodel. C .= model. C
0 commit comments