Chapter 8 introduced the DFT as the discrete transform of a discrete (finite-length) sequence. Recall its definition, written compactly using the twiddle factor(旋轉因子) $W_N$:
$W_N$ is a unit-magnitude complex number sitting at angle $-2\pi/N$ on the unit circle. Because $W_N^{r}$ only depends on $r \bmod N$, the powers $W_N^r$ take on only $N$ distinct values — the $N$-th roots of unity. Two consequences of this structure drive everything in this chapter:
In matrix form the DFT is a dense $N\times N$ matrix–vector product,
but the matrix is anything but arbitrary: every entry is one of only $N$ values, and the entries are arranged in a highly regular pattern. Figure 15-1 visualizes the real and imaginary parts of the $N=32$ DFT matrix — the structure(規律性結構)is exactly the opportunity for efficiency that the FFT exploits.
Evaluate the DFT sum literally. For each output point $X[k]$ we need $N$ complex multiplies and $N-1$ complex adds; there are $N$ output points ($k = 0,\dots,N-1$). Converting to real arithmetic with
$(a+jb)(c+jd) = (ac-bd) + j(ad+bc)$ = 4 real mults + 2 real adds, 1 complex add = 2 real adds,
the total damage is:
The cost grows with the square of the length: doubling $N$ quadruples the work. At $N = 1024$ the direct DFT needs about $4\times 10^6$ complex operations; at $N = 10^6$ (one second of audio at 1 MHz) it needs $10^{12}$ — completely impractical for real-time processing. An $O(N^2)$ barrier(直接計算的平方複雜度)is the reason the 1965 Cooley–Tukey FFT is routinely listed among the most important algorithms of the 20th century.
Before attacking the full DFT, the lecture gives a first taste of exploiting twiddle structure: Goertzel's algorithm(Goertzel 演算法) computes a single DFT bin as the output of a small recursive filter. Start from the DFT sum and pull out a factor $W_N^{kN} = 1$:
The right-hand sum looks like a convolution evaluated at time $N$: it is $\sum_\ell x[\ell]\, h_k[N-\ell]$ with $h_k[n] = W_N^{-kn}u[n]$. Therefore
So one first-order complex recursion, clocked $N+1$ times (feeding $x_e[N]=0$ at the end), delivers $y_k[N] = X[k]$:
Properties claimed on the slide, worth memorizing:
The recursion now uses the real coefficient $2\cos(2\pi k/N)$ — only 2 real mults per step — and the complex numerator $(1 - W_N^k z^{-1})$ is evaluated only once, at the last step $n=N$.
Goertzel costs $O(N)$ per bin; the FFT costs $O(N\log_2 N)$ for all $N$ bins. So if you need only $M$ bins, Goertzel wins roughly when $M \lesssim \log_2 N$. A DTMF detector needing 8 tone frequencies out of $N=205$ samples is the classic use case.(只要少數幾個頻點時用 Goertzel,整條頻譜都要時用 FFT。)
The decimation-in-time(時間抽取)DIT FFT rearranges the DFT sum into two halves: terms with even time index $n=2m$ and terms with odd index $n = 2m+1$ (assume $N$ even, ultimately $N = 2^M$):
The key step uses $W_N^{2mk} = W_{N/2}^{mk}$ (index halving). $X_0$ is the $N/2$-point DFT of the even-indexed samples, and $X_1$ is the $N/2$-point DFT of the odd-indexed samples. Because an $N/2$-point DFT is periodic in $k$ with period $N/2$, we evaluate both at $\langle k\rangle_{N/2}$ ($k$ modulo $N/2$). The result, in the lecture's compact notation:
Why does this save anything? Count again:
One split halves the computation (the $\varepsilon$ accounts for the $N$ extra twiddle multiplies and adds needed to combine the halves). We can evaluate an $N$-pt DFT as two $N/2$-pt DFTs plus a few mults/adds.
Writing the combination for all $k = 0,\dots,N-1$ and using periodicity $X_0[\langle k\rangle_{N/2}]$, $X_1[\langle k\rangle_{N/2}]$, the structure for $N=8$ is shown in Fig. 15-3. Note carefully — as the slide stresses — the twiddle factors $W_N^k$ always apply to the odd-half output $X_1[\cdot]$, and they are NOT mirror-imaged: output $X[k+N/2]$ uses $W_N^{k+N/2} = -W_N^k$, not $W_N^{k}$ again.
If decomposing one $\mathrm{DFT}_N$ into two smaller $\mathrm{DFT}_{N/2}$'s speeds things up — why not further divide into $\mathrm{DFT}_{N/4}$'s? Apply the identical split to $X_0[k]$ (the even-sample DFT): split its inputs into even-of-even and odd-of-even subsets:
where $X_{00}$ is the $N/4$-pt DFT of the even points within the even subset of $x[n]$ (i.e. $x[0],x[4],x[8],\dots$), $X_{01}$ the $N/4$-pt DFT of the odd points of the even subset, and so on. Note that the second-level twiddle is $W_{N/2}^{k}$ — for $N=8$ that means $W_4^k = W_8^{2k}$, so only $W_8^0$ and $W_8^2$ appear in the second stage.
Keep recursing until we hit 2-point DFTs, which need no multiplies at all:
An $N = 2^M$-point DFT thus reduces to $M = \log_2 N$ stages of twiddle factors and summation — the $O(N^2)$ part vanishes entirely.
At every stage the elementary operation pairs two values $r$ and $r + N/2$ apart and produces two outputs. This is the butterfly(蝶形運算). As first derived, it needs two complex multiplies, $W_N^r$ and $W_N^{r+N/2}$. But by half-period symmetry,
so the second multiply is just the negative of the first — i.e. subtract rather than add. Each butterfly then costs one complex multiply and two complex adds:
Assembling all $M = \log_2 8 = 3$ stages of simplified butterflies gives the classic flowgraph of Fig. 15-5. Trace any output back: stage 1 computes four 2-pt DFTs, stage 2 merges them into two 4-pt DFTs (twiddles $W_8^0, W_8^2$ — i.e. $W_4^0, W_4^1$), stage 3 merges those into the final 8-pt DFT (twiddles $W_8^0,\dots,W_8^3$).
In stage $s$ ($s = 1,\dots,M$) the butterflies span $2^{s-1}$ rows and the twiddles are powers of $W_{2^s}$, equivalently $W_N^{rN/2^s}$. Only $N/2$ complex multiplies can occur per stage (one per butterfly), and many of those are by $W^0 = 1$ and cost nothing. Trivial factors: $W^0=1$ (free), $W_8^2 = -j$ (a swap of real/imag parts plus sign — also multiplication-free in practice).
Each DIT split sends even-indexed samples up and odd-indexed samples down — i.e. it sorts on the least significant bit (LSB) of the time index. Recursing sorts on the next bit, and so on. After $M$ levels, the sample at input row $r$ is $x[\text{bit-reverse}(r)]$: the address with its $M$-bit binary representation reversed(位元反轉).
| Row $r$ | $r$ binary | reversed | input sample |
|---|---|---|---|
| 0 | 000 | 000 | $x[0]$ |
| 1 | 001 | 100 | $x[4]$ |
| 2 | 010 | 010 | $x[2]$ |
| 3 | 011 | 110 | $x[6]$ |
| 4 | 100 | 001 | $x[1]$ |
| 5 | 101 | 101 | $x[5]$ |
| 6 | 110 | 011 | $x[3]$ |
| 7 | 111 | 111 | $x[7]$ |
Look again at Fig. 15-5: every butterfly takes two values from rows $(p, q)$ and writes its two outputs back to the same two rows $(p, q)$. No other butterfly in that stage touches those rows. Consequently the whole FFT is an in-place algorithm(原位演算法): one length-$N$ complex array suffices — after the initial bit-reversal shuffle, the $M$ stages overwrite the array sequentially, and the final array contents are $X[0],\dots,X[N-1]$ in natural order. Memory cost: $N$ complex words plus a small twiddle table (or none for Goertzel-style on-the-fly generation).
An $N = 2^M$-pt DFT reduces to $M = \log_2 N$ stages. Each stage has $N/2$ butterflies, each with at most 1 complex multiply (4 real mults) and 2 complex adds (4 real adds):
The quadratic term is gone. Figure 15-6 shows just how dramatic the difference is — at $N = 2^{16}$ the FFT needs about 3 orders of magnitude fewer multiplies.
The count $\frac N2 \log_2 N$ is complex multiplies, and it is an upper bound (many twiddles are $\pm 1, \pm j$ and are free). If a problem asks for real multiplies, multiply by 4. And remember the direct DFT baseline is $N^2$ complex = $4N^2$ real multiplies — don't mix the two units when computing a speed-up ratio.
Having $N = 2^M$ meant we could divide each stage into 2 halves — the radix-2 FFT(基數 2 FFT). The same divide-and-conquer approach works more generally:
Modern libraries (FFTW — used by MATLAB — numpy.fft, etc.) implement mixed-radix and even prime-length algorithms (Rader, Bluestein), so any $N$ runs in $O(N\log N)$. But the constant factor is smallest for $N = 2^M$; a prime $N$ can easily be several times slower (see Fig. 15-7). When you control the length, choose a power of two.
Recall the IDFT:
The only differences from the forward DFT are the $1/N$ scale and the sign of the exponent. Conjugating twice fixes the sign:
The bracketed sum is exactly a forward DFT of $x'[n] = X^*[k]\big|_{k=n}$ — a "time" sequence made from the spectrum. So the recipe is: conjugate the spectrum, run the same FFT engine, conjugate the result, divide by $N$. One FFT implementation serves both directions; in a pure real flowgraph this amounts to swapping the roles of real/imaginary parts with a couple of sign flips and $1/N$ scalings at the ports.
If $x[n]$ is pure-real, the DFT wastes multiplies: by conjugate symmetry(共軛對稱), $X[k] = X^*[-k] = X^*[N-k]$, so half the outputs are redundant. The lecture's trick: pack two real sequences into one complex FFT. Given real $x[n]$ and $w[n]$, form $y[n] = x[n] + j\,w[n]$ and take a single $N$-pt DFT $V[k] = \mathrm{DFT}\{y[n]\} = X[k] + Y[k]$, where $Y[k] = \mathrm{DFT}\{j\,w[n]\} = jW[k]$. Then
(Here $V^*[-k] = V^*[\langle N-k\rangle_N]$, and the cancellations use the conjugate symmetry of the real-input spectra $X$ and $W$.) That is: compute the DFTs of two $N$-pt real sequences with a single $N$-pt complex DFT — Exercise 5 verifies this numerically to machine precision.
MATLAB's fft/ifft call the FFTW library — mixed-radix $O(N\log N)$ for every length, fastest for $N = 2^M$:
N = 4096;
x = randn(1, N);
X = fft(x); % N-point FFT (FFTW under the hood)
xr = ifft(X); % inverse; max(abs(xr - x)) ~ 1e-16
X2 = fft(x, 8192); % zero-pads x to 8192 points first
% --- timing: power-of-two vs prime length ---
N1 = 2^16; N2 = 65537; % 65536 vs the prime 65537
x1 = randn(1, N1); x2 = randn(1, N2);
t1 = timeit(@() fft(x1)); % ~ a few ms
t2 = timeit(@() fft(x2)); % noticeably slower
fprintf('N = %6d : %8.3f ms\n', N1, 1e3*t1);
fprintf('N = %6d : %8.3f ms\n', N2, 1e3*t2);
Figure 15-7 shows measured run times on this machine (numpy's FFTPACK-style engine; MATLAB/FFTW behaves the same way qualitatively): both power-of-two and prime lengths scale like $N \log N$, but the prime-length constant is ~5× worse, and the direct $O(N^2)$ matrix product blows past both almost immediately.
nextpow2(L) gives $M$ with $2^M \ge L$; use fft(x, 2^nextpow2(L)) to zero-pad to a fast length.fftshift(X) reorders the output so $k=0$ sits in the middle for plotting.fftw('planner','measure') lets FFTW search for the fastest plan.1:N/2+1 for analysis.$N$ complex mults + $N{-}1$ adds per bin, $\times N$ bins → $N^2$ complex = $4N^2$ real mults, $4N^2{-}2N$ real adds. $O(N^2)$.
$W_N = e^{-j2\pi/N}$; only $N$ distinct powers. Periodicity $W_N^{k+N} = W_N^k$, symmetry $W_N^{k+N/2} = -W_N^k$, halving $W_N^2 = W_{N/2}$.
$X[k] = y_k[N]$ from a 1st-order recursion; real-denominator form needs only 2 real mults/step. $O(N)$ per bin — best when you need few bins.
$X[k] = X_0[\langle k\rangle_{N/2}] + W_N^k X_1[\langle k\rangle_{N/2}]$ — even-sample DFT plus twiddled odd-sample DFT. One split halves the work; recurse to 2-pt DFTs.
$X[r] = X_0[r] + W_N^r X_1[r]$, $X[r{+}N/2] = X_0[r] - W_N^r X_1[r]$: one complex mult, two adds (SUB instead of a second mult).
Inputs in bit-reversed order, outputs natural; each butterfly overwrites its own two slots → whole FFT runs in one length-$N$ array.
$M = \log_2 N$ stages × $N/2$ butterflies → $\le \frac N2 \log_2 N$ complex mults, $N \log_2 N$ adds: $O(N\log_2 N)$.
Radix-3/4, mixed radix for composite $N$, zero-pad to $2^M$; IFFT = conjugate → FFT → conjugate → $/N$; two real $N$-pt DFTs from one complex FFT.
Problem: A real-time system must compute a 4096-point DFT. (a) How many real multiplications does direct evaluation require? (b) How many complex multiplications does a radix-2 DIT FFT require (upper bound)? (c) What is the speed-up factor in complex multiplies? (d) If one complex multiply takes 5 ns, compare the two run times.
(a) Direct: $4N^2 = 4\cdot 4096^2 = 67{,}108{,}864$ real multiplications (and $4N^2 - 2N = 67{,}100{,}672$ real adds).
(b) $N = 4096 = 2^{12}$, so $M = 12$ stages with $N/2 = 2048$ butterflies each:
$$\frac N2 \log_2 N = 2048 \times 12 = 24{,}576 \text{ complex multiplies (upper bound).}$$(c) In complex multiplies: $\dfrac{N^2}{(N/2)\log_2 N} = \dfrac{16{,}777{,}216}{24{,}576} = \dfrac{2N}{\log_2 N} \approx 683\times$.
(d) Direct: $16{,}777{,}216 \times 5\,\text{ns} \approx 83.9\,\text{ms}$. FFT: $24{,}576 \times 5\,\text{ns} \approx 0.123\,\text{ms}$. At a 44.1 kHz audio rate a 4096-pt frame lasts ~93 ms — the direct DFT barely keeps up using all its time budget, while the FFT uses ~0.1%.
Problem: Starting from the $N$-point DFT definition ($N$ even), (a) show that $X[k] = X_0[\langle k\rangle_{N/2}] + W_N^{k} X_1[\langle k\rangle_{N/2}]$ where $X_0, X_1$ are the $N/2$-point DFTs of the even- and odd-indexed samples. (b) Explain why $X_0$ and $X_1$ must be evaluated modulo $N/2$, and (c) show explicitly that $X[k + N/2] = X_0[k] - W_N^{k}X_1[k]$ for $0 \le k < N/2$.
(a) Split the sum over even $n = 2m$ and odd $n = 2m+1$:
$$X[k] = \sum_{m=0}^{\frac N2 -1} x[2m] W_N^{2mk} + \sum_{m=0}^{\frac N2 -1} x[2m+1] W_N^{(2m+1)k} = \sum_m x[2m] \big(W_N^2\big)^{mk} + W_N^k \sum_m x[2m+1]\big(W_N^2\big)^{mk}$$Since $W_N^2 = e^{-j2\pi\cdot 2/N} = e^{-j2\pi/(N/2)} = W_{N/2}$, the two sums are exactly $N/2$-point DFTs of $x_0[m] = x[2m]$ and $x_1[m] = x[2m+1]$.
(b) $X[k]$ is needed for $k = 0,\dots,N-1$, but an $N/2$-point DFT only defines $N/2$ values. By periodicity of the DFT, $X_0[k + N/2] = X_0[k]$ (the kernel $W_{N/2}^{m(k+N/2)} = W_{N/2}^{mk}$), so for $k \ge N/2$ we read the small DFTs at $\langle k\rangle_{N/2}$.
(c) For $0 \le k < N/2$:
$$X[k+\tfrac N2] = X_0\big[\langle k+\tfrac N2\rangle_{N/2}\big] + W_N^{k+\frac N2} X_1\big[\langle k+\tfrac N2\rangle_{N/2}\big] = X_0[k] + W_N^{k+\frac N2} X_1[k]$$and the half-period symmetry $W_N^{k + N/2} = W_N^k\,e^{-j\pi} = -W_N^k$ gives
$$\boxed{X[k+\tfrac N2] = X_0[k] - W_N^{k} X_1[k]}$$This is precisely the lower branch of the simplified butterfly — the same product $W_N^k X_1[k]$ is reused with a sign flip, which is why each butterfly needs only one complex multiply.
Problem: Compute the 4-point DFT of $x[n] = \{1, 2, 3, 4\}$ by tracing the radix-2 DIT flowgraph: write the bit-reversed input order, evaluate both stages of butterflies, and verify one output bin against the DFT definition.
Step 1 — bit-reversed input. $N=4$, 2 bits: rows receive $x[00_2], x[10_2], x[01_2], x[11_2] = x[0], x[2], x[1], x[3] = 1, 3, 2, 4$.
Step 2 — stage 1 (2-pt DFTs, no twiddles).
$$\begin{aligned} a_0 &= x[0] + x[2] = 1 + 3 = 4, & a_1 &= x[0] - x[2] = 1 - 3 = -2\\ a_2 &= x[1] + x[3] = 2 + 4 = 6, & a_3 &= x[1] - x[3] = 2 - 4 = -2 \end{aligned}$$Step 3 — stage 2 (twiddles $W_4^0 = 1$, $W_4^1 = e^{-j\pi/2} = -j$).
$$\begin{aligned} X[0] &= a_0 + W_4^0\, a_2 = 4 + 6 = 10\\ X[1] &= a_1 + W_4^1\, a_3 = -2 + (-j)(-2) = -2 + 2j\\ X[2] &= a_0 - W_4^0\, a_2 = 4 - 6 = -2\\ X[3] &= a_1 - W_4^1\, a_3 = -2 - 2j \end{aligned}$$Step 4 — check $X[1]$ directly.
$$X[1] = \sum_{n=0}^{3} x[n]e^{-j\pi n/2} = 1 + 2(-j) + 3(-1) + 4(j) = -2 + 2j \checkmark$$Note the count: 1 complex multiply total (the $-j\cdot a_3$, itself trivial) vs $N^2 = 16$ for the direct DFT. Also note $X[3] = X^*[1]$ — conjugate symmetry, since $x[n]$ is real.
Problem: For a 16-point radix-2 DIT FFT: (a) list the required input ordering; (b) which indices remain in place, and why? (c) How many stages does the FFT have, what butterflies does stage 3 contain (row spans and twiddles), and how many complex multiplies does the whole transform need (upper bound)?
(a) Reverse 4-bit addresses ($0000 \to 0000$, $0001 \to 1000$, …). Input order:
$$x[0], x[8], x[4], x[12], x[2], x[10], x[6], x[14], x[1], x[9], x[5], x[13], x[3], x[11], x[7], x[15]$$(b) An index stays in place iff its 4-bit pattern is a palindrome: $0000 = 0$, $0110 = 6$, $1001 = 9$, $1111 = 15$. (The remaining 12 indices form 6 swap pairs — bit reversal is its own inverse, so the shuffle is done with simple pairwise swaps, in place.)
(c) $M = \log_2 16 = 4$ stages. In stage 3 the butterflies span $2^{3-1} = 4$ rows: groups $(0\text{–}3$ with $4\text{–}7)$ and $(8\text{–}11$ with $12\text{–}15)$, twiddles $W_{8}^{0..3} = W_{16}^{0}, W_{16}^{2}, W_{16}^{4}, W_{16}^{6}$ applied to the lower input of each butterfly. Total complex multiplies $\le \frac{N}{2}\log_2 N = 8 \times 4 = 32$ (vs $N^2 = 256$ direct; even fewer in practice since $W^0, W^{N/4}$ are trivial).
Problem: Write MATLAB code that computes the DFTs of the two real sequences
$x[n] = \cos(2\pi\,5n/N) + 0.5\cos(2\pi\,12n/N)$ and $w[n] = \sin(2\pi\,9n/N) + 0.3\,\text{randn}$, $N = 64$, using a single 64-point complex FFT. Recover $X[k]$ and $W[k]$, verify both against direct fft calls, and plot the recovered magnitude spectra.
Pack $y[n] = x[n] + j\,w[n]$, transform once, then split with the conjugate-symmetry formulas of §15.4.3. The only subtlety is indexing $V^*[-k]$: with MATLAB's 1-based arrays, $V^*[\langle N-k\rangle_N]$ for $k = 0,\dots,N{-}1$ is conj(V(mod(N-(0:N-1),N)+1)).
N = 64; n = 0:N-1; x = cos(2*pi*5*n/N) + 0.5*cos(2*pi*12*n/N); % real sequence 1 w = sin(2*pi*9*n/N) + 0.3*randn(1,N); % real sequence 2 y = x + 1j*w; % pack into ONE complex sequence V = fft(y); % single N-pt complex FFT Vc = conj(V(mod(N-(0:N-1), N) + 1)); % V*[_N] (= V*[-k]) X = (V + Vc)/2; % spectrum of x W = (V - Vc)/(2j); % spectrum of w (-j/2 form) errX = max(abs(X - fft(x))) % ~ 3.6e-15 errW = max(abs(W - fft(w))) % ~ 5.3e-15 subplot(2,1,1); stem(n, abs(X)); ylabel('|X[k]|'); title('Recovered from one complex FFT'); subplot(2,1,2); stem(n, abs(W)); ylabel('|W[k]|'); xlabel('k');
Regenerated result (numpy, same algorithm) — both spectra are recovered to machine precision ($\sim 10^{-15}$):
Why it works: $x$ real $\Rightarrow X[k] = X^*[-k]$; $jw$ contributes the anti-symmetric part. Adding/subtracting $V^*[-k]$ separates the symmetric ($X$) and antisymmetric ($jW$) parts — two real $N$-pt DFTs for the price of one complex FFT, a ~2× saving.
Problem: (a) Derive the second-order (real-coefficient) Goertzel transfer function from $H(z) = 1/(1 - W_N^{-k}z^{-1})$. (b) Count the real multiplies needed to compute one bin $X[k]$ of an $N$-point DFT with it. (c) A DTMF receiver needs $M = 8$ bins of an $N = 256$-point DFT. Which is cheaper, Goertzel or a radix-2 FFT? Find the break-even number of bins.
(a) Multiply numerator and denominator by $(1 - W_N^{k}z^{-1})$:
$$H(z) = \frac{1}{1 - W_N^{-k}z^{-1}}\cdot\frac{1 - W_N^{k}z^{-1}}{1 - W_N^{k}z^{-1}} = \frac{1 - W_N^{k}z^{-1}}{1 - \big(W_N^{k} + W_N^{-k}\big)z^{-1} + z^{-2}} = \frac{1 - W_N^{k}z^{-1}}{1 - 2\cos\!\big(\tfrac{2\pi k}{N}\big)z^{-1} + z^{-2}}$$using $W_N^k + W_N^{-k} = 2\cos(2\pi k/N)$. The denominator is now real.
(b) Run the all-pole recursion $s[n] = x[n] + 2\cos(2\pi k/N)\,s[n-1] - s[n-2]$ for $n = 0..N$: one real coefficient × (real input + real states) = 2 real mults per step for complex… for real input $x[n]$ the states stay real, so 1 real mult/step, $\approx N$ real mults total. The complex numerator $y[n] = s[n] - W_N^k s[n-1]$ is evaluated only at the last step $n = N$: + 4 real mults. Total $\approx N + 4$ real mults per bin (vs $4N$ for direct evaluation of one bin).
(c) Goertzel for $M$ bins: $\approx M(N+4) = 8 \times 260 = 2080$ real mults. Radix-2 FFT: $4\cdot\frac N2\log_2 N = 2\cdot 256\cdot 8 = 4096$ real mults (upper bound) — and it computes all 256 bins. Goertzel wins here. Break-even: $M(N+4) \approx 2N\log_2 N \Rightarrow M \approx 2\log_2 N = 16$ bins. Rule of thumb from §15.1.3: Goertzel is preferable when the number of needed bins $M \lesssim 2\log_2 N$; it also needs no input buffer (streaming) and no twiddle table.