Outline大綱アウトライン
15.1 Computing the DFT Directly15.1 直接計算 DFT15.1 DFT を直接計算する
15.2 Decimation-in-Time FFT15.2 時間抽取 FFT15.2 時間間引き FFT
15.3 The Complete Radix-2 FFT15.3 完整的基 2 FFT15.3 完全な基数 2 FFT
15.4 FFT Variations15.4 FFT 的各種變形15.4 FFT の変種
15.5 The FFT in MATLAB15.5 MATLAB 中的 FFT15.5 MATLAB での FFT
15.6 Summary15.6 總結15.6 まとめ
Exercises習題演習問題
DSP Study Guide · Chapter 15DSP 學習指南 · 第 15 章DSP 学習ガイド · 第 15 章

The Fast Fourier Transform快速傅立葉轉換高速フーリエ変換

Why the direct DFT costs O(N²), how Goertzel's algorithm and the decimation-in-time radix-2 FFT exploit twiddle-factor structure, butterflies, bit reversal, in-place computation, and fast transforms in practice直接計算 DFT 為何要 O(N²)、Goertzel 演算法與時間抽取基 2 FFT 如何利用旋轉因子的結構、蝶形運算、位元反轉、原位計算,以及快速轉換在實務上的使用直接 DFT が O(N²) となる理由、Goertzel のアルゴリズムと時間間引き基数 2 FFT が回転因子の構造をどう利用するか、バタフライ演算、ビット反転、その場計算、そして実務における高速変換

15.1 Computing the DFT Directly15.1 直接計算 DFT15.1 DFT を直接計算する

15.1.1 The DFT and twiddle factors15.1.1 DFT 與旋轉因子15.1.1 DFT と回転因子

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$:第 8 章把 DFT 介紹成離散(有限長度)序列的離散轉換。回想它的定義,用旋轉因子 $W_N$ 寫成緊湊的形式:第 8 章では DFT を、離散(有限長)系列に対する離散変換として導入した。その定義を回転因子 $W_N$ を使って簡潔に書き直すと次のようになる。

DFT and twiddle factorDFT 與旋轉因子DFT と回転因子 $$X[k] = \sum_{n=0}^{N-1} x[n]\, W_N^{kn}, \qquad k = 0,\dots,N-1, \qquad W_N \equiv e^{-j\frac{2\pi}{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:$W_N$ 是單位圓上角度為 $-2\pi/N$ 的單位長度複數。由於 $W_N^{r}$ 只取決於 $r \bmod N$,冪次 $W_N^r$ 只會取到$N$ 個相異值——也就是 $N$ 次單位根。這個結構帶來的兩個推論,支配了本章的一切:$W_N$ は単位円上の角度 $-2\pi/N$ に位置する、大きさ 1 の複素数である。$W_N^{r}$ は $r \bmod N$ にしか依存しないので、べき $W_N^r$ は$N$ 個の相異なる値——すなわち 1 の $N$ 乗根——しか取らない。この構造から導かれる二つの帰結が、本章のすべてを動かしている。

Twiddle-factor properties旋轉因子的性質回転因子の性質 $$\underbrace{W_N^{r+N} = W_N^{r}}_{\text{periodicity 週期性}} \qquad \underbrace{W_N^{\,r+N/2} = -\,W_N^{r}}_{\text{half-period symmetry 對稱性}} \qquad \underbrace{W_N^{2} = W_{N/2}}_{\text{index halving}}$$

In matrix form the DFT is a dense $N\times N$ matrix–vector product,寫成矩陣形式,DFT 就是一個稠密的 $N\times N$ 矩陣與向量的乘積,行列の形で書けば、DFT は密な $N\times N$ 行列とベクトルの積である。

Matrix form矩陣形式行列形式 $$\begin{bmatrix} X[0]\\ X[1]\\ X[2]\\ \vdots\\ X[N-1] \end{bmatrix} = \begin{bmatrix} 1 & 1 & 1 & \cdots & 1\\ 1 & W_N^{1} & W_N^{2} & \cdots & W_N^{(N-1)}\\ 1 & W_N^{2} & W_N^{4} & \cdots & W_N^{2(N-1)}\\ \vdots & \vdots & \vdots & \ddots & \vdots\\ 1 & W_N^{(N-1)} & W_N^{2(N-1)} & \cdots & W_N^{(N-1)^2} \end{bmatrix} \begin{bmatrix} x[0]\\ x[1]\\ x[2]\\ \vdots\\ x[N-1] \end{bmatrix}$$

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.但這個矩陣絕非任意:每個元素都只是那 $N$ 個值之一,而且排列得極為規律。圖 15-1 把 $N=32$ 的 DFT 矩陣的實部與虛部畫了出來——這份結構正是 FFT 所利用的效率機會。しかしこの行列は決して任意ではない。各要素はあの $N$ 個の値のどれかにすぎず、しかも極めて規則的に並んでいる。図 15-1 は $N=32$ の DFT 行列の実部と虚部を可視化したものである。この構造こそ、FFT が利用する効率化の余地にほかならない。

2026-06-12T22:38:04.002423 image/svg+xml Matplotlib v3.10.8, https://matplotlib.org/ 0 10 20 30 n 0 5 10 15 20 25 30 k R e { }     ( N   =   3 2 ) W N k n 0 10 20 30 n 0 5 10 15 20 25 30 k I m { }     ( N   =   3 2 ) W N k n −1.00 −0.75 −0.50 −0.25 0.00 0.25 0.50 0.75 1.00
Fig. 15-1 — Real and imaginary parts of the DFT matrix $W_N^{kn}$ for $N=32$. Each row $k$ is a sampled complex exponential; the regular pattern (only $N$ distinct values, mirror symmetries) is what fast algorithms exploit.(DFT 矩陣高度規律,並非任意矩陣 — 這正是 FFT 可以加速的原因。)圖 15-1 — $N=32$ 時 DFT 矩陣 $W_N^{kn}$ 的實部與虛部。每一列 $k$ 都是一條取樣後的複指數;這種規律的樣式(相異值只有 $N$ 個,還帶有鏡像對稱)正是快速演算法所利用的東西。図 15-1 — $N=32$ における DFT 行列 $W_N^{kn}$ の実部と虚部。各行 $k$ は標本化された複素指数であり、この規則的な模様(相異なる値は $N$ 個だけで、鏡映対称もある)こそ高速アルゴリズムが利用するものである。

15.1.2 Cost of direct evaluation15.1.2 直接計算的代價15.1.2 直接計算のコスト

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照字面把 DFT 的和算出來。對每一個輸出點 $X[k]$ 都需要 $N$ 次複數乘法與 $N-1$ 次複數加法;而輸出點共有 $N$ 個($k = 0,\dots,N-1$)。再用下式換算成實數運算DFT の和を文字どおりに計算してみる。一つの出力点 $X[k]$ ごとに複素乗算が $N$ 回、複素加算が $N-1$ 回必要であり、出力点は $N$ 個ある($k = 0,\dots,N-1$)。次式で実数演算に換算すると

$(a+jb)(c+jd) = (ac-bd) + j(ad+bc)$ = 4 real mults + 2 real adds,   1 complex add = 2 real adds,$(a+jb)(c+jd) = (ac-bd) + j(ad+bc)$ = 4 次實數乘法 + 2 次實數加法,  1 次複數加法 = 2 次實數加法,$(a+jb)(c+jd) = (ac-bd) + j(ad+bc)$ = 実数乗算 4 回 + 実数加算 2 回、  複素加算 1 回 = 実数加算 2 回、

the total damage is:總開銷就是:総計は次のようになる。

Direct DFT cost直接計算 DFT 的代價直接 DFT のコスト $$\text{complex: } N^2 \text{ mults},\; N(N-1) \text{ adds} \qquad\Longrightarrow\qquad \boxed{\,4N^2 \text{ real mults},\quad 4N^2 - 2N \text{ real adds}\,}$$
Why O(N²) hurtsO(N²) 為何致命O(N²) がなぜ致命的か

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.代價隨長度的平方成長:$N$ 加倍,工作量就變成四倍。在 $N = 1024$ 時直接計算 DFT 約需 $4\times 10^6$ 次複數運算;在 $N = 10^6$(1 MHz 取樣下一秒的音訊)時則需要 $10^{12}$ 次——對即時處理而言完全不切實際。這道 $O(N^2)$ 的牆,正是 1965 年的 Cooley–Tukey FFT 經常被列為二十世紀最重要演算法之一的原因。コストは長さの二乗で増える。$N$ を倍にすれば仕事量は 4 倍になる。$N = 1024$ では直接 DFT に約 $4\times 10^6$ 回の複素演算が要り、$N = 10^6$(1 MHz で 1 秒ぶんの音声)では $10^{12}$ 回となって、実時間処理にはまったく実用にならない。この $O(N^2)$ の壁こそ、1965 年の Cooley–Tukey FFT が 20 世紀で最も重要なアルゴリズムの一つに数えられる理由である。

15.1.3 Goertzel's algorithm15.1.3 Goertzel 演算法15.1.3 Goertzel のアルゴリズム

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$:在正面處理整個 DFT 之前,課程先讓我們嚐一口利用旋轉因子結構的滋味:Goertzel 演算法把單一個 DFT 頻格算成一個小型遞迴濾波器的輸出。從 DFT 的和出發,提出一個因子 $W_N^{kN} = 1$:完全な DFT に取りかかる前に、講義は回転因子の構造を利用する最初の一例を示す。Goertzel のアルゴリズムは、一つの DFT ビンを小さな再帰フィルタの出力として計算する。DFT の和から出発し、因子 $W_N^{kN} = 1$ をくくり出す。

DFT bin as a convolution把 DFT 頻格寫成摺積DFT ビンを畳み込みとして書く $$X[k] = \sum_{\ell=0}^{N-1} x[\ell]\, W_N^{k\ell} = W_N^{kN}\sum_{\ell} x[\ell]\, W_N^{-k(N-\ell)}$$

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右邊那個和看起來就像摺積在時刻 $N$ 的值:它就是 $\sum_\ell x[\ell]\, h_k[N-\ell]$,其中 $h_k[n] = W_N^{-kn}u[n]$。因此右辺の和は、時刻 $N$ で評価した畳み込みの形をしている。すなわち $h_k[n] = W_N^{-kn}u[n]$ とおいた $\sum_\ell x[\ell]\, h_k[N-\ell]$ である。したがって

Goertzel recursionGoertzel 遞迴式Goertzel の再帰式 $$X[k] = y_k[N], \qquad y_k[n] = x_e[n] \circledast h_k[n], \qquad h_k[n] = \begin{cases} W_N^{-kn} & n \ge 0\\ 0 & n < 0\end{cases}$$ $$\text{with } x_e[n] = \begin{cases} x[n] & 0 \le n < N\\ 0 & n = N \end{cases} \qquad\Longrightarrow\qquad y_k[n] = x_e[n] + W_N^{-k}\, y_k[n-1],\quad y_k[-1]=0$$

So one first-order complex recursion, clocked $N+1$ times (feeding $x_e[N]=0$ at the end), delivers $y_k[N] = X[k]$:所以只要一條一階複數遞迴,跑 $N+1$ 拍(最後一拍餵入 $x_e[N]=0$),就能得到 $y_k[N] = X[k]$:したがって 1 次の複素再帰を $N+1$ 回クロックし(最後に $x_e[N]=0$ を入力する)だけで、$y_k[N] = X[k]$ が得られる。

xe[n] + yk[n] z−1 WN−k yk[−1] = 0,   xe[N] = 0 yk[N] = X[k]
Fig. 15-2 — Goertzel's algorithm: a first-order recursive filter whose state after $N$ steps equals one DFT bin $X[k]$.(用一個一階遞迴濾波器「跑」過整段訊號,最後一步的輸出就是單一頻點 $X[k]$。)圖 15-2 — Goertzel 演算法:一個一階遞迴濾波器「跑」過整段訊號,走完 $N$ 步之後的狀態就等於單一個 DFT 頻格 $X[k]$;最後一步的輸出即為 $X[k]$。図 15-2 — Goertzel のアルゴリズム:1 次の再帰フィルタに信号全体を通し、$N$ ステップ後の状態が一つの DFT ビン $X[k]$ に等しくなる。最後のステップの出力がそのまま $X[k]$ である。

Properties claimed on the slide, worth memorizing:投影片上列出的性質,值得記下來:スライドが挙げている性質で、覚えておく価値があるもの。

Goertzel, second-order formGoertzel 的二階形式Goertzel の 2 次形式 $$H(z) = \frac{1}{1 - W_N^{-k} z^{-1}} = \frac{1 - W_N^{k} z^{-1}}{1 - 2\cos\!\big(\tfrac{2\pi k}{N}\big) z^{-1} + z^{-2}}$$

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$.現在這條遞迴用的是實數係數 $2\cos(2\pi k/N)$——每一步只要2 次實數乘法——而複數的分子 $(1 - W_N^k z^{-1})$ 只在最後一步 $n=N$ 算一次。この再帰が使うのは実数係数 $2\cos(2\pi k/N)$ であり、1 ステップあたり実数乗算 2 回だけで済む。複素の分子 $(1 - W_N^k z^{-1})$ は最後のステップで一度だけ、$n=N$ において評価される。

When Goertzel beats the FFTGoertzel 何時勝過 FFTGoertzel が FFT に勝つとき

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。)Goertzel 的代價是每個頻格 $O(N)$;FFT 則是用 $O(N\log_2 N)$ 一次算出全部 $N$ 個頻格。所以若只需要 $M$ 個頻格,大致在 $M \lesssim \log_2 N$ 時 Goertzel 勝出。要從 $N=205$ 個樣本中偵測 8 個按鍵音頻率的 DTMF 偵測器,就是經典的用例。Goertzel のコストは1 ビンあたり $O(N)$ であり、FFT は全 $N$ ビンをまとめて $O(N\log_2 N)$ で求める。したがって必要なビンが $M$ 個だけなら、おおむね $M \lesssim \log_2 N$ のとき Goertzel が有利である。$N=205$ 標本から 8 個のトーン周波数を検出する DTMF 検出器が、その典型的な用例である。

15.2 Decimation-in-Time FFT15.2 時間抽取 FFT15.2 時間間引き FFT

15.2.1 Splitting the DFT into even/odd halves15.2.1 把 DFT 拆成偶數/奇數兩半15.2.1 DFT を偶数・奇数の半分に分割する

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$):時間抽取(DIT)FFT 把 DFT 的和重新排成兩半:時間索引為偶數 $n=2m$ 的項,以及索引為奇數 $n = 2m+1$ 的項(先假設 $N$ 是偶數,最終取 $N = 2^M$):時間間引き(DIT)FFT は、DFT の和を二つの半分に並べ替える。時間索引が偶数 $n=2m$ の項と、奇数 $n = 2m+1$ の項である($N$ は偶数、最終的には $N = 2^M$ とする)。

