Reading and display settings

Appearance

System follows your operating system and keeps following it, even if you change it later. The header's sun, moon and monitor cycle the same three options.

Text size (%) 100%

Default. Scales every text size on the site, equations and tables included.

Reading width 70ch

How much text runs across one line of prose. Narrower is easier to track; wider fits more on screen.

Line spacing 1.6

The leading on body text. Taller leading helps a tired eye stay on the line.

Density

Padding and gaps around controls, cards, and tables — how much breathing room the layout leaves itself.

Motion

System follows your operating system. Reduced removes every transition on this site. Full keeps them on unless your system asks for less.

1

The question

A state you cannot see, from data you cannot trust

A robot drives along a corridor. Its true position, a single number along the corridor, is a hidden state: no sensor reports it directly. What you get instead are two weak signals. The first is a control, the command you sent — go forward about a metre — whose real effect is corrupted by wheel slip and a slightly uneven floor. The second is a measurement, a range reading to a wall or a landmark, which is corrupted by sensor noise and by the fact that several positions can produce similar readings. Neither signal is good enough alone, and you want them to combine.

It is tempting to keep a point estimate: start at the believed position, add the commanded motion, then nudge toward whatever the sensor says. That is what a great many robots do, and it fails in a specific and instructive way. Adding motions accumulates error, and the error accumulates faster than any single reading can correct for. Nudge too hard toward a noisy reading and you chase noise; nudge too softly and you drift. A point estimate throws away the one thing you need to set that balance: how uncertain you are.

The Bayes filter keeps uncertainty explicitly. Instead of one number it keeps a whole probability distribution over the state, written bel(xt), the belief at time t. It is the probability of each possible position given every control and every measurement so far. A sharp spike means you know where you are; a broad smear means you do not. The width of that distribution is not a side note, it is the quantity that decides how much the next reading should be trusted.

The corridor in this part is a loop, a ring of known length. That choice is not just scenery. On a loop there is no boundary: position x = L is the same place as position x = 0, so probability that leaves one end of the number line re-enters at the other. If the state lives on a circle, the arithmetic has to respect that, and watching it happen is the clearest way to see why the filter is a convolution. By the end you will have watched the belief locate itself, and understood why the same two lines of reasoning run every filter in this volume.

💡 By the end of this part you'll see why the filter is just Bayes' rule applied in a loop, where uncertainty grows in the predict step and shrinks in the update step, and why the corridor being a loop makes the predict step a wrapped convolution.
2

The recursive Bayes filter

Two lines of Bayes, applied forever

Name the three objects. The state is xt, the thing we want. The control is ut, the action taken between the last step and this one. The measurement is zt, the reading that arrives now. All we ever want is the belief, the posterior over the current state given the whole history of controls and measurements.

$$bel(x_t)=p\!\left(x_t\mid z_{1:t},\,u_{1:t}\right).$$

Applied naively, that posterior is a nightmare: the history grows without limit, so each new step would require re-deriving the joint distribution over every past state. The recursion escapes the nightmare with two assumptions, each of which is a modelling decision you can check against the world. First, the Markov property: the current state is a sufficient summary of the past, so once you condition on xt, older states add nothing. Second, the measurement depends only on the current state, not on how you got there. Under those two assumptions, the whole history collapses into the previous belief.

Write bel(xt) for the prediction, the belief before the new measurement is used, and bel(xt) for the belief after. The filter is then exactly two equations, repeated forever: propagate the previous belief through the motion model, then correct it with the measurement model.

$$\overline{bel}(x_t)=\int p\!\left(x_t\mid u_t,\,x_{t-1}\right)bel(x_{t-1})\,dx_{t-1},\qquad bel(x_t)=\eta\,p\!\left(z_t\mid x_t\right)\overline{bel}(x_t).$$

