Part 7 · Chapter 26

The Discrete Fourier Transform and FFT

Every transform so far has been an object to write down and reason about; the discrete Fourier transform is the one a machine can actually evaluate, and the whole of this chapter follows from asking what has to be given up — a finite record and a finite set of frequencies — and what that sacrifice costs.

Signals and Systems Prof. Mithun Mondal Reading time ≈ 65 min
i What you'll learn
  • Why the DTFT of Chapter 16 cannot be computed, and the two restrictions — finite length and finitely many frequencies — that turn it into the DFT.
  • The DFT pair, the twiddle factor \(W_N = e^{-j2\pi/N}\), and a proof of the inversion formula that rests on nothing but a geometric series.
  • Time-domain aliasing: sampling the spectrum forces the time signal to become periodic, which is the source of every "circular" oddity that follows.
  • Circular shift and circular convolution, and the exact zero-padding condition \(N \ge L+M-1\) that makes circular convolution reproduce the linear convolution of Chapter 7.
  • Overlap-add and overlap-save — how a filter is run on a signal that never ends using a transform that insists on finite blocks.
  • The radix-2 decimation-in-time FFT derived from scratch: the parity split, the butterfly, bit-reversed input order, and the drop from \(N^2\) to \(\tfrac{N}{2}\log_2 N\) multiplications.
  • What the DFT of a measured signal really tells you: leakage, windows, resolution, and why zero-padding gives more points but no more detail.
Section 26-1

A Spectrum a Machine Can Hold

Chapter 16 defined the discrete-time Fourier transform, and Chapters 23 to 25 built the z-transform on top of it. Both are complete answers to the question "what frequencies is this sequence made of". Neither can be evaluated by a computer, and the reason is worth stating precisely, because the fix is forced on us by the difficulty rather than chosen for convenience.

The DTFT of Chapter 16 — correct, and uncomputable
\[ X(e^{j\Omega}) \;=\; \sum_{n=-\infty}^{\infty} x[n]\,e^{-j\Omega n} \]

Two things stand in the way. The sum runs over infinitely many samples, and no machine has an infinite record. And \(\Omega\) is a continuous variable, so \(X(e^{j\Omega})\) is a function on an interval — uncountably many numbers, and no machine has memory for that either. A computable transform therefore has to be finite twice over: finitely many samples going in, finitely many numbers coming out.

Both restrictions are natural in practice. Any real measurement is a finite record: you switch on the instrument, you collect \(N\) samples, you switch it off. And any real display of a spectrum is a finite list: an analyser draws a few hundred or a few thousand points, not a continuum. So the question is not whether to make these two restrictions but what they cost, and the honest answer — worked out in Section 26-4 and returned to in Section 26-9 — is that they cost rather more than a beginner expects.

The transform that results is the discrete Fourier transform. It is not a fifth transform to be memorised alongside the Fourier series, the Fourier transform, the DTFT and the z-transform. It is the DTFT of a finite-length sequence, read off at finitely many frequencies, and every one of its peculiarities can be traced back to that single sentence.

A naming warning. The DFT is a transform; the FFT is an algorithm for computing that transform. They are not alternatives and they do not give different answers — an FFT returns exactly the DFT, to within rounding. Speaking of "taking the FFT of a signal" is universal shorthand, but when a result is being derived it is always the DFT that is meant.
Section 26-2

Sampling the DTFT: the DFT

Take a sequence that is zero outside \(0 \le n \le N-1\). Its DTFT sum then has only \(N\) non-zero terms, and the first difficulty disappears by itself.

The DTFT of a length-\(N\) sequence
\[ X(e^{j\Omega}) \;=\; \sum_{n=0}^{N-1} x[n]\,e^{-j\Omega n} \]

This is a finite sum, but still a function of a continuous \(\Omega\). So sample it. The DTFT is periodic in \(\Omega\) with period \(2\pi\), so one period carries everything; divide that period into \(N\) equal parts and evaluate there.

Why exactly \(N\) points? Because the sequence is specified by \(N\) numbers, so \(N\) numbers of spectrum is precisely enough to specify it back. Fewer would lose information irrecoverably; more would be redundant, since the extra values could be reconstructed from the first \(N\). The count is not a compromise — it is the exact bookkeeping that makes the transform invertible.

🔑
The discrete Fourier transform pair
\[ X[k] = \sum_{n=0}^{N-1} x[n]\,e^{-j\frac{2\pi}{N}kn}, \qquad x[n] = \frac{1}{N}\sum_{k=0}^{N-1} X[k]\,e^{+j\frac{2\pi}{N}kn} \]

Both indices run over \(0,1,\dots,N-1\). The forward transform carries the minus sign and no scale factor; the inverse carries the plus sign and the \(1/N\). The \(k\)-th coefficient is the DTFT evaluated at \(\Omega_k = 2\pi k/N\), so \(X[k] = X(e^{j\Omega})\big|_{\Omega = 2\pi k/N}\).

The exponential appears so often that it is given a name. The twiddle factor is

The twiddle factor and its three useful identities
\[ W_N \;=\; e^{-j\frac{2\pi}{N}} \qquad\Longrightarrow\qquad W_N^{N} = 1, \qquad W_N^{k+N} = W_N^{k}, \qquad W_N^{k+N/2} = -\,W_N^{k} \]

With it the pair reads \(X[k] = \sum_n x[n]W_N^{kn}\) and \(x[n] = \tfrac1N\sum_k X[k]W_N^{-kn}\). Geometrically, \(W_N^{kn}\) walks around the unit circle in steps of \(2\pi/N\); the three identities say that after \(N\) steps you are home, that the walk repeats, and that half a lap is a sign change. The third identity is small, obvious and the entire reason the FFT of Section 26-7 exists.