DIT split — derivationDIT 拆分——推導DIT 分割 — 導出 $$\begin{aligned} X[k] &= \sum_{n=0}^{N-1} x[n]\, W_N^{nk}, \qquad k = 0,\dots,N-1\\[2pt] &= \sum_{m=0}^{\frac{N}{2}-1}\Big( x[2m]\,W_N^{2mk} + x[2m+1]\, W_N^{(2m+1)k}\Big)\\[2pt] &= \underbrace{\sum_{m=0}^{\frac{N}{2}-1} x[2m]\, W_{N/2}^{mk}}_{\textstyle X_0\big[\langle k\rangle_{N/2}\big]} \;+\; W_N^{k}\underbrace{\sum_{m=0}^{\frac{N}{2}-1} x[2m+1]\, W_{N/2}^{mk}}_{\textstyle X_1\big[\langle k\rangle_{N/2}\big]} \end{aligned}$$

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:關鍵的一步用到 $W_N^{2mk} = W_{N/2}^{mk}$(索引減半)。$X_0$ 是偶數索引樣本的 $N/2$ 點 DFT,$X_1$ 則是奇數索引樣本的 $N/2$ 點 DFT。由於 $N/2$ 點 DFT 對 $k$ 具有週期 $N/2$ 的週期性,兩者都在 $\langle k\rangle_{N/2}$(也就是 $k$ 對 $N/2$ 取模)處取值。用課程的緊湊記法寫出來,結果是:鍵となる一歩で $W_N^{2mk} = W_{N/2}^{mk}$(索引の半減)を使う。$X_0$ は偶数索引の標本の $N/2$ 点 DFTであり、$X_1$ は奇数索引の標本の $N/2$ 点 DFTである。$N/2$ 点 DFT は $k$ について周期 $N/2$ をもつので、どちらも $\langle k\rangle_{N/2}$($k$ を $N/2$ で割った余り)で評価する。講義の簡潔な記法で書けば、結果は次のとおりである。

One-step DIT decomposition單步 DIT 分解1 段の DIT 分解 $$\mathrm{DFT}_N\{x[n]\} \;=\; \mathrm{DFT}_{\frac{N}{2}}\{x_0[n]\} \;+\; W_N^{k}\,\mathrm{DFT}_{\frac{N}{2}}\{x_1[n]\} \qquad \begin{cases} x_0[n] = x[2n] & \text{even samples}\\ x_1[n] = x[2n+1] & \text{odd samples} \end{cases}$$
直觀解釋(點擊展開)
把 $N$ 點訊號按「偶數位置」與「奇數位置」抽開(這就是「時間抽取」的意思),各自做 $N/2$ 點 DFT。偶數那組直接貢獻 $X_0[k]$;奇數那組因為整體往右平移了一格,依時移性質要多乘一個相位 $W_N^k$(旋轉因子)。兩者相加就還原出完整的 $N$ 點 DFT。重點在於:兩個小 DFT 的成本各是 $(N/2)^2$,加起來只有原本 $N^2$ 的一半 — 而且這招可以對小 DFT 反覆使用,一路砍到只剩 2 點 DFT 為止。

Why does this save anything? Count again:這樣到底省在哪裡?再數一次:これでなぜ節約になるのか。もう一度数えてみる。

One split ≈ half the work拆一次 ≈ 工作量減半1 回の分割 ≈ 仕事量は半分 $$\mathrm{DFT}_N \sim O(N^2),\qquad \mathrm{DFT}_{N/2} \sim O\big((N/2)^2\big) = \tfrac14\,O(N^2) \;\;\Longrightarrow\;\; \text{total} \sim 2\cdot\tfrac14\,O(N^2) = \tfrac12\,O(N^2)\;(+\,\varepsilon)$$

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.拆一次就把計算量減半(其中 $\varepsilon$ 代表合併兩半時額外需要的 $N$ 次旋轉因子乘法與加法)。我們可以把一個 $N$ 點 DFT 算成兩個 $N/2$ 點 DFT 再加上少數幾次乘法/加法。1 回の分割で計算量は半分になる($\varepsilon$ は、二つの半分を合成するために余分に必要な $N$ 回の回転因子乗算と加算を表す)。$N$ 点 DFT は、二つの $N/2$ 点 DFT と少数の乗算・加算で評価できるのである。

