注:本文为 “快速傅里叶变换(FFT)” 相关合辑。
图片清晰度受引文原图所限。
略作重排,未整理去重。
如有内容异常,请看原文。


快速理解 FFT 算法

cronus-裁 发布于 2021-10-23 21:19

0. 引言

学习 FFT 算法应优先聚焦其傅里叶变换本质,而非高关注度资料中提及的多项式系数表示法与点值表示法。这类表示法仅为 FFT 算法的应用场景之一,若未先明晰傅里叶变换的物理意义便学习 FFT,易导致认知混淆,无法达成对算法的完整理解。

逻辑梳理:FFT 算法是 DFT 算法的优化实现形式,DFT 算法是傅里叶变换的离散化表达形式。遵循"傅里叶变换 → \to DFT → \to FFT"的推导路径,可系统理解 FFT 算法的设计原理。

1. 傅里叶变换的物理意义

为简化表述,本节省略傅里叶变换的完整数学推导过程,仅阐释其物理意义。

若已掌握傅里叶变换的物理意义,可跳过本节直接阅读 2. DFT 部分;若尚未理解傅里叶变换的基本概念,建议参考傅里叶变换专项讲解资料或高等数学教材。

1.1 周期函数与非周期函数的傅里叶分析

周期函数的傅里叶级数本质是将函数 f ( t ) f(t) f(t) 分解为无穷多个不同频率、不同幅值的正弦与余弦信号的叠加,且这些信号的频率均为基频 ω 0 \omega_0 ω0 的整数倍(即 n ω 0 n\omega_0 nω0)。通过无穷多个不同频率、不同幅值的正余弦信号线性组合,可逼近周期函数 f ( t ) f(t) f(t);分解过程中,每个频率分量 n ω 0 n\omega_0 nω0 对应一个幅值,该幅值与频率 n ω 0 n\omega_0 nω0 构成的函数关系(自变量为 n ω 0 n\omega_0 nω0,因变量为对应频率信号的幅值)被定义为频谱函数

非周期函数的傅里叶变换以频谱密度函数为求解目标,该函数以角频率 ω \omega ω 为自变量,因变量为信号幅值在频域中的分布密度(即单位频率区间内的信号强度)。(若具备概率论基础,可将频谱函数与频谱密度函数分别类比为离散型随机变量的概率质量函数与连续型随机变量的概率密度函数。)

若上述物理意义未完全理解,可继续阅读下文;若已理解,可跳转至 2. DFT 部分。

1.2 傅里叶变换的数学推导

将周期函数的傅里叶级数转化为指数形式,表达式如下:

c n = 1 T ∫ − T 2 T 2 f ( t ) e − j n ω 0 t   d t f ( t ) = ∑ n = − ∞ + ∞ c n e j n ω 0 t \begin{aligned} c_{n} &= \frac{1}{T}\int_{-\frac{T}{2}}^{\frac{T}{2}} f(t)\mathrm{e}^{-\mathrm{j}n\omega_0 t}\,\mathrm{d}t \\ f(t) &= \sum_{n=-\infty}^{+\infty} c_n \mathrm{e}^{\mathrm{j}n\omega_0 t} \end{aligned} cnf(t)=T12T2Tf(t)ejnω0tdt=n=+cnejnω0t

傅里叶级数的周期为 T T T,无法直接用于表示非周期函数。针对非周期函数,将其视为周期 T → ∞ T \to \infty T 的极限情况,此时基频 ω 0 = 2 π T → 0 \omega_0 = \frac{2\pi}{T} \to 0 ω0=T2π0;相邻频率分量的差值 ( n + 1 ) ω 0 − n ω 0 = ω 0 (n+1)\omega_0 - n\omega_0 = \omega_0 (n+1)ω0nω0=ω0 记为 Δ ω \Delta\omega Δω,在极限情况下成为微分元 d ω \mathrm{d}\omega dω,离散频率 n ω 0 n\omega_0 nω0 对应连续变量 ω \omega ω。由此推导非周期函数的频谱密度函数:

c n = Δ ω 2 π F ( ω ) c_n = \frac{\Delta\omega}{2\pi} F(\omega) cn=2πΔωF(ω),其中 F ( ω ) = ∫ − ∞ + ∞ f ( τ ) e − j ω τ   d τ F(\omega) = \int_{-\infty}^{+\infty} f(\tau)\mathrm{e}^{-\mathrm{j}\omega \tau}\,\mathrm{d}\tau F(ω)=+f(τ)ejωτdτ(为避免混淆,积分变量改用 τ \tau τ)。

τ \tau τ积分哑变量(dummy variable / bound variable),可任意替换,仅存在于积分号内,积分完成后"消失"; f ( τ ) f(\tau) f(τ) 中的 τ \tau τ 为被积函数的求值点,由积分遍历积分区间所有值。

T → ∞ T \to \infty T 时, c n → 0 c_n \to 0 cn0,将其代入 f ( t ) = ∑ n = − ∞ + ∞ c n e j n ω 0 t f(t) = \sum_{n=-\infty}^{+\infty} c_n \mathrm{e}^{\mathrm{j}n\omega_0 t} f(t)=n=+cnejnω0t,可得:

f ( t ) = ∑ n = − ∞ + ∞ ( Δ ω 2 π ∫ − ∞ + ∞ f ( τ ) e − j n ω 0 τ   d τ ) e j n ω 0 t → 1 2 π ∫ − ∞ + ∞ ( ∫ − ∞ + ∞ f ( τ ) e − j ω τ   d τ ) e j ω t   d ω \begin{aligned} f(t) &= \sum_{n=-\infty}^{+\infty} \left(\frac{\Delta\omega}{2\pi} \int_{-\infty}^{+\infty} f(\tau)\mathrm{e}^{-\mathrm{j}n\omega_0 \tau}\,\mathrm{d}\tau\right) \mathrm{e}^{\mathrm{j}n\omega_0 t} \\ &\to \frac{1}{2\pi} \int_{-\infty}^{+\infty} \left(\int_{-\infty}^{+\infty} f(\tau)\mathrm{e}^{-\mathrm{j}\omega \tau}\,\mathrm{d}\tau\right) \mathrm{e}^{\mathrm{j}\omega t}\,\mathrm{d}\omega \end{aligned} f(t)=n=+(2πΔω+f(τ)ejnω0τdτ)ejnω0t2π1+(+f(τ)ejωτdτ)ejωtdω

据此定义非周期函数的傅里叶变换

F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − j ω t   d t F(\omega) = \int_{-\infty}^{+\infty} f(t)\mathrm{e}^{-\mathrm{j}\omega t}\,\mathrm{d}t F(ω)=+f(t)ejωtdt

由推导过程可知 c n = d ω 2 π F ( ω ) c_n = \frac{\mathrm{d}\omega}{2\pi} F(\omega) cn=2πdωF(ω),即傅里叶变换选取信号幅值在频域中的分布密度 F ( ω ) F(\omega) F(ω) 作为表征量(而非对应频率的信号幅值 c n c_n cn)。若直接选取 c n c_n cn,在 T → ∞ T \to \infty T 时函数值均趋于 0,无实际应用价值。

傅里叶变换也可采用频率 f f f(单位:Hz)作为自变量,表达式为:

F ( f ) = ∫ − ∞ + ∞ f ( t ) e − j 2 π f t   d t F(f) = \int_{-\infty}^{+\infty} f(t)\mathrm{e}^{-\mathrm{j}2\pi f t}\,\mathrm{d}t F(f)=+f(t)ej2πftdt

1.3 结论

傅里叶变换的目标是将时域信号分解为无穷多个不同频率正弦信号的叠加,并揭示各正弦信号的强度与频率之间的对应关系。

2. DFT(离散傅里叶变换)

若已掌握 DFT 的基本原理,可跳过本节直接阅读 3. FFT 部分。

傅里叶变换的目标是求解信号的频谱密度函数(自变量为 ω \omega ω,因变量为信号幅值在频域中的分布密度),该函数反映信号强度与频率的对应关系。其基本表达式为:

F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − j ω t   d t F(\omega) = \int_{-\infty}^{+\infty} f(t)\mathrm{e}^{-\mathrm{j}\omega t}\,\mathrm{d}t F(ω)=+f(t)ejωtdt

理论分析中 f ( t ) f(t) f(t) 多为时域连续函数,但计算机采集的信号经采样处理后为时域离散信号,且计算机仅能计算有限个频率点的频谱值(频率需离散化)。DFT 是时域与频域均离散化的傅里叶变换形式。