Two coefficients can be written down without any arithmetic. Setting \(k=0\) kills the exponential, so \(X[0] = \sum_n x[n]\) is the sum of the samples — the DC value, and a free check on every DFT you compute. If \(N\) is even, setting \(k = N/2\) gives \(e^{-j\pi n} = (-1)^n\), so \(X[N/2] = \sum_n (-1)^n x[n]\) is the alternating sum, the coefficient at \(\Omega = \pi\), the highest frequency a sampled signal can carry.

Ω |X(e^jΩ)| 0 1 2 3 4 5 6 7 bin index k — spacing 2π/N, here N = 8
The DFT is the DTFT read off at \(N\) equally spaced points — the grey curve is what exists, the gold stems are what you get

The figure is worth carrying around. The grey curve is the true spectrum of the finite record; the gold stems are the \(N\) numbers the DFT returns. Nothing in the gold stems says how the curve behaves between them, and a great many practical mistakes come from forgetting that the DFT reports a sampled spectrum, not a continuous one.

Section 26-3

Why the Inverse Works

The inversion formula was asserted above; it deserves a proof, and the proof is short. Everything rests on one orthogonality statement about the twiddle factors, which is itself nothing more than the sum of a geometric series.

🔑
Orthogonality of the DFT exponentials
\[ \frac{1}{N}\sum_{k=0}^{N-1} e^{\,j\frac{2\pi}{N}k(n-m)} \;=\; \begin{cases} 1, & n \equiv m \pmod N \\[2pt] 0, & \text{otherwise} \end{cases} \]

The \(N\) discrete exponentials are mutually orthogonal over one period, which is exactly the property the Fourier series needed in Chapter 10 and the Fourier transform needed in Chapter 13. The DFT is the same idea with a finite basis.

To see it, put \(r = e^{j2\pi(n-m)/N}\) and read the sum as \(\sum_{k=0}^{N-1} r^{k}\). If \(n-m\) is a multiple of \(N\), then \(r = 1\) and every term is 1, so the sum is \(N\) and the normalised value is 1. Otherwise \(r \neq 1\) and the finite geometric series applies:

The geometric sum that does all the work
\[ \sum_{k=0}^{N-1} r^{k} \;=\; \frac{1-r^{N}}{1-r}, \qquad r^{N} = e^{\,j2\pi(n-m)} = 1 \quad\Longrightarrow\quad \sum_{k=0}^{N-1} r^{k} = 0 \]

The numerator vanishes because \(n-m\) is an integer, and the denominator does not vanish because \(r \ne 1\). Now substitute the forward transform into the claimed inverse and exchange the two finite sums, which is always legal:

The inversion, in three lines
\[ \frac{1}{N}\sum_{k=0}^{N-1} X[k]\,e^{\,j\frac{2\pi}{N}kn} = \frac{1}{N}\sum_{k=0}^{N-1}\sum_{m=0}^{N-1} x[m]\,e^{-j\frac{2\pi}{N}km}\,e^{\,j\frac{2\pi}{N}kn} = \sum_{m=0}^{N-1} x[m]\left[\frac{1}{N}\sum_{k=0}^{N-1} e^{\,j\frac{2\pi}{N}k(n-m)}\right] = x[n] \]

The bracket is the orthogonality sum, which is 1 when \(m = n\) and 0 for every other \(m\) in the range, so the outer sum collapses to the single term \(x[n]\). That is the whole proof, and it explains where the \(1/N\) comes from: the exponentials are orthogonal but not normalised, and each has squared length \(N\).

Where the \(1/N\) lives is a convention. Some texts and some software libraries put \(1/\sqrt{N}\) on both transforms, which makes the DFT a unitary matrix and Parseval's relation perfectly symmetric. Others place \(1/N\) on the forward transform. Nothing physical changes, but a factor of \(N\) is the single most common bug in DFT code, so check which convention your library uses before trusting an amplitude.
Section 26-4

The Price: Time-Domain Aliasing

So far the derivation assumed the sequence really was zero outside \(0 \le n \le N-1\). Suppose it is not — suppose \(x[n]\) runs on forever and we sample its DTFT at \(N\) points anyway. What sequence does the inverse DFT hand back?

The calculation is the same one as in the previous section, but now the inner sum over \(m\) runs over all integers, and the orthogonality relation says the bracket is 1 whenever \(m\) and \(n\) differ by a multiple of \(N\) — not only when they are equal.

What the inverse DFT actually returns
\[ x_p[n] \;=\; \frac{1}{N}\sum_{k=0}^{N-1} X\!\left(e^{\,j\frac{2\pi k}{N}}\right) e^{\,j\frac{2\pi}{N}kn} \;=\; \sum_{m=-\infty}^{\infty} x[m]\!\!\sum_{r=-\infty}^{\infty}\!\!\delta[n-m+rN] \;=\; \sum_{r=-\infty}^{\infty} x[n+rN] \]
🔑
Sampling in frequency causes periodicity in time
\[ X[k] = X\!\left(e^{\,j2\pi k/N}\right) \quad\Longleftrightarrow\quad x_p[n] = \sum_{r=-\infty}^{\infty} x[n+rN] \]

The inverse DFT returns not \(x[n]\) but its periodic extension with period \(N\), formed by shifting the signal by every multiple of \(N\) and adding. If \(x[n]\) is shorter than \(N\) the shifted copies do not overlap and nothing is lost. If it is longer, the tails fold back on top of the head and the damage is irreversible.

Chapter 20 established the dual of this statement: sampling a signal in time makes its spectrum periodic, and if the signal is not band-limited the spectral copies overlap and alias. Here the roles are exchanged. Sampling the spectrum in frequency makes the signal periodic, and if the signal is not time-limited to \(N\) samples the time copies overlap. The phenomenon is called time-domain aliasing, and the two statements are the same theorem read in two directions.