15.2.2 One-stage DIT flowgraph15.2.2 單級 DIT 訊號流程圖15.2.2 1 段の DIT 信号流れ図

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.把合併式對所有 $k = 0,\dots,N-1$ 寫出來,並利用週期性 $X_0[\langle k\rangle_{N/2}]$、$X_1[\langle k\rangle_{N/2}]$,$N=8$ 時的結構就如圖 15-3 所示。要特別注意——投影片也強調過——旋轉因子 $W_N^k$ 永遠只乘在奇數那一半的輸出 $X_1[\cdot]$ 上,而且它們並不是鏡像對稱的:輸出 $X[k+N/2]$ 用的是 $W_N^{k+N/2} = -W_N^k$,而不是再用一次 $W_N^{k}$。合成式をすべての $k = 0,\dots,N-1$ について書き下し、周期性 $X_0[\langle k\rangle_{N/2}]$、$X_1[\langle k\rangle_{N/2}]$ を使うと、$N=8$ の場合の構造は図 15-3 のようになる。スライドが強調するとおり、ここは注意を要する。回転因子 $W_N^k$ は常に奇数側の出力 $X_1[\cdot]$ にのみ掛かり、しかも鏡映にはならない。出力 $X[k+N/2]$ が使うのは $W_N^{k+N/2} = -W_N^k$ であって、$W_N^{k}$ をもう一度使うのではない。

x[0] x[2] x[4] x[6] x[1] x[3] x[5] x[7] DFT₄ even n DFT₄ odd n X₀[0] X₀[1] X₀[2] X₀[3] X₁[0] X₁[1] X₁[2] X₁[3] W₈⁰ W₈¹ W₈² W₈³ −1 −1 −1 −1 X[0] X[1] X[2] X[3] X[4] X[5] X[6] X[7] classic FFT structure
Fig. 15-3 — One-stage DIT decomposition of an 8-pt DFT (simplified butterflies): $X[k] = X_0[k] + W_8^{k}X_1[k]$ and $X[k+4] = X_0[k] - W_8^{k}X_1[k]$ for $k=0..3$. Twiddles apply only to the odd-half outputs $X_1[\cdot]$; the $-1$ on the lower horizontal branch implements $W_8^{k+4} = -W_8^k$.(旋轉因子只乘在奇數那一半的輸出上,下半部輸出用減法。)圖 15-3 — 8 點 DFT 的單級 DIT 分解(已化簡的蝶形):對 $k=0..3$ 有 $X[k] = X_0[k] + W_8^{k}X_1[k]$ 與 $X[k+4] = X_0[k] - W_8^{k}X_1[k]$。旋轉因子只乘在奇數那一半的輸出 $X_1[\cdot]$ 上;下方水平支路上的 $-1$ 實現的正是 $W_8^{k+4} = -W_8^k$,所以下半部的輸出改用減法。図 15-3 — 8 点 DFT の 1 段 DIT 分解(簡略化したバタフライ)。$k=0..3$ に対して $X[k] = X_0[k] + W_8^{k}X_1[k]$ および $X[k+4] = X_0[k] - W_8^{k}X_1[k]$ である。回転因子は奇数側の出力 $X_1[\cdot]$ にのみ掛かり、下側の水平枝にある $-1$ が $W_8^{k+4} = -W_8^k$ を実現している。

15.2.3 Recursing to multiple stages15.2.3 遞迴到多級15.2.3 多段への再帰

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:如果把一個 $\mathrm{DFT}_N$ 分解成兩個較小的 $\mathrm{DFT}_{N/2}$ 可以加速——那為什麼不再往下分成 $\mathrm{DFT}_{N/4}$ 呢?把完全相同的拆分手法套用到 $X_0[k]$(偶數樣本的那個 DFT):把它的輸入再拆成偶中之偶與偶中之奇兩個子集:一つの $\mathrm{DFT}_N$ を二つの小さな $\mathrm{DFT}_{N/2}$ に分解して速くなるなら、さらに $\mathrm{DFT}_{N/4}$ まで分割してはどうか。まったく同じ分割を $X_0[k]$(偶数標本の DFT)に適用し、その入力を偶数の中の偶数と偶数の中の奇数の部分集合に分ける。

Second-level split第二層拆分2 段目の分割 $$X[k] = X_0\big[\langle k\rangle_{\frac N2}\big] + W_N^{k} X_1\big[\langle k\rangle_{\frac N2}\big],\qquad 0 \le k < N$$ $$X_0[k] = X_{00}\big[\langle k\rangle_{\frac N4}\big] + W_{\frac N2}^{\,k} X_{01}\big[\langle k\rangle_{\frac N4}\big],\qquad 0 \le k < N/2$$ $$X_1[k] = X_{10}\big[\langle k\rangle_{\frac N4}\big] + W_{\frac N2}^{\,k} X_{11}\big[\langle k\rangle_{\frac N4}\big]$$

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.其中 $X_{00}$ 是 $x[n]$ 偶數子集之內那些偶數點的 $N/4$ 點 DFT(也就是 $x[0],x[4],x[8],\dots$),$X_{01}$ 則是偶數子集中奇數點的 $N/4$ 點 DFT,其餘依此類推。注意第二層的旋轉因子是 $W_{N/2}^{k}$——$N=8$ 時就是 $W_4^k = W_8^{2k}$,所以第二級只會出現 $W_8^0$ 與 $W_8^2$。ここで $X_{00}$ は $x[n]$ の偶数部分集合の中にある偶数点の $N/4$ 点 DFT(すなわち $x[0],x[4],x[8],\dots$)であり、$X_{01}$ は偶数部分集合の中の奇数点の $N/4$ 点 DFT、以下同様である。2 段目の回転因子が $W_{N/2}^{k}$ である点に注意せよ。$N=8$ ならこれは $W_4^k = W_8^{2k}$ であり、2 段目には $W_8^0$ と $W_8^2$ しか現れない。

Keep recursing until we hit 2-point DFTs, which need no multiplies at all:一直遞迴下去,直到碰上2 點 DFT,它根本不需要任何乘法:そのまま再帰を続け、2 点 DFT に行き着く。これは乗算をまったく必要としない。

2-pt DFT — the atomic butterfly2 點 DFT——最小單位的蝶形2 点 DFT — 最小単位のバタフライ $$\mathrm{DFT}_2:\quad X[0] = x[0] + x[1], \qquad X[1] = x[0] - x[1] \qquad (1 = W_2^0,\;\; -1 = W_2^1)$$

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.於是一個 $N = 2^M$ 點 DFT 就化約成 $M = \log_2 N$ 級的旋轉因子與加總——$O(N^2)$ 那一部分完全消失了。こうして $N = 2^M$ 点 DFT は、回転因子と総和からなる $M = \log_2 N$ 段へと帰着し、$O(N^2)$ の部分は完全に消え去る。

15.2.4 The butterfly and its simplification15.2.4 蝶形運算與它的化簡15.2.4 バタフライ演算とその簡略化

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,在每一級,基本運算都把相隔 $r$ 與 $r + N/2$ 的兩個值配成一對,產生兩個輸出。這就是蝶形運算。照最初推導出來的樣子,它需要兩次複數乘法,$W_N^r$ 與 $W_N^{r+N/2}$。但由半週期對稱性,どの段でも、基本演算は $r$ と $r + N/2$ だけ離れた二つの値を組にし、二つの出力を生む。これがバタフライ演算である。最初に導いた形では複素乗算が二つ、すなわち $W_N^r$ と $W_N^{r+N/2}$ が必要になる。しかし半周期の対称性により、

Twiddle symmetry kills one multiply旋轉因子的對稱性省掉一次乘法回転因子の対称性が乗算を一つ消す $$W_N^{\,r+\frac N2} = e^{-j\frac{2\pi (r+\frac N2)}{N}} = e^{-j\frac{2\pi r}{N}}\cdot e^{-j\frac{2\pi (N/2)}{N}} = W_N^{r}\cdot e^{-j\pi} = -\,W_N^{r}$$

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:所以第二次乘法只是第一次的相反數——也就是改成相減而不是相加。於是每個蝶形只花一次複數乘法與兩次複數加法:したがって二つ目の乗算は一つ目の符号を変えたものにすぎない。つまり加えるかわりに引けばよい。こうして各バタフライのコストは複素乗算一つと複素加算二つになる。

(a) Butterfly as derived — 2 complex mults X₀[r] X₁[r] WNr WNr+N/2 X[r] X[r+N/2] (b) Simplified butterfly — just 1 complex mult X₀[r] X₁[r] WNr −1 i.e. SUB rather than ADD X[r] X[r+N/2]
Fig. 15-4 — The basic butterfly. (a) As derived: gains $W_N^{r}$ (to the top output) and $W_N^{r+N/2}$ (to the bottom output) on the two edges leaving $X_1[r]$ — two complex multiplies. (b) Since $W_N^{r+N/2} = -W_N^{r}$, multiply $X_1[r]$ by $W_N^{r}$ once, then add for $X[r]$ and subtract for $X[r+N/2]$ — one complex multiply.(蝶形運算化簡:下半輸出改用減法,省掉一次複數乘法。)圖 15-4 — 基本蝶形。(a) 照推導的樣子:從 $X_1[r]$ 出發的兩條邊各帶增益 $W_N^{r}$(通往上方輸出)與 $W_N^{r+N/2}$(通往下方輸出)——兩次複數乘法。(b) 由於 $W_N^{r+N/2} = -W_N^{r}$,只要把 $X_1[r]$ 乘上 $W_N^{r}$ 一次,再相加得 $X[r]$、相減得 $X[r+N/2]$——一次複數乘法就夠了。図 15-4 — 基本バタフライ。(a) 導出どおりの形:$X_1[r]$ から出る二つの枝にそれぞれ利得 $W_N^{r}$(上側の出力へ)と $W_N^{r+N/2}$(下側の出力へ)が付き、複素乗算は二つになる。(b) $W_N^{r+N/2} = -W_N^{r}$ であるから、$X_1[r]$ に $W_N^{r}$ を一度だけ掛け、加えて $X[r]$、引いて $X[r+N/2]$ を得る。複素乗算は一つで済む。
Simplified butterfly equations化簡後的蝶形方程式簡略化したバタフライの式 $$\boxed{\;X[r] = X_0[r] + W_N^{r}\,X_1[r], \qquad X\big[r+\tfrac N2\big] = X_0[r] - W_N^{r}\,X_1[r]\;}$$