The symbol η is a normalising constant, chosen so the corrected belief integrates to one. It is not arbitrary: it equals one over the total probability of the measurement, the evidence, and it is the number that would tell you how surprising this reading was under your model. The first equation is the law of total probability; the second is Bayes' rule. Nothing else is going on. Every named filter in this volume is a decision about how to represent the distribution and how to compute these two integrals.

That is the punchline of the whole subject, so it is worth saying slowly. Prediction adds uncertainty and moves probability with the motion. Correction removes uncertainty and pulls probability toward the measurement. Whatever representation you choose — a list of histograms, a mean and a covariance, a cloud of particles — the loop is the same, and the belief at time t is always a complete summary of the data up to time t. The animation below is this loop run eight times on the looped corridor, with the true position drawn as a dashed tick at each step.

Each ridge is one full predict–then–update step. The filled shape is bel(x) across the corridor; the dashed tick inside it is the true position. The shapes start broad and settle onto the truth as measurements accumulate.

Watch the order of operations. Each ridge is a posterior: the prediction already happened, then the reading was folded in. The motion shifts each ridge slightly forward and blurs it; the reading sharpens it again around the true position. When the two happen in the other order the result is nearly identical, because the multiply and the convolution commute, but the standard order is predict then update because the world moves before it is measured.

3

The predict step

Motion is a convolution, and it costs certainty

The motion model is the distribution p(xt | ut, xt−1): given that you were at xt−1 and you applied control ut, where could you be now? The control says where you tried to go; the model adds the spread of everything that could have gone wrong. The predict equation sums this over every place you might have started, weighted by how much you believed you were there. That weighted sum is a convolution of the belief with the motion kernel.

On a discretised corridor the integral becomes a sum over cells. If cell j is centred at xj and cell i at xi, the motion kernel is a probability over the displacement, and the new belief is the sum over old cells of old belief times kernel.

$$\overline{bel}(x_i)=\sum_{j=1}^{n}p\!\left(x_i\mid u_t,\,x_j\right)bel(x_j),\qquad p\!\left(x_i\mid u_t,\,x_j\right)\propto\exp\!\left(-\frac{(x_i-x_j-u_t)^2}{2\sigma_u^2}\right).$$

Two effects are visible in that one line. The kernel is centred on the displacement ut, so the belief translates: a step forward moves the whole shape forward. The kernel has width σu, so the belief blurs: a spread of possible displacements smears the shape outward. Translation is the signal you wanted, blur is the uncertainty you paid. Add up independent sources of motion noise and their variances add, so the belief only ever loses sharpness in this step. Nothing in the predict step can make you more certain.

The demo below applies exactly one predict to a known starting belief. Drag the shift to translate, drag the motion noise to blur, and toggle the wrap to see what the loop does. With wrap off, mass that crosses the right edge falls off the end of the corridor and is discarded; with wrap on it reappears at the left. That single toggle is the difference between a line and a circle, and it is the reason the state space in the next section is written modulo the corridor length.

Grey is the belief before motion, blue is the prediction bel after one convolution. The dashed lines mark the old and new centres.

One subtlety hides inside the kernel: real motion is rarely a pure translation with symmetric Gaussian noise. A differential-drive robot turning while it drives rotates the belief as well as shifting it, and the kernel becomes a rotation of the state space. For richer models the convolution is still the right mental picture, but the kernel is no longer a shift-invariant blur and the tidy sum above generalises to a matrix of transition probabilities. That matrix is a Markov chain, which is why the Markov-chains part of this volume and the hidden-Markov-model part are the same idea in different clothing.

4

The update step

A reading is a multiplication, and it buys certainty

The measurement model is the distribution p(zt | xt): how likely would this reading be if the state were here? For a range sensor it is a bell centred at the true distance with width set by the sensor noise, plus whatever outliers your model allows. Bayes' rule turns that likelihood into a posterior by multiplying it into the prediction, cell by cell, and rescaling.

