@@ -271,7 +271,6 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
271271 Q̂:: Hermitian{NT, Matrix{NT}}
272272 R̂:: Hermitian{NT, Matrix{NT}}
273273 K̂:: Matrix{NT}
274- M̂:: Matrix{NT}
275274 direct:: Bool
276275 corrected:: Vector{Bool}
277276 buffer:: StateEstimatorBuffer{NT}
@@ -291,7 +290,6 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
291290 P̂_0 = Hermitian (P̂_0, :L )
292291 P̂ = copy (P̂_0)
293292 K̂ = zeros (NT, nx̂, nym)
294- M̂ = Hermitian (zeros (NT, nym, nym), :L )
295293 corrected = [false ]
296294 buffer = StateEstimatorBuffer {NT} (nu, nx̂, nym, ny, nd)
297295 return new {NT, SM} (
@@ -301,7 +299,7 @@ struct KalmanFilter{NT<:Real, SM<:LinModel} <: StateEstimator{NT}
301299 As, Cs_u, Cs_y, nint_u, nint_ym,
302300 Â, B̂u, Ĉ, B̂d, D̂d,
303301 P̂_0, Q̂, R̂,
304- K̂, M̂,
302+ K̂,
305303 direct, corrected,
306304 buffer
307305 )
@@ -783,7 +781,6 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
783781 Q̂:: Hermitian{NT, Matrix{NT}}
784782 R̂:: Hermitian{NT, Matrix{NT}}
785783 K̂:: Matrix{NT}
786- M̂:: Matrix{NT}
787784 F̂_û:: Matrix{NT}
788785 Ĥ :: Matrix{NT}
789786 direct:: Bool
@@ -806,7 +803,6 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
806803 R̂ = Hermitian (R̂, :L )
807804 P̂ = copy (P̂_0)
808805 K̂ = zeros (NT, nx̂, nym)
809- M̂ = Hermitian (zeros (NT, nym, nym), :L )
810806 F̂_û, Ĥ = zeros (NT, nx̂+ nu, nx̂), zeros (NT, ny, nx̂)
811807 corrected = [false ]
812808 buffer = StateEstimatorBuffer {NT} (nu, nx̂, nym, ny, nd)
@@ -817,7 +813,7 @@ struct ExtendedKalmanFilter{NT<:Real, SM<:SimModel} <: StateEstimator{NT}
817813 As, Cs_u, Cs_y, nint_u, nint_ym,
818814 Â, B̂u, Ĉ, B̂d, D̂d,
819815 P̂_0, Q̂, R̂,
820- K̂, M̂,
816+ K̂,
821817 F̂_û, Ĥ,
822818 direct, corrected,
823819 buffer
@@ -991,40 +987,44 @@ function validate_kfcov(nym, nx̂, Q̂, R̂, P̂_0=nothing)
991987end
992988
993989"""
994- correct_estimate_kf!(estim::StateEstimator , y0m, d0, Ĉm)
990+ correct_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter} , y0m, d0, Ĉm)
995991
996992Correct time-varying/extended Kalman Filter estimates with augmented `Ĉm` matrices.
997993
998994Allows code reuse for [`KalmanFilter`](@ref), [`ExtendedKalmanFilterKalmanFilter`](@ref).
999995See [`update_estimate_kf!`](@ref) for more information.
1000996"""
1001- function correct_estimate_kf! (estim:: StateEstimator , y0m, d0, Ĉm)
1002- R̂, M̂, K̂ = estim. R̂, estim . M̂ , estim. K̂
997+ function correct_estimate_kf! (estim:: Union{KalmanFilter, ExtendedKalmanFilter} , y0m, d0, Ĉm)
998+ R̂, K̂ = estim. R̂, estim. K̂
1003999 x̂0, P̂ = estim. x̂0, estim. P̂
1000+ # in-place operations to reduce allocations:
10041001 P̂_Ĉmᵀ = K̂
10051002 mul! (P̂_Ĉmᵀ, P̂. data, Ĉm' ) # the ".data" weirdly removes a type instability in mul!
1006- mul! (M̂, Ĉm, P̂_Ĉmᵀ)
1007- M̂ .+ = R̂
1003+ Ŝ = estim. buffer. R̂
1004+ mul! (Ŝ, Ĉm, P̂_Ĉmᵀ)
1005+ Ŝ .+ = R̂
10081006 K̂ = P̂_Ĉmᵀ
1009- M̂_chol = cholesky! (Hermitian (M̂ )) # also modifies M̂
1007+ M̂_chol = cholesky! (Hermitian (Ŝ )) # also modifies Ŝ
10101008 rdiv! (K̂, M̂_chol)
10111009 ŷ0 = estim. buffer. ŷ
10121010 ĥ! (ŷ0, estim, estim. model, x̂0, d0)
10131011 ŷ0m = @views ŷ0[estim. i_ym]
10141012 v̂ = ŷ0m
10151013 v̂ .= y0m .- ŷ0m
1016- x̂0corr, P̂corr = estim . x̂0, estim . P̂
1017- mul! (x̂0corr, K̂, v̂, 1 , 1 )
1018- I_minus_K̂_Ĉm = estim. buffer. P̂
1014+ x̂0corr = x̂0
1015+ mul! (x̂0corr, K̂, v̂, 1 , 1 ) # also modifies estim.x̂0
1016+ I_minus_K̂_Ĉm = estim. buffer. Q̂
10191017 mul! (I_minus_K̂_Ĉm, K̂, Ĉm)
10201018 lmul! (- 1 , I_minus_K̂_Ĉm)
1021- I_minus_K̂_Ĉm[diagind (I_minus_K̂_Ĉm)] .+ = 1 # compute I - K̂*Ĉm
1022- P̂corr .= Hermitian (I_minus_K̂_Ĉm * P̂) # TODO : remove this allocation
1019+ I_minus_K̂_Ĉm[diagind (I_minus_K̂_Ĉm)] .+ = 1 # compute I - K̂*Ĉm in-place
1020+ P̂corr = estim. buffer. P̂
1021+ mul! (P̂corr, I_minus_K̂_Ĉm, P̂)
1022+ estim. P̂ .= Hermitian (P̂corr, :L )
10231023 return nothing
10241024end
10251025
10261026"""
1027- update_estimate_kf!(estim::StateEstimator , y0m, d0, u0, Ĉm, Â)
1027+ update_estimate_kf!(estim::Union{KalmanFilter, ExtendedKalmanFilter} , y0m, d0, u0, Ĉm, Â)
10281028
10291029Update time-varying/extended Kalman Filter estimates with augmented `Ĉm` and `Â` matrices.
10301030
@@ -1034,18 +1034,23 @@ substitutes the augmented model matrices with its Jacobians (`Â = F̂` and `C
10341034The implementation uses in-place operations and explicit factorization to reduce
10351035allocations. See e.g. [`KalmanFilter`](@ref) docstring for the equations.
10361036"""
1037- function update_estimate_kf! (estim:: StateEstimator , y0m, d0, u0, Ĉm, Â)
1037+ function update_estimate_kf! (estim:: Union{KalmanFilter, ExtendedKalmanFilter} , y0m, d0, u0, Ĉm, Â)
10381038 if ! estim. direct
10391039 correct_estimate_kf! (estim, y0m, d0, Ĉm)
10401040 end
10411041 x̂0corr, P̂corr = estim. x̂0, estim. P̂
10421042 Q̂ = estim. Q̂
10431043 x̂0next, û0 = estim. buffer. x̂, estim. buffer. û
1044+ # in-place operations to reduce allocations:
10441045 f̂! (x̂0next, û0, estim, estim. model, x̂0corr, u0, d0)
1045- # TODO : use buffer.P̂ to reduce allocations
1046- P̂next = Hermitian (Â * P̂corr * Â' .+ Q̂, :L )
1046+ P̂corr_Âᵀ = estim. buffer. P̂
1047+ mul! (P̂corr_Âᵀ, P̂corr, Â' )
1048+ Â_P̂corr_Âᵀ = estim. buffer. Q̂
1049+ mul! (Â_P̂corr_Âᵀ, Â, P̂corr_Âᵀ)
1050+ P̂next = estim. buffer. P̂
1051+ P̂next .= Â_P̂corr_Âᵀ .+ Q̂
10471052 x̂0next .+ = estim. f̂op .- estim. x̂op
10481053 estim. x̂0 .= x̂0next
1049- estim. P̂ .= P̂next
1054+ estim. P̂ .= Hermitian ( P̂next, :L )
10501055 return nothing
10511056end
0 commit comments