dailymathdailymathMainPostsLogin
dailymath logo
dailymath
Login
Login
MainPosts

Curricula

RO M1UK A-LevelUK GCSEIB AAUS APUS SATUS HonorsFR SpéFR SecondeFR Expertes
AboutPostsPracticeSubmit a problemPrivacyTermsCookies

© 2026 dailymath

Back to posts
University / ProfessionalLessonEstimation & filtering

The Kalman Filter: Two Bad Guesses, One Good Estimate

How the Kalman filter fuses a drifting model and a noisy sensor into one estimate better than either — weighed by nothing but their variances.

dailymath · July 17, 2026 · 10 min read

Picture a drone somewhere over a field, and two ways of knowing where it is. The first is a physics model: you knew its velocity a moment ago, so you extrapolate — a fraction of a second later, it should be roughly where velocity times time says it should be. The catch is that this never accounts for the gust that just nudged it, the motor that's spinning a hair slower than commanded, the hundred small forces no model captures. Left uncorrected, that guess drifts, and drift compounds. Ten seconds of pure extrapolation and the model can be meters away from reality and have no idea.

The second is GPS. It has no memory and doesn't care about your model — it just reports a position, fresh, every tick. The catch: consumer GPS is noisy, typically off by a few meters in any direction, and it doesn't get less noisy the longer you wait. Trust it blindly and you get a jittery, zigzagging trace that never lies twice in the same direction but sometimes lies by a lot.

Neither is usable alone. The model is smooth but wanders off, unmoored from the truth. The sensor is anchored to the truth but jumpy, occasionally badly wrong. The idea that fixes this runs underneath almost everything that estimates a moving quantity from imperfect information: blend the two, weighted by how much you trust each one *right now*. Get the blend right and the result beats both inputs individually — smoother than the sensor, tighter to reality than the model ever manages alone. By the end of this you'll know the two equations that do that blending — one that runs every time new information should shift what you believe, and one that runs every time it shouldn't yet — the same pair that guided Apollo to the Moon and now runs, silently, in your pocket.

Fig. 1 · Position vs time — 1-D target

051015time (s)-100102030position (m)
filter estimate ±1σ
sensor reading
true position (unknowable)
The gray dashed line is the true position — unknowable in practice, drawn here only because this is a simulation. The scattered dots are raw sensor readings, noisy by design. The orange line is the filter's estimate, with its ±1σ confidence band shaded around it. The estimate tracks the truth far more tightly than the sensor's own scatter, and stays inside its own stated confidence band almost the whole way — the band isn't decoration, it's the filter telling you, honestly, how sure it is.

Why averaging by variance is the whole idea

Start smaller than a moving target: fuse two noisy measurements of one static quantity. Two rangefinders both aim at the same wall. One reads x1=4.8x_1 = 4.8x1​=4.8 m with known noise σ1=0.5\sigma_1 = 0.5σ1​=0.5 m; the other reads x2=5.4x_2 = 5.4x2​=5.4 m with noise σ2=1.0\sigma_2 = 1.0σ2​=1.0 m. Both instruments are unbiased — average infinitely many readings from either one and you'd land on the true distance — they just differ in how much any single reading wobbles around that truth. What's the best single estimate of the wall's true distance, given both readings at once?

Averaging them straight — (4.8+5.4)/2=5.1(4.8+5.4)/2 = 5.1(4.8+5.4)/2=5.1 — throws information away: it treats the noisier gauge as equally credible as the precise one. The better answer weights each reading by how much you trust it, and "how much you trust it" is exactly what the variance measures. This weighting isn't a heuristic — it's provably the estimate with the smallest possible variance among every way of combining the two readings:
x^=σ22σ12+σ22x1+σ12σ12+σ22x2\hat{x} = \frac{\sigma_2^2}{\sigma_1^2+\sigma_2^2}x_1 + \frac{\sigma_1^2}{\sigma_1^2+\sigma_2^2}x_2x^=σ12​+σ22​σ22​​x1​+σ12​+σ22​σ12​​x2​
Notice the swap: x1x_1x1​'s weight uses σ22\sigma_2^2σ22​, not σ12\sigma_1^2σ12​. The precise instrument (small σ1\sigma_1σ1​) earns a *big* weight because it's the *other* sensor's variance sitting in its numerator — the formula rewards confidence by inverting it. Plug in the numbers and the fused estimate lands around 4.92 m: pulled toward the more trustworthy rangefinder, but not fully snapped to it, because the noisier one still carries some information. Make one sensor infinitely noisy (σ2→∞\sigma_2 \to \inftyσ2​→∞) and its weight vanishes entirely — the formula degrades gracefully to "just trust the good one," exactly as it should.