2.1 采样的数学原理

若已掌握采样的基本原理,可跳过本节直接阅读 2.2 部分。

采样的数学实现依赖冲激函数(Dirac 函数),其定义为:

  • t ≠ 0 t \neq 0 t=0 时, δ ( t ) = 0 \delta(t) = 0 δ(t)=0
  • 积分满足 ∫ − ∞ + ∞ δ ( t )   d t = 1 \int_{-\infty}^{+\infty} \delta(t)\,\mathrm{d}t = 1 +δ(t)dt=1

冲激函数的筛选性质: ∫ − ∞ + ∞ δ ( t − t 0 ) f ( t )   d t = f ( t 0 ) \int_{-\infty}^{+\infty} \delta(t-t_0)f(t)\,\mathrm{d}t = f(t_0) +δ(tt0)f(t)dt=f(t0),可提取函数 f ( t ) f(t) f(t) t 0 t_0 t0 处的函数值,实现单点采样。

单点采样无法满足时域离散化需求,需将多个不同时刻的冲激函数叠加构成梳状函数(理想采样函数):

δ T ( t ) = ∑ n = − ∞ + ∞ δ ( t − n T s ) \delta_T(t) = \sum_{n=-\infty}^{+\infty} \delta(t-nT_s) δT(t)=n=+δ(tnTs)

其中 T s T_s Ts 为采样周期,。

将时域连续信号与梳状函数相乘,得到时域离散的采样信号:

f s ( t ) = f ( t ) ⋅ δ T ( t ) = ∑ n = − ∞ + ∞ f ( n T s ) δ ( t − n T s ) f_s(t) = f(t) \cdot \delta_T(t) = \sum_{n=-\infty}^{+\infty} f(nT_s)\delta(t-nT_s) fs(t)=f(t)δT(t)=n=+f(nTs)δ(tnTs)

2.2 时域离散化计算

对采样得到的离散信号 x s ( t ) = ∑ n = − ∞ + ∞ x ( n T s ) δ ( t − n T s ) x_s(t) = \sum_{n=-\infty}^{+\infty} x(nT_s)\delta(t-nT_s) xs(t)=n=+x(nTs)δ(tnTs) 进行傅里叶变换。

根据傅里叶变换定义:

X ( ω ) = ∫ − ∞ + ∞ x ( t ) e − j ω t   d t X(\omega) = \int_{-\infty}^{+\infty} x(t)\mathrm{e}^{-\mathrm{j}\omega t}\,\mathrm{d}t X(ω)=+x(t)ejωtdt

采样信号的傅里叶变换为:

X s ( ω ) = ∫ − ∞ + ∞ ( ∑ n = − ∞ + ∞ x ( n T s ) δ ( t − n T s ) ) e − j ω t   d t X_s(\omega) = \int_{-\infty}^{+\infty} \left(\sum_{n=-\infty}^{+\infty} x(nT_s)\delta(t-nT_s)\right) \mathrm{e}^{-\mathrm{j}\omega t}\,\mathrm{d}t Xs(ω)=+(n=+x(nTs)δ(tnTs))ejωtdt

交换积分与求和顺序:

X s ( ω ) = ∑ n = − ∞ + ∞ x ( n T s ) ∫ − ∞ + ∞ δ ( t − n T s ) e − j ω t   d t X_s(\omega) = \sum_{n=-\infty}^{+\infty} x(nT_s) \int_{-\infty}^{+\infty} \delta(t-nT_s)\mathrm{e}^{-\mathrm{j}\omega t}\,\mathrm{d}t Xs(ω)=n=+x(nTs)+δ(tnTs)ejωtdt

根据冲激函数筛选性质,最终得到时域离散化结果(即离散时间傅里叶变换,DTFT):

X s ( ω ) = ∑ n = − ∞ + ∞ x ( n T s ) e − j ω n T s X_s(\omega) = \sum_{n=-\infty}^{+\infty} x(nT_s)\mathrm{e}^{-\mathrm{j}\omega nT_s} Xs(ω)=n=+x(nTs)ejωnTs

或简记为(令 x [ n ] = x ( n T s ) x[n] = x(nT_s) x[n]=x(nTs) Ω = ω T s \Omega = \omega T_s Ω=ωTs):

X ( e j Ω ) = ∑ n = − ∞ + ∞ x [ n ] e − j Ω n X(\mathrm{e}^{\mathrm{j}\Omega}) = \sum_{n=-\infty}^{+\infty} x[n]\mathrm{e}^{-\mathrm{j}\Omega n} X(ejΩ)=n=+x[n]ejΩn

2.3 频域离散化计算

时域离散化得到的 X s ( ω ) X_s(\omega) Xs(ω) 仍为频域连续函数(周期为 ω s = 2 π / T s \omega_s = 2\pi/T_s ωs=2π/Ts),且对应无限长序列 x [ n ] x[n] x[n],而计算机只能存储有限长序列并计算有限个频率点,不符合工程需求。

2.3.1 处理思路

对信号 x ( t ) x(t) x(t) 进行 N N N 次(有限值)采样,得到有限长序列 x [ n ] x[n] x[n] n = 0 , 1 , … , N − 1 n = 0, 1, \ldots, N-1 n=0,1,,N1。DFT 隐含假设该有限长序列是某个周期序列的一个周期(时域周期延拓),周期为 T 0 = N T s T_0 = NT_s T0=NTs。周期序列的频谱为离散谱(傅里叶级数),由此实现频域离散化。

:时域周期延拓是 DFT 的数学构造,并非实际物理操作。

2.3.2 数学推导

一个周期内离散信号的表达式:

x ~ ( t ) = ∑ n = 0 N − 1 x ( n T s ) δ ( t − n T s ) \tilde{x}(t) = \sum_{n=0}^{N-1} x(nT_s)\delta(t-nT_s) x~(t)=n=0N1x(nTs)δ(tnTs)

周期信号 x ~ ( t ) \tilde{x}(t) x~(t) 的傅里叶级数系数为:

X ~ ( k ω 0 ) = 1 T 0 ∫ 0 T 0 x ~ ( t ) e − j k ω 0 t   d t \tilde{X}(k\omega_0) = \frac{1}{T_0}\int_{0}^{T_0} \tilde{x}(t)\mathrm{e}^{-\mathrm{j}k\omega_0 t}\,\mathrm{d}t X~(kω0)=T010T0x~(t)ejkω0tdt

其中基频 ω 0 = 2 π T 0 \omega_0 = \frac{2\pi}{T_0} ω0=T02π

代入 x ~ ( t ) \tilde{x}(t) x~(t) 并交换积分与求和顺序:

X ~ ( k ω 0 ) = 1 T 0 ∑ n = 0 N − 1 x ( n T s ) ∫ 0 T 0 δ ( t − n T s ) e − j k ω 0 t   d t \tilde{X}(k\omega_0) = \frac{1}{T_0}\sum_{n=0}^{N-1} x(nT_s) \int_{0}^{T_0} \delta(t-nT_s)\mathrm{e}^{-\mathrm{j}k\omega_0 t}\,\mathrm{d}t X~(kω0)=T01n=0N1x(nTs)0T0δ(tnTs)ejkω0tdt

根据冲激函数筛选性质:

X ~ ( k ω 0 ) = 1 T 0 ∑ n = 0 N − 1 x ( n T s ) e − j k ω 0 n T s \tilde{X}(k\omega_0) = \frac{1}{T_0}\sum_{n=0}^{N-1} x(nT_s)\mathrm{e}^{-\mathrm{j}k\omega_0 nT_s} X~(kω0)=T01n=0N1x(nTs)ejkω0nTs

代入 T 0 = N T s T_0 = NT_s T0=NTs ω 0 = 2 π T 0 \omega_0 = \frac{2\pi}{T_0} ω0=T02π 化简:

X ~ ( k ω 0 ) = 1 N T s ∑ n = 0 N − 1 x ( n T s ) e − j 2 π N T s k n T s = 1 N T s ∑ n = 0 N − 1 x ( n T s ) e − j 2 π N k n \begin{aligned} \tilde{X}(k\omega_0) &= \frac{1}{NT_s}\sum_{n=0}^{N-1} x(nT_s)\mathrm{e}^{-\mathrm{j}\frac{2\pi}{NT_s}knT_s} \\ &= \frac{1}{NT_s}\sum_{n=0}^{N-1} x(nT_s)\mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn} \end{aligned} X~(kω0)=NTs1n=0N1x(nTs)ejNTs2πknTs=NTs1n=0N1x(nTs)ejN2πkn