$$bel(x_t)=\eta\,p\!\left(z_t\mid x_t\right)\overline{bel}(x_t),\qquad \eta=\left(\sum_{i}p\!\left(z_t\mid x_i\right)\overline{bel}(x_i)\right)^{-1}.$$

The word to hold onto is pointwise. This is not another convolution; it does not move probability around at all. Each cell keeps its own argument and is simply multiplied by how well that cell explains the reading. Cells where the sensor says the state cannot be get a small factor and shrink; cells where the sensor says the state would fit nicely get a large factor and grow. Then η rescales the whole array so it sums to one, and the belief is again a probability distribution.

The effect on sharpness is the mirror image of the predict step. For a Gaussian belief and a Gaussian sensor, the posterior is Gaussian, and its precision — one over the variance — is the sum of the two precisions. Sharp likelihood times sharp belief gives an even sharper posterior; a broad, noisy likelihood barely changes the shape. That is the quantitative version of an intuition you already have: a vague sensor tells you little, and the belief should not move much for it. It also explains a failure mode. If the likelihood is broad because the sensor is noisy, the update cannot re-sharpen a belief that motion keeps blurring, and the filter settles into a wide steady state.

$$\frac{1}{\sigma_{\text{post}}^2}=\frac{1}{\sigma_{\text{prior}}^2}+\frac{1}{\sigma_{z}^2},\qquad H(bel)=-\sum_i bel(x_i)\log_2 bel(x_i)\ \text{bits}.$$

The demo below isolates the multiplication. The grey bars are a broad prior, the dashed curve is the sensor likelihood for one reading, and the blue bars are their pointwise product after normalisation. Move the reading and it slides the posterior toward itself; make the sensor noisier and the posterior relaxes back toward the prior. Nothing here is specific to corridors or robots. The update equation is Bayes' rule, so every Bayesian inference you have done is a one-step, one-cell update of this filter.

Grey: the prediction bel. Dashed: the likelihood p(z|x), scaled to fit. Blue: the posterior, the pointwise product renormalised.

There is a reason this looks so much like the likelihood part of this volume. Index the cells and hold the reading fixed, and the array p(z | xi) is exactly a likelihood as a function of the unknown state. The filter is doing maximum-likelihood-flavoured inference at every step, except that it keeps the whole distribution and lets the motion model supply the prior from the previous instant. Priors made from yesterday's data, updated by today's: that is the recursion, and it is why the same code handles a static parameter and a moving robot.

5

Histogram filters and the corridor

Discretise the state, then let the loop do the work

The simplest representation of a belief is a list of numbers. Cut the corridor into n cells, store a probability for each, and require the list to sum to one. This is a histogram filter, and it makes both equations concrete. Prediction becomes a discrete convolution: each cell sprays its probability across nearby cells according to the motion kernel, and the wrapped index arithmetic keeps the loop closed. Correction becomes a pointwise multiply by the likelihood evaluated at each cell centre, followed by a divide so the list sums to one again.

$$\overline{bel}(x_i)=\sum_{j=1}^{n}k\!\left(\tfrac{(i-j)\,\Delta x-u_t}{\sigma_u}\right)bel(x_j)\pmod n,\qquad bel(x_i)=\eta\,p\!\left(z_t\mid x_i\right)\overline{bel}(x_i).$$

The cell size Δx = L/n is the one real design choice. Finer cells resolve a sharper belief and let the reading pull the shape around more precisely, but the array grows and the convolution costs more. Coarser cells are cheap but pile up position error within each cell, and a belief narrower than a cell is smeared out almost immediately. The slider below lets you change the resolution and watch that trade-off directly: too few cells and the filter cannot express how sure it is.

The corridor being a loop changes the predict step from a truncation to a wrap. In the sum above, indices are taken modulo n, so probability that would have left the right-hand end of the array reappears at the left-hand end instead of vanishing. That is exactly what a circular corridor requires: walking off the end of the corridor puts you back at the start. If you forget the wrap and use a straight line instead, the belief quietly loses probability at the edges and the filter becomes confidently wrong near the seam. The wrap arrow drawn across the top of the histogram, and the ring below it, are the same statement in two pictures.