15.3 The Complete Radix-2 FFT15.3 完整的基 2 FFT15.3 完全な基数 2 FFT

15.3.1 The 8-point DIT flowgraph15.3.1 8 點 DIT 訊號流程圖15.3.1 8 点 DIT 信号流れ図

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$).把全部 $M = \log_2 8 = 3$ 級的化簡蝶形組裝起來,就得到圖 15-5 那張經典的訊號流程圖。隨便挑一個輸出往回追:第 1 級算出四個 2 點 DFT,第 2 級把它們併成兩個 4 點 DFT(旋轉因子 $W_8^0, W_8^2$——也就是 $W_4^0, W_4^1$),第 3 級再把這兩個併成最終的 8 點 DFT(旋轉因子 $W_8^0,\dots,W_8^3$)。簡略化したバタフライを $M = \log_2 8 = 3$ 段ぶん組み上げると、図 15-5 の古典的な信号流れ図が得られる。どの出力でもよいので遡ってみよ。第 1 段は 2 点 DFT を四つ計算し、第 2 段はそれらを二つの 4 点 DFT に併合し(回転因子 $W_8^0, W_8^2$、すなわち $W_4^0, W_4^1$)、第 3 段がそれらを最終的な 8 点 DFT に併合する(回転因子 $W_8^0,\dots,W_8^3$)。

000 100 010 110 001 101 011 111 x[0] x[4] x[2] x[6] x[1] x[5] x[3] x[7] −1 −1 −1 −1 W₈² W₈² −1 −1 −1 −1 W₈¹ W₈² W₈³ −1 −1 −1 −1 X[0] X[1] X[2] X[3] X[4] X[5] X[6] X[7] Stage 1 — four 2-pt DFTs Stage 2 — two 4-pt DFTs Stage 3 — one 8-pt DFT
Fig. 15-5 — Complete 8-pt DIT FFT flowgraph (simplified butterflies). Inputs enter in bit-reversed order (green binary labels), outputs leave in natural order. All $W_8^0 = 1$ multipliers have disappeared; the $-1$'s are absorbed into the summation nodes (lower butterfly branch subtracts). Stage 2 uses $W_8^0, W_8^2$ ($=W_4^0, W_4^1$); stage 3 uses $W_8^0, W_8^1, W_8^2, W_8^3$.(輸入位元反轉排序、輸出自然排序;每級只剩一半的旋轉因子乘法。)圖 15-5 — 完整的 8 點 DIT FFT 訊號流程圖(化簡蝶形)。輸入依位元反轉順序進入(綠色的二進位標籤),輸出則以自然順序離開。所有 $W_8^0 = 1$ 的乘法都不見了;那些 $-1$ 被吸收進加總節點(蝶形的下支路改成相減)。第 2 級用 $W_8^0, W_8^2$($=W_4^0, W_4^1$);第 3 級用 $W_8^0, W_8^1, W_8^2, W_8^3$。図 15-5 — 完全な 8 点 DIT FFT 信号流れ図(簡略化したバタフライ)。入力はビット反転順序で入り(緑の 2 進ラベル)、出力は自然順序で出てくる。$W_8^0 = 1$ の乗算はすべて消えており、$-1$ は総和ノードに吸収されている(バタフライの下側の枝が減算になる)。第 2 段は $W_8^0, W_8^2$($=W_4^0, W_4^1$)を、第 3 段は $W_8^0, W_8^1, W_8^2, W_8^3$ を使う。
Reading the flowgraph怎麼讀這張訊號流程圖信号流れ図の読み方

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).在第 $s$ 級($s = 1,\dots,M$),蝶形跨越 $2^{s-1}$ 列,旋轉因子是 $W_{2^s}$ 的冪次,等價地也就是 $W_N^{rN/2^s}$。每一級最多只會出現 $N/2$ 次複數乘法(一個蝶形一次),而其中許多還是乘以 $W^0 = 1$,不花任何代價。平凡的因子有:$W^0=1$(免費)、$W_8^2 = -j$(把實部與虛部對調再加個符號——實作上同樣不需要乘法)。第 $s$ 段($s = 1,\dots,M$)では、バタフライは $2^{s-1}$ 行にまたがり、回転因子は $W_{2^s}$ のべき、すなわち $W_N^{rN/2^s}$ である。1 段あたりに生じうる複素乗算は $N/2$ 回だけ(バタフライ 1 個につき 1 回)であり、そのうち多くは $W^0 = 1$ 倍でコストがかからない。自明な因子は $W^0=1$(無料)と $W_8^2 = -j$(実部と虚部の入れ替えと符号だけなので、実装上も乗算不要)である。

15.3.2 Bit-reversed input ordering15.3.2 輸入的位元反轉排序15.3.2 入力のビット反転順序

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(位元反轉).每一次 DIT 拆分都把偶數索引的樣本送上去、奇數索引的樣本送下來——也就是依時間索引的最低有效位元(LSB)做排序。再遞迴一層就依下一個位元排序,依此類推。經過 $M$ 層之後,輸入第 $r$ 列上的樣本就是 $x[\text{bit-reverse}(r)]$:也就是把位址的 $M$ 位元二進位表示反轉過來的那個位址。DIT の分割は毎回、偶数索引の標本を上へ、奇数索引の標本を下へ送る。つまり時間索引の最下位ビット(LSB)で並べ替えているのである。再帰すれば次のビットで並べ替え、以下同様となる。$M$ 段を経たあと、入力の第 $r$ 行にある標本は $x[\text{bit-reverse}(r)]$ である。すなわちアドレスの $M$ ビット 2 進表現を逆順にしたものである。

Row $r$第 $r$ 列第 $r$ 行$r$ binary$r$ 的二進位$r$ の 2 進表現reversed反轉後反転後input sample輸入樣本入力標本
0000000$x[0]$
1001100$x[4]$
2010010$x[2]$
3011110$x[6]$
4100001$x[1]$
5101101$x[5]$
6110011$x[3]$
7111111$x[7]$
直觀解釋(點擊展開)
為什麼是「位元反轉」?第一次抽取按「最低位元」分組(偶數 LSB=0 在上、奇數 LSB=1 在下);對每半再抽取一次,是按「第二低位元」分組,依此類推。所以樣本最後落在哪一列,是由它的索引位元「由低到高」依序決定的 — 等於把二進位位址整個反過來讀。例如 $x[6]=x[110_2]$:LSB=0 進上半,次位=1 進上半的下半,最高位=1 → 列 $011_2=3$。實作上只要把陣列先做一次位元反轉重排,後面所有蝶形就可以順序進行。

15.3.3 In-place computation15.3.3 原位計算15.3.3 その場計算

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).再看一次圖 15-5:每個蝶形從第 $(p, q)$ 兩列取兩個值,又把兩個輸出寫回同樣那兩列 $(p, q)$。該級中沒有別的蝶形會碰到這兩列。因此整個 FFT 是一個原位演算法:一個長度為 $N$ 的複數陣列就夠了——在最初的位元反轉重排之後,$M$ 個級依序覆寫這個陣列,最後陣列的內容就是自然順序的 $X[0],\dots,X[N-1]$。記憶體代價:$N$ 個複數字組,再加上一張小小的旋轉因子表(若像 Goertzel 那樣即時產生,連表都不用)。図 15-5 をもう一度見てほしい。どのバタフライも第 $(p, q)$ 行から二つの値を取り、二つの出力を同じその二行 $(p, q)$ に書き戻す。その段のほかのバタフライがこの二行に触れることはない。したがって FFT 全体はその場アルゴリズムである。長さ $N$ の複素配列が一つあれば足りる。最初のビット反転の並べ替えのあと、$M$ 段が順に配列を上書きしていき、最終的な配列の中身が自然順序の $X[0],\dots,X[N-1]$ となる。メモリのコストは複素数 $N$ 語と、小さな回転因子表(Goertzel 流にその都度生成するなら表も不要)である。

15.3.4 Complexity: (N/2) log₂ N15.3.4 複雜度:(N/2) log₂ N15.3.4 計算量:(N/2) log₂ N

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):一個 $N = 2^M$ 點 DFT 化約成 $M = \log_2 N$ 級。每一級有 $N/2$ 個蝶形,每個蝶形最多 1 次複數乘法(4 次實數乘法)與 2 次複數加法(4 次實數加法):$N = 2^M$ 点 DFT は $M = \log_2 N$ 段に帰着する。各段には $N/2$ 個のバタフライがあり、それぞれ複素乗算が高々 1 回(実数乗算 4 回)、複素加算が 2 回(実数加算 4 回)である。

Radix-2 FFT complexity基 2 FFT 的複雜度基数 2 FFT の計算量 $$\text{complex mults} \;\le\; \frac N2\,\log_2 N, \qquad \text{complex adds} \;=\; N\log_2 N$$ $$\text{real mults} < 4N\,M, \qquad \text{real adds} < 2\cdot 2N\,M \qquad\Longrightarrow\qquad \boxed{\;\text{complexity} \sim O(N\cdot M) = O(N\log_2 N)\;}$$

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.平方項消失了。圖 15-6 顯示這個差距有多戲劇性——在 $N = 2^{16}$ 時,FFT 所需的乘法次數少了大約三個數量級。二乗の項は消え去った。図 15-6 はその差がいかに劇的かを示している。$N = 2^{16}$ では、FFT に必要な乗算回数は3 桁ほど少ない。

