The Kalman Filter: an interactive explanation

State prediction, optimal gain, key equations — with interactive simulations to build intuition.

For recruiters (quick read)

The Kalman Filter is a recursive optimal estimator (in the MSE sense) for linear noisy systems. I use it as a modelling tool to understand:

  • Information fusion: how to combine a dynamic model with imperfect sensors.
  • Uncertainty propagation: covariance matrices, process noise \(Q\), measurement noise \(R\).
  • Bayesian optimisation: the Kalman gain is the closed-form solution to a variance-weighting problem.
  • Nonlinear extensions: EKF (Extended), UKF (Unscented), particle filters.
Bayesian estimation Dynamical systems Recursive least squares Sensor fusion

Why the Kalman Filter?

Imagine a radar tracking an aircraft. The measured position is noisy — ten different radars would give ten slightly different readings. At the same time, you know the aircraft flies at roughly constant velocity: you have a model of its behaviour.

The Kalman Filter answers a simple question: how do we optimally combine a noisy measurement with an imperfect prediction? The answer is a weighted average where the weights depend on the respective confidence levels — and that is precisely the Kalman gain.

Beyond radar, the Kalman Filter appears in GPS/IMU navigation, robot control, financial state-space models, and even brain-computer interfaces.

State-space model

The system is described by a state vector \(\mathbf{x}_k\) (position, velocity, temperature…) that evolves according to two equations:

Process equation
Dynamic model
\[\mathbf{x}_{k} = \mathbf{F}\,\mathbf{x}_{k-1} + \mathbf{B}\,\mathbf{u}_k + \mathbf{w}_k\]
  • \(\mathbf{F}\) — state transition matrix
  • \(\mathbf{B},\mathbf{u}_k\) — control input
  • \(\mathbf{w}_k \sim \mathcal{N}(0,\mathbf{Q})\) — process noise
Measurement equation
Sensor model
\[\mathbf{z}_k = \mathbf{H}\,\mathbf{x}_k + \mathbf{v}_k\]
  • \(\mathbf{z}_k\) — measurement vector (what the sensor sees)
  • \(\mathbf{H}\) — observation matrix
  • \(\mathbf{v}_k \sim \mathcal{N}(0,\mathbf{R})\) — measurement noise

The estimated state \(\hat{\mathbf{x}}_{k|k}\) is represented as a Gaussian parameterised by its mean and covariance matrix \(\mathbf{P}\): \(\hat{\mathbf{x}} \sim \mathcal{N}(\hat{\mathbf{x}}, \mathbf{P})\). This representation lets us propagate uncertainty at every step.

The Predict – Update cycle

The filter runs in a loop: at each time step it predicts the next state using the dynamic model, then corrects that prediction with the current measurement.

① Initialise

Set \(\hat{\mathbf{x}}_{0|0}\) and \(\mathbf{P}_{0|0}\)

② Predict

Propagate via \(\mathbf{F}\), \(\mathbf{B}\), \(\mathbf{Q}\)

③ Update

Compute gain \(\mathbf{K}\), correct with \(\mathbf{z}_k\)

Steps ② and ③ repeat at every time step.

Complete equations

Predict step

Predicted state
\[\hat{\mathbf{x}}_{k|k-1} = \mathbf{F}\,\hat{\mathbf{x}}_{k-1|k-1} + \mathbf{B}\,\mathbf{u}_k\]
Predicted covariance
\[\mathbf{P}_{k|k-1} = \mathbf{F}\,\mathbf{P}_{k-1|k-1}\,\mathbf{F}^\top + \mathbf{Q}\]

Update step

Kalman gain
\[\mathbf{K}_k = \mathbf{P}_{k|k-1}\,\mathbf{H}^\top\!\left(\mathbf{H}\,\mathbf{P}_{k|k-1}\,\mathbf{H}^\top + \mathbf{R}\right)^{-1}\]
Updated state
\[\hat{\mathbf{x}}_{k|k} = \hat{\mathbf{x}}_{k|k-1} + \mathbf{K}_k\!\left(\mathbf{z}_k - \mathbf{H}\,\hat{\mathbf{x}}_{k|k-1}\right)\]
Updated covariance (Joseph form)
\[\mathbf{P}_{k|k} = \left(\mathbf{I} - \mathbf{K}_k\mathbf{H}\right)\mathbf{P}_{k|k-1}\left(\mathbf{I} - \mathbf{K}_k\mathbf{H}\right)^\top + \mathbf{K}_k\mathbf{R}\,\mathbf{K}_k^\top\]
Innovation (residual): \(\tilde{\mathbf{y}}_k = \mathbf{z}_k - \mathbf{H}\,\hat{\mathbf{x}}_{k|k-1}\) — difference between the observed measurement and the predicted measurement. The gain \(\mathbf{K}_k\) determines how much of this new information to incorporate.