This is the fact that explains everything strange about the DFT. Because the inverse transform can only ever return a periodic sequence, the DFT necessarily treats its input as one period of a periodic signal. It does not know the difference between the record you gave it and an endless repetition of that record. Shifts therefore wrap round, convolutions wrap round, and the index \(n\) is really \(n \bmod N\) everywhere.

The implicit periodicity is not an interpretation, it is arithmetic. Ask a DFT for \(X[k]\) with \(k = N+3\) and the exponential \(e^{-j2\pi(N+3)n/N} = e^{-j2\pi 3n/N}\) gives you \(X[3]\); ask an inverse DFT for \(x[N+3]\) and you get \(x[3]\). Both sequences are periodic with period \(N\) whether or not that is what you wanted. Every "circular" property in the next section is a consequence of this and of nothing else.
Section 26-5

Circular Shift and Circular Convolution

Write \((n)_N\) for \(n\) reduced modulo \(N\). A circular shift by \(m\) is the sequence \(x[(n-m)_N]\): samples pushed off the right-hand end of the record reappear at the left. Picturing the \(N\) samples around a ring, as in the figure, makes it obvious — a circular shift is a rotation of the ring, and nothing is ever lost or created.

x[0]x[1] x[2]x[3] x[4]x[5] x[6]x[7] original rotate 2 x[6]x[7] x[0]x[1] x[2]x[3] x[4]x[5] x[(n−2)₈] nothing enters, nothing leaves — the record is a closed ring
A circular shift is a rotation — the only kind of shift a DFT can represent

The transform of a circular shift is easy, and the proof shows where the wrap-around earns its keep. Put \(p = (n-m)_N\); as \(n\) runs once through \(0,\dots,N-1\), so does \(p\). Then \(W_N^{kn} = W_N^{k(p+m)} = W_N^{km}W_N^{kp}\), where the step is legitimate because \(W_N^{kN}=1\) absorbs the modulo. Hence

Circular time shift, and its dual
\[ x[(n-m)_N] \;\stackrel{\text{DFT}}{\longleftrightarrow}\; W_N^{km}X[k] = e^{-j\frac{2\pi}{N}km}X[k], \qquad W_N^{-\ell n}x[n] \;\stackrel{\text{DFT}}{\longleftrightarrow}\; X[(k-\ell)_N] \]

Circular convolution follows the same pattern. Define, for two length-\(N\) sequences,

\(N\)-point circular convolution
\[ \big(x_1 \circledast x_2\big)[n] \;=\; \sum_{m=0}^{N-1} x_1[m]\,x_2\big[(n-m)_N\big], \qquad n = 0,1,\dots,N-1 \]

Substituting into the DFT and exchanging the sums gives the theorem in two steps. With \(p = (n-m)_N\) again,

The circular convolution theorem, derived
\[ \sum_{n=0}^{N-1}\sum_{m=0}^{N-1} x_1[m]\,x_2[(n-m)_N]\,W_N^{kn} = \sum_{m=0}^{N-1} x_1[m]W_N^{km}\sum_{p=0}^{N-1} x_2[p]W_N^{kp} = X_1[k]\,X_2[k] \]
🔑
Multiplication of DFTs is circular, not linear, convolution
\[ x_1[n] \circledast x_2[n] \;\stackrel{\text{DFT}}{\longleftrightarrow}\; X_1[k]\,X_2[k] \]

Chapter 7 established that an LTI system performs linear convolution. Multiplying two DFTs performs circular convolution instead. Section 26-6 shows exactly how much zero padding removes the difference — and until that padding is applied, the two are not the same and the error is not small.

The remaining properties are collected below. Linearity needs no comment. The symmetry property is the DFT version of the conjugate symmetry of Chapter 14: for a real signal the second half of the spectrum is the mirror image of the first, so of the \(N\) complex numbers only about \(N/2\) are independent — which is why a real-input FFT can be run at roughly half the cost.

PropertySequenceDFT
Linearity\(a\,x_1[n] + b\,x_2[n]\)\(a\,X_1[k] + b\,X_2[k]\)
Circular time shift\(x[(n-m)_N]\)\(W_N^{km}X[k]\)
Circular frequency shift\(W_N^{-\ell n}x[n]\)\(X[(k-\ell)_N]\)
Circular convolution\(x_1[n]\circledast x_2[n]\)\(X_1[k]\,X_2[k]\)
Multiplication\(x_1[n]\,x_2[n]\)\(\tfrac{1}{N}\,X_1[k]\circledast X_2[k]\)
Circular time reversal\(x[(-n)_N]\)\(X[(-k)_N]\)
Conjugate symmetry (real \(x\))\(x[n]\) real\(X[(N-k)_N] = X^{*}[k]\)
Parseval\(\sum_{n=0}^{N-1}|x[n]|^2\)\(\tfrac{1}{N}\sum_{k=0}^{N-1}|X[k]|^2\)
Section 26-6

Linear Convolution by DFT

Filtering is convolution, and convolution is expensive: an \(L\)-point signal through an \(M\)-tap filter costs about \(LM\) multiplications done directly. The circular convolution theorem promises to replace that with two forward transforms, \(N\) multiplications and one inverse transform, which — once the FFT of the next section is available — is dramatically cheaper. The obstacle is the word circular.

The fix comes straight from Section 26-4. Circular convolution is linear convolution wrapped modulo \(N\); if the linear result is short enough to fit inside \(N\) samples, there is nothing to wrap and the two coincide. Chapter 7 gave the length of a linear convolution: an \(L\)-point sequence convolved with an \(M\)-point sequence produces \(L+M-1\) points. So the condition writes itself.

🔑
When circular convolution equals linear convolution
\[ N \;\ge\; L + M - 1 \]

