Convolutions: from infections to observations

The case curve we actually see — symptom onsets, reports — is never the same as the latent infections that drove it. Each infection is observed only after an individual delay, and adding those delayed contributions up across the whole population is a convolution. It shifts the curve later and smears it wider. This is the forward data-generating process; inference later runs it in reverse.

The idea in one equation

Population-level delays turn into a convolution of two time series

Work in discrete daily time. Let I(t) be the number of latent infections on day t, and let f(s) be the delay distribution — the probability that an infected person is observed (e.g. develops symptoms) exactly s days later. An infection on day ts shows up on day t with probability f(s). Sum those contributions over every earlier day and you get the observed count C(t):

C(t) = Σs=0 I(t − s) · f(s)

That single sum is the convolution, written C = If. Read it as a recipe: for each output day t, walk back over the infection history, weight each past day by how likely its infections are to surface today, and add. Two things happen as a result, and they are the whole story of this page:

A clean spike of infections never produces a clean spike of onsets. The delay distribution acts like a blur filter sliding along the time axis. The wider the delay, the later and flatter the curve you observe — which is exactly why nowcasting the "true" recent signal from delayed reports is hard.
SymbolMeaningIn the figures
I(t)latent incidence (infections) on day tblue filled bars
f(s)discretised delay distribution (a PMF over days)teal kernel weights
C(t)observed counts (onsets / reports) on day torange bold line

The delay, as a daily PMF f(s)

A continuous delay distribution, discretised into per-day probabilities

The incubation period is naturally a continuous distribution, but our counts are tallied by day. We therefore discretise it into a probability mass function f(s), one bar per whole day of delay. Here we use a lognormal delay with a chosen mean m and standard deviation ssd. Match the moments, then take daily differences of the CDF:

σ² = log(1 + ssd² / m²)    μ = log(m) − σ²/2
F(x) = Φ( (log x − μ) / σ )    f(s) = F(s+1) − F(s)

The bars are then renormalised to sum to 1 over the days we keep (0 … Smax). Slide the mean and the spread and watch the shape: a small mean piles probability on the first day or two; a large spread flattens it into a long right tail. This f(s) is the kernel that does all the shifting and smearing in the next figures.

delay PMF f(s) mean delay m
mode ≈ day P(delay = 0) = P(delay ≤ mean) =

Convolution builder forward process

Feed an infection curve through the delay and watch the onsets appear

Here is the whole forward process at a glance. The blue filled bars are a latent infection curve I(t) — control its peak day and width, and add an optional second wave. The orange line is the resulting onset curve C(t) after convolving with the same delay PMF as above. Move any slider and watch the orange curve slide right (by about the delay mean) and flatten out (by about the delay spread).

infections I(t) onsets C(t) peak of I vs peak of C
peak of I ≈ day peak of C ≈ day shift ≈ days
The shift between the two peaks tracks the mean of the delay; the broadening tracks its spread. Set the delay spread small and the orange curve keeps the shape of the blue one, just translated. Crank the spread up and even a tall, narrow outbreak is observed as a low, lazy hump.

Slide, multiply, sum how C(t) is built

The convolution sum, one output day at a time

This is the heart of it. To get the single observed value C(t*) on one output day t*, the convolution does three things:

Drag t* across the axis — or press ▶ play — and watch the flipped kernel sweep left to right, its weighted products rise and fall, and their running sum trace out the entire onset curve, point by point.

infections I(τ) weighted product I(τ)·f(t*−τ) onsets C(t) so far current sum C(t*)
C(t*) = Σ I(τ)·f(t*−τ) =
largest single contribution: day
Notice that the biggest contribution to today's onsets usually comes not from today's infections but from those around m days ago — wherever the flipped kernel's peak lands on the infection curve. That lag is the shift you saw in the builder, now visible term by term.

Forward and back deconvolution

Why inference is the convolution run in reverse

Everything above is the forward direction: given infections and a delay, produce the observations. In practice we have the opposite problem — we see the onsets C(t) and want the infections I(t) that we never observed directly. Recovering I from C and f is deconvolution, and the course fits it as a Bayesian model.

The forward convolution is the easy, honest part of the model — a clear statement of how delays generate the data. The hard, interesting work is inverting it well: estimating the latent infection curve, with calibrated uncertainty, from the shifted and smeared signal you actually get to see.
Forward (this page)Inverse (inference)
You knowI(t) and f(s)C(t) and f(s)
You wantC(t)I(t)
Operationconvolution Ifdeconvolution
Difficultyone direct sumill-posed; needs priors & MCMC
Uncertaintynone (deterministic)large, esp. for recent days