Skip to content

Commit e97e607

Browse files
committed
reduce allocation UnscentedKalmanFilter
1 parent 2387b15 commit e97e607

File tree

1 file changed

+33
-18
lines changed

1 file changed

+33
-18
lines changed

src/estimator/kalman.jl

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -558,31 +558,46 @@ function update_estimate!(estim::UnscentedKalmanFilter{NT}, u, ym, d) where NT<:
558558
x̂, P̂, Q̂, R̂, K̂ = estim.x̂, estim.P̂, estim.Q̂, estim.R̂, estim.
559559
nym, nx̂, nσ = estim.nym, estim.nx̂, estim.
560560
γ, m̂, Ŝ = estim.γ, estim.m̂, estim.
561-
# --- correction step ---
562-
sqrt_P̂ = cholesky(P̂).L
563-
= repeat(x̂, 1, nσ) + [zeros(NT, nx̂) +γ*sqrt_P̂ -γ*sqrt_P̂]
561+
# --- initialize matrices ---
562+
= Matrix{NT}(undef, nx̂, nσ)
563+
ŷm = Vector{NT}(undef, nym)
564564
Ŷm = Matrix{NT}(undef, nym, nσ)
565+
sqrt_P̂ = LowerTriangular{NT, Matrix{NT}}(Matrix{NT}(undef, nx̂, nx̂))
566+
# --- correction step ---
567+
sqrt_P̂.data .= cholesky(P̂).L
568+
γ_sqrt_P̂ = lmul!(γ, sqrt_P̂)
569+
X̂ .=
570+
X̂[:, 2:nx̂+1] .+= γ_sqrt_P̂
571+
X̂[:, nx̂+2:end] .-= γ_sqrt_P̂
565572
for j in axes(Ŷm, 2)
566-
Ŷm[:, j] = (estim, estim.model, X̂[:, j], d)[estim.i_ym]
573+
Ŷm[:, j] = @views (estim, estim.model, X̂[:, j], d)[estim.i_ym]
567574
end
568-
ŷm = Ŷm *
569-
=.-
570-
Ȳm = Ŷm .- ŷm
575+
mul!(ŷm, Ŷm, m̂)
576+
X̄, Ȳm = X̂, Ŷm
577+
X̄ .=.-
578+
Ȳm .= Ŷm .- ŷm
571579
= Hermitian(Ȳm ** Ȳm' + R̂, :L)
572580
mul!(K̂, X̄, lmul!(Ŝ, Ȳm'))
573581
rdiv!(K̂, cholesky(M̂))
574-
x̂_cor =+* (ym - ŷm)
582+
v̂m = ŷm
583+
v̂m .= ym .- ŷm
584+
x̂_cor =+* v̂m
575585
P̂_cor =- Hermitian(K̂ **', :L)
576586
# --- prediction step ---
577-
sqrt_P̂_cor = cholesky(P̂_cor).L
578-
X̂_cor = repeat(x̂_cor, 1, nσ) + [zeros(NT, nx̂) +γ*sqrt_P̂_cor -γ*sqrt_P̂_cor]
579-
X̂_next = Matrix{NT}(undef, nx̂, nσ)
587+
X̂_cor, sqrt_P̂_cor = X̂, sqrt_P̂
588+
sqrt_P̂_cor.data .= cholesky(P̂_cor).L
589+
γ_sqrt_P̂_cor = lmul!(γ, sqrt_P̂_cor)
590+
X̂_cor .= x̂_cor
591+
X̂_cor[:, 2:nx̂+1] .+= γ_sqrt_P̂_cor
592+
X̂_cor[:, nx̂+2:end] .-= γ_sqrt_P̂_cor
593+
X̂_next = X̂_cor
580594
for j in axes(X̂_next, 2)
581-
X̂_next[:, j] = (estim, estim.model, X̂_cor[:, j], u, d)
595+
X̂_next[:, j] = @views (estim, estim.model, X̂_cor[:, j], u, d)
582596
end
583-
x̂[:] = X̂_next *
584-
X̄_next = X̂_next .-
585-
.data[:] = X̄_next ** X̄_next' +# .data is necessary for Hermitians
597+
mul!(x̂, X̂_next, m̂)
598+
X̄_next = X̂_next
599+
X̄_next .= X̂_next .-
600+
.data .= X̄_next ** X̄_next' .+# .data is necessary for Hermitians
586601
return nothing
587602
end
588603

@@ -744,7 +759,7 @@ end
744759
function init_estimate_cov!(
745760
estim::Union{KalmanFilter, UnscentedKalmanFilter, ExtendedKalmanFilter}, _ , _ , _
746761
)
747-
estim..data[:] = estim.P̂0 # .data is necessary for Hermitians
762+
estim..data .= estim.P̂0 # .data is necessary for Hermitians
748763
return nothing
749764
end
750765

@@ -785,8 +800,8 @@ function update_estimate_kf!(estim, u, ym, d, Â, Ĉm, P̂, x̂=nothing)
785800
if !isnothing(x̂)
786801
mul!(estim.K̂, Â, M̂)
787802
ŷm = @views (estim, estim.model, x̂, d)[estim.i_ym]
788-
[:] = (estim, estim.model, x̂, u, d) + estim.* (ym - ŷm)
803+
.= (estim, estim.model, x̂, u, d) .+ estim.* (ym - ŷm)
789804
end
790-
.data[:] =* (P̂ -* Ĉm * P̂) *' +# .data is necessary for Hermitians
805+
.data .=* (P̂ -* Ĉm * P̂) *' +# .data is necessary for Hermitians
791806
return nothing
792807
end

0 commit comments

Comments
 (0)