Pad both sequences with zeros to a common length \(N\) satisfying this inequality, take their DFTs, multiply point by point, and invert. The first \(L+M-1\) samples of the result are exactly the linear convolution; the rest are zero. If \(N\) is smaller, the last \(L+M-1-N\) samples fold back onto the first ones and corrupt them.

That handles one block. A real filtering problem has a signal that is far longer than the filter, or has no end at all — audio arriving from a microphone, samples arriving from an ADC. Transforming the whole thing is impossible, and would in any case introduce an unacceptable delay. The signal is therefore cut into blocks, and the two standard ways of stitching the blocked results back together are worth knowing by name.

Overlap-add cuts the input into non-overlapping blocks of length \(L\). Each block is convolved with the \(M\)-tap filter using an \(N\)-point DFT with \(N \ge L+M-1\), producing a block of output of length \(L+M-1\). Because convolution is linear and the input blocks add up to the input, the output blocks must add up to the output — but consecutive output blocks overlap by \(M-1\) samples, and in that overlap region they are added. The name is a literal description.

Overlap-save arranges the bookkeeping the other way. Input blocks of length \(N\) are taken with an overlap of \(M-1\) samples between consecutive blocks. Each block is circularly convolved with the padded filter, and the first \(M-1\) output samples of each block — precisely the ones corrupted by wrap-around — are thrown away. Nothing is added; the surviving pieces are simply concatenated. It needs no output buffer, which is why it is the usual choice in hardware.

Which \(N\)? Larger blocks amortise the transform overhead over more output samples, so the cost per sample falls — but the latency rises, because no output emerges until a whole block has arrived. Real designs pick \(N\) as the smallest power of two that meets the latency budget, typically four to eight times \(M\). Beyond that the cost per sample flattens out and only the delay keeps growing.
Section 26-7

The Cost, and the Idea Behind the FFT

Count the arithmetic in the DFT as written. Each of the \(N\) values \(X[k]\) is a sum of \(N\) products, so the direct computation costs \(N^2\) complex multiplications and \(N(N-1)\) complex additions. The quadratic growth is the problem. Doubling the record length quadruples the work, and a 4096-point transform needs almost seventeen million complex multiplications — perfectly respectable for a modern processor once, and hopeless if it must be done a thousand times a second.

Cooley and Tukey published the escape in 1965, though Gauss had found the same trick in 1805 and left it unpublished in Latin. The idea is divide and conquer, and the lever is the third twiddle identity, \(W_N^{k+N/2} = -W_N^{k}\).

Let \(N\) be even and split the sum by the parity of the sample index — the even-numbered samples in one group, the odd-numbered in the other. Writing \(n = 2r\) for the even terms and \(n = 2r+1\) for the odd:

Splitting the DFT by parity — decimation in time
\[ X[k] \;=\; \sum_{r=0}^{N/2-1} x[2r]\,W_N^{2rk} \;+\; \sum_{r=0}^{N/2-1} x[2r+1]\,W_N^{(2r+1)k} \;=\; \sum_{r=0}^{N/2-1} x[2r]\,W_N^{2rk} \;+\; W_N^{k}\sum_{r=0}^{N/2-1} x[2r+1]\,W_N^{2rk} \]

Now the crucial observation about the exponent. Since \(W_N^{2} = e^{-j4\pi/N} = e^{-j2\pi/(N/2)} = W_{N/2}\), both remaining sums are exactly \(N/2\)-point DFTs — of the even-indexed subsequence and of the odd-indexed subsequence respectively. Call them \(G[k]\) and \(H[k]\).

Two half-length transforms, recombined
\[ X[k] \;=\; G[k] \;+\; W_N^{k}\,H[k], \qquad G[k]=\!\!\sum_{r=0}^{N/2-1}\!\! x[2r]W_{N/2}^{rk}, \quad H[k]=\!\!\sum_{r=0}^{N/2-1}\!\! x[2r+1]W_{N/2}^{rk} \]

This looks like it only covers \(k = 0,\dots,N/2-1\), since \(G\) and \(H\) are \(N/2\)-point transforms and are only defined that far. But they are periodic with period \(N/2\), so \(G[k+N/2] = G[k]\) and \(H[k+N/2] = H[k]\); and the twiddle identity gives \(W_N^{k+N/2} = -W_N^{k}\). Substituting \(k+N/2\) therefore costs nothing new:

🔑
The radix-2 butterfly
\[ X[k] = G[k] + W_N^{k}H[k], \qquad X\!\left[k+\tfrac{N}{2}\right] = G[k] - W_N^{k}H[k], \qquad k = 0,\dots,\tfrac{N}{2}-1 \]

One complex multiplication \(W_N^k H[k]\) produces two output values, one by adding and one by subtracting. That two-for-one is the entire saving, and everything else in the FFT is bookkeeping around it.

Count what has been achieved. Computing two \(N/2\)-point DFTs directly costs \(2(N/2)^2 = N^2/2\) multiplications, and the recombination costs \(N/2\) more — already roughly half the original \(N^2\). But the two half-length transforms can be split the same way, and their halves after that. If \(N\) is a power of two the splitting continues until the transforms are of length 1, and a 1-point DFT is the identity: \(X[0] = x[0]\), no arithmetic at all.

The recursion and its solution
\[ T(N) = 2\,T\!\left(\tfrac{N}{2}\right) + \tfrac{N}{2}, \qquad T(1) = 0 \qquad\Longrightarrow\qquad T(N) = \tfrac{N}{2}\log_2 N \]

There are \(\log_2 N\) levels of splitting, each level containing \(N/2\) butterflies, each butterfly costing one complex multiplication and two complex additions. The total is \(\tfrac{N}{2}\log_2 N\) complex multiplications and \(N\log_2 N\) complex additions, and the transform has gone from quadratic to very nearly linear.