定义简化符号:

  • X [ k ] = N T s ⋅ X ~ ( k ω 0 ) X[k] = N T_s \cdot \tilde{X}(k\omega_0) X[k]=NTsX~(kω0)(或根据归一化方式不同,定义为 X [ k ] = X ~ ( k ω 0 ) ⋅ T s X[k] = \tilde{X}(k\omega_0) \cdot T_s X[k]=X~(kω0)Ts 等,需保持前后一致)
  • x [ n ] = x ( n T s ) x[n] = x(nT_s) x[n]=x(nTs)

最终得到 DFT 表达式(采用无系数形式,与 FFT 文献常用形式一致):

X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j 2 π N k n , k = 0 , 1 , … , N − 1 X[k] = \sum_{n=0}^{N-1} x[n]\mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn}, \quad k = 0, 1, \ldots, N-1 X[k]=n=0N1x[n]ejN2πkn,k=0,1,,N1

:DFT 定义中系数 1 / N 1/N 1/N 可置于正变换或逆变换,或两边均分 1 / N 1/\sqrt{N} 1/N ,不同领域惯例不同。本文采用信号处理领域常见形式(正变换无系数,逆变换含 1 / N 1/N 1/N)。

2.4 DFT 的复杂度

对于给定的 k k k 值,求解 X [ k ] X[k] X[k] 需完成 N N N 次复数乘法( x [ n ] x[n] x[n] e − j 2 π N k n \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn} ejN2πkn)和 N − 1 N-1 N1 次复数加法。

由于 e − j 2 π N k n \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn} ejN2πkn k k k 具有周期性(周期为 N N N),实际计算仅需 k = 0 , 1 , … , N − 1 k = 0, 1, \ldots, N-1 k=0,1,,N1。因此 DFT 算法的时间复杂度为 O ( N 2 ) \mathcal{O}(N^2) O(N2)

3. FFT(快速傅里叶变换)

3.1 数学原理

DFT 表达式为 X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j 2 π N k n X[k] = \sum_{n=0}^{N-1} x[n]\mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn} X[k]=n=0N1x[n]ejN2πkn,时间复杂度为 O ( N 2 ) \mathcal{O}(N^2) O(N2)。其中:

  • n n n 对应时域采样序号;
  • k k k 对应频率序号,实际频率为 f k = k N T s f_k = \frac{k}{NT_s} fk=NTsk 或角频率 ω k = 2 π k N T s \omega_k = \frac{2\pi k}{NT_s} ωk=NTs2πk
  • X [ k ] X[k] X[k] 对应频率 ω k \omega_k ωk 处的频谱值。
3.1.1 旋转因子的周期性

降低 DFT 复杂度的思路是利用 e − j 2 π N k n \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn} ejN2πkn 的周期性。定义旋转因子 W N n k = e − j 2 π N n k W_N^{nk} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}nk} WNnk=ejN2πnk

n n n 为偶数(令 n = 2 m n = 2m n=2m)时:

W N 2 m k = e − j 2 π N 2 m k = e − j 2 π N / 2 m k = W N / 2 m k W_N^{2mk} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}2mk} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N/2}mk} = W_{N/2}^{mk} WN2mk=ejN2π2mk=ejN/22πmk=WN/2mk

且满足 W N / 2 m k = W N / 2 m ( k + N / 2 ) W_{N/2}^{mk} = W_{N/2}^{m(k+N/2)} WN/2mk=WN/2m(k+N/2),即 W N / 2 m k W_{N/2}^{mk} WN/2mk k k k 的周期为 N / 2 N/2 N/2

3.1.2 奇偶项拆分

X [ k ] X[k] X[k] n n n 的奇偶性拆分为两部分:

X [ k ] = ∑ m = 0 N / 2 − 1 x [ 2 m ] W N 2 m k + ∑ m = 0 N / 2 − 1 x [ 2 m + 1 ] W N ( 2 m + 1 ) k X[k] = \sum_{m=0}^{N/2-1} x[2m]W_N^{2mk} + \sum_{m=0}^{N/2-1} x[2m+1]W_N^{(2m+1)k} X[k]=m=0N/21x[2m]WN2mk+m=0N/21x[2m+1]WN(2m+1)k

化简过程:

X [ k ] = ∑ m = 0 N / 2 − 1 x [ 2 m ] W N / 2 m k + W N k ∑ m = 0 N / 2 − 1 x [ 2 m + 1 ] W N / 2 m k \begin{aligned} X[k] &= \sum_{m=0}^{N/2-1} x[2m]W_{N/2}^{mk} + W_N^k \sum_{m=0}^{N/2-1} x[2m+1]W_{N/2}^{mk} \end{aligned} X[k]=m=0N/21x[2m]WN/2mk+WNkm=0N/21x[2m+1]WN/2mk

定义:

  • 偶数项部分: E [ k ] = ∑ m = 0 N / 2 − 1 x [ 2 m ] W N / 2 m k E[k] = \sum_{m=0}^{N/2-1} x[2m]W_{N/2}^{mk} E[k]=m=0N/21x[2m]WN/2mk
  • 奇数项部分: O [ k ] = ∑ m = 0 N / 2 − 1 x [ 2 m + 1 ] W N / 2 m k O[k] = \sum_{m=0}^{N/2-1} x[2m+1]W_{N/2}^{mk} O[k]=m=0N/21x[2m+1]WN/2mk

X [ k ] X[k] X[k] 简化为:

X [ k ] = E [ k ] + W N k O [ k ] X[k] = E[k] + W_N^k O[k] X[k]=E[k]+WNkO[k]

3.1.3 周期性推导

由于 W N / 2 m k W_{N/2}^{mk} WN/2mk k k k 的周期为 N / 2 N/2 N/2,因此 E [ k ] = E [ k + N / 2 ] E[k] = E[k+N/2] E[k]=E[k+N/2] O [ k ] = O [ k + N / 2 ] O[k] = O[k+N/2] O[k]=O[k+N/2]

且旋转因子满足 W N k + N / 2 = − W N k W_N^{k+N/2} = -W_N^k WNk+N/2=WNk,推导如下:

W N k + N / 2 = e − j 2 π N ( k + N / 2 ) = e − j 2 π N k e − j π = − e − j 2 π N k = − W N k \begin{aligned} W_N^{k+N/2} &= \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}(k+N/2)} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}k}\mathrm{e}^{-\mathrm{j}\pi} = -\mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}k} = -W_N^k \end{aligned} WNk+N/2=ejN2π(k+N/2)=ejN2πkejπ=ejN2πk=WNk

由此可得:

X [ k + N / 2 ] = E [ k ] − W N k O [ k ] X[k+N/2] = E[k] - W_N^k O[k] X[k+N/2]=E[k]WNkO[k]

N = 8 N=8 N=8 为例:

X [ 0 ] = E [ 0 ] + W 8 0 O [ 0 ] , X [ 4 ] = E [ 0 ] − W 8 0 O [ 0 ] X[0] = E[0] + W_8^0 O[0], \quad X[4] = E[0] - W_8^0 O[0] X[0]=E[0]+W80O[0],X[4]=E[0]W80O[0]

即求解得到 E [ 0 ] E[0] E[0] O [ 0 ] O[0] O[0] 后,可同时得到 X [ 0 ] X[0] X[0] X [ 4 ] X[4] X[4],无需重复计算。

3.2 算法流程

N = 8 N=8 N=8 为例,求解 X [ 0 ] X[0] X[0] X [ 4 ] X[4] X[4] 仅需计算 E [ 0 ] E[0] E[0] O [ 0 ] O[0] O[0]
对任意 k = 0 , 1 , … , N / 2 − 1 k=0,1,\dots,N/2-1 k=0,1,,N/21,已知频域奇偶分解结果 E [ k ] E[k] E[k] O [ k ] O[k] O[k],可通过一次复数乘法与两次复数加减运算同时得到 X [ k ] X[k] X[k] X [ k + N / 2 ] X[k+N/2] X[k+N/2]
由于 E [ k ] E[k] E[k] O [ k ] O[k] O[k] 均以 N / 2 N/2 N/2 为周期,满足
[
E[k+N/2] = E[k],\quad O[k+N/2] = O[k]
]
因此 X [ k ] X[k] X[k] X [ k + N / 2 ] X[k+N/2] X[k+N/2]共享同一组奇偶分解结果,只需计算一次 E [ k ] E[k] E[k] O [ k ] O[k] O[k] 即可完成一对频点的求解。