The final ingredient is a way to say how much the filter knows, and entropy answers it. A uniform belief over n cells has entropy log2 n bits, the maximum possible; a belief concentrated on one cell has entropy zero. Predict blurs, so it raises entropy; update multiplies, so it lowers it. Run the loop and the entropy trace falls as readings accumulate, until it levels off at the point where the information each reading brings is exactly cancelled by the uncertainty each motion adds. That plateau is the best the filter can do with this sensor and this motion, and it is the honest answer to "how well do we know where the robot is?"

The ring is the corridor: it has no ends, so position L is the same place as position 0. Bars point inward to show bel(x); the dot marks the true position, the triangle marks the sensor reading.

The same belief as a flat histogram. The two dashed lines are the true position and the reading; the arrow across the top is the wrap from x = L back to x = 0.

Entropy of the belief in bits after each step. It starts at the uniform maximum and falls as readings sharpen the belief, then plateaus.

Keys: P predict · U update · R reset

Step it by hand and watch the story unfold. Press Predict a few times with the shift positive and the robot marches forward while the belief smears and slides; press Update and the reading snaps it back to a peak, occasionally to the wrong place on the loop when the sensor is noisy. Then raise the sensor noise slider and repeat: each reading now barely reshapes the belief, so the smear from the motion wins, the entropy plateau rises, and the dot and the triangle drift apart. Lower it again and the peak tightens. That single slider is the whole trade-off between trusting your model and trusting your senses, and the entropy trace is the ledger that records it.

6

Where this shows up

One recursion, many filters

Robotics

Odometry fused with sensors

Every mobile robot fuses odometry with range and bearing readings through exactly this recursion. Odometry is the motion model; the rangefinder is the measurement model; the belief over pose is what the navigation stack consumes.

Vision

SLAM is this filter, plus a map

Simultaneous localisation and mapping in nonlinear optimization runs the Bayes filter over a joint state of robot pose and landmark positions. The predict step is the motion model, and the update step conditions on every observed feature at once.

Math

Hidden Markov models

A hidden Markov model is this filter on a finite state set. The forward algorithm is the predict–update recursion in matrix form, and bel before normalisation is the forward message the next part of the trellis builds on.

Math

Kalman filters are the Gaussian special case

If the belief and both models are Gaussian, the convolution and the pointwise product have closed forms, and the Kalman filter tracks a mean and a covariance instead of an array. The next part of this volume derives it directly from these two equations.

7

Cheat sheet

Every formula in one place

IdeaFormulaIntuition
Beliefbel(xt) = p(xt | z1:t, u1:t)The full posterior over the hidden state; a running summary of all data.
Predictbel(xt) = ∫ p(xt | ut, xt−1) bel(xt−1) dxt−1Convolve with the motion model: translates the belief and blurs it.
Updatebel(xt) = η p(zt | xt) bel(xt)Multiply pointwise by the likelihood, then renormalise.
Discrete predictbel(xi) = Σj p(xi | ut, xj) bel(xj)A sum over source cells; the transition kernel spreads each cell.
Discrete updatebel(xi) = η p(zt | xi) bel(xi)Cell by cell multiplication; no probability moves between cells.
Normaliserη = 1 / Σi p(zt | xi) bel(xi)One over the evidence; makes the posterior sum to one.
Gaussian fusion1/σpost2 = 1/σprior2 + 1/σz2Fusing sharpens: precisions add, so uncertainty shrinks.
Wrapi → (i mod n)On a loop, mass leaving one end re-enters at the other.
EntropyH(bel) = −Σi bel(xi) log2 bel(xi)Predict raises it, update lowers it; the plateau is the best achievable.
8

Further reading

Where to go deeper

9

Check your understanding

0/6 answered