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!
393
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.
565
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!
6844end
6945
46+
7047@doc raw """
7148 linearize(model::SimModel; x=model.x0+model.xop, u=model.uop, d=model.dop) -> linmodel
7249
@@ -181,8 +158,7 @@ function linearize!(
181158 u0 .= u .- nonlinmodel. uop
182159 d0 .= d .- nonlinmodel. dop
183160 # --- 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)
186162 # --- compute the nonlinear model output at operating points ---
187163 xnext0, y0 = linmodel. buffer. x, linmodel. buffer. y
188164 h! (y0, nonlinmodel, x0, d0, model. p)
@@ -203,22 +179,19 @@ function linearize!(
203179 return linmodel
204180end
205181
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)
217190 return nothing
218191end
219192
220193" 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 , _ , _ , _ )
222195 linmodel. A .= model. A
223196 linmodel. Bu .= model. Bu
224197 linmodel. C .= model. C
0 commit comments