在这里插入图片描述

基于递归思想,对 E [ k ]   ( k = 0 , 1 , 2 , 3 ) E[k]\ (k = 0, 1, 2, 3) E[k] (k=0,1,2,3) 继续拆分:

  • E [ k ] E[k] E[k] 对应偶数序号样本 x [ 0 ] , x [ 2 ] , x [ 4 ] , x [ 6 ] x[0], x[2], x[4], x[6] x[0],x[2],x[4],x[6],可视为长度 N / 2 = 4 N/2 = 4 N/2=4 的 DFT;
  • 利用旋转因子关系
    e − j 2 π N ⋅ 2 n k = e − j 2 π N / 2 ⋅ n k \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N} \cdot 2nk} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N/2} \cdot nk} ejN2π2nk=ejN/22πnk
    E [ k ] E[k] E[k] 进一步拆分为偶数项与奇数项,重复拆分操作直至每一部分仅包含单个样本。

在这里插入图片描述

关于蝶形图的详细解析可参考相关专项资料。

3.3 FFT 的复杂度

若对数据结构与算法、FFT 复杂度推导过程无学习需求,可跳过本节。

时间复杂度表征算法处理规模为 N N N 的数据集时所需的运算次数,记为 T ( N ) T(N) T(N)

3.3.1 递归关系推导

基于3.2节的拆分逻辑,FFT算法的时间复杂度满足递归关系:
T ( N ) = 2 T ( N / 2 ) + O ( N ) T(N) = 2T(N/2) + \mathcal{O}(N) T(N)=2T(N/2)+O(N)
推导依据:将 N N N 点 DFT 拆分为两个 N / 2 N/2 N/2 点 DFT(对应 2 T ( N / 2 ) 2T(N/2) 2T(N/2));合并两个子问题结果时,需执行 N N N 次复数加法和 N / 2 N/2 N/2 次复数乘法( W N k O [ k ] W_N^k O[k] WNkO[k]),这部分运算量为 O ( N ) \mathcal{O}(N) O(N)

3.3.2 复杂度求解

复杂度分析的本质是“阶数”而非“精确数值”。

对递归公式展开(假设 N = 2 L N = 2^L N=2L L = log ⁡ 2 N L = \log_2 N L=log2N):
T ( N ) = 2 T ( N / 2 ) + N = 2 ( 2 T ( N / 4 ) + N 2 ) + N = 4 T ( N / 4 ) + 2 N = 4 ( 2 T ( N / 8 ) + N 4 ) + 2 N = 8 T ( N / 8 ) + 3 N = ⋯ = 2 L T ( 1 ) + L ⋅ N \begin{aligned} T(N) &= 2T(N/2) + N \\ &= 2\left(2T(N/4) + \frac{N}{2}\right) + N = 4T(N/4) + 2N \\ &= 4\left(2T(N/8) + \frac{N}{4}\right) + 2N = 8T(N/8) + 3N \\ &= \cdots \\ &= 2^L T(1) + L\cdot N \end{aligned} T(N)=2T(N/2)+N=2(2T(N/4)+2N)+N=4T(N/4)+2N=4(2T(N/8)+4N)+2N=8T(N/8)+3N==2LT(1)+LN

前提:单点 DFT( N = 1 N=1 N=1 时,仅需直接取样本值 X [ 0 ] = x [ 0 ] X[0] = x[0] X[0]=x[0])无需任何复数乘法/加法运算,因此 T ( 1 ) = 0 T(1) = 0 T(1)=0。代入后可得:
T ( N ) = N log ⁡ 2 N T(N) = N\log_2 N T(N)=Nlog2N

由此可知,FFT 算法的时间复杂度为 O ( N log ⁡ N ) \mathcal{O}(N\log N) O(NlogN)。结合 FFT 蝶形运算的实际执行过程,可进一步明确具体运算次数:

  • 复数乘法次数: N 2 log ⁡ 2 N \frac{N}{2}\log_2 N 2Nlog2N(仅在合并奇偶子问题时需计算旋转因子与 O [ k ] O[k] O[k] 的乘积,共 N / 2 N/2 N/2 次/层,总计 log ⁡ 2 N \log_2 N log2N 层);
  • 复数加法次数: N log ⁡ 2 N N\log_2 N Nlog2N(每对 X [ k ] X[k] X[k] X [ k + N / 2 ] X[k+N/2] X[k+N/2] 需 2 次加减运算,共 N / 2 N/2 N/2 对/层,总计 log ⁡ 2 N \log_2 N log2N 层)。

4. 总结

  1. 傅里叶变换的本质是将时域信号分解为不同频率复指数信号的叠加,DFT 是其时域与频域均离散化的工程实现,FFT 则是 DFT 的高效算法;
  2. FFT 算法利用旋转因子的周期性与对称性,将 DFT 的 O ( N 2 ) \mathcal{O}(N^2) O(N2) 复杂度降至 O ( N log ⁡ N ) \mathcal{O}(N\log N) O(NlogN),手段为递归奇偶分解与蝶形运算复用;
  3. FFT 算法通过分治与复用策略,大幅降低频域分析运算量,是数字信号处理中高效的频谱分析方法。

如何理解和掌握快速傅里叶变换的计算和概念?

杨宇翔 编辑于2014-05-10 18:29

离散傅里叶变换(DFT)的定义

离散傅里叶变换(Discrete Fourier Transform, DFT)的定义为:

X [ k ] = ∑ n = 0 N − 1 x [ n ]   e − j 2 π N k n , 0 ≤ k ≤ N − 1 X[k] = \sum_{n=0}^{N-1} x[n] \, \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}kn}, \quad 0 \leq k \leq N-1 X[k]=n=0N1x[n]ejN2πkn,0kN1

为表达简洁,令 W N = e − j 2 π N W_N = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N}} WN=ejN2π,则上式可写为:

X [ k ] = ∑ n = 0 N − 1 x [ n ]   W N k n X[k] = \sum_{n=0}^{N-1} x[n] \, W_N^{kn} X[k]=n=0N1x[n]WNkn

FFT 的种类很多,本文以最简单的基 2 FFT(信号长度 N N N 为 2 的整数幂)为例进行说明。

FFT 本质上是一种分治算法。该算法将长度为 N N N 的信号分解为两个长度为 N 2 \frac{N}{2} 2N 的子信号进行处理,如此递归分解直至长度为 1。每一次分解均可减少计算量。理解 FFT 可分为以下三个步骤:

步骤 1:将信号 x [ n ] x[n] x[n] 分解为两个子信号

  • 偶数样本点信号: x [ 2 n ] x[2n] x[2n]
  • 奇数样本点信号: x [ 2 n + 1 ] x[2n+1] x[2n+1],其中 n = 0 , 1 , … , N 2 − 1 n = 0, 1, \ldots, \frac{N}{2}-1 n=0,1,,2N1

则:

X [ k ] = ∑ n = 0 N − 1 x [ n ]   W N k n = ∑ n = 0 N 2 − 1 x [ 2 n ]   W N k ( 2 n ) + ∑ n = 0 N 2 − 1 x [ 2 n + 1 ]   W N k ( 2 n + 1 ) X[k] = \sum_{n=0}^{N-1} x[n] \, W_N^{kn} = \sum_{n=0}^{\frac{N}{2}-1} x[2n] \, W_N^{k(2n)} + \sum_{n=0}^{\frac{N}{2}-1} x[2n+1] \, W_N^{k(2n+1)} X[k]=n=0N1x[n]WNkn=n=02N1x[2n]WNk(2n)+n=02N1x[2n+1]WNk(2n+1)

步骤 2:将两个求和项理解为两个长度为 N 2 \frac{N}{2} 2N 的 DFT

X [ k ] = ∑ n = 0 N 2 − 1 x [ 2 n ]   W N k ( 2 n ) + W N k ∑ n = 0 N 2 − 1 x [ 2 n + 1 ]   W N k ( 2 n ) X[k] = \sum_{n=0}^{\frac{N}{2}-1} x[2n] \, W_N^{k(2n)} + W_N^k \sum_{n=0}^{\frac{N}{2}-1} x[2n+1] \, W_N^{k(2n)} X[k]=n=02N1x[2n]WNk(2n)+WNkn=02N1x[2n+1]WNk(2n)