Section 26-8

Butterflies, Bit Reversal, and the Operation Count

The recombination formula is drawn as a two-input, two-output crossing whose shape gives it its name. The upper input passes straight through to both outputs; the lower input is multiplied by the twiddle factor once and then added at the top and subtracted at the bottom.

× W ᴺ ᵏ G[k] H[k] X[k] X[k+N/2] +
One butterfly — one complex multiply, two complex adds, two outputs

Stacking \(N/2\) butterflies per stage and \(\log_2 N\) stages produces the flow graph below for \(N = 8\). Read it left to right: the first stage combines samples in pairs, the second combines the pair results, the third combines those. Three stages, four butterflies each, twelve butterflies in all — against the sixty-four multiplications a direct 8-point DFT would need.

stage 1 stage 2 stage 3 x[0]x[4] x[2]x[6] x[1]x[5] x[3]x[7] X[0]X[1] X[2]X[3] X[4]X[5] X[6]X[7] W⁰ grey = pass through and add · gold = multiply by a twiddle and cross
The 8-point decimation-in-time FFT — three stages, four butterflies each, inputs bit-reversed

The input ordering looks arbitrary and is not. The first split separates even from odd indices; the second splits each half by the next bit of the index; and so on. After \(\log_2 N\) splits, sample \(n\) has migrated to the position whose binary representation is that of \(n\) written backwards. For \(N = 8\): index 1 is \(001\), reversed \(100 = 4\), so \(x[1]\) sits in position 4 — exactly where the figure shows it.

\(n\) decimal\(n\) binaryreversedposition
00000000
10011004
20100102
30111106
41000011
51011015
61100113
71111117

Reading the "position" column downwards gives \(0,4,2,6,1,5,3,7\), the input order in the flow graph. The permutation is its own inverse, so a single in-place pass of pairwise swaps performs it, and the whole transform then proceeds in the same array with no extra storage. That in-place property matters as much as the speed on small hardware.

There is a mirror-image algorithm, decimation in frequency, which splits the output index instead of the input index. It takes the inputs in natural order and delivers the outputs bit-reversed, has the same operation count, and differs only in whether the twiddle multiplication happens before or after the add-subtract. Neither is better; libraries choose whichever fits their memory layout.

The payoff is best appreciated numerically.

\(N\)Direct DFT: \(N^2\) multsRadix-2 FFT: \(\tfrac{N}{2}\log_2 N\)Speed-up
864125.3 ×
644 09619221.3 ×
25665 5361 02464 ×
1 0241 048 5765 120204.8 ×
4 09616 777 21624 576682.7 ×
65 5364 294 967 296524 2888 192 ×
Why this algorithm changed engineering. Before 1965, spectrum analysis meant analogue filter banks and swept oscillators. The FFT made a digital spectrum cheap enough to compute in real time, and with it came digital filtering by fast convolution, OFDM modulation, MP3 and JPEG coding, MRI reconstruction and radar pulse compression. The mathematics of this chapter is a hundred and fifty years old; the practice of the last sixty years rests on one observation about the sign of \(W_N^{k+N/2}\).
Section 26-9

Spectral Analysis in Practice

Suppose a continuous signal is sampled at \(f_s\) hertz, \(N\) samples are collected, and their DFT is taken. Bin \(k\) sits at \(\Omega_k = 2\pi k/N\) radians per sample, which by Chapter 20's relation \(\Omega = 2\pi f/f_s\) corresponds to the analogue frequency

Bin index to hertz, and the record length
\[ f_k = \frac{k\,f_s}{N} \quad\text{hertz}, \qquad \Delta f = \frac{f_s}{N}, \qquad T = \frac{N}{f_s} = \frac{1}{\Delta f} \]

The bin spacing \(\Delta f\) is the reciprocal of the record duration \(T\), and that single relation governs everything that follows. Watch a signal for a tenth of a second and the spectrum arrives on a 10 Hz grid, whatever the sampling rate.

Now the difficulty. Truncating an infinite sinusoid to \(N\) samples is multiplication by a rectangular window, and Chapter 14 established that multiplication in time is convolution in frequency. The true spectrum of a pure tone is a single line; convolved with the transform of the rectangular window — a Dirichlet kernel, the discrete cousin of the sinc — it becomes a main lobe of finite width surrounded by a fence of side lobes. This smearing is spectral leakage, and it is present in every DFT of every measured signal.

There is one lucky case. If the tone's frequency lands exactly on a bin, then an integer number of its cycles fits inside the record, the periodic extension of Section 26-4 joins up seamlessly, and every side lobe falls precisely on a zero of the kernel. The DFT then shows a single clean spike. Move the tone half a bin off centre and the record no longer joins up: the discontinuity at the seam has broadband content, the side lobes no longer land on zeros, and energy appears across the whole spectrum.

🔑
Leakage is caused by the seam, not by the transform
\[ f_{\text{tone}} = \frac{k f_s}{N} \ \ \text{(exactly)} \;\Longrightarrow\; \text{no leakage}; \qquad \text{otherwise, leakage into every bin} \]

The DFT is behaving correctly in both cases; it reports the spectrum of the periodic extension of what you gave it, and when the record does not join up smoothly that periodic extension genuinely contains a step discontinuity every \(N\) samples.

The cure is to taper the record so it joins up smoothly, which means multiplying by a window that falls to zero at both ends instead of cutting abruptly. A gentler taper lowers the side lobes dramatically, at the cost of a wider main lobe — you trade the ability to see a small tone next to a large one against the ability to separate two tones of similar size. That trade-off is the whole subject of window design.