There's a cleaner way to see the same result, and it's the one the Kalman filter actually uses internally. Instead of variance (σ2\sigma^2σ2), think in precision (1/σ21/\sigma^21/σ2) — how sure you are, where bigger means more confident. Fusing two independent estimates simply adds their precisions:
1σ2=1σ12+1σ22\frac{1}{\sigma^2} = \frac{1}{\sigma_1^2} + \frac{1}{\sigma_2^2}σ21​=σ12​1​+σ22​1​
This is the exact shape of resistors combining in parallel — total conductance sums, and the combined resistance is always lower than either resistor alone. Same rule here: combined *precision* is always higher than either input's precision, which means the fused variance σ2\sigma^2σ2 is always smaller than both σ12\sigma_1^2σ12​ and σ22\sigma_2^2σ22​. Two okay estimates, correctly combined, produce a genuinely better one — not an average of the uncertainty, a reduction of it, no matter how mediocre either sensor is on its own.

That single idea — weigh by confidence, and confidence only grows when you combine sources — is the entire content of the Kalman filter. The only thing left to add is time: instead of fusing two static readings once, fuse a moving model's prediction against a fresh sensor reading, every tick, forever. Everything from here is that same idea running on a clock.

Predict, then update, forever

Fig. 2 · The two-step cycle

Kalman filter predict–update cyclePredict
x^k−=F x^k−1\hat{x}^-_k = F\,\hat{x}_{k-1}x^k−​=Fx^k−1​
Update
x^k=x^k−+Kyk\hat{x}_k = \hat{x}^-_k + K y_kx^k​=x^k−​+Kyk​
zkz_kzk​
x^k−, Pk−\hat{x}^-_k,\ P^-_kx^k−​, Pk−​
x^k, Pk (next step)\hat{x}_k,\ P_k \ \text{(next step)}x^k​, Pk​ (next step)
x^0\hat{x}_0x^0​
The cycle that runs at every tick. Predict pushes the last estimate forward using nothing but the motion model — no new information arrives, so uncertainty only grows. Update folds in the fresh measurement zkz_kzk​, weighted by the Kalman gain KKK, and uncertainty shrinks back down. The output feeds directly into the next predict, forever: grow, shrink, grow, shrink. Colors carry over from Fig. 1 — blue is the sensor's measurement arriving, orange is the estimate being formed.
The static-fusion idea repeats every tick of the clock, but now the thing being estimated is moving — position and velocity both — tracked through a matrix version of exactly the same math. Two steps, back to back, forever, and the whole filter is just those two steps on a loop.

Predict. Before any new measurement arrives, project the last estimate forward using the motion model alone:
x^k−=Fx^k−1Pk−=FPk−1F⊤+Q\hat{x}^-_k = F\hat{x}_{k-1} \qquad P^-_k = FP_{k-1}F^\top + Qx^k−​=Fx^k−1​Pk−​=FPk−1​F⊤+Q
FFF *is* the model — for a constant-velocity target it just carries position forward by velocity times the time step. PPP is the covariance, the multi-dimensional stand-in for σ2\sigma^2σ2: how uncertain the estimate is, position and velocity together. Predicting always adds uncertainty (the +Q+Q+Q term) — extrapolating without new evidence can only ever make you less sure, never more.

Update. When a measurement zkz_kzk​ arrives, fuse it with the predicted state exactly the way the two rangefinders were fused above:
Kk=Pk−H⊤(HPk−H⊤+R)−1x^k=x^k−+Kk(zk−Hx^k−)K_k = P^-_k H^\top (HP^-_kH^\top + R)^{-1} \qquad \hat{x}_k = \hat{x}^-_k + K_k(z_k - H\hat{x}^-_k)Kk​=Pk−​H⊤(HPk−​H⊤+R)−1x^k​=x^k−​+Kk​(zk​−Hx^k−​)
HHH just says which parts of the state the sensor can actually see — for a GPS reading position but not velocity, HHH picks out position and ignores the rest. RRR is the sensor's own variance — how much you distrust the measurement. KkK_kKk​, the Kalman gain, is the matrix version of the weight in the resistor formula: recomputed fresh every tick from Pk−P^-_kPk−​ and RRR, it decides how much of the *innovation* (zk−Hx^k−)(z_k - H\hat{x}^-_k)(zk​−Hx^k−​) — the gap between what was predicted and what was actually measured — gets folded into the new estimate. Fold in the innovation, shrink PPP, and you're back at the top of the loop, ready to predict again. Grow, shrink, grow, shrink — that alternation is the filter's entire life cycle, and it never stops running as long as the system does.

