Skip to content

Commit 5a119a1

Browse files
committed
added : reduce allocations KalmanFilter and ExtendedKalmanFilter
1 parent 66771f1 commit 5a119a1

File tree

7 files changed

+73
-47
lines changed

7 files changed

+73
-47
lines changed

src/estimator/construct.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -146,13 +146,13 @@ end
146146
Return empty matrices, and `x̂op` & `f̂op` vectors, if `model` is not a [`LinModel`](@ref).
147147
"""
148148
function augment_model(model::SimModel{NT}, As, args... ; verify_obsv=false) where NT<:Real
149-
nu, nx, nd = model.nu, model.nx, model.nd
149+
nu, nx, nd, ny = model.nu, model.nx, model.nd, model.ny
150150
nxs = size(As, 1)
151151
= zeros(NT, 0, nx+nxs)
152152
B̂u = zeros(NT, 0, nu)
153-
= zeros(NT, 0, nx+nxs)
153+
= zeros(NT, ny, 0)
154154
B̂d = zeros(NT, 0, nd)
155-
D̂d = zeros(NT, 0, nd)
155+
D̂d = zeros(NT, ny, 0)
156156
x̂op, f̂op = [model.xop; zeros(nxs)], [model.fop; zeros(nxs)]
157157
return Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op
158158
end

src/estimator/execute.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ in which ``\mathbf{Ĉ^m, D̂_d^m}`` are the rows of `estim.Ĉ, estim.D̂d` th
153153
measured outputs ``\mathbf{y^m}``.
154154
"""
155155
function init_estimate!(estim::StateEstimator, ::LinModel, y0m, d0, u0)
156-
Â, B̂u, Ĉ, B̂d, D̂d = estim.Â, estim.B̂u, estim.Ĉ, estim.B̂d, estim.D̂d
157-
Ĉm, D̂dm = @views Ĉ[estim.i_ym, :], D̂d[estim.i_ym, :] # measured outputs ym only
156+
Â, B̂u, B̂d = estim.Â, estim.B̂u, estim.B̂d
157+
Ĉm, D̂dm = estim.Ĉm, estim.D̂dm
158158
# TODO: use estim.buffer.x̂ to reduce allocations
159159
estim.x̂0 .= [I - Â; Ĉm]\[B̂u*u0 + B̂d*d0 + estim.f̂op - estim.x̂op; y0m - D̂dm*d0]
160160
return nothing
@@ -390,6 +390,8 @@ function setmodel_estimator!(estim::StateEstimator, model, _ , _ , _ , Q̂, R̂)
390390
estim.Ĉ .=
391391
estim.B̂d .= B̂d
392392
estim.D̂d .= D̂d
393+
estim.Ĉm .= @views Ĉ[estim.i_ym, :]
394+
estim.D̂dm .= @views D̂d[estim.i_ym, :]
393395
# --- update state estimate and its operating points ---
394396
estim.x̂0 .+= estim.x̂op # convert x̂0 to x̂ with the old operating point
395397
estim.x̂op .= x̂op