WindowDefinition on \(0 \le n \le N-1\)Main-lobe widthPeak side lobe
Rectangular\(w[n]=1\)2 bins\(-13\) dB
Hann\(0.5-0.5\cos\!\frac{2\pi n}{N-1}\)4 bins\(-31\) dB
Hamming\(0.54-0.46\cos\!\frac{2\pi n}{N-1}\)4 bins\(-43\) dB
Blackman\(0.42-0.5\cos\!\frac{2\pi n}{N-1}+0.08\cos\!\frac{4\pi n}{N-1}\)6 bins\(-58\) dB

Two further practical points close the chapter. The first is resolution. Two tones can be told apart only if their main lobes do not merge, so with a rectangular window they must be separated by roughly \(1/T\) hertz, and with a Hann or Hamming window by roughly \(2/T\). Resolution is bought with observation time and with nothing else — not with a faster sampling rate, and not with a longer transform of the same data.

That last remark is the second point. Zero-padding a record to a longer transform length produces more bins, spaced more finely, and a visibly smoother plot. It adds no information whatever: the extra samples are zeros, the record duration \(T\) is unchanged, and the finer grid merely interpolates the same underlying DTFT. Zero-padding is useful — it locates a peak more precisely and removes the picket-fence effect, in which a peak falling between bins is under-read by up to 3.9 dB — but a claim that it improves resolution is simply false.

Two knobs, two effects. The sampling rate \(f_s\) sets the highest frequency you can see without aliasing (Chapter 20). The record length \(T = N/f_s\) sets how finely you can distinguish frequencies. They are independent, and confusing them is the most common error in laboratory spectrum measurements: sampling faster does not improve resolution, and watching longer does not extend the bandwidth.
Section 26-10

Worked Examples

1 A 4-point DFT by hand, checked with Parseval

Problem. Compute the 4-point DFT of \(x[n] = \{1,\,2,\,3,\,4\}\) for \(n = 0,1,2,3\), and verify the answer using Parseval's relation.

Solution. With \(N = 4\) the twiddle factor is \(W_4 = e^{-j\pi/2} = -j\), so the whole computation is powers of \(-j\) and no trigonometry is needed. Since \(X[k] = \sum_{n} x[n](-j)^{kn}\),

Working — the four coefficients
\[ \begin{aligned} X[0] &= 1+2+3+4 = 10\\ X[1] &= 1 + 2(-j) + 3(-j)^2 + 4(-j)^3 = 1 - 2j - 3 + 4j = -2 + 2j\\ X[2] &= 1 + 2(-1) + 3(1) + 4(-1) = -2\\ X[3] &= 1 + 2(j) + 3(-1) + 4(-j) = -2 - 2j \end{aligned} \]

Two checks are immediate. \(X[0] = 10\) is the sum of the samples, as it must be; and \(X[2] = X[N/2]\) is the alternating sum \(1-2+3-4 = -2\), also as it must be. The signal is real, so conjugate symmetry demands \(X[3] = X^{*}[1]\), and indeed \(-2-2j\) is the conjugate of \(-2+2j\).

Parseval's relation is the strongest test, because it involves every number:

Working — energy check
\[ \sum_{n=0}^{3}|x[n]|^2 = 1+4+9+16 = 30, \qquad \frac{1}{4}\sum_{k=0}^{3}|X[k]|^2 = \frac{100 + 8 + 4 + 8}{4} = \frac{120}{4} = 30 \]

using \(|-2+2j|^2 = 4+4 = 8\). The two agree, so the transform is right.

2 Time-domain aliasing made visible

Problem. The sequence \(x[n] = (0.5)^n u[n]\) is infinitely long. Its DTFT is sampled at \(N = 4\) points and the inverse DFT is taken. What comes back, and by how much does it differ from \(x[n]\)?

Solution. By the result of Section 26-4 the answer is the aliased periodic extension \(x_p[n] = \sum_{r} x[n+rN]\). Since \(x[n]\) is causal, only \(r \ge 0\) contributes, and each term is a constant multiple of the previous one:

Working — folding the tail back
\[ x_p[n] = \sum_{r=0}^{\infty} (0.5)^{\,n+4r} = (0.5)^n\sum_{r=0}^{\infty}\big[(0.5)^4\big]^r = \frac{(0.5)^n}{1-(0.5)^4} = \frac{(0.5)^n}{0.9375} \]

Numerically \(x_p = \{1.0667,\ 0.5333,\ 0.2667,\ 0.1333\}\) against the true \(\{1,\ 0.5,\ 0.25,\ 0.125\}\). Every sample is too large by the same factor \(1/0.9375\), that is by 6.67% — the folded-back tail is itself a scaled copy of the head, because a geometric sequence is self-similar under shifting.

Confirm that the 4-point DFT of \(x_p\) really does reproduce the DTFT samples. The DTFT is \(X(e^{j\Omega}) = 1/(1-0.5e^{-j\Omega})\), so at \(\Omega_0 = 0\) it equals \(1/0.5 = 2\); and the sum of \(x_p\) is \(1.0667+0.5333+0.2667+0.1333 = 2.000\). At \(\Omega_1 = \pi/2\), \(X = 1/(1+0.5j) = 0.8 - 0.4j\); and

Working — the \(k=1\) coefficient
\[ X_p[1] = 1.0667 - 0.5333j - 0.2667 + 0.1333j = 0.8 - 0.4j \]

exactly as required. The DFT values are correct samples of the DTFT; it is the sequence they invert to that has been corrupted. Increasing \(N\) shrinks the error like \(0.5^N\), which is why a decaying signal is usually safe if the record covers several time constants.

3 Circular against linear convolution, and the cure

Problem. Let \(x[n] = \{1,2,3\}\) and \(h[n] = \{1,1\}\). Find the linear convolution, then the 3-point circular convolution, and show how zero-padding reconciles them.

Solution. The linear convolution has length \(3+2-1 = 4\). Sliding \(h\) along \(x\) in the manner of Chapter 7 gives