其中 W N k ( 2 n ) = e − j 2 π N ⋅ 2 n = e − j 2 π N / 2 ⋅ n = W N / 2 k n W_N^{k(2n)} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N} \cdot 2n} = \mathrm{e}^{-\mathrm{j}\frac{2\pi}{N/2} \cdot n} = W_{N/2}^{kn} WNk(2n)=ejN2π2n=ejN/22πn=WN/2kn,因此:

X [ k ] = E [ k ] + W N k   O [ k ] , 0 ≤ k ≤ N − 1 X[k] = E[k] + W_N^k \, O[k], \quad 0 \leq k \leq N-1 X[k]=E[k]+WNkO[k],0kN1

式中,
偶数样本点信号的 DFT 为:

E [ k ] = ∑ n = 0 N 2 − 1 x [ 2 n ]   W N / 2 k n E[k] = \sum_{n=0}^{\frac{N}{2}-1} x[2n] \, W_{N/2}^{kn} E[k]=n=02N1x[2n]WN/2kn

奇数样本点信号的 DFT 为:

O [ k ] = ∑ n = 0 N 2 − 1 x [ 2 n + 1 ]   W N / 2 k n O[k] = \sum_{n=0}^{\frac{N}{2}-1} x[2n+1] \, W_{N/2}^{kn} O[k]=n=02N1x[2n+1]WN/2kn

步骤 3:FFT 的具体计算过程(通过蝶形图可视化)

由于 W N k n W_N^{kn} WNkn k k k n n n 均具有周期性: W N k n = W N k ( n + N ) = W N ( k + N ) n W_N^{kn} = W_N^{k(n+N)} = W_N^{(k+N)n} WNkn=WNk(n+N)=WN(k+N)n,故:

E [ k ] = E [ k + N 2 ] , O [ k ] = O [ k + N 2 ] (周期性) E[k] = E\left[k+\frac{N}{2}\right], \quad O[k] = O\left[k+\frac{N}{2}\right] \quad \text{(周期性)} E[k]=E[k+2N],O[k]=O[k+2N](周期性)

N = 8 N = 8 N=8 为例,信号的 FFT 计算过程如下:

第 1 次分解:

img

第 2 次分解:

在这里插入图片描述

第 3 次分解:

img

FFT 与 DFT 的性能比较

根据 DFT 的定义:

  • 对于任意 k k k,需进行 N N N 次乘法运算,故 DFT 共需 N 2 N^2 N2 次乘法运算;
  • 对于任意 k k k,需进行 N − 1 N-1 N1 次加法运算,故 DFT 共需 N ( N − 1 ) N(N-1) N(N1) 次加法运算。

从 FFT 的蝶形图可知:

在这里插入图片描述
共需 N ( log ⁡ 2 N − 1 ) N(\log_2 N - 1) N(log2N1) 次乘法运算和 N log ⁡ 2 N N \log_2 N Nlog2N 次加法运算。


如何理解和掌握快速傅里叶变换的计算和概念?

游凯超 编辑于 2023-06-18 09:17 北京

离散傅里叶变换(DFT)是信号处理中的重要方法,快速傅里叶变换(FFT)是其一种快速实现方式。本文从算法复杂度角度,阐述快速傅里叶变换"快"在何处。

从矩阵-向量乘法说起

对于大小为 N N N 的矩阵 A N × N \boldsymbol{A}_{N \times N} AN×N,该矩阵作用于 N N N 维向量 x \boldsymbol{x} x 的矩阵-向量乘法 A x \boldsymbol{A}\boldsymbol{x} Ax 的复杂度显然为 O ( N 2 ) \mathcal{O}(N^2) O(N2)

离散傅里叶变换 DFT

对长度为 N N N 的向量 x \boldsymbol{x} x 作离散傅里叶变换,本质上是用一个特殊的矩阵——离散傅里叶变换矩阵 D N × N \boldsymbol{D}_{N \times N} DN×N x \boldsymbol{x} x 作矩阵-向量乘法 X = D x \boldsymbol{X} = \boldsymbol{D}\boldsymbol{x} X=Dx。其中,离散傅里叶变换矩阵的元素具有规律性: D i j = ω i j D_{ij} = \omega^{ij} Dij=ωij 0 ≤ i , j ≤ N − 1 0 \leq i, j \leq N-1 0i,jN1 ω = e − 2 π i / N \omega = \mathrm{e}^{-2\pi\mathrm{i}/N} ω=e2πi/N 为复数方程 z N = 1 z^N = 1 zN=1 的单位根,此处 i \mathrm{i} i 为虚数单位,注意与行列下标 i , j i, j i,j 区分)。

img
DFT 矩阵

快速傅里叶变换算法 FFT

由于离散傅里叶变换矩阵具有高度规律性,涉及该矩阵的乘法必然存在巧妙的计算方法以加速运算。快速傅里叶变换算法(FFT)正是这样一种加速 DFT 矩阵-向量乘法的算法。

FFT 算法的关键:奇偶分离(以 8 个数为例)

FFT 算法的原理十分简洁,仅需对矩阵乘法的列进行重新排列即可发现规律。以 8 元离散傅里叶变换为例,其原始形式如下:

在这里插入图片描述

8 元离散傅里叶变换

在矩阵乘法中,对右侧向量的行进行置换,同时对矩阵的列进行相应置换,结果保持不变。因此,可将偶数列(0, 2, 4, 6 列,程序员下标从 0 开始)移至左侧,对应地将偶数下标的 x x x(0, 2, 4, 6 行)移至上方,得到变换后的结果:

img

奇偶分离的 8 元离散傅里叶变换

观察上述变换后的分块矩阵,可见每一列的上下子矩阵之间均相差一个固定倍数。这并非偶然,正是 FFT 算法的关键所在。

奇偶分离的形式化描述

一般地(对于偶数 N N N),上述分块结果可表示为下图,其中 x N 2 \boldsymbol{x}_{\frac{N}{2}} x2N 表示偶数行, x N 2 + 1 \boldsymbol{x}_{\frac{N}{2}+1} x2N+1 表示奇数行。

在这里插入图片描述

ω \omega ω 为方程 z N = 1 z^N = 1 zN=1 的单位根,故 ω N = 1 \omega^N = 1 ωN=1。为方便讨论,此处考虑 N N N 为偶数的情形,于是 ω N 2 = − 1 \omega^{\frac{N}{2}} = -1 ω2N=1。由此可得四个分块矩阵的关系:

D 2 = D 1 ⋅ ω N j = D 1 \boldsymbol{D}_2 = \boldsymbol{D}_1 \cdot \omega^{Nj} = \boldsymbol{D}_1 D2=D1ωNj=D1

D 4 = D 3 ⋅ ω N j + N 2 ( − N + 1 ) = D 3   ω N 2 = − D 3 \boldsymbol{D}_4 = \boldsymbol{D}_3 \cdot \omega^{Nj + \frac{N}{2}(-N+1)} = \boldsymbol{D}_3 \, \omega^{\frac{N}{2}} = -\boldsymbol{D}_3 D4=D3ωNj+2N(N+1)=D3ω2N=D3

借助以上关系, N N N 个数的傅里叶变换结果可简化为:

img

因此,只需计算对偶数下标元素作用 D 1 \boldsymbol{D}_1 D1、对奇数下标元素作用 D 3 \boldsymbol{D}_3 D3 所得结果 D 1 x N 2 \boldsymbol{D}_1 \boldsymbol{x}_{\frac{N}{2}} D1x2N D 3 x N 2 + 1 \boldsymbol{D}_3 \boldsymbol{x}_{\frac{N}{2}+1} D3x2N+1,即可得到 D x \boldsymbol{D}\boldsymbol{x} Dx 的完整结果。

离散傅里叶变换的递归结构

注意到 D 1 = ω i ⋅ ( 2 j ) = ( ω 2 ) i j \boldsymbol{D}_1 = \omega^{i \cdot (2j)} = (\omega^2)^{ij} D1=ωi(2j)=(ω2)ij 即为 N 2 \frac{N}{2} 2N 个元素的 DFT 矩阵,故 D 1 x N 2 \boldsymbol{D}_1 \boldsymbol{x}_{\frac{N}{2}} D1x2N 是对下标为偶数的 N 2 \frac{N}{2} 2N 个元素进行离散傅里叶变换的结果。