2026-06-12T22:37:39.790922 image/svg+xml Matplotlib v3.10.8, https://matplotlib.org/ 1 0 1 1 0 2 1 0 3 1 0 4 1 0 5 Transform length N 1 0 1 1 0 3 1 0 5 1 0 7 1 0 9 Complex multiplications N = 1024: speed-up ×205 N = 65536: speed-up ×8 192 Direct DFT vs radix-2 FFT: complex-multiply count D i r e c t   D F T :   N 2 R a d i x - 2   F F T :   ( / 2 ) l o g N N 2
Fig. 15-6 — Complex-multiply counts: direct DFT ($N^2$) vs radix-2 FFT ($\tfrac N2 \log_2 N$), log–log scale. At $N=1024$ the FFT is ~205× cheaper; at $N = 65536$ it is ~8192× cheaper.(兩條線在對數座標上的差距隨 $N$ 不斷拉大 — 這就是「快速」的由來。)圖 15-6 — 複數乘法次數:直接計算 DFT($N^2$)對上基 2 FFT($\tfrac N2 \log_2 N$),雙對數座標。在 $N=1024$ 時 FFT 便宜約 205 倍;在 $N = 65536$ 時便宜約 8192 倍。兩條線的差距隨 $N$ 不斷拉大,這就是「快速」的由來。図 15-6 — 複素乗算の回数:直接 DFT($N^2$)と基数 2 FFT($\tfrac N2 \log_2 N$)、両対数目盛。$N=1024$ では FFT が約 205 倍安く、$N = 65536$ では約 8192 倍安い。二本の線の差は $N$ とともに開きつづける。これが「高速」の由来である。
Exam trap — counting FFT multiplies考試陷阱——數 FFT 的乘法次數試験の落とし穴 — FFT の乗算回数を数える

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.$\frac N2 \log_2 N$ 這個數字算的是複數乘法,而且是上界(很多旋轉因子是 $\pm 1, \pm j$,根本不用乘)。如果題目問的是實數乘法,要再乘以 4。還要記得直接計算 DFT 的基準是 $N^2$ 次複數 = $4N^2$ 次實數乘法——算加速比時別把兩種單位混在一起。$\frac N2 \log_2 N$ という数は複素乗算の回数であり、しかも上界である(回転因子の多くは $\pm 1, \pm j$ で、ただで済む)。問題が実数乗算を問うているなら 4 倍せよ。また直接 DFT の基準は複素 $N^2$ 回、すなわち実数 $4N^2$ 回であることを忘れてはならない。高速化率を求めるときに二つの単位を混ぜてはいけない。

15.4 FFT Variations15.4 FFT 的各種變形15.4 FFT の変種

15.4.1 FFT for other values of N15.4.1 其他 N 值的 FFT15.4.1 その他の N に対する FFT

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:因為有 $N = 2^M$,我們才能把每一級切成兩半——這就是基 2 FFT。同樣的分治手法可以推廣得更一般:$N = 2^M$ であったからこそ、各段を 2 等分できた——これが基数 2 FFT である。同じ分割統治の手法はもっと一般に使える。

Practical note實務提醒実務上の注意

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.現代的函式庫(MATLAB 用的 FFTW、numpy.fft 等等)都實作了混合基數、甚至質數長度的演算法(Rader、Bluestein),所以任何 $N$ 都能在 $O(N\log N)$ 內跑完。但常數因子在 $N = 2^M$ 時最小;質數的 $N$ 很容易慢上好幾倍(見圖 15-7)。長度由你決定時,就選 2 的冪。現代のライブラリ(MATLAB が使う FFTW、numpy.fft など)は混合基数どころか素数長のアルゴリズム(Rader、Bluestein)まで実装しており、どんな $N$ でも $O(N\log N)$ で走る。しかし定数因子が最小になるのは $N = 2^M$ のときであり、素数の $N$ は数倍遅くなることも珍しくない(図 15-7 参照)。長さを自分で決められるときは 2 のべき乗を選ぶべきである。

15.4.2 Inverse FFT via the forward FFT15.4.2 用正向 FFT 做反 FFT15.4.2 順方向 FFT による逆 FFT

Recall the IDFT:回想 IDFT:IDFT を思い出そう。

IDFT反變換 IDFT逆変換 IDFT $$x[n] = \frac1N \sum_{k=0}^{N-1} X[k]\, W_N^{-nk}$$

The only differences from the forward DFT are the $1/N$ scale and the sign of the exponent. Conjugating twice fixes the sign:與正向 DFT 的差別只有 $1/N$ 這個比例因子和指數的符號。取兩次共軛就能修正符號:順方向 DFT との違いは $1/N$ の係数と指数の符号だけである。共役を 2 回とれば符号は直る。

IFFT via forward FFT用正向 FFT 實現 IFFT順方向 FFT による IFFT $$N\,x^{*}[n] = \sum_{k=0}^{N-1}\big(X[k]\,W_N^{-nk}\big)^{*} = \sum_{k=0}^{N-1} X^{*}[k]\, W_N^{nk} \qquad\Longrightarrow\qquad \boxed{\;x[n] = \frac1N\Bigg[\sum_{k=0}^{N-1} X^{*}[k]\, W_N^{nk}\Bigg]^{*}\;}$$

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.括號裡的那個和,正好就是 $x'[n] = X^*[k]\big|_{k=n}$ 的正向 DFT——一條用頻譜做出來的「時間」序列。所以做法是:把頻譜取共軛,送進同一套 FFT 引擎,結果再取共軛,然後除以 $N$。一份 FFT 實作就能服務兩個方向;在純實數的訊號流程圖裡,這相當於把實部與虛部的角色對調,再在埠口加上幾個符號反轉與 $1/N$ 的縮放。角括弧の中の和は、$x'[n] = X^*[k]\big|_{k=n}$ の順方向 DFT にほかならない。スペクトルから作った「時間」系列である。したがって手順は、スペクトルの共役をとり、同じ FFT エンジンに通し、結果の共役をとって $N$ で割る、というだけである。FFT の実装は一つで双方向に使える。純実数の信号流れ図でいえば、実部と虚部の役割を入れ替え、端子でいくつかの符号反転と $1/N$ のスケーリングを行うことに相当する。

15.4.3 DFT of real sequences — two for the price of one15.4.3 實數序列的 DFT——一次的代價做兩條15.4.3 実数系列の DFT — 一つの値段で二つ

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如果 $x[n]$ 是純實數,DFT 就浪費了乘法:由共軛對稱性,$X[k] = X^*[-k] = X^*[N-k]$,所以有一半的輸出是多餘的。課程的技巧是:把兩條實數序列打包進一次複數 FFT。給定實數的 $x[n]$ 與 $w[n]$,組成 $y[n] = x[n] + j\,w[n]$,然後只做一個 $N$ 點 DFT $V[k] = \mathrm{DFT}\{y[n]\} = X[k] + Y[k]$,其中 $Y[k] = \mathrm{DFT}\{j\,w[n]\} = jW[k]$。於是$x[n]$ が純実数なら、DFT は乗算を無駄にしている。共役対称性により $X[k] = X^*[-k] = X^*[N-k]$ であるから、出力の半分は冗長である。講義の技は、実数系列二つを一回の複素 FFT に詰め込むことである。実数の $x[n]$ と $w[n]$ が与えられたら $y[n] = x[n] + j\,w[n]$ を作り、$N$ 点 DFT を一回だけとって $V[k] = \mathrm{DFT}\{y[n]\} = X[k] + Y[k]$ を得る。ここで $Y[k] = \mathrm{DFT}\{j\,w[n]\} = jW[k]$ である。すると

Recovering both spectra把兩個頻譜還原出來二つのスペクトルを復元する $$V[k] + V^{*}[-k] = X[k] + \underbrace{X^{*}[-k]}_{=X[k]} + jW[k] + \underbrace{(jW[-k])^{*}}_{=-jW^{*}[-k] = -jW[k]^{*\,*}} \;\Longrightarrow\; \boxed{\;X[k] = \tfrac12\big(V[k] + V^{*}[-k]\big), \qquad W[k] = -\tfrac{j}{2}\big(V[k] - V^{*}[-k]\big)\;}$$

