Fourier Transform and Convolution Theorem
Rewrite a signal by frequency instead of by time. Convolution then becomes pointwise multiplication, which is why fast filtering works.
Why Does This Exist?
Smoothing, filtering, and detecting patterns all convolve: slide a kernel across a signal and accumulate. Directly that costs length-times-length work, which is why long audio filters and large image blurs were once impractical. Frequency thinking removes the bottleneck.
The Fourier transform rewrites the signal by frequency instead of by time. In that domain the convolution theorem turns sliding convolution into pointwise multiplication: transform both sides, multiply bin by bin, invert once. Fast convolution through the discrete Fourier transform and FFT is the payoff, built on the sliding mechanics in convolution mathematics.
The one idea you need first
A sinusoid at frequency is a pure tone. Here means how much of that tone the signal contains, with magnitude for strength and angle for shift. The building sines and cosines come from trigonometry: . The transform just measures the signal against each tone in turn.
Think of It Like This
Chords instead of key presses
A piano roll lists every key press in time order. A chord chart lists which notes sound together and how loudly, ignoring when each began. Same music, different index: time versus frequency.
Convolution in piano-roll form is tedious: every echo of every note overlaps every other. In chord-chart form each note multiplies independently, since echoes only scale and shift each tone. Multiply the charts, convert back to a roll, and the echoes are all placed. Where the analogy stops: real spectra carry phase as well as magnitude, and discarding phase destroys timing while the chord chart still looks right.
How It Actually Works
For length , the discrete transform and its inverse pair measurements with tones. Here is the time sample at index , is the spectrum bin at frequency , and is the imaginary unit:
The convolution theorem says pointwise multiplication in one domain is convolution in the other. With for convolution and for pointwise product, and for the transform:
Direct convolution of length costs multiplies: 64 for . The FFT costs : steps for the same size, over two times fewer, widening fast as grows. Zero-pad both inputs to a shared length first, so linear convolution matches the circular form the theorem computes.
Worked example
Pad to length 4 with and . Direct linear convolution slides and accumulates:
So . Through the theorem, transform both to and , multiply pointwise at each of the 4 bins, and invert: the inverse transform of returns , matching the slide-and-sum exactly. Same numbers, two routes, which is the theorem as an executable identity.
Code
The point is the check: verify the theorem on the worked example with standard-library complex arithmetic only.
import cmathimport math
def dft(x: list[float]) -> list[complex]: n = len(x) return [sum(v * cmath.exp(-2j * math.pi * k * t / n) for t, v in enumerate(x)) for k in range(n)]
def idft(X: list[complex]) -> list[complex]: n = len(X) return [sum(v * cmath.exp(2j * math.pi * k * t / n) for k, v in enumerate(X)) / n for t in range(n)]
f = [2.0, 1.0, 0.0, 0.0]g = [3.0, 4.0, 0.0, 0.0]prod = [a * b for a, b in zip(dft(f), dft(g))]back = [round(v.real, 6) for v in idft(prod)]print(back)# -> [6.0, 11.0, 4.0, 0.0]print(8 * 8, 8 * 3)# -> 64 24The inverse lands on from the hand computation, and 64 naive multiplies drop to 24 FFT steps at . The code is the theorem, evaluated where the page reasons about it.
Watch Out For
Convolving without padding and reading wrap-around as signal
The DFT form is circular: energy that slides past the end wraps to the start. Without zero-padding to at least length , the tail of the true convolution lands on the head of the computed one and no error is raised.
Symptom: filtered output starts with a ghost of its own ending. Fix: pad both inputs to the FFT length before transforming, and trim after inverting. If the first samples look like the last, suspect wrap-around before suspecting the kernel.
Multiplying magnitudes and dropping phase
Magnitude spectra are tempting to display and easy to multiply alone, but timing lives in phase. Multiplying magnitudes while ignoring angles keeps energy right and places events wrong.
Symptom: the spectrum product looks correct yet the inverted signal smears or shifts. Fix: always carry full complex bins through the product, and treat any magnitude-only pipeline as a detector, never as a reconstruction.
The Quick Version
- The Fourier transform indexes a signal by frequency instead of by time.
- The convolution theorem turns convolution into pointwise multiplication of spectra.
- Zero-padded convolved with gives by either route.
- Direct convolution costs while the FFT costs : 24 steps versus 64 at .
- Pad to avoid circular wrap-around, and always carry phase through the product.