Hi!
I am writing a Kalman filter code for some particular state space representation. With my current code, I still end up with a lot allocations, so I guess there are still a lot of potential efficiency gain. Could someone help for a newbie to improve? Thanks
using LinearAlgebra
using BenchmarkTools
mutable struct kalman{S <: AbstractFloat}
btt::Vector{S}
Vtt::Matrix{S}
end
function forecast!(k::kalman{S}, Qt::Matrix{S}) where {S <: AbstractFloat}
k.Vtt .= k.Vtt .+ Qt
return nothing
end
function update!(k::kalman{S}, y::Vector{S}, X::Matrix{S}, Ht::Matrix{S}) where {S <: AbstractFloat}
bp, Vp = k.btt, k.Vtt
cfe = y - X * bp
f = X * Vp * X' + Ht
invf = inv(f)
k.btt = bp + Vp * X' * invf * cfe
k.Vtt = Vp - Vp * X' * invf * X * Vp
return nothing
end
function kf(y::AbstractMatrix{S}, Z::AbstractMatrix{S}, Ht::AbstractArray{S,3}, Qt::AbstractMatrix{S}, K::Int, N::Int, T::Int, b0::AbstractVector{S}, V0::AbstractMatrix{S}) where {S <: AbstractFloat}
bt = Array{Float64}(undef, K, T)
Vt = Array{Float64}(undef, K^2, T)
k = kalman(b0, V0)
for i = 1:T
update!(k, y[:,i], Z[(i - 1) * N + 1:i * N,:], Ht[:,:,i])
@inbounds bt[:,i] = k.btt
@inbounds Vt[:,i] = vec(k.Vtt);
forecast!(k, Qt)
end
return bt, Vt
end
function test()
T = 100
N = 3
K = 21
y = randn(N, T)
Z = randn(T * N, K)
Ht = randn(N, N, T)
Qt = randn(K, K)
b0 = randn(K)
V0 = randn(K, K)
@benchmark a, b = kf($y, $Z, $Ht, $Qt, $K, $N, $T, $b0, $V0)
end
test()