src/estimator/internal_model.jl

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,13 @@ struct InternalModel{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
1616
Bs::Matrix{NT}
1717
Cs::Matrix{NT}
1818
Ds::Matrix{NT}
19-
::Matrix{NT}
20-
B̂u::Matrix{NT}
21-
::Matrix{NT}
22-
B̂d::Matrix{NT}
23-
D̂d::Matrix{NT}
19+
::Matrix{NT}
20+
B̂u ::Matrix{NT}
21+
::Matrix{NT}
22+
B̂d ::Matrix{NT}
23+
D̂d ::Matrix{NT}
24+
Ĉm ::Matrix{NT}
25+
D̂dm ::Matrix{NT}
2426
Âs::Matrix{NT}
2527
B̂s::Matrix{NT}
2628
direct::Bool
@@ -36,6 +38,7 @@ struct InternalModel{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
3638
nxs = size(As,1)
3739
nx̂ = model.nx
3840
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = matrices_internalmodel(model)
41+
Ĉm, D̂dm = Ĉ[i_ym,:], D̂d[i_ym,:]
3942
Âs, B̂s = init_internalmodel(As, Bs, Cs, Ds)
4043
lastu0 = zeros(NT, nu)
4144
# x̂0 and x̂d are same object (updating x̂d will update x̂0):
@@ -50,7 +53,7 @@ struct InternalModel{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
5053
lastu0, x̂op, f̂op, x̂0, x̂d, x̂s, ŷs,
5154
i_ym, nx̂, nym, nyu, nxs,
5255
As, Bs, Cs, Ds,
53-
Â, B̂u, Ĉ, B̂d, D̂d,
56+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
5457
Âs, B̂s,
5558
direct, corrected,
5659
buffer
@@ -156,8 +159,8 @@ function matrices_internalmodel(model::LinModel)
156159
end
157160
"Return empty matrices, and `x̂op` & `f̂op` vectors, if `model` is not a [`LinModel`](@ref)."
158161
function matrices_internalmodel(model::SimModel{NT}) where NT<:Real
159-
nu, nx, nd = model.nu, model.nx, model.nd
160-
Â, B̂u, Ĉ, B̂d, D̂d = zeros(NT,0,nx), zeros(NT,0,nu), zeros(NT,0,nx), zeros(NT,0,nd), zeros(NT,0,nd)
162+
nu, nx, nd, ny = model.nu, model.nx, model.nd, model.ny
163+
Â, B̂u, Ĉ, B̂d, D̂d = zeros(NT,0,nx), zeros(NT,0,nu), zeros(NT,ny,0), zeros(NT,0,nd), zeros(NT,ny,0)
161164
x̂op, f̂op = copy(model.xop), copy(model.fop)
162165
return Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op
163166
end
@@ -225,6 +228,8 @@ function setmodel_estimator!(estim::InternalModel, model, _ , _ , _ , _ , _ )
225228
estim.Ĉ .=
226229
estim.B̂d .= B̂d
227230
estim.D̂d .= D̂d
231+
estim.Ĉm .= @views Ĉ[estim.i_ym,:]
232+
estim.D̂m .= @views D̂d[estim.i_ym,:]
228233
# --- update state estimate and its operating points ---
229234
estim.x̂0 .+= estim.x̂op # convert x̂0 to x̂ with the old operating point
230235
estim.x̂op .= x̂op

src/estimator/kalman.jl

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
1919
::Matrix{NT}
2020
B̂d ::Matrix{NT}
2121
D̂d ::Matrix{NT}
22+
Ĉm ::Matrix{NT}
23+
D̂dm ::Matrix{NT}
2224
::Hermitian{NT, Matrix{NT}}
2325
::Hermitian{NT, Matrix{NT}}
2426
::Matrix{NT}
@@ -34,6 +36,7 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
3436
nxs = size(As, 1)
3537
nx̂ = model.nx + nxs
3638
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
39+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
3740
validate_kfcov(nym, nx̂, Q̂, R̂)
3841
= try
3942
Q̂_kalman = Matrix(Q̂) # Matrix() required for Julia 1.6
@@ -59,7 +62,7 @@ struct SteadyKalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
5962
lastu0, x̂op, f̂op, x̂0,
6063
i_ym, nx̂, nym, nyu, nxs,
6164
As, Cs_u, Cs_y, nint_u, nint_ym,
62-
Â, B̂u, Ĉ, B̂d, D̂d,
65+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
6366
Q̂, R̂,
6467
K̂,
6568
direct, corrected,
@@ -233,7 +236,7 @@ end
233236

234237
"Allow code reuse for `SteadyKalmanFilter` and `Luenberger` (observers with constant gain)."
235238
function correct_estimate_obsv!(estim::StateEstimator, y0m, d0, K̂)
236-
Ĉm, D̂dm = @views estim.Ĉ[estim.i_ym, :], estim.D̂d[estim.i_ym, :]
239+
Ĉm, D̂dm = estim.Ĉm, estim.D̂dm
237240
ŷ0m = @views estim.buffer.ŷ[estim.i_ym]
238241
# in-place operations to reduce allocations:
239242
mul!(ŷ0m, Ĉm, estim.x̂0)
@@ -281,6 +284,8 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
281284
::Matrix{NT}
282285
B̂d ::Matrix{NT}
283286
D̂d ::Matrix{NT}
287+
Ĉm ::Matrix{NT}
288+
D̂dm ::Matrix{NT}
284289
P̂_0::Hermitian{NT, Matrix{NT}}
285290
::Hermitian{NT, Matrix{NT}}
286291
::Hermitian{NT, Matrix{NT}}
@@ -297,6 +302,7 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
297302
nxs = size(As, 1)
298303
nx̂ = model.nx + nxs
299304
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
305+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
300306
validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0)
301307
lastu0 = zeros(NT, nu)
302308
x̂0 = [zeros(NT, model.nx); zeros(NT, nxs)]
@@ -311,7 +317,7 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
311317
lastu0, x̂op, f̂op, x̂0, P̂,
312318
i_ym, nx̂, nym, nyu, nxs,
313319
As, Cs_u, Cs_y, nint_u, nint_ym,
314-
Â, B̂u, Ĉ, B̂d, D̂d,
320+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
315321
P̂_0, Q̂, R̂,
316322
K̂,
317323
direct, corrected,
@@ -408,8 +414,7 @@ It computes the corrected state estimate ``\mathbf{x̂}_{k}(k)`` estimation cova
408414
``\mathbf{P̂}_{k}(k)``.
409415
"""
410416
function correct_estimate!(estim::KalmanFilter, y0m, d0)
411-
Ĉm = @views estim.Ĉ[estim.i_ym, :]
412-
return correct_estimate_kf!(estim, y0m, d0, Ĉm)
417+
return correct_estimate_kf!(estim, y0m, d0, estim.Ĉm)
413418
end
414419

415420

@@ -447,11 +452,10 @@ provided below, see [^2] for details.
447452
<https://en.wikipedia.org/wiki/Kalman_filter>, Accessed 2024-08-08.
448453
"""
449454
function update_estimate!(estim::KalmanFilter, y0m, d0, u0)
450-
Ĉm = @views estim.Ĉ[estim.i_ym, :]
451455
if !estim.direct
452-
correct_estimate_kf!(estim, y0m, d0, Ĉm)
456+
correct_estimate_kf!(estim, y0m, d0, estim.Ĉm)
453457
end
454-
return predict_estimate_kf!(estim, y0m, d0, u0, Ĉm, estim.Â)
458+
return predict_estimate_kf!(estim, u0, d0, estim.Â)
455459
end
456460

457461

@@ -472,11 +476,13 @@ struct UnscentedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
472476
Cs_y::Matrix{NT}
473477
nint_u ::Vector{Int}
474478
nint_ym::Vector{Int}
475-
::Matrix{NT}
476-
B̂u::Matrix{NT}
477-
::Matrix{NT}
478-
B̂d::Matrix{NT}
479-
D̂d::Matrix{NT}
479+
::Matrix{NT}
480+
B̂u ::Matrix{NT}
481+
::Matrix{NT}
482+
B̂d ::Matrix{NT}
483+
D̂d ::Matrix{NT}
484+
Ĉm ::Matrix{NT}
485+
D̂dm ::Matrix{NT}
480486
P̂_0::Hermitian{NT, Matrix{NT}}
481487
::Hermitian{NT, Matrix{NT}}
482488
::Hermitian{NT, Matrix{NT}}
@@ -502,6 +508,7 @@ struct UnscentedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
502508
nxs = size(As, 1)
503509
nx̂ = model.nx + nxs
504510
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
511+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
505512
validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0)
506513
nσ, γ, m̂, Ŝ = init_ukf(model, nx̂, α, β, κ)
507514
lastu0 = zeros(NT, nu)
@@ -520,7 +527,7 @@ struct UnscentedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
520527
lastu0, x̂op, f̂op, x̂0, P̂,
521528
i_ym, nx̂, nym, nyu, nxs,
522529
As, Cs_u, Cs_y, nint_u, nint_ym,
523-
Â, B̂u, Ĉ, B̂d, D̂d,
530+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
524531
P̂_0, Q̂, R̂,
525532
K̂,
526533
M̂, X̂0, X̄0, Ŷ0m, Ȳ0m,
@@ -822,11 +829,13 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
822829
Cs_y::Matrix{NT}
823830
nint_u ::Vector{Int}
824831
nint_ym::Vector{Int}
825-
::Matrix{NT}
826-
B̂u::Matrix{NT}
827-
::Matrix{NT}
828-
B̂d::Matrix{NT}
829-
D̂d::Matrix{NT}
832+
::Matrix{NT}
833+
B̂u ::Matrix{NT}
834+
::Matrix{NT}
835+
B̂d ::Matrix{NT}
836+
D̂d ::Matrix{NT}
837+
Ĉm ::Matrix{NT}
838+
D̂dm ::Matrix{NT}
830839
P̂_0::Hermitian{NT, Matrix{NT}}
831840
::Hermitian{NT, Matrix{NT}}
832841
::Hermitian{NT, Matrix{NT}}
@@ -845,6 +854,7 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
845854
nxs = size(As, 1)
846855
nx̂ = model.nx + nxs
847856
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
857+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
848858
validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0)
849859
lastu0 = zeros(NT, nu)
850860
x̂0 = [zeros(NT, model.nx); zeros(NT, nxs)]
@@ -861,7 +871,7 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
861871
lastu0, x̂op, f̂op, x̂0, P̂,
862872
i_ym, nx̂, nym, nyu, nxs,
863873
As, Cs_u, Cs_y, nint_u, nint_ym,
864-
Â, B̂u, Ĉ, B̂d, D̂d,
874+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
865875
P̂_0, Q̂, R̂,
866876
K̂,
867877
F̂_û, Ĥ,
@@ -1008,8 +1018,6 @@ function update_estimate!(estim::ExtendedKalmanFilter{NT}, y0m, d0, u0) where NT
10081018
ForwardDiff.jacobian!(Ĥ, ĥAD!, ŷ0, x̂0)
10091019
Ĥm = @views Ĥ[estim.i_ym, :]
10101020
correct_estimate_kf!(estim, y0m, d0, Ĥm)
1011-
else
1012-
Ĥm = @views Ĥ[estim.i_ym, :]
10131021
end
10141022
x̂0corr = estim.x̂0
10151023
# concatenate x̂0next and û0 vectors to allows û0 vector with dual numbers for AD:
@@ -1020,7 +1028,7 @@ function update_estimate!(estim::ExtendedKalmanFilter{NT}, y0m, d0, u0) where NT
10201028
)
10211029
ForwardDiff.jacobian!(estim.F̂_û, f̂AD!, x̂0nextû, x̂0corr)
10221030
= @views estim.F̂_û[1:estim.nx̂, :]
1023-
return predict_estimate_kf!(estim, y0m, d0, u0, Ĥm, F̂)
1031+
return predict_estimate_kf!(estim, u0, d0, F̂)
10241032
end
10251033