注意到 D 3 = ω i ( 2 j − N + 1 ) = ( ω 2 ) i j ⋅ ω i \boldsymbol{D}_3 = \omega^{i(2j-N+1)} = (\omega^2)^{ij} \cdot \omega^i D3=ωi(2jN+1)=(ω2)ijωi D 3 \boldsymbol{D}_3 D3 D 1 \boldsymbol{D}_1 D1 仅相差一个行变换,因此 D 3 x N 2 + 1 \boldsymbol{D}_3 \boldsymbol{x}_{\frac{N}{2}+1} D3x2N+1 是对下标为奇数的 N 2 \frac{N}{2} 2N 个元素进行离散傅里叶变换后,再对第 i i i 个元素乘以 ω i \omega^i ωi 的结果。

由此得到离散傅里叶变换的递归结构

N N N 个元素的离散傅里叶变换结果可由奇数下标、偶数下标的 N 2 \frac{N}{2} 2N 个元素分别进行离散傅里叶变换的结果组合得到。

快速傅里叶变换的复杂度

N N N 个元素的快速傅里叶变换复杂度为 T ( N ) T(N) T(N),根据递归结构,可得递归公式:

T ( N ) = 2 T ( N 2 ) + O ( N ) T(N) = 2T\left(\frac{N}{2}\right) + \mathcal{O}(N) T(N)=2T(2N)+O(N)

根据复杂度分析的主定理,立即可得快速傅里叶变换的时间复杂度为 O ( N log ⁡ N ) \mathcal{O}(N \log N) O(NlogN)

离散傅里叶变换的应用

离散傅里叶变换矩阵常出现在一些特殊矩阵的分解中。

循环矩阵(Circulant Matrix)

循环矩阵由第一行经循环移位生成:

在这里插入图片描述

可以证明, C = D − 1 d i a g { D c } D \boldsymbol{C} = \boldsymbol{D}^{-1} \mathrm{diag}\{\boldsymbol{D}\boldsymbol{c}\} \boldsymbol{D} C=D1diag{Dc}D,其中 c \boldsymbol{c} c C \boldsymbol{C} C 的第一列。于是 C x = D − 1 d i a g { D c } D x \boldsymbol{C}\boldsymbol{x} = \boldsymbol{D}^{-1} \mathrm{diag}\{\boldsymbol{D}\boldsymbol{c}\} \boldsymbol{D}\boldsymbol{x} Cx=D1diag{Dc}Dx,即 D c \boldsymbol{D}\boldsymbol{c} Dc D x \boldsymbol{D}\boldsymbol{x} Dx 的逐元素乘法结果再做离散傅里叶逆变换 D − 1 \boldsymbol{D}^{-1} D1。因此,涉及循环矩阵的矩阵-向量乘法亦可在 O ( N log ⁡ N ) \mathcal{O}(N \log N) O(NlogN) 时间内完成。

Toeplitz 矩阵

Toeplitz 矩阵由第一行和第一列共同决定,其余元素沿对角线方向复制:

img

值得注意的是:大小为 n × n n \times n n×n 的 Toeplitz 矩阵可嵌入大小为 2 n × 2 n 2n \times 2n 2n×2n 的循环矩阵中。下图的分块矩阵中,左上角和右下角为两个相同的 Toeplitz 矩阵。

在这里插入图片描述

因此,包含 Toeplitz 矩阵的矩阵-向量乘法可转化为循环矩阵的乘法,亦可在 O ( N log ⁡ N ) \mathcal{O}(N \log N) O(NlogN) 时间内完成。

T v ‾ = ( I n 0 n ) A ( v ‾ 0 n ) T\underline{v} = \begin{pmatrix} I_n & 0_n \end{pmatrix} A \begin{pmatrix} \underline{v} \\ 0_n \end{pmatrix} Tv=(In0n)A(v0n)

附加说明

  • 为书写方便,本文仅讨论 N N N 为偶数的情形。 N N N 为奇数的情形类似,读者可自行验证。
  • 本文中 D 1 = ω i ⋅ ( 2 j ) \boldsymbol{D}_1 = \omega^{i \cdot (2j)} D1=ωi(2j) 的表示形式意指该矩阵的第 i i i 行第 j j j 列元素为 ω i ⋅ ( 2 j ) \omega^{i \cdot (2j)} ωi(2j),行列值从 0 开始计数。
  • 本文参考了 MIT 课件维基百科。部分文献中的离散傅里叶变换矩阵 D \boldsymbol{D} D 包含归一化系数 1 N \frac{1}{\sqrt{N}} N 1 或使用相反的辐角 ω = e 2 π i / N \omega = \mathrm{e}^{2\pi\mathrm{i}/N} ω=e2πi/N,这些区别不影响对 FFT 算法复杂度的分析。
  • 复杂度分析的主定理参见 维基百科
  • 离散傅里叶变换的应用、循环矩阵和 Toeplitz 矩阵的分解参考了 MIT 课件
  • 循环矩阵在深度学习中的应用,可参见 ICCV 2015 论文《An Exploration of Parameter Redundancy in Deep Networks with Circulant Projections》。

如何理解和掌握快速傅里叶变换的计算和概念?

学理科的徐大喵 编辑于 2023-07-14 14:58 · 浙江

一、周期序列的离散傅里叶级数

首先给出周期性离散时间信号 f N ( k ) f_N(k) fN(k) 的定义,下标 N N N 表示其周期,即:
f N ( k ) = f N ( k + l N ) , l = 0 , ± 1 , ± 2 , … f_N(k) = f_N(k + lN), \quad l = 0, \pm 1, \pm 2, \ldots fN(k)=fN(k+lN),l=0,±1,±2,

周期离散序列:序列 f N ( k ) f_N(k) fN(k) 在整数 k k k 上周期重复,周期为 N N N。即对于任意整数 l l l,序列值在 k k k k + l N k+lN k+lN 处相等。这是离散傅里叶级数(DFS)和离散傅里叶变换(DFT)的基础假设。

根据前文所述,周期为 T T T 的连续时间信号 f ( t ) f(t) f(t) 可表示为一系列虚指数项 e j n 2 π T t \mathrm{e}^{\mathrm{j}n\frac{2\pi}{T}t} ejnT2πt 之和,称为傅里叶级数的复数形式:
f ( t ) = ∑ n = − ∞ + ∞ c n e j n 2 π T t c n = 1 T ∫ − T / 2 T / 2 f ( t ) e − j n 2 π T t   d t \begin{aligned} f(t) &= \sum_{n=-\infty}^{+\infty} c_n \mathrm{e}^{\mathrm{j}n\frac{2\pi}{T}t} \\[8pt] c_n &= \frac{1}{T}\int_{-T/2}^{T/2} f(t) \mathrm{e}^{-\mathrm{j}n\frac{2\pi}{T}t} \,\mathrm{d}t \end{aligned} f(t)cn=n=+cnejnT2πt=T1T/2T/2f(t)ejnT2πtdt

类似地,这种傅里叶级数的分析方法亦可应用于离散周期序列。这是因为,离散周期序列 f N ( k ) f_N(k) fN(k) 可由周期为 T T T 的连续时间信号 f ( t ) f(t) f(t) 经周期性采样获得(采样周期为 T s T_s Ts):

在这里插入图片描述
此时,得到的离散序列其周期可以表示为 N = T / T s N = T/T_s N=T/Ts,因此周期序列 f N ( k ) f_N(k) fN(k) 也可以表示为一系列虚指数项 e j n 2 π N k \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} ejnN2πk 和的形式:

e j n 2 π T k T s = e j n 2 π N k \mathrm{e}^{\mathrm{j}n\frac{2\pi}{T}kT_s} = \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} ejnT2πkTs=ejnN2πk

同时,根据复数运算,这组虚指数满足:

e j ( n + l N ) 2 π N k = e j n 2 π N k , l = 0 , ± 1 , ± 2 , … \mathrm{e}^{\mathrm{j}(n+lN)\frac{2\pi}{N}k} = \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k}, \quad l = 0, \pm 1, \pm 2, \ldots ej(n+lN)N2πk=ejnN2πk,l=0,±1,±2,

因此,其中独立分布的虚指数仅有 N N N 项,取 n = 0 , 1 , … , N − 1 n = 0, 1, \ldots, N-1 n=0,1,,N1 并写出 f N ( k ) f_N(k) fN(k) 的展开式:

f N ( k ) = ∑ n = 0 N − 1 c n e j n 2 π N k f_N(k) = \sum_{n=0}^{N-1} c_n \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} fN(k)=n=0N1cnejnN2πk

