Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Model formulation

We consider the following general state space model made of a state equation and an observation equation:

where:

  • is the state vector at time step ,
  • is the observation/measurement vector.

We also have the following hyperparameters assumed to be known:

  • is the state transition matrix,
  • is the observation matrix,
  • is the process noise covariance,
  • is the observation noise covariance.

The aim is to estimate the state given the noisy observations .

Kalman filtering

We start with an initial state and we want to determine the conditional distribution of the next state. Using Baye's rule, one has The likelihood can easily be determined thanks to the chosen observation equation. The marginal distribution can be obtained by marginalizing . This marginal distribution can be seen as our prior knowledge before seeing . It can easily be shown that with This first estimate is what we will call the prediction step. Using this result, we can determine : with which gives us our estimate the next state given the observation . This is what we call the update step.

General equations

For an arbitrary time step , the prediction step yields: and the update step is given by where the Kalman gain is defined as

Implementing the Kalman filter boils down to implement these few equations!

Crate

At the end of the chapter, we obtain a small standalone crate with the following layout:

├── Cargo.toml
└── src
    ├── algorithm.rs
    └── lib.rs

The module algorithm.rs implements the whole Kalman filter method defined as a struct with a few implementations.

For this crate, we only need a few imports from nalgebra, rand, and rand_distr. In the algorithm module, we have:

#![allow(unused)]
fn main() {
use nalgebra::{Cholesky, DMatrix, DVector};
use rand::thread_rng;
use rand_distr::{Distribution, StandardNormal};
}

And the Cargo.toml configuration file is given by

[package]
name = "kalman_filter"
version = "0.1.0"
edition = "2024"

[dependencies]
rustineers = { path = "../../" }
nalgebra = "0.33"
rand = "0.8"
rand_distr = "0.4"
thiserror = "1.0"