Skip to content

Discrete convolution

Give the "add up shifted copies of h" trick from 5.1 a name, a flip-and-slide picture, and a sum.

Before thisThe impulse response (5.1)

Before this5.1
Chapter 5 · Lesson 2 of 4

First, the picture

Two input spikes each launch a copy of h[n]h[n]. Step Which copy through Copy 0, Copy 1 and Sum, and watch how the sum is built.

Overlaying every copy at once

Every input sample launches its own copy of h. Convolution is that construction, given one name and one picture.

copy 0 (from x[0])copy 1 (from x[1])sum, y[n]
Which copy

Fixed h[n] = 1.00, 0.50, 0.25. Input: x[0] = 2, x[1] = 1.

Describe this picture

One plot of samples with two launched copies of hh, “copy 0 (from x[0])” and “copy 1 (from x[1])”, and their sum, “sum, y[n]”. Three “Which copy” buttons, “Copy 0”, “Copy 1” and “Sum”, highlight one of them.

Naming what you already built

Last page, I fed a system a short input, one number-worth of “spike” at a time, and watched each spike launch its own scaled, shifted copy of the impulse response h[n]h[n]. The output was just those copies, added up. I used h[n]=1, 0.5, 0.25h[n]=1,\,0.5,\,0.25 and an input x[0]=2x[0]=2, x[1]=1x[1]=1, and got y=2,2,1,0.25y=2,2,1,0.25 by stacking two launched copies.

That construction is common enough to earn its own name and its own symbol. It’s called convolution, and I write it y=x∗hy=x*h. Nothing new is happening here: the picture at the top of the page just draws both launched copies and their sum at once, instead of placing them one spike at a time.

Notice its Sum is exactly the same output trace I built by hand last page, 2,2,1,0.252,2,1,0.25: convolution is that construction, now with a name.

Flip and slide: a mechanical way to compute it

Overlaying every copy at once works, but it means drawing a separate copy for every input sample. There’s a faster, purely mechanical way to get the same numbers, one output value at a time, and it’s the picture worth having in your head whenever you see convolution.

Here’s the recipe in words. To find the output at one instant, flip hh left-to-right, slide it so it sits at that instant, multiply every pair of numbers that now overlap, and add up the products. That total is y[n]y[n] at that instant. Slide to the next instant and do it again.

Written down, that recipe is

y[n]=∑kx[k] h[n−k]y[n]=\sum_k x[k]\,h[n-k]

Read it the same way you just did it by hand. nn is the instant you’re asking about. kk runs over every index where xx or hh has a value. h[n−k]h[n-k] is hh, flipped and slid to instant nn: plugging in k=nk=n gives h[0]h[0], sitting right under x[n]x[n], and every other kk lands on some other flipped, shifted sample of hh. Multiplying by x[k]x[k] and summing over every kk is exactly “multiply the overlaps and add them up.” The ∗* symbol is shorthand for this whole sum: x∗hx*h means “compute y[n]y[n] this way for every nn.”

Drag Position n from 0 to 3, one step at a time, and read Total at this position.

Flip and slide

Flip h left-to-right, slide it under x, and multiply every overlapping pair. Their total is y[n] at that position.

x[k]h[0 - k]product
y[n] so farthis position
0
Total at this position
2.00
Describe this picture

Two plots against the index kk. The upper one shows x[k]x[k], fixed, with h[n−k]h[n - k] flipped and slid underneath it and the products of the overlapping pairs. The lower one shows y[n]y[n] so far, with this position marked. The “Position n” slider runs from 0 to 3, and the readout “Total at this position” gives the sum of the products.

Notice it retraces the same four numbers, 2,2,1,0.252,2,1,0.25, one at a time instead of all at once, exactly matching the sum trace from the last instrument.

It does not matter which one you flip