式中 c n c_n cn 为待定系数。类比连续傅里叶级数求解待定系数的方法,上式两端同乘 e − j m 2 π N k \mathrm{e}^{-\mathrm{j}m\frac{2\pi}{N}k} ejmN2πk 并在一个周期内对 k k k 求和(右端交换求和次序):

∑ k = 0 N − 1 f N ( k ) e − j m 2 π N k = ∑ k = 0 N − 1 [ e − j m 2 π N k ∑ n = 0 N − 1 c n e j n 2 π N k ] = ∑ n = 0 N − 1 [ c n ∑ k = 0 N − 1 e j ( n − m ) 2 π N k ] \begin{aligned} \sum_{k=0}^{N-1} f_N(k) \mathrm{e}^{-\mathrm{j}m\frac{2\pi}{N}k} &= \sum_{k=0}^{N-1}\left[ \mathrm{e}^{-\mathrm{j}m\frac{2\pi}{N}k} \sum_{n=0}^{N-1} c_n \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} \right] \\[8pt] &= \sum_{n=0}^{N-1}\left[ c_n \sum_{k=0}^{N-1} \mathrm{e}^{\mathrm{j}(n-m)\frac{2\pi}{N}k} \right] \end{aligned} k=0N1fN(k)ejmN2πk=k=0N1[ejmN2πkn=0N1cnejnN2πk]=n=0N1[cnk=0N1ej(nm)N2πk]

根据等比数列求和公式,右端的求和项满足:

∑ k = 0 N − 1 e j ( n − m ) 2 π N k = { N , n = m 1 − e j ( n − m ) 2 π N ⋅ N 1 − e j ( n − m ) 2 π N = 0 , n , m = 0 , 1 , … , N − 1 ,   n ≠ m \sum_{k=0}^{N-1} \mathrm{e}^{\mathrm{j}(n-m)\frac{2\pi}{N}k} = \begin{cases} N, & n = m \\[12pt] \displaystyle\frac{1-\mathrm{e}^{\mathrm{j}(n-m)\frac{2\pi}{N}\cdot N}}{1-\mathrm{e}^{\mathrm{j}(n-m)\frac{2\pi}{N}}} = 0, & n,m = 0,1,\ldots,N-1,\ n \neq m \end{cases} k=0N1ej(nm)N2πk= N,1ej(nm)N2π1ej(nm)N2πN=0,n=mn,m=0,1,,N1, n=m

即当 m = n m = n m=n 时,求得待定系数:

c n = 1 N ∑ k = 0 N − 1 f N ( k ) e − j n 2 π N k c_n = \frac{1}{N}\sum_{k=0}^{N-1} f_N(k) \mathrm{e}^{-\mathrm{j}n\frac{2\pi}{N}k} cn=N1k=0N1fN(k)ejnN2πk

至此,离散周期序列可表示为一系列虚指数项之和的形式:

f N ( k ) = ∑ n = 0 N − 1 c n e j n 2 π N k c n = 1 N ∑ k = 0 N − 1 f N ( k ) e − j n 2 π N k \begin{aligned} f_N(k) &= \sum_{n=0}^{N-1} c_n \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} \\[8pt] c_n &= \frac{1}{N}\sum_{k=0}^{N-1} f_N(k) \mathrm{e}^{-\mathrm{j}n\frac{2\pi}{N}k} \end{aligned} fN(k)cn=n=0N1cnejnN2πk=N1k=0N1fN(k)ejnN2πk

给出一个实例,如下图所示为一离散周期序列 N = 4 N = 4 N=4,将其分解为离散傅里叶级数:

在这里插入图片描述
img

作出分解的结果示意图:

clear all
t = linspace(-2, 6, 1000);
f = 1/2 + 0.25*cos(t*pi/2) + 0.25*sin(t*pi/2) + 0.25*cos(3*t*pi/2) - 0.25*sin(3*t*pi/2);
plot(t, f, '--', 'LineWidth', 1.2)
grid on
hold on
k = [-1 0 1 2 3 4 5];
fk = [0 1 1 0 0 1 1];
stem(k, fk, '.', 'LineWidth', 1.2, 'MarkerSize', 20)
xlabel('k')
ylabel('f_N')

在这里插入图片描述

分解结果符合原周期序列。

二、快速傅里叶变换(FFT)

(a)离散傅里叶变换(DFT)

离散傅里叶变换主要用于计算机实现对信息的处理。由于计算机只能处理有限长度的离散数据,而周期序列的离散傅里叶级数恰好满足这些特征:只需对计算机输入在信号的一个周期 T T T 内采样得到的 N N N 个数据点(采样周期为 T s T_s Ts),通过计算即可得到以虚指数项 e j n 2 π N k \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} ejnN2πk 表示的 N N N 个谐波分量:

f N ( k ) = ∑ n = 0 N − 1 c n e j n 2 π N k c n = 1 N ∑ k = 0 N − 1 f N ( k ) e − j n 2 π N k \begin{aligned} f_N(k) &= \sum_{n=0}^{N-1} c_n \mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} \\[8pt] c_n &= \frac{1}{N}\sum_{k=0}^{N-1} f_N(k) \mathrm{e}^{-\mathrm{j}n\frac{2\pi}{N}k} \end{aligned} fN(k)cn=n=0N1cnejnN2πk=N1k=0N1fN(k)ejnN2πk

根据各虚指数项的系数 c n c_n cn,定义周期序列的离散傅里叶变换为:

F N ( n ) = ∑ k = 0 N − 1 f N ( k ) e − j n 2 π N k , n = 0 , 1 , … , N − 1 F_N(n) = \sum_{k=0}^{N-1} f_N(k) \mathrm{e}^{-\mathrm{j}n\frac{2\pi}{N}k}, \quad n = 0, 1, \ldots, N-1 FN(n)=k=0N1fN(k)ejnN2πk,n=0,1,,N1
为还原该周期序列,其逆变换为:

f N ( k ) = 1 N ∑ n = 0 N − 1 F N ( n ) ⋅ e j n 2 π N k f_N(k) = \frac{1}{N} \sum_{n=0}^{N-1} F_N(n) \cdot e^{j n \frac{2\pi}{N} k} fN(k)=N1n=0N1FN(n)ejnN2πk

(b)MATLAB 应用实例

给出一连续时间信号:

f ( t ) = 1 2 + 2 sin ⁡ ( 10 ω t ) + sin ⁡ ( 20 ω t ) f(t) = \frac{1}{2} + 2\sin(10\omega t) + \sin(20\omega t) f(t)=21+2sin(10ωt)+sin(20ωt)

其中,角频率 ω = 100 π \omega = 100\pi ω=100π。取采样频率为基波频率的 100 倍,对其进行离散化采样得到周期序列 f N ( k ) f_N(k) fN(k),使用离散傅里叶变换进行分析:

clear all
N = 100;        % 100 个采样点
w = 2*pi*50;    % 基波 50 Hz
T = 1/50;       % 基波周期
Ts = T/N;       % 采样周期
kN = 0:(N-1);
% 原连续时间信号
% ft = 1/2 + 2*sin(10*w*t) + sin(20*w*t);
% 采样获得有限长度离散数据
fN = 1/2 + 2*sin(10*w*kN*Ts) + sin(20*w*kN*Ts);
% 定义离散傅里叶变换
Fn = zeros(1, N);
for n = 0:N-1
    for k = 0:N-1
        Fn(n+1) = Fn(n+1) + fN(k+1)*exp(-1j*n*2*pi*k/N);
    end
end
A = abs(Fn);
plot(kN, A, 'LineWidth', 1.5)
grid on
xlabel('n')
ylabel('F_n')

作出离散傅里叶变换所得的幅度谱:
在这里插入图片描述

观察该幅度谱,可以发现其具有以下特点:

1) 在各次谐波分量中,除直流分量外,幅度谱关于 N / 2 N/2 N/2 对称。观察这一系列虚指数:

在这里插入图片描述

即其中关于 N / 2 N/2 N/2 对称的虚指数是一对共轭复数,它们幅值相等、相位相反。因此根据复数运算法则,关于 N / 2 N/2 N/2 对称的 F ( n ) F(n) F(n) 也是一对共轭复数,于是可知幅度谱关于 N / 2 N/2 N/2 对称。