10261034
"Set `estim.P̂` to `estim.P̂_0` for the time-varying Kalman Filters."
@@ -1079,30 +1087,32 @@ function correct_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter},
10791087
I_minus_K̂_Ĉm = estim.buffer.
10801088
mul!(I_minus_K̂_Ĉm, K̂, Ĉm)
10811089
lmul!(-1, I_minus_K̂_Ĉm)
1082-
I_minus_K̂_Ĉm[diagind(I_minus_K̂_Ĉm)] .+= 1 # compute I - K̂*Ĉm in-place
1090+
for i=diagind(I_minus_K̂_Ĉm)
1091+
I_minus_K̂_Ĉm[i] += 1 # compute I - K̂*Ĉm in-place
1092+
end
10831093
P̂corr = estim.buffer.
10841094
mul!(P̂corr, I_minus_K̂_Ĉm, P̂)
10851095
estim.P̂ .= Hermitian(P̂corr, :L)
10861096
return nothing
10871097
end
10881098

10891099
"""
1090-
predict_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, y0m, d0, u0, Ĉm, Â)
1100+
predict_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, u0, d0, Â)
10911101
10921102
Predict time-varying/extended Kalman Filter estimates with augmented `Ĉm` and `Â` matrices.
10931103
10941104
Allows code reuse for [`KalmanFilter`](@ref), [`ExtendedKalmanFilterKalmanFilter`](@ref).
10951105
They predict the state `x̂` and covariance `P̂` with the same equations. See
10961106
[`update_estimate`](@ref) methods for the equations.
10971107
"""
1098-
function predict_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, y0m, d0, u0, Ĉm, Â)
1108+
function predict_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter}, u0, d0, Â)
10991109
x̂0corr, P̂corr = estim.x̂0, estim.
11001110
= estim.
11011111
x̂0next, û0 = estim.buffer.x̂, estim.buffer.
11021112
# in-place operations to reduce allocations:
11031113
f̂!(x̂0next, û0, estim, estim.model, x̂0corr, u0, d0)
11041114
P̂corr_Âᵀ = estim.buffer.
1105-
mul!(P̂corr_Âᵀ, P̂corr, Â')
1115+
mul!(P̂corr_Âᵀ, P̂corr.data, Â') # the ".data" weirdly removes a type instability in mul!
11061116
Â_P̂corr_Âᵀ = estim.buffer.
11071117
mul!(Â_P̂corr_Âᵀ, Â, P̂corr_Âᵀ)
11081118
P̂next = estim.buffer.

src/estimator/luenberger.jl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ struct Luenberger{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
1919
::Matrix{NT}
2020
B̂d ::Matrix{NT}
2121
D̂d ::Matrix{NT}
22+
Ĉm ::Matrix{NT}
23+
D̂dm ::Matrix{NT}
2224
::Matrix{NT}
2325
direct::Bool
2426
corrected::Vector{Bool}
@@ -33,6 +35,7 @@ struct Luenberger{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
3335
nxs = size(As, 1)
3436
nx̂ = model.nx + nxs
3537
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
38+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
3639
= try
3740
ControlSystemsBase.place(Â, Ĉ, poles, :o; direct)[:, i_ym]
3841
catch
@@ -47,7 +50,7 @@ struct Luenberger{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
4750
lastu0, x̂op, f̂op, x̂0,
4851
i_ym, nx̂, nym, nyu, nxs,
4952
As, Cs_u, Cs_y, nint_u, nint_ym,
50-
Â, B̂u, Ĉ, B̂d, D̂d,
53+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
5154
K̂,
5255
direct, corrected,
5356
buffer

src/estimator/mhe/construct.jl

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ struct MovingHorizonEstimator{
7676
::Matrix{NT}
7777
B̂d ::Matrix{NT}
7878
D̂d ::Matrix{NT}
79+
Ĉm ::Matrix{NT}
80+
D̂dm ::Matrix{NT}
7981
::Matrix{NT}
8082
F ::Vector{NT}
8183
G ::Matrix{NT}
@@ -120,6 +122,7 @@ struct MovingHorizonEstimator{
120122
nxs = size(As, 1)
121123
nx̂ = model.nx + nxs
122124
Â, B̂u, Ĉ, B̂d, D̂d, x̂op, f̂op = augment_model(model, As, Cs_u, Cs_y)
125+
Ĉm, D̂dm = Ĉ[i_ym, :], D̂d[i_ym, :]
123126
validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0)
124127
lastu0 = zeros(NT, nu)
125128
x̂0 = [zeros(NT, model.nx); zeros(NT, nxs)]
@@ -129,7 +132,7 @@ struct MovingHorizonEstimator{
129132
invQ̂_He = Hermitian(repeatdiag(inv(Q̂), He), :L)
130133
invR̂_He = Hermitian(repeatdiag(inv(R̂), He), :L)
131134
E, G, J, B, ex̄, Ex̂, Gx̂, Jx̂, Bx̂ = init_predmat_mhe(
132-
model, He, i_ym, Â, B̂u, , B̂d, D̂d, x̂op, f̂op
135+
model, He, i_ym, Â, B̂u, Ĉm, B̂d, D̂dm, x̂op, f̂op
133136
)
134137
# dummy values (updated just before optimization):
135138
F, fx̄, Fx̂ = zeros(NT, nym*He), zeros(NT, nx̂), zeros(NT, nx̂*He)
@@ -155,7 +158,7 @@ struct MovingHorizonEstimator{
155158
He, nϵ,
156159
i_ym, nx̂, nym, nyu, nxs,
157160
As, Cs_u, Cs_y, nint_u, nint_ym,
158-
Â, B̂u, Ĉ, B̂d, D̂d,
161+
Â, B̂u, Ĉ, B̂d, D̂d, Ĉm, D̂dm,
159162
Ẽ, F, G, J, B, ẽx̄, fx̄,
160163
H̃, q̃, p,
161164
P̂_0, Q̂, R̂, invP̄, invQ̂_He, invR̂_He, Cwt,
@@ -891,7 +894,7 @@ end
891894

892895
@doc raw"""
893896
init_predmat_mhe(
894-
model::LinModel, He, i_ym, Â, B̂u, , B̂d, D̂d, x̂op, f̂op
897+
model::LinModel, He, i_ym, Â, B̂u, Ĉm, B̂d, D̂dm, x̂op, f̂op
895898
) -> E, G, J, B, ex̄, Ex̂, Gx̂, Jx̂, Bx̂
896899
897900
Construct the MHE prediction matrices for [`LinModel`](@ref) `model`.
@@ -989,11 +992,10 @@ calculated with:
989992
All these matrices are truncated when ``N_k < H_e`` (at the beginning).
990993
"""
991994
function init_predmat_mhe(
992-
model::LinModel{NT}, He, i_ym, Â, B̂u, , B̂d, D̂d, x̂op, f̂op
995+
model::LinModel{NT}, He, i_ym, Â, B̂u, Ĉm, B̂d, D̂dm, x̂op, f̂op
993996
) where {NT<:Real}
994997
nu, nd = model.nu, model.nd
995998
nym, nx̂ = length(i_ym), size(Â, 2)
996-
Ĉm, D̂dm = Ĉ[i_ym,:], D̂d[i_ym,:] # measured outputs ym only
997999
nŵ = nx̂
9981000
# --- pre-compute matrix powers ---
9991001
# Apow 3D array : Apow[:,:,1] = A^0, Apow[:,:,2] = A^1, ... , Apow[:,:,He+1] = A^He

0 commit comments

Comments
 (0)