Working — linear convolution
\[ y_{\text{lin}} = \{1,\ 1+2,\ 2+3,\ 3\} = \{1,\ 3,\ 5,\ 3\} \]

Now the 3-point circular convolution. Pad \(h\) to \(\{1,1,0\}\) so both sequences have length 3, and evaluate \(y[n] = \sum_{m=0}^{2}x[m]h[(n-m)_3]\):

Working — 3-point circular convolution
\[ \begin{aligned} y[0] &= x[0]h[0] + x[1]h[2] + x[2]h[1] = 1 + 0 + 3 = 4\\ y[1] &= x[0]h[1] + x[1]h[0] + x[2]h[2] = 1 + 2 + 0 = 3\\ y[2] &= x[0]h[2] + x[1]h[1] + x[2]h[0] = 0 + 2 + 3 = 5 \end{aligned} \]

So \(y_{\text{circ}} = \{4,3,5\}\). Compare with the linear result: the fourth sample, 3, had nowhere to go in a length-3 record and has wrapped round onto the first, turning 1 into \(1+3 = 4\). Nothing else changed. This is time-domain aliasing in its most concrete form.

The condition \(N \ge L+M-1 = 4\) says to use a 4-point transform. Pad to \(x = \{1,2,3,0\}\) and \(h = \{1,1,0,0\}\) and repeat:

Working — 4-point circular convolution
\[ y[0]=1,\quad y[1]=1+2=3,\quad y[2]=2+3=5,\quad y[3]=3+0=3 \]

which is \(\{1,3,5,3\}\), the linear convolution exactly. One extra zero on each sequence was the entire difference between a wrong answer and a right one.

4 An 8-point FFT traced through its butterflies

Problem. Compute the 8-point DFT of \(x[n] = \{1,1,1,1,0,0,0,0\}\) using the decimation-in-time decomposition, and confirm \(X[1]\) against a direct evaluation.

Solution. Split by parity. The even-indexed samples are \(g = \{x[0],x[2],x[4],x[6]\} = \{1,1,0,0\}\) and the odd-indexed are \(h = \{x[1],x[3],x[5],x[7]\} = \{1,1,0,0\}\) — the same sequence, so one 4-point DFT serves for both. With \(W_4 = -j\),

Working — the two 4-point transforms
\[ G[k] = H[k] = 1 + (-j)^k \;\Longrightarrow\; G = H = \{\,2,\ 1-j,\ 0,\ 1+j\,\} \]

Now recombine with the butterfly, using \(W_8 = e^{-j\pi/4}\), so that \(W_8^0 = 1\), \(W_8^1 = \tfrac{\sqrt2}{2}(1-j)\), \(W_8^2 = -j\) and \(W_8^3 = -\tfrac{\sqrt2}{2}(1+j)\). The twiddled odd terms are

Working — the products \(W_8^k H[k]\)
\[ W_8^0H[0] = 2, \quad W_8^1H[1] = \tfrac{\sqrt2}{2}(1-j)(1-j) = -j\sqrt2, \quad W_8^2H[2] = 0, \quad W_8^3H[3] = -\tfrac{\sqrt2}{2}(1+j)(1+j) = -j\sqrt2 \]

using \((1-j)^2 = -2j\) and \((1+j)^2 = 2j\). Adding and subtracting these from \(G[k]\) gives all eight outputs at once:

Working — the eight coefficients
\[ \begin{aligned} X[0] &= 2+2 = 4, &\quad X[4] &= 2-2 = 0\\ X[1] &= (1-j) - j\sqrt2 = 1 - j2.4142, &\quad X[5] &= (1-j) + j\sqrt2 = 1 + j0.4142\\ X[2] &= 0+0 = 0, &\quad X[6] &= 0-0 = 0\\ X[3] &= (1+j) - j\sqrt2 = 1 - j0.4142, &\quad X[7] &= (1+j) + j\sqrt2 = 1 + j2.4142 \end{aligned} \]

Three checks. \(X[0] = 4\) is the sum of the samples. The conjugate symmetry \(X[8-k] = X^{*}[k]\) holds for every pair. And a direct evaluation of \(X[1] = \sum_{n=0}^{3}e^{-j\pi n/4}\) sums a geometric series to \((1-e^{-j\pi})/(1-e^{-j\pi/4}) = 2/(0.2929+0.7071j) = 1 - 2.4142j\), matching the butterfly result.

Count the work: twelve butterflies, against sixty-four multiplications for the direct transform — and half of these butterflies had a twiddle factor of 1 or 0 and cost nothing at all.

5 Is fast convolution actually worth it?

Problem. A 256-tap FIR filter is to be run on a long real signal using overlap-add with 1024-point FFTs. Compare the arithmetic cost per output sample against direct convolution.

Solution. With \(M = 256\) and \(N = 1024\), each block can carry \(L = N - M + 1 = 769\) new input samples and still satisfy \(N \ge L+M-1\). The filter's DFT is computed once and reused, so per block the cost is one forward FFT, \(N\) complex multiplications in the frequency domain, and one inverse FFT:

Working — cost of one block
\[ 2 \times \frac{N}{2}\log_2 N \;+\; N \;=\; 2(512)(10) + 1024 \;=\; 10\,240 + 1024 \;=\; 11\,264 \ \text{complex multiplications} \]

Dividing by the 769 output samples the block produces gives \(11\,264/769 \approx 14.6\) complex multiplications per output sample. A complex multiplication is four real multiplications, so this is about 58.6 real multiplications per sample.

Direct convolution costs one real multiplication per tap per sample, that is 256. Fast convolution is therefore about \(256/58.6 \approx 4.4\) times cheaper here. Doubling the filter to 512 taps doubles the direct cost while barely moving the FFT cost, so the advantage roughly doubles too; going the other way, for a filter of ten or twenty taps the transform overhead swamps the saving and direct convolution wins outright.