(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.(這裡 $V^*[-k] = V^*[\langle N-k\rangle_N]$,而那些抵消用到的是實數輸入頻譜 $X$ 與 $W$ 的共軛對稱性。)也就是說:用單一個 $N$ 點複數 DFT 就能算出兩條 $N$ 點實數序列的 DFT——習題 5 會用數值把這件事驗證到機器精度。(ここで $V^*[-k] = V^*[\langle N-k\rangle_N]$ であり、打ち消しには実数入力のスペクトル $X$ と $W$ の共役対称性を使っている。)すなわち、$N$ 点の実数系列二つの DFT を、$N$ 点の複素 DFT 一回で計算できるのである。演習 5 ではこれを数値的に機械精度まで確かめる。

15.5 The FFT in MATLAB15.5 MATLAB 中的 FFT15.5 MATLAB での FFT

MATLAB's fft/ifft call the FFTW library — mixed-radix $O(N\log N)$ for every length, fastest for $N = 2^M$:MATLAB 的 fft/ifft 會呼叫 FFTW 函式庫——對任何長度都是混合基數的 $O(N\log N)$,而在 $N = 2^M$ 時最快:MATLAB の fft/ifft は FFTW ライブラリを呼ぶ。どんな長さでも混合基数の $O(N\log N)$ であり、$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.圖 15-7 顯示在這台機器上實測的執行時間(numpy 的 FFTPACK 式引擎;MATLAB/FFTW 在定性上行為相同):2 的冪與質數長度都按 $N \log N$ 成長,但質數長度的常數差了約 5 倍,而直接做 $O(N^2)$ 的矩陣乘積幾乎立刻就把兩者遠遠甩在後頭。図 15-7 はこの計算機で実測した実行時間である(numpy の FFTPACK 系エンジン。MATLAB/FFTW も定性的には同じ振る舞いをする)。2 のべき乗長も素数長もともに $N \log N$ でスケールするが、素数長の定数は約 5 倍悪く、直接の $O(N^2)$ 行列積はほとんど即座に両者を置き去りにして伸びていく。

2026-06-12T22:38:03.298176 image/svg+xml Matplotlib v3.10.8, https://matplotlib.org/ 1 0 3 1 0 4 1 0 5 Transform length N 1 0 − 5 1 0 − 4 1 0 − 3 1 0 − 2 Time per transform (s) Measured FFT run time vs N Direct DFT (matrix product) f f t ,   = 2 N M fft, N prime
Fig. 15-7 — Measured time per transform vs $N$ (log–log). Grey: direct DFT as a matrix–vector product ($O(N^2)$ — already ~13 ms at $N=4096$). Green: FFT at $N = 2^M$. Red: FFT at prime $N$ — same slope, larger constant. At $N \approx 65536$: FFT ≈ 2.3 ms vs prime-length ≈ 14 ms.(質數長度仍是 $O(N\log N)$,但常數大很多;能選長度時選 2 的冪。)圖 15-7 — 每次轉換的實測時間對 $N$(雙對數)。灰色:把直接 DFT 當成矩陣與向量的乘積($O(N^2)$——在 $N=4096$ 時已經要約 13 ms)。綠色:$N = 2^M$ 的 FFT。紅色:質數 $N$ 的 FFT——斜率相同,常數較大。在 $N \approx 65536$ 時:FFT 約 2.3 ms,質數長度約 14 ms。質數長度仍是 $O(N\log N)$,但常數大很多;能選長度時就選 2 的冪。図 15-7 — 1 回の変換あたりの実測時間と $N$(両対数)。灰:直接 DFT を行列・ベクトル積として実行したもの($O(N^2)$。$N=4096$ ですでに約 13 ms)。緑:$N = 2^M$ の FFT。赤:素数 $N$ の FFT。傾きは同じで定数が大きい。$N \approx 65536$ では FFT が約 2.3 ms、素数長が約 14 ms である。素数長も $O(N\log N)$ ではあるが定数がずっと大きい。長さを選べるなら 2 のべき乗にすべきである。
MATLAB practiceMATLAB 實務MATLAB の実務
  • nextpow2(L) gives $M$ with $2^M \ge L$; use fft(x, 2^nextpow2(L)) to zero-pad to a fast length.nextpow2(L) 會給出滿足 $2^M \ge L$ 的 $M$;用 fft(x, 2^nextpow2(L)) 就能補零到一個快速的長度。nextpow2(L) は $2^M \ge L$ を満たす $M$ を返す。fft(x, 2^nextpow2(L)) を使えば高速な長さまでゼロ詰めできる。
  • fftshift(X) reorders the output so $k=0$ sits in the middle for plotting.fftshift(X) 會把輸出重新排序,讓 $k=0$ 落在中間,方便畫圖。fftshift(X) は出力を並べ替え、描画しやすいように $k=0$ を中央に置く。
  • For repeated transforms of the same size, fftw('planner','measure') lets FFTW search for the fastest plan.若要重複做同樣大小的轉換,fftw('planner','measure') 可以讓 FFTW 去搜尋最快的執行計畫。同じ大きさの変換を繰り返すなら、fftw('planner','measure') によって FFTW に最速のプランを探させられる。
  • For real inputs MATLAB already exploits conjugate symmetry internally; keep only bins 1:N/2+1 for analysis.對實數輸入,MATLAB 內部已經利用了共軛對稱性;分析時只要留下 1:N/2+1 這些頻格即可。実数入力に対して MATLAB は内部ですでに共役対称性を利用している。解析では 1:N/2+1 のビンだけを残せばよい。

15.6 Summary15.6 總結15.6 まとめ

Direct DFT cost直接計算 DFT 的代價直接 DFT のコスト

$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)$.每個頻格 $N$ 次複數乘法 + $N{-}1$ 次加法,$\times N$ 個頻格 → $N^2$ 次複數 = $4N^2$ 次實數乘法、$4N^2{-}2N$ 次實數加法。$O(N^2)$。1 ビンあたり複素乗算 $N$ 回 + 加算 $N{-}1$ 回、$\times N$ ビン → 複素 $N^2$ 回 = 実数乗算 $4N^2$ 回、実数加算 $4N^2{-}2N$ 回。$O(N^2)$ である。

Twiddle factor $W_N$旋轉因子 $W_N$回転因子 $W_N$

$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}$.$W_N = e^{-j2\pi/N}$;只有 $N$ 個相異的冪次。週期性 $W_N^{k+N} = W_N^k$,對稱性 $W_N^{k+N/2} = -W_N^k$,減半 $W_N^2 = W_{N/2}$。$W_N = e^{-j2\pi/N}$。相異なるべきは $N$ 個だけ。周期性 $W_N^{k+N} = W_N^k$、対称性 $W_N^{k+N/2} = -W_N^k$、半減 $W_N^2 = W_{N/2}$。

GoertzelGoertzel 演算法Goertzel のアルゴリズム

$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] = y_k[N]$;實數分母的形式每一步只要 2 次實數乘法。每個頻格 $O(N)$——只需要少數幾個頻格時最划算。1 次の再帰から $X[k] = y_k[N]$ が得られる。分母を実数にした形なら 1 ステップあたり実数乗算 2 回で済む。1 ビンあたり $O(N)$ であり、必要なビンが少ないときに最も有利である。

DIT splitDIT 拆分DIT 分割

$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[k] = X_0[\langle k\rangle_{N/2}] + W_N^k X_1[\langle k\rangle_{N/2}]$——偶數樣本的 DFT,加上乘了旋轉因子的奇數樣本 DFT。拆一次就把工作量減半;一路遞迴到 2 點 DFT。$X[k] = X_0[\langle k\rangle_{N/2}] + W_N^k X_1[\langle k\rangle_{N/2}]$ —— 偶数標本の DFT に、回転因子を掛けた奇数標本の DFT を足したもの。1 回の分割で仕事量は半分になり、2 点 DFT まで再帰する。

Butterfly蝶形運算バタフライ演算

$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).$X[r] = X_0[r] + W_N^r X_1[r]$、$X[r{+}N/2] = X_0[r] - W_N^r X_1[r]$:一次複數乘法、兩次加法(用減法取代第二次乘法)。$X[r] = X_0[r] + W_N^r X_1[r]$、$X[r{+}N/2] = X_0[r] - W_N^r X_1[r]$:複素乗算 1 回、加算 2 回(2 回目の乗算のかわりに減算を使う)。

Bit reversal & in-place位元反轉與原位計算ビット反転とその場計算

Inputs in bit-reversed order, outputs natural; each butterfly overwrites its own two slots → whole FFT runs in one length-$N$ array.輸入依位元反轉順序,輸出為自然順序;每個蝶形只覆寫自己的那兩格 → 整個 FFT 在一個長度為 $N$ 的陣列裡跑完。入力はビット反転順序、出力は自然順序。各バタフライは自分の二つの枠だけを上書きする → FFT 全体が長さ $N$ の配列一つで走る。

FFT complexityFFT 的複雜度FFT の計算量

$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)$.$M = \log_2 N$ 級 × $N/2$ 個蝶形 → 複數乘法 $\le \frac N2 \log_2 N$ 次、加法 $N \log_2 N$ 次:$O(N\log_2 N)$。$M = \log_2 N$ 段 × $N/2$ 個のバタフライ → 複素乗算は $\le \frac N2 \log_2 N$ 回、加算は $N \log_2 N$ 回:$O(N\log_2 N)$ である。

Variations各種變形変種

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.基 3/基 4、對合成數 $N$ 用混合基數、補零到 $2^M$;IFFT = 取共軛 → FFT → 取共軛 → $/N$;一次複數 FFT 做出兩條 $N$ 點實數序列的 DFT。基数 3・基数 4、合成数 $N$ には混合基数、$2^M$ までゼロ詰め。IFFT = 共役 → FFT → 共役 → $/N$。複素 FFT 一回で $N$ 点の実数系列二つの DFT が得られる。

Exercises習題演習問題

Exercise 1 — Operation counts and speed-up習題 1 — 運算量計算與加速比演習 1 — 演算回数と高速化率

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.問題:某即時系統必須計算一個 4096 點的 DFT。(a) 直接計算需要幾次實數乘法?(b) 基 2 DIT FFT 需要幾次複數乘法(上界)?(c) 以複數乘法計,加速比是多少?(d) 若一次複數乘法要 5 ns,比較兩者的執行時間。問題:ある実時間システムで 4096 点 DFT を計算しなければならない。(a) 直接計算には実数乗算が何回必要か。(b) 基数 2 DIT FFT には複素乗算が何回必要か(上界)。(c) 複素乗算で測った高速化率はいくらか。(d) 複素乗算 1 回が 5 ns かかるとして、両者の実行時間を比較せよ。

Click to reveal solution點擊展開解答クリックして解答を表示

(a) Direct: $4N^2 = 4\cdot 4096^2 = 67{,}108{,}864$ real multiplications (and $4N^2 - 2N = 67{,}100{,}672$ real adds).(a) 直接計算:$4N^2 = 4\cdot 4096^2 = 67{,}108{,}864$ 次實數乘法(以及 $4N^2 - 2N = 67{,}100{,}672$ 次實數加法)。(a) 直接計算:$4N^2 = 4\cdot 4096^2 = 67{,}108{,}864$ 回の実数乗算(および $4N^2 - 2N = 67{,}100{,}672$ 回の実数加算)。