K is a trust dial, not a smoothing knob

Stare at the update equation and KkK_kKk​ is doing all the interesting work. When KkK_kKk​ is close to 1, nearly the whole innovation gets folded in — the filter is trusting the new measurement far more than its own prediction. When KkK_kKk​ is close to 0, the innovation gets almost ignored — the filter trusts its model and shrugs off the new reading as probably noise. Every value in between is a genuine blend, not a switch between two extremes.

The part that surprises people the first time: nobody sets KKK. It isn't a dial you tune by hand the way you'd hand-tune a PID controller's gains. It falls straight out of Pk−P^-_kPk−​ and RRR every single tick, computed from the actual uncertainties in play, not chosen. A confident model (small PPP) against a noisy sensor (large RRR) produces a small KKK automatically. A shaky model against a precise sensor produces a large KKK automatically. The trust dial turns itself, tick after tick, without anyone touching it — which is exactly why the filter can start out unsure and grow more decisive as its own uncertainty shrinks, all from the same unchanging equations.

What you *do* set is QQQ, the process noise — your stated humility about your own model. QQQ says: even between measurements, I don't fully believe my own extrapolation; leave room for the world to surprise me. Set QQQ too small and the filter grows overconfident in its model, discounts real deviations as sensor noise, and lags behind a target that's actually maneuvering. Set QQQ to zero outright and the filter goes deaf: PPP stops growing during predict, KKK collapses toward zero for good, and the filter clings to its original model no matter what the sensor keeps reporting. Set QQQ too large, and the opposite failure appears — the filter barely trusts its own model at all, tracking every sensor jitter as if it were real motion, which defeats the point of having a model in the first place. Humility about the model isn't optional, and it isn't free either — it's the knob that keeps the filter listening, tuned to match how much the real system actually wanders.

Fig. 3 · Gain vs sensor quality

051015time (s)00.20.40.60.81Kalman gain K
σ = 1 m (trusts the sensor)
σ = 3 m
σ = 9 m (trusts the model)
Same target, same motion model, three sensors of different quality. The σ = 1 m trace (a confident sensor) converges to a high steady-state gain — the filter leans hard on every new reading. The σ = 9 m trace (a noisy sensor) converges to a much lower gain — the filter leans on its own model instead and barely moves per measurement. Nobody set these three numbers by hand: each curve is the automatic output of the same equations run against a different sensor variance.

The hidden-state trick

The sensor in Fig. 1 only ever measures position — never velocity, not once. Yet the filter's velocity estimate stays close to the true value throughout. That isn't a free lunch; it's the off-diagonal term in PPP. During predict, FFF mixes position and velocity together (the predicted position depends on the previous velocity), so the covariance's off-diagonal entry stops being zero — it encodes a *correlation* between how wrong the position guess is and how wrong the velocity guess is. When a position measurement corrects the position, that same correlation drags the velocity estimate along with it, even though velocity was never directly observed. This is the trick behind every Kalman filter that tracks more states than it measures: correlated uncertainty spreads a correction from an observed state into a hidden one.
The filter's proof of concept was as demanding as it gets. The Apollo Guidance Computer ran a Kalman filter — invented less than a decade earlier by Rudolf Kálmán — to fuse an inertial platform's drifting model of position against periodic star-sighting measurements, on a computer with less memory than a modern light bulb. That debut set the pattern every later use follows: a model that drifts, a sensor that's sparse or noisy, fused into something better than either alone.

Your phone runs the same idea dozens of times a second: GPS is noisy and slow to update, so the phone fuses it with the accelerometer and gyroscope's dead-reckoning model to produce the smooth blue dot you actually see on the map. Drones and rockets fuse an inertial-measurement-unit's model against GPS or barometric altitude the same way. A robot doing SLAM — simultaneous localization and mapping — runs a Kalman filter, or one of its extended or unscented cousins, to fuse wheel-odometry drift against landmark sightings. Quant finance runs the identical state-space machinery to fuse a drifting model of some latent signal — an interest rate, a volatility level — against noisy market observations. Even a phone or laptop battery's "time remaining" estimate is usually a Kalman filter fusing a discharge model against noisy voltage readings, which is why that number gets steadier, not jumpier, the longer you watch it.
1

Check your intuition

Question 1 of 4

The Kalman gain KKK is close to 1. What is the filter doing?

The Kalman filter is variance with a job — a model that drifts and a sensor that lies, weighed against each other by nothing but their variances, married into something better than either. If chasing that kind of intuition down to the arithmetic is your thing, solve a fresh math problem every morning with dailymath. One drop, one coffee, one win.

Try dailymath
EstimationKalman filterControl theoryRoboticsQuantLesson