Interactive simulation

The simulation below shows an object moving at roughly constant velocity (with slight random acceleration). Position measurements are noisy. Adjust \(Q\) (process noise) and \(R\) (measurement noise) to see how the filter responds.

1D Kalman Filter — position and velocity

20
0.50
2.0
True state Noisy measurement Estimate (filter) Prediction (before update)

What to notice: When \(R\) is large (unreliable sensor), the filter trusts the dynamic model more. When \(Q\) is large (unreliable model), the filter reacts faster to measurements. The Kalman gain automatically balances these two sources.

Kalman gain intuition

In 1D, the gain simplifies to:

\[K_k = \frac{p_{k|k-1}}{p_{k|k-1} + r}\]

It is simply the ratio of the predicted uncertainty to the total uncertainty. If \(r \to 0\) (perfect sensor), \(K \to 1\): fully trust the measurement. If \(p \to 0\) (perfect model), \(K \to 0\): ignore the measurement.

Visualising gain \(K\) as a function of \(p\) and \(r\)

10.0
10.0

Numerical example: 1D radar

Consider the classic example of a radar tracking an aircraft in a straight line. The state is \(\mathbf{x} = [r,\, v]^\top\) (range in m, velocity in m/s). At \(t_0\): initial measurement \(\mathbf{z}_0 = [10\,000,\; 200]^\top\).

Initialisation

\[\hat{\mathbf{x}}_{0|0} = \begin{bmatrix}10\,000\\200\end{bmatrix},\quad \mathbf{P}_{0|0} = \begin{bmatrix}16 & 0\\0 & 0.25\end{bmatrix}\]

Prediction at \(t_1\) (\(\Delta t = 5\,\text{s}\))

\[\mathbf{F} = \begin{bmatrix}1 & 5\\0 & 1\end{bmatrix},\quad \hat{\mathbf{x}}_{1|0} = \mathbf{F}\hat{\mathbf{x}}_{0|0} = \begin{bmatrix}11\,000\\200\end{bmatrix}\]
\[\mathbf{P}_{1|0} = \mathbf{F}\mathbf{P}_{0|0}\mathbf{F}^\top + \mathbf{Q} = \begin{bmatrix}28.5 & 3.75\\3.75 & 1.25\end{bmatrix}\]

Update with \(\mathbf{z}_1 = [11\,020,\; 202]^\top\)

With \(\mathbf{H} = \mathbf{I}\) and \(\mathbf{R}_1 = \mathrm{diag}(36,\; 2.25)\):

\[\mathbf{K}_1 = \begin{bmatrix}0.44 & 0.64\\0.04 & 0.31\end{bmatrix}\]
\[\hat{\mathbf{x}}_{1|1} = \hat{\mathbf{x}}_{1|0} + \mathbf{K}_1(\mathbf{z}_1 - \hat{\mathbf{x}}_{1|0}) = \begin{bmatrix}11\,009.4\\201.4\end{bmatrix}\]
The updated covariance \(\mathbf{P}_{1|1} \approx \mathrm{diag}(14.6,\; 0.71)\) is smaller than both \(\mathbf{P}_{1|0}\) and \(\mathbf{R}_1\). By combining two sources, the estimate is better than either source alone — this is the core insight of the Kalman Filter.

Limits and extensions

Standard assumptionIf violated → solution
Linear systemEKF: local linearisation (Jacobian)
Gaussian noiseUKF: unscented transform (sigma points)
Multimodal distributionsParticle filter: sequential Monte Carlo
Known \(Q\) and \(R\)Adaptive estimation (EM, sliding window)

Further reading: kalmanfilter.net (full tutorial) • Bzarg — in picturesLabbe — Python