The recipe said “flip hh.” Nothing in the arithmetic actually needs it to be hh that gets flipped rather than xx: flipping and sliding xx under a fixed hh multiplies and adds up the exact same pairs, just written down the other way around, y[n]=∑kh[k] x[n−k]y[n]=\sum_k h[k]\,x[n-k].

Slide Position n, then switch Flip between Flip h and Flip x at the same position.

It does not matter which one you flip

Flip h and slide it past x, or flip x and slide it past h: either way the plotted y[n] is pixel for pixel identical.

x[k]h[0 - k]product
0
Flip
Total at this position
2.00
Describe this picture

The same two plots as before: one sequence fixed, the other flipped and slid underneath it with the products of the overlapping pairs, and the output trace y[n]y[n] below. The “Position n” slider moves the slide, the “Flip” buttons choose “Flip h” or “Flip x”, and the readout “Total at this position” gives the sum of the products.

Notice the picture underneath looks completely different, but the plotted output trace never moves: x∗hx*h and h∗xh*x give the identical numbers. Convolution is commutative, so it never matters which sequence you call “the input” and which you call “the impulse response.”

How long is the output

Flip-and-slide only has something to multiply while the flipped, sliding sequence still overlaps the fixed one at all. Slide it in from far enough away and there’s no overlap yet, so y[n]=0y[n]=0; slide it out far enough past the other side and there’s no overlap left, so y[n]=0y[n]=0 again. In between, for two finite sequences of length NxN_x and NhN_h, there are exactly Nx+Nh−1N_x+N_h-1 sliding positions with any overlap at all, so that’s how many samples of yy can be nonzero.

But if hh never quite settles to zero (an infinite impulse response, previewed here and covered properly later), there’s no “far enough past the other side”: the output can keep going forever too, even while it keeps shrinking.

Switch h type between Finite pulse and Decaying, and read the verdict readout.

How long is the output

Two finite sequences give a finite output with a hard edge. A never-quite-zero h keeps the output going too.

h type
The output
hits exactly 0 right after n = 3
Describe this picture

One plot of the output of a 3-sample pulse convolved with hh, and two “h type” buttons: “Finite pulse”, a 2-sample pulse, and “Decaying”. The readout “The output” gives the verdict on how the output ends.

Notice the finite pulse’s output hits exactly zero right after n=3n=3, matching a 3-sample xx and a 2-sample hh, Nx+Nh−2=3N_x+N_h-2=3, while the decaying hh‘s output only ever gets smaller, never hitting zero on the nose.

Same rule, different h

Every one of those instruments ran the exact same flip-and-slide machinery. What changes the effect entirely is only the numbers you put in hh.

Average a handful of neighboring samples together and you get a moving average, a simple smoother: it’s what a running weather report does when it quotes “the average of the last three days’ temperatures” instead of today’s alone, damping out day-to-day noise. Put a small copy of the signal a few samples later, scaled down, and you get an echo, the same effect as sound bouncing off a far wall and arriving again, quieter, a moment after the original. Subtract the sample before it from each sample, h=[1,−1]h=[1,-1], and you get back the first difference from 2.2: the same “how fast is it changing” measurement, now written as a convolution.

Step Filter through Moving average, Echo and Differencer on the same noisy clip.

Same rule, different h

It's the same flip-and-slide machinery every time. Only the numbers in h change, and the effect looks completely different.

Filter
Describe this picture

Two plots: a fixed noisy clip x[n]x[n], and xx convolved with the chosen hh. Three “Filter” buttons choose “Moving average”, “Echo” or “Differencer”.

Notice the output trace looks completely different each time, even though it’s the identical flip-and-slide rule running underneath, just with a different hh.

Two more views of the same numbers

There are two other ways to describe exactly the same operation, and both are useful later.

Write a sequence’s samples as the coefficients of a polynomial in a placeholder variable zz: the sequence 1,2,31,2,3 becomes 1+2z+3z21+2z+3z^2. Multiply two such polynomials the ordinary way you learned in algebra, collecting like powers of zz, and the coefficients of the product are exactly the convolution of the two original sequences. It’s the same arithmetic you already know, just with znz^n standing in for “the sample at index nn.”