The break-even point is usually somewhere between 30 and 60 taps on a general-purpose processor. Below it, convolve directly; above it, transform.

6 Reading a laboratory spectrum correctly

Problem. A signal is sampled at \(f_s = 8\) kHz and \(N = 1024\) samples are transformed. (a) What is the bin spacing? (b) Where does a 1000 Hz tone appear, and will it leak? (c) Can two tones at 1000 Hz and 1006 Hz be resolved? (d) Would zero-padding to 4096 points help?

Solution (a). \(\Delta f = f_s/N = 8000/1024 = 7.8125\) Hz, and the record lasts \(T = 1024/8000 = 0.128\) s. As promised, \(1/T = 7.8125\) Hz.

Solution (b). \(k = 1000/7.8125 = 128\) exactly, so the tone falls precisely on bin 128. An integer number of cycles — 128 of them — fits inside the record, the periodic extension joins up without a seam, and the spectrum shows a single clean line at bin 128 (with its mirror at bin \(1024-128 = 896\)) and essentially nothing elsewhere. A tone at 1005 Hz would sit at \(k = 128.64\), between bins, and would leak into all of them.

Solution (c). The tones are 6 Hz apart, which is less than the 7.8125 Hz bin spacing, so they land in the same bin and cannot be separated — no amount of processing recovers them. Resolution demands a longer observation: a rectangular window needs \(T \ge 1/6 \approx 0.167\) s, hence \(N \ge 8000/6 \approx 1334\), rounded up to 2048 samples. With a Hann window, whose main lobe is twice as wide, \(T \ge 2/6 = 0.333\) s and \(N \ge 2667\), rounded up to 4096.

Solution (d). No. Zero-padding the same 1024 samples to a 4096-point transform quarters the bin spacing to 1.95 Hz and draws a smoother curve, but \(T\) is still 0.128 s and the underlying DTFT is unchanged — the two tones remain merged inside one main lobe, now sampled more densely. Zero-padding interpolates; it does not resolve. It is worth doing for the 1005 Hz case in part (b), where a finer grid pins down the peak location and avoids the picket-fence under-reading of up to 3.9 dB.

Review

Chapter Summary

The DFT pair

\(X[k]=\sum_{n=0}^{N-1}x[n]W_N^{kn}\), \(x[n]=\tfrac1N\sum_k X[k]W_N^{-kn}\), with \(W_N=e^{-j2\pi/N}\). It is the DTFT sampled at \(\Omega_k = 2\pi k/N\).

Time-domain aliasing

Sampling the spectrum makes the signal periodic: the inverse DFT returns \(\sum_r x[n+rN]\). Everything circular follows from this.

Circular convolution

\(X_1[k]X_2[k]\) inverts to circular, not linear, convolution. Pad to \(N \ge L+M-1\) and the two agree.

The butterfly

\(X[k]=G[k]+W_N^kH[k]\), \(X[k+N/2]=G[k]-W_N^kH[k]\). One multiply, two outputs — the whole saving of the FFT.

The operation count

\(N^2\) becomes \(\tfrac{N}{2}\log_2 N\): a factor of 205 at \(N=1024\) and 8192 at \(N=65536\). Inputs arrive bit-reversed.

Reading a spectrum

\(\Delta f = f_s/N = 1/T\). Off-bin tones leak; windows trade side lobes for width; zero-padding interpolates but never resolves.

Practice

Problems

Problems 1 to 3 exercise the definition and its properties; 4 and 5 concern circular convolution; 6 and 7 the FFT structure; 8 the practicalities of measurement. Check every numerical transform with \(X[0]\) and with Parseval before moving on.

  1. Compute the 4-point DFT of \(x[n] = \{1,\,0,\,-1,\,0\}\). Verify \(X[0]\), confirm the conjugate symmetry, and check Parseval's relation.
  2. The 4-point DFT of some real sequence is \(X = \{6,\ -2+2j,\ -2,\ -2-2j\}\). Recover \(x[n]\) using the inverse DFT, and state without computing what the DFT of \(x[(n-1)_4]\) would be.
  3. Show that if \(x[n]\) is real and even about \(n = 0\) in the circular sense, that is \(x[(-n)_N] = x[n]\), then \(X[k]\) is real for every \(k\). Test your argument on \(x = \{3,\,1,\,2,\,1\}\) with \(N=4\).
  4. Let \(x = \{1,\,-1,\,2\}\) and \(h = \{2,\,1\}\). Find the linear convolution, the 3-point circular convolution, and the smallest transform length for which the circular result equals the linear one.
  5. A 64-tap filter is applied by overlap-add using 512-point transforms. How many new input samples does each block carry, by how many samples do consecutive output blocks overlap, and how many complex multiplications does each output sample cost?
  6. Draw the 4-point decimation-in-time flow graph. Label the input order, mark every twiddle factor, and count the multiplications that are actually non-trivial.
  7. Show that the total number of complex additions in a radix-2 FFT of length \(N\) is \(N\log_2 N\). Then explain why the saving over the direct DFT is smaller for additions than for multiplications.
  8. A 2 kHz tone and a 2.1 kHz tone of very different amplitudes are sampled at 20 kHz. (a) What record length is needed to resolve them with a rectangular window? (b) Why might a Hamming window be preferred even though it needs a longer record? (c) If \(N = 1024\), on which bin does the 2 kHz tone land, and does it leak?
Tip: in every DFT question, first ask what the implied period is. If the question involves a shift, a convolution or a reversal, the answer is circular unless enough zeros have been supplied to make it linear. And in every measurement question, write down \(\Delta f = f_s/N\) and \(T = N/f_s\) before anything else — most of the answer is usually already in those two numbers.