(b) $N = 4096 = 2^{12}$, so $M = 12$ stages with $N/2 = 2048$ butterflies each:(b) $N = 4096 = 2^{12}$,所以有 $M = 12$ 級,每級 $N/2 = 2048$ 個蝶形:(b) $N = 4096 = 2^{12}$ なので $M = 12$ 段、各段に $N/2 = 2048$ 個のバタフライがある。

$$\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$.(c) 以複數乘法計:$\dfrac{N^2}{(N/2)\log_2 N} = \dfrac{16{,}777{,}216}{24{,}576} = \dfrac{2N}{\log_2 N} \approx 683\times$。(c) 複素乗算で見ると:$\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%.(d) 直接計算:$16{,}777{,}216 \times 5\,\text{ns} \approx 83.9\,\text{ms}$。FFT:$24{,}576 \times 5\,\text{ns} \approx 0.123\,\text{ms}$。在 44.1 kHz 的音訊取樣率下,一幀 4096 點長約 93 ms——直接計算 DFT 幾乎要把整個時間預算用光才勉強跟得上,而 FFT 只用掉約 0.1%。(d) 直接計算:$16{,}777{,}216 \times 5\,\text{ns} \approx 83.9\,\text{ms}$。FFT:$24{,}576 \times 5\,\text{ns} \approx 0.123\,\text{ms}$。44.1 kHz の音声標本化率では 4096 点のフレームは約 93 ms であり、直接 DFT は時間予算をほぼ使い切ってかろうじて間に合う一方、FFT は約 0.1% しか使わない。

Exercise 2 — Deriving the DIT decomposition習題 2 — 推導 DIT 分解演習 2 — DIT 分解の導出

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$.問題:從 $N$ 點 DFT 的定義出發($N$ 為偶數),(a) 證明 $X[k] = X_0[\langle k\rangle_{N/2}] + W_N^{k} X_1[\langle k\rangle_{N/2}]$,其中 $X_0, X_1$ 分別是偶數索引與奇數索引樣本的 $N/2$ 點 DFT。(b) 說明為什麼 $X_0$ 與 $X_1$ 必須以 $N/2$ 取模來取值,以及 (c) 明確證明對 $0 \le k < N/2$ 有 $X[k + N/2] = X_0[k] - W_N^{k}X_1[k]$。問題:$N$ 点 DFT の定義から出発して($N$ は偶数)、(a) $X[k] = X_0[\langle k\rangle_{N/2}] + W_N^{k} X_1[\langle k\rangle_{N/2}]$ を示せ。ここで $X_0, X_1$ はそれぞれ偶数索引・奇数索引の標本の $N/2$ 点 DFT である。(b) $X_0$ と $X_1$ を $N/2$ を法として評価しなければならない理由を説明せよ。(c) $0 \le k < N/2$ に対して $X[k + N/2] = X_0[k] - W_N^{k}X_1[k]$ となることを明示的に示せ。

Click to reveal solution點擊展開解答クリックして解答を表示

(a) Split the sum over even $n = 2m$ and odd $n = 2m+1$:(a) 把和拆成偶數 $n = 2m$ 與奇數 $n = 2m+1$ 兩部分:(a) 和を偶数 $n = 2m$ と奇数 $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]$.由於 $W_N^2 = e^{-j2\pi\cdot 2/N} = e^{-j2\pi/(N/2)} = W_{N/2}$,這兩個和正好就是 $x_0[m] = x[2m]$ 與 $x_1[m] = x[2m+1]$ 的 $N/2$ 點 DFT。$W_N^2 = e^{-j2\pi\cdot 2/N} = e^{-j2\pi/(N/2)} = W_{N/2}$ であるから、二つの和はちょうど $x_0[m] = x[2m]$ と $x_1[m] = x[2m+1]$ の $N/2$ 点 DFT である。

(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}$.(b) $X[k]$ 在 $k = 0,\dots,N-1$ 上都要,但 $N/2$ 點 DFT 只定義了 $N/2$ 個值。由 DFT 的週期性,$X_0[k + N/2] = X_0[k]$(因為核 $W_{N/2}^{m(k+N/2)} = W_{N/2}^{mk}$),所以當 $k \ge N/2$ 時,我們改在 $\langle k\rangle_{N/2}$ 處讀取那些小 DFT。(b) $X[k]$ は $k = 0,\dots,N-1$ について必要だが、$N/2$ 点 DFT が定義するのは $N/2$ 個の値だけである。DFT の周期性により $X_0[k + N/2] = X_0[k]$ であり(核が $W_{N/2}^{m(k+N/2)} = W_{N/2}^{mk}$ だからである)、$k \ge N/2$ のときは小さい DFT を $\langle k\rangle_{N/2}$ で読めばよい。

(c) For $0 \le k < N/2$:(c) 對 $0 \le k < N/2$:(c) $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再由半週期對稱性 $W_N^{k + N/2} = W_N^k\,e^{-j\pi} = -W_N^k$ 得到さらに半周期の対称性 $W_N^{k + N/2} = W_N^k\,e^{-j\pi} = -W_N^k$ から次が得られる。

$$\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.這正是化簡蝶形的下支路——同一個乘積 $W_N^k X_1[k]$ 換個符號再用一次,這就是每個蝶形只需要一次複數乘法的原因。これはまさに簡略化したバタフライの下側の枝である。同じ積 $W_N^k X_1[k]$ を符号だけ変えて再利用しており、各バタフライに複素乗算が一つしか要らないのはこのためである。

Exercise 3 — 4-point DIT FFT by hand習題 3 — 手算 4 點 DIT FFT演習 3 — 手計算による 4 点 DIT FFT

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.問題:沿著基 2 DIT 訊號流程圖,計算 $x[n] = \{1, 2, 3, 4\}$ 的 4 點 DFT:寫出位元反轉後的輸入順序,算出兩級蝶形,並用 DFT 的定義驗證其中一個輸出頻格。問題:基数 2 DIT の信号流れ図をたどって $x[n] = \{1, 2, 3, 4\}$ の 4 点 DFT を計算せよ。ビット反転した入力順序を書き、2 段のバタフライを評価し、出力ビンの一つを DFT の定義と照合して確かめよ。

Click to reveal solution點擊展開解答クリックして解答を表示

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$.第 1 步 — 位元反轉後的輸入。$N=4$,2 個位元:各列收到的是 $x[00_2], x[10_2], x[01_2], x[11_2] = x[0], x[2], x[1], x[3] = 1, 3, 2, 4$。ステップ 1 — ビット反転した入力。$N=4$、2 ビットである。各行が受け取るのは $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).第 2 步 — 第 1 級(2 點 DFT,沒有旋轉因子)。ステップ 2 — 第 1 段(2 点 DFT、回転因子なし)。

$$\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$).第 3 步 — 第 2 級(旋轉因子 $W_4^0 = 1$、$W_4^1 = e^{-j\pi/2} = -j$)。ステップ 3 — 第 2 段(回転因子 $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.第 4 步 — 直接驗算 $X[1]$。ステップ 4 — $X[1]$ を直接検算する。

$$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.注意運算量:總共只有 1 次複數乘法(就是 $-j\cdot a_3$,而且它本身還是平凡的),直接計算 DFT 則要 $N^2 = 16$ 次。另外注意 $X[3] = X^*[1]$——這是共軛對稱性,因為 $x[n]$ 是實數。回数に注目せよ。複素乗算は合計 1 回だけ($-j\cdot a_3$ であり、これ自体も自明な乗算である)であるのに対し、直接 DFT では $N^2 = 16$ 回である。また $X[3] = X^*[1]$ となっていることにも注意。$x[n]$ が実数なので共役対称性が成り立つのである。

Exercise 4 — Bit reversal for N = 16習題 4 — N = 16 的位元反轉演習 4 — N = 16 のビット反転

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)?問題:對一個 16 點的基 2 DIT FFT:(a) 列出所需的輸入順序;(b) 哪些索引會留在原地,為什麼?(c) 這個 FFT 有幾級?第 3 級包含哪些蝶形(跨幾列、用哪些旋轉因子)?整個轉換需要幾次複數乘法(上界)?問題:16 点の基数 2 DIT FFT について、(a) 必要な入力順序を列挙せよ。(b) その場に留まる索引はどれか、またそれはなぜか。(c) この FFT は何段あるか、第 3 段にはどのようなバタフライが含まれるか(またがる行数と回転因子)、そして変換全体に必要な複素乗算は何回か(上界)。

Click to reveal solution點擊展開解答クリックして解答を表示

(a) Reverse 4-bit addresses ($0000 \to 0000$, $0001 \to 1000$, …). Input order:(a) 把 4 位元位址反轉($0000 \to 0000$、$0001 \to 1000$,……)。輸入順序為:(a) 4 ビットのアドレスを反転する($0000 \to 0000$、$0001 \to 1000$、……)。入力順序は次のとおりである。

$$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.)(b) 一個索引留在原地,當且僅當它的 4 位元樣式是迴文:$0000 = 0$、$0110 = 6$、$1001 = 9$、$1111 = 15$。(其餘 12 個索引構成 6 組交換對——位元反轉是自己的反運算,所以這個重排可以用簡單的兩兩交換原地完成。)(b) 索引がその場に留まるのは、4 ビットのパターンが回文であるとき、かつそのときに限る:$0000 = 0$、$0110 = 6$、$1001 = 9$、$1111 = 15$ である。(残る 12 個の索引は 6 組の交換ペアをなす。ビット反転はそれ自身が逆写像なので、並べ替えは単純な 2 要素交換によってその場で行える。)