在此基础上可推得:关于 N / 2 N/2 N/2 对称的项 F ( n ) e j n 2 π N k F(n)\mathrm{e}^{\mathrm{j}n\frac{2\pi}{N}k} F(n)ejnN2πk 也是一对共轭复数,这意味着它们的实部相等。在离散傅里叶级数中,当等式左端 f N ( k ) f_N(k) fN(k) 为实数序列时,等式右端复数求和项中的虚部会相消,仅保留实部(可参考第二部分实例)。因此关于 N / 2 N/2 N/2 对称的虚指数项可看作同一次谐波,即离散傅里叶变换最高可分解出 ( N / 2 − 1 ) (N/2 - 1) (N/21) 次谐波(计算中向上取整)。

在这里插入图片描述

在本节实例中, N = 100 N = 100 N=100 则最高可分解出 49 次谐波;若 N = 101 N = 101 N=101 则最高可分解出 50 次谐波。

2) 原连续时间信号中的直流分量 A 0 A_0 A0、基波分量和各次谐波分量的幅值 A ( n ) A(n) A(n) 与离散傅里叶变换各项幅值之间的关系满足:

在这里插入图片描述

其中,系数 1 / N 1/N 1/N 由离散傅里叶变换的定义显然可知;系数 2 2 2 与上一条中将关于 N / 2 N/2 N/2 对称的虚指数项看作同一次谐波相对应。

因此由离散傅里叶变换得到原连续时间信号各次谐波的幅值:

clear all
N = 100;        % 100 个采样点
w = 2*pi*50;    % 基波 50 Hz
T = 1/50;       % 基波周期
Ts = T/N;       % 采样周期
f = 50;
kN = 0:(N-1);
% 原连续时间信号
% ft = 1/2 + 2*sin(10*w*t) + sin(20*w*t);
% 采样获得有限长度离散数据
fN = 1/2 + 2*sin(10*w*kN*Ts) + cos(20*w*kN*Ts);
% 定义离散傅里叶变换
Fn = zeros(1, N);
for n = 0:N-1
    for k = 0:N-1
        Fn(n+1) = Fn(n+1) + fN(k+1)*exp(-1j*n*2*pi*k/N);
    end
end
A = abs(Fn);
if mod(N, 2) == 0
    fp = (0:N/2-1)*f;
    Ap(1) = A(1)/N;
    Ap(2:N/2-1+1) = 2*A(2:N/2-1+1)/N;         % MATLAB 数组标号起始为 1
else
    fp = (0:(N+1)/2-1)*f;
    Ap(1) = A(1)/N;
    Ap(2:(N+1)/2-1+1) = 2*A(2:(N+1)/2-1+1)/N; % MATLAB 数组标号起始为 1
end
plot(fp, Ap, 'LineWidth', 1.5)
grid on
xlabel('f/Hz')
ylabel('A_n')

在这里插入图片描述

(c)采样定理

连续时间信号的基波周期为 T T T,基波频率为 ω T = 2 π / T \omega_T = 2\pi/T ωT=2π/T

离散化采样周期为 T s T_s Ts,采样频率为 ω s = 2 π / T s \omega_s = 2\pi/T_s ωs=2π/Ts

其中,离散序列的周期 N = T / T s N = T/T_s N=T/Ts,即 N = ω s / ω T N = \omega_s/\omega_T N=ωs/ωT

根据前述离散傅里叶变换幅度谱的特点(1),在此条件下能够分解出 0 ∼ ( N / 2 − 1 ) 0 \sim (N/2 - 1) 0(N/21) 次谐波分量。定义连续时间信号中的最高次谐波频率为 ω m \omega_m ωm,那么要保证傅里叶变换能够分解出原信号的所有谐波分量,必须满足:

在这里插入图片描述

由于 N N N 只能取整数,不等式亦可写为:

在这里插入图片描述

此即符合采样定理

(d)快速傅里叶变换(FFT)

快速傅里叶变换(FFT)利用了虚指数项的对称性等特点,对离散傅里叶变换(DFT)的计算实现了简化,从而提高计算机的求解速度,其计算结果与离散傅里叶变换(DFT)完全一致。本节介绍一种快速傅里叶变换算法,适用于序列周期为 2 的整数次幂( N = 2 l N = 2^l N=2l)的情况——

首先将离散傅里叶变换中的奇数项和偶数项分离(假设 N = 2 l N = 2^l N=2l):

在这里插入图片描述

上式中,将原周期序列 f N ( k ) f_N(k) fN(k) 中的奇数项和偶数项分别看作以 N / 2 N/2 N/2 为周期的新序列 f N / 2 ′ f_{N/2}' fN/2 f N / 2 ′ ′ f_{N/2}'' fN/2′′,那么当 n n n 的取值范围为 0 ∼ N / 2 − 1 0 \sim N/2-1 0N/21 时,上式中的两个求和项显然满足离散傅里叶变换的定义式,即:

在这里插入图片描述

此时,就将 N N N 个数据点的离散傅里叶变换( N N N 点 DFT)转化为了两个 N / 2 N/2 N/2 个数据点的离散傅里叶变换( N / 2 N/2 N/2 点 DFT)。但考虑到 n n n 的取值范围,显然只计算出了" N N N 点 DFT"的前半部分,还需找到后半部分的值。根据虚指数的对称性:
在这里插入图片描述

N N N 点 DFT” 后半部分的值为:

在这里插入图片描述

因此," N N N 点 DFT"的计算结果可用奇偶分离后两个" N / 2 N/2 N/2 点 DFT"的计算结果来表示。以 N = 8 N = 8 N=8 为例,画出示意图(图中 W N n = e j n 2 π / N W_N^n = \mathrm{e}^{\mathrm{j}n2\pi/N} WNn=ejn2π/N):

在这里插入图片描述

对于" N / 2 N/2 N/2 点 DFT"还可对该序列继续进行奇偶分离,将其简化为" N / 4 N/4 N/4 点 DFT":
在这里插入图片描述

继续进行奇偶分离,直至分解为"1 点 DFT":

在这里插入图片描述

根据定义,原" N N N 点 DFT"的计算量为: N 2 N^2 N2 次复数乘法运算和 N ( N − 1 ) N(N-1) N(N1) 次加法运算:
在这里插入图片描述

而参考前述示意图,当 N = 2 l N = 2^l N=2l 时,奇偶分离后的快速傅里叶变换( N N N 点 FFT)包含 l l l 级,每级进行 N / 2 N/2 N/2 次复数乘法和 N N N 次加法运算,显然计算得到了简化。

奇偶分离的过程天然适用于递归算法,给出递归算法实现快速傅里叶变换(FFT)的 MATLAB 程序:

function Fn = myDFTx(x)
% x 为输入序列
N = length(x);      % 序列长度
L = 2^nextpow2(N);
if L == N           % 序列长度为 2 的幂次,进入 FFT 算法
    if N == 1
        Fn = x;
    else
        n = 0:N/2-1;
        wn = exp(-1j*2*pi/N);
        Wn = wn.^(n');
        x_even = x(1:2:end); % 提取偶数项
        x_odd = x(2:2:end);  % 提取奇数项
        Xe = myDFT2(x_even);
        Xo = myDFT2(x_odd);
        Fn = [Xe + Wn.*Xo; Xe - Wn.*Xo];
    end
else                % 序列长度非 2 的幂次,进入 DFT 算法
    Fn = zeros(1, N);
    for n = 0:N-1
        for k = 0:N-1
            Fn(n+1) = Fn(n+1) + x(k+1)*exp(-1j*n*2*pi*k/N);
        end
    end
end

:本节所述快速傅里叶算法假设了数据点数量满足 N = 2 l N = 2^l N=2l,因此在数据点数量不满足条件时,程序中仍采用定义法求解离散傅里叶变换。为加快求解速度,当采样点数量不满足 N = 2 l N = 2^l N=2l 时,可对序列补零后使用快速傅里叶算法。补零后,快速傅里叶变换(FFT)计算出的结果存在偏差,更加优化的操作还请读者继续查阅资料。

三、总结

在 Simulink 仿真中,我们常使用 FFT 分析工具,截取一个基波周期的波形,在数据处理后能够得到直流分量以及各次谐波分量相对于基波分量的大小:

在这里插入图片描述

在这里插入图片描述

亦可选择将波形数据导入 MATLAB 工作区,在数组中截取一个基波周期的 N N N 个数据点,使用自带的 fft 函数进行分析。如前所述:

  1. fft 计算结果中 n n n 表示谐波的次数,最多可分解出 N / 2 − 1 N/2 - 1 N/21 次及以下谐波;
  2. 计算结果的幅值与实际直流分量以及各次谐波幅值之间的关系满足如下关系式:

在这里插入图片描述


参考文献

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