The other view stacks hh‘s job into a grid of numbers, a matrix HH, where every column is a shifted copy of hh; multiplying that matrix by the vector xx produces y=Hxy=Hx, the same output as convolution, one row of the grid at a time. This is only a light preview, matrices get their own full treatment in a linear algebra course, but it’s worth seeing once here.

Switch View between Polynomial and Matrix.

Two more views of the same numbers

Convolution is also polynomial multiplication of the coefficients, and a matrix times a vector. Same numbers, three descriptions.

x(z) = 1 + 2z + 3z^2

h(z) = 1 + z

x(z) h(z) = 1 + 3z + 5z^2 + 3z^3

View
Describe this picture

The output y[n]y[n] and two “View” buttons. Polynomial writes the convolution as a product of two polynomials in zz; Matrix writes it as a grid of shifted copies of hh times the column xx.

Notice both land on the exact same output numbers as every earlier instrument, just written two more ways.

The maths behind it · matrix-vector products

Stack the samples of xx into a column and put shifted copies of hh side by side in a grid of numbers (a matrix HH), and convolution becomes one grid-times-column product, y=Hxy = Hx. Linear algebra studies exactly this kind of product, and Chapter 14 comes back to this grid when it finds a faster way to compute it.

Worked example

Multiply the polynomials (1+2z+3z2)(1+2z+3z^2) and (1+z)(1+z), matching x=1,2,3x=1,2,3 and h=1,1h=1,1:

  • y[0]=1⋅1=1y[0]=1\cdot1=1
  • y[1]=1⋅1+2⋅1=3y[1]=1\cdot1+2\cdot1=3
  • y[2]=2⋅1+3⋅1=5y[2]=2\cdot1+3\cdot1=5
  • y[3]=3⋅1=3y[3]=3\cdot1=3

So x∗h=1,3,5,3x*h=1,3,5,3, a sequence of length 3+2−1=43+2-1=4, exactly the numbers both the polynomial and matrix views above land on.

For the moving-average case, take h=13,13,13h=\tfrac13,\tfrac13,\tfrac13 and let xx be a step, x[n]=1x[n]=1 for n≥0n\ge0 and 00 before. Then y[0]=13y[0]=\tfrac13, y[1]=23y[1]=\tfrac23, y[2]=1y[2]=1, and y[n]=1y[n]=1 for every n≥2n\ge2: the running average climbs up to, then settles at, the step’s steady value.

Where you’ll meet this

Every audio effect that smooths, echoes or filters a recording, every camera blur, and every “apply this impulse response” trick from the last page, runs on exactly this sum: flip one sequence, slide it past the other, multiply the overlaps, and add. Chapter 14 comes back to it from a different angle and finds a way to compute the exact same yy far faster once the sequences get long.

Reference card

QuantityFormulaNotes
Convolutiony[n]=∑kx[k] h[n−k]=∑kh[k] x[n−k]y[n]=\sum_k x[k]\,h[n-k]=\sum_k h[k]\,x[n-k]commutative: x∗h=h∗xx*h=h*x
Flip-and-slideflip one sequence, slide it past the other, multiply overlaps, sumthe mechanical way to compute the sum above
Output lengthNx+Nh−1N_x+N_h-1for two finite sequences of length NxN_x, NhN_h
Infinite hhoutput can stay nonzero forever, even while shrinkingpreviews finite vs. infinite impulse responses
Polynomial viewcoefficients of X(z)H(z)X(z)H(z)zn↔z^n \leftrightarrow the sample at index nn
Matrix viewy=Hxy=Hx, columns of HH are shifted copies of hhbridge to linear algebra

End of lesson 5.2

Where to go next.

Phasorium
LibraryEvery lesson, in order

Parts

About Phasorium
Look