(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).(c) $M = \log_2 16 = 4$ 級。第 3 級的蝶形跨越 $2^{3-1} = 4$ 列:分成 $(0\text{–}3$ 與 $4\text{–}7)$、$(8\text{–}11$ 與 $12\text{–}15)$ 兩組,旋轉因子 $W_{8}^{0..3} = W_{16}^{0}, W_{16}^{2}, W_{16}^{4}, W_{16}^{6}$ 乘在每個蝶形的下方輸入上。複數乘法總數 $\le \frac{N}{2}\log_2 N = 8 \times 4 = 32$(直接計算則是 $N^2 = 256$;實務上還更少,因為 $W^0, W^{N/4}$ 都是平凡的)。(c) $M = \log_2 16 = 4$ 段である。第 3 段のバタフライは $2^{3-1} = 4$ 行にまたがり、$(0\text{–}3$ と $4\text{–}7)$、$(8\text{–}11$ と $12\text{–}15)$ の組をなす。回転因子は $W_{8}^{0..3} = W_{16}^{0}, W_{16}^{2}, W_{16}^{4}, W_{16}^{6}$ であり、各バタフライの下側の入力に掛かる。複素乗算の総数は $\le \frac{N}{2}\log_2 N = 8 \times 4 = 32$ である(直接計算なら $N^2 = 256$。$W^0, W^{N/4}$ が自明なので実際にはさらに少ない)。

Exercise 5 — MATLAB: two real DFTs from one complex FFT習題 5 — MATLAB:用一次複數 FFT 做出兩條實數 DFT演習 5 — MATLAB:複素 FFT 一回で実数 DFT を二つ

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.問題:寫一段 MATLAB 程式,只用單一個 64 點複數 FFT 計算兩條實數序列 $x[n] = \cos(2\pi\,5n/N) + 0.5\cos(2\pi\,12n/N)$ 與 $w[n] = \sin(2\pi\,9n/N) + 0.3\,\text{randn}$($N = 64$)的 DFT。把 $X[k]$ 與 $W[k]$ 還原出來,分別與直接呼叫 fft 的結果比對驗證,並畫出還原後的振幅頻譜。問題:一回の 64 点複素 FFT だけを使って、二つの実数系列 $x[n] = \cos(2\pi\,5n/N) + 0.5\cos(2\pi\,12n/N)$ と $w[n] = \sin(2\pi\,9n/N) + 0.3\,\text{randn}$($N = 64$)の DFT を計算する MATLAB コードを書け。$X[k]$ と $W[k]$ を復元し、どちらも fft を直接呼んだ結果と照合して確かめ、復元した振幅スペクトルを描け。

Click to reveal solution點擊展開解答クリックして解答を表示

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)).把 $y[n] = x[n] + j\,w[n]$ 打包起來,只做一次轉換,再用 §15.4.3 的共軛對稱公式拆開。唯一要小心的是 $V^*[-k]$ 的索引:MATLAB 的陣列從 1 開始,所以對 $k = 0,\dots,N{-}1$ 的 $V^*[\langle N-k\rangle_N]$ 要寫成 conj(V(mod(N-(0:N-1),N)+1))。$y[n] = x[n] + j\,w[n]$ と詰め込んで一度だけ変換し、§15.4.3 の共役対称の式で分離する。唯一の細かい注意点は $V^*[-k]$ の索引付けである。MATLAB の配列は 1 始まりなので、$k = 0,\dots,N{-}1$ に対する $V^*[\langle N-k\rangle_N]$ は 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}$):重新產生的結果(numpy,同樣的演算法)——兩個頻譜都還原到機器精度($\sim 10^{-15}$):同じアルゴリズムを numpy で再現した結果である。両方のスペクトルが機械精度($\sim 10^{-15}$)まで復元されている。

2026-06-12T22:38:04.777192 image/svg+xml Matplotlib v3.10.8, https://matplotlib.org/ 0 10 20 30 40 50 60 0 10 20 30 |X[k]| |X[k]| recovered from one complex FFT (max error 3.56e-15) 0 10 20 30 40 50 60 k 0 10 20 30 |W[k]| |W[k]| recovered from the same FFT (max error 5.33e-15)
Fig. 15-8 — $|X[k]|$ shows the two cosine lines at $k = 5, 12$ (and mirrors at $59, 52$); $|W[k]|$ shows the sine line at $k = 9$ ($55$) over the noise floor. Max recovery error $\approx 4\times 10^{-15}$.圖 15-8 — $|X[k]|$ 顯示出位在 $k = 5, 12$ 的兩條餘弦譜線(以及鏡像的 $59, 52$);$|W[k]|$ 則在雜訊底層之上顯示出位在 $k = 9$($55$)的正弦譜線。最大還原誤差 $\approx 4\times 10^{-15}$。図 15-8 — $|X[k]|$ には $k = 5, 12$ にある二本の余弦の線(およびその鏡像 $59, 52$)が現れ、$|W[k]|$ には雑音の床の上に $k = 9$($55$)の正弦の線が現れる。復元誤差の最大値は $\approx 4\times 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.為什麼行得通:$x$ 是實數 $\Rightarrow X[k] = X^*[-k]$;而 $jw$ 貢獻的是反對稱的部分。把 $V^*[-k]$ 加上去、減下來,就把對稱部分($X$)與反對稱部分($jW$)分開了——用一次複數 FFT 的代價換到兩條 $N$ 點實數序列的 DFT,大約省下一半。なぜうまくいくのか:$x$ が実数なら $\Rightarrow X[k] = X^*[-k]$ であり、$jw$ は反対称な部分を担う。$V^*[-k]$ を足し引きすれば、対称な部分($X$)と反対称な部分($jW$)が分離される。複素 FFT 一回の値段で $N$ 点の実数 DFT が二つ得られる、およそ 2 倍の節約である。

Exercise 6 — Goertzel vs FFT習題 6 — Goertzel 與 FFT 的比較演習 6 — Goertzel と FFT の比較

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) 從 $H(z) = 1/(1 - W_N^{-k}z^{-1})$ 推導出二階(實係數)的 Goertzel 轉移函數。(b) 數一數用它計算 $N$ 點 DFT 的單一個頻格 $X[k]$ 需要幾次實數乘法。(c) 某 DTMF 接收器需要 $N = 256$ 點 DFT 中的 $M = 8$ 個頻格。Goertzel 與基 2 FFT 哪個比較便宜?求出兩者打平時的頻格數。問題:(a) $H(z) = 1/(1 - W_N^{-k}z^{-1})$ から 2 次(実係数)の Goertzel 伝達関数を導け。(b) これを使って $N$ 点 DFT のビン $X[k]$ を一つ計算するのに必要な実数乗算の回数を数えよ。(c) ある DTMF 受信機は $N = 256$ 点 DFT のうち $M = 8$ ビンを必要とする。Goertzel と基数 2 FFT のどちらが安いか。損益分岐となるビン数を求めよ。

Click to reveal solution點擊展開解答クリックして解答を表示

(a) Multiply numerator and denominator by $(1 - W_N^{k}z^{-1})$:(a) 分子分母同乘 $(1 - W_N^{k}z^{-1})$:(a) 分子と分母に $(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.其中用到 $W_N^k + W_N^{-k} = 2\cos(2\pi k/N)$。現在分母是實數了。ここで $W_N^k + W_N^{-k} = 2\cos(2\pi k/N)$ を使った。これで分母は実数になった。

(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).(b) 對 $n = 0..N$ 跑全極點遞迴 $s[n] = x[n] + 2\cos(2\pi k/N)\,s[n-1] - s[n-2]$:一個實係數 ×(實輸入 + 實狀態)= 複數情形下每一步 2 次實數乘法……而對實數輸入 $x[n]$,狀態一直是實數,所以每步只要 1 次實數乘法,總共約 $\approx N$ 次。複數的分子 $y[n] = s[n] - W_N^k s[n-1]$ 只在最後一步 $n = N$ 計算:再加 4 次實數乘法。每個頻格總計 $\approx N + 4$ 次實數乘法(直接計算單一頻格則要 $4N$ 次)。(b) 全極型の再帰 $s[n] = x[n] + 2\cos(2\pi k/N)\,s[n-1] - s[n-2]$ を $n = 0..N$ について回す。実係数 1 個 ×(実入力 + 実状態)で、複素の場合は1 ステップあたり実数乗算 2 回である……実数入力 $x[n]$ なら状態は実数のままなので 1 ステップ 1 回、合計で $\approx N$ 回の実数乗算となる。複素の分子 $y[n] = s[n] - W_N^k s[n-1]$ は最後のステップでのみ、$n = N$ において評価する。ここで実数乗算が + 4 回。1 ビンあたり合計 $\approx N + 4$ 回の実数乗算である(1 ビンを直接計算すると $4N$ 回)。

(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.(c) Goertzel 算 $M$ 個頻格:$\approx M(N+4) = 8 \times 260 = 2080$ 次實數乘法。基 2 FFT:$4\cdot\frac N2\log_2 N = 2\cdot 256\cdot 8 = 4096$ 次實數乘法(上界)——而且它把全部 256 個頻格都算了出來。這裡是 Goertzel 勝。打平點:$M(N+4) \approx 2N\log_2 N \Rightarrow M \approx 2\log_2 N = 16$ 個頻格。§15.1.3 的經驗法則:當所需頻格數 $M \lesssim 2\log_2 N$ 時以 Goertzel 為佳;它還不需要輸入緩衝區(可串流),也不需要旋轉因子表。(c) Goertzel で $M$ ビン:$\approx M(N+4) = 8 \times 260 = 2080$ 回の実数乗算。基数 2 FFT:$4\cdot\frac N2\log_2 N = 2\cdot 256\cdot 8 = 4096$ 回の実数乗算(上界)であり、しかも 256 ビンすべてを計算する。ここでは Goertzel の勝ちである。損益分岐点は $M(N+4) \approx 2N\log_2 N \Rightarrow M \approx 2\log_2 N = 16$ ビンとなる。§15.1.3 の経験則:必要なビン数が $M \lesssim 2\log_2 N$ のときは Goertzel が好ましい。さらに入力バッファ(ストリーミング可)も回転因子表も不要である。