快速傅里叶变换 FFT 算法 | 分治策略、蝶形运算与旋转因子

注:本文为 "快速傅里叶变换 FFT 算法 " 相关合辑。

图片清晰度受引文原图所限。

略作重排,未整理去重。

如有内容异常,请看原文。


彻底搞懂快速傅里叶变换 FFT 思想------分而治之

牙非涯 发布于 2022-02-27 22:44

通过离散傅里叶变换与窗函数,完成了对实际信号的傅里叶变换运算。即便处理时长较短的信号,该运算的计算复杂度仍较高。采用分而治之策略对问题进行分解,可显著降低计算开销。

分而治之是快速傅里叶变换(FFT)的构成基础。FFT 算法首次发表于 1965 年题为 An Algorithm for the Machine Calculation of Complex Fourier Series 的学术论文,由 IBM 研究员 James Cooley 与普林斯顿大学教授 John Tukey 共同提出。

什么是分而治之

首先考察与傅里叶变换无关的基础问题:给定包含 16 个数值的序列,求解序列中的最大值。

常规求解方式为顺序遍历并逐次比较,以确定 16 个数值中的最大值。该方法的操作复杂度与序列长度及最大值位置相关,整体过程较为繁琐。

更为高效的思路是将原问题分解为规模逐步减小的子问题,直至子问题具有直接求解的简单形式,该思路即为分而治之。将包含 16 个数值的序列划分为 2 组,每组包含 8 个数值;前 8 个数值构成第一组,后 8 个数值构成第二组。进一步将序列分解为 8 组,每组包含 2 个数值。

对上述 8 组数值分别执行比较操作,保留每组中的较大值并以橙色标记,舍弃较小值。重复该过程直至仅剩余一个数值,该数值即为序列最大值。该过程为分治法求解最大值问题。

总比较次数为:
8 + 4 + 2 + 1 = 15 8 + 4 + 2 + 1 = 15 8+4+2+1=15

该比较次数显著少于顺序查找方式。

分而治之在 FFT 中的应用

将分治法的执行阶段应用于傅里叶变换,可归纳为以下三个步骤:

  • DIVIDE:将样本序列划分为长度为原长度一半的子序列,直至每个子序列仅包含一对样本
  • CONQUER:对每一对样本执行离散傅里叶变换(DFT)
  • COMBINE:利用子序列 DFT 结果进行组合,生成下一阶段的输入序列

重复执行 CONQUERCOMBINE 阶段,直至得到最终变换结果。

第一阶段:划分

DFT 无法直接采用数值比较类问题的划分方式。对于周期为 T T T 的余弦波与正弦波,在 DFT 计算中,相隔一个周期 T T T 的离散点对应的复指数取值相等,仅信号取值 x ( n ) x(n) x(n) 存在差异。因此仅需存储一个周期内的 cos ⁡ \cos cos 与 sin ⁡ \sin sin 取值。

离散傅里叶变换定义为:
X ( k ) = ∑ n = 0 N − 1 x ( n ) cos ⁡ ( 2 π k n N ) − i ∑ n = 0 N − 1 x ( n ) sin ⁡ ( 2 π k n N ) X(k) = \sum_{n=0}^{N-1} x(n)\cos\left(\frac{2\pi kn}{N}\right)- i\sum_{n=0}^{N-1} x(n)\sin\left(\frac{2\pi kn}{N}\right) X(k)=n=0∑N−1x(n)cos(N2πkn)−in=0∑N−1x(n)sin(N2πkn)

以周期为 2 π 2\pi 2π 的余弦波为例,时域中相隔 2 π 2\pi 2π(对应索引间隔为 8)的点取值相等。该性质为序列分组提供理论依据。

随着余弦波频率的提升,该周期性依然成立。考察索引为 0 与 8 的两个点(间隔为一个周期的点对)。

设原始离散信号的样本点数为 16,如图中绿线所示,蓝线为参考余弦波。傅里叶级数运算为信号取值与对应余弦波取值相乘后累加。

频率提升过程中,索引 0 处取值保持不变,索引 8 处取值在 1 与 -1 之间交替。频率增加 2 Hz 后取值回归初始值 1。

在该示例中,频率为 0 Hz、2 Hz、4 Hz、6 Hz、8 Hz 等条件下,由索引 0 与 8 构成的点对对应的 DFT 结果相等。即每隔 2 Hz,无需重复执行乘加运算,可直接复用前期计算结果。

对于索引 4 与 12 构成的点对,存在同类规律:其计算结果在 0 Hz、4 Hz、8 Hz 等频率处重复,即每隔 4 Hz 重复一次。

通过类推可得到其余点对的重复规律。对前期计算结果的重复利用,可减少运算次数,该机制构成了快速傅里叶变换高效性的来源。

如何找到这些分组

基于前述两条结论,点对之间的时间间隔对应一个信号周期。对于长度为 16 的信号序列,可确定点对为:0 与 8、1 与 9、2 与 10......

为便于后续组合计算,对点对执行排序,确定计算优先级:按点对取值重复出现的频率由高到低排序

例如,点对 0 与 8 在频率 0、2、4、6、8......处均出现相同取值,共重复 8 次。样本 0 与 8 的重复频率最高,样本 7 与 15 的重复频率最低。

至此,通过分治算法将整体计算分解为若干小规模子块。各子块的快速求解方式将在下一章内容中阐述:蝴蝶操作。


彻底搞懂快速傅里叶变换 FFT------蝴蝶操作

牙非涯 发布于 2022-02-27 22:50

在上一章内容中,阐述了分治法在傅里叶变换中的应用思路,以及将信号分解为仅包含一对样本的子序列的方法。对两个样本执行 DFT 具有直接求解的形式。为进一步降低计算量,引入蝴蝶图结构。该运算结构的几何形态与蝴蝶翅膀形态相似,故得名蝴蝶图。

划分阶段的样本对重组

在划分阶段完成后,长度为 16 的样本信号被分解为 8 个样本对,并按照特定规则完成排序,结果如下。

对第一个样本对 sample- 0 \text{sample-}0 sample-0 与 sample- 8 \text{sample-}8 sample-8 执行 DFT 运算。将该两个样本输入第一个蝶形运算结构。

蝴蝶操作的基本定义

蝴蝶操作属于联合计算结构,运算形式如图所示。输入值 x 0 x_0 x0 与 x 8 x_8 x8 被重复调用参与运算,其中下方支路乘以因子 − 1 -1 −1,得到两个输出结果,记为 a 0 a_0 a0、 a 1 a_1 a1。 x 0 x_0 x0、 x 8 x_8 x8 分别为索引 0 与 8 对应的信号取值。

2 个样本 DFT 计算

在执行两个样本点的 DFT 之前,给出相关定义:周期信号 x ( n ) x(n) x(n) 可表示为若干正弦波的叠加,每一正弦波具有频率、幅度与相位三个属性。

当信号仅包含 2 个采样点时,其频域表示最多包含 2 个正弦分量,因此仅需考察 2 个频率分量。

为简化计算,设采样率 R R R 与样本个数 N N N 相等,即 N = 2 Hz/s N = 2\ \text{Hz/s} N=2 Hz/s。此时考察的两个频率为 0 Hz 与 1 Hz。

下面计算仅包含样本点 0 与 8 的离散傅里叶变换。

0 Hz 余弦分量:蓝线为频率 0 Hz 的余弦波,绿线为待分析信号。

R ( a 0 ) = ∑ n = 0 N − 1 x ( n ) × cos ⁡ ( 2 π k n N ) = x 0 × 1 + x 8 × 1 \begin{align*} \mathcal{R}(a_0) & = \sum_{n=0}^{N-1} x(n) \times \cos\left(2\pi k \frac{n}{N}\right) \\ & = x_0 \times 1 + x_8 \times 1 \end{align*} R(a0)=n=0∑N−1x(n)×cos(2πkNn)=x0×1+x8×1

依据傅里叶变换公式,频率为 0 时的余弦分量结果为 x 0 + x 8 x_0 + x_8 x0+x8,即两点取值相乘后求和。同理可得 1 Hz 余弦分量结果为 x 0 − x 8 x_0 - x_8 x0−x8。

1 Hz 余弦分量:蓝线为频率 0 Hz 的余弦波,绿线为待分析信号。

R ( a 1 ) = x 0 × 1 + x 8 × − 1 \mathcal{R}(a_1) = x_0 \times 1 + x_8 \times -1 R(a1)=x0×1+x8×−1

同理计算正弦分量,结果均为 0。该结果可直接由 DFT 公式推导得到。

回顾前述蝴蝶操作,可见两点 DFT 计算结果与蝴蝶操作输出完全一致。

蝴蝶操作的推广限制

由此可得到推论:在第一阶段中,可求解所有点对在 0 Hz 与 1 Hz 处的频率分量,即

实际运算过程并不满足该简单推论。考察索引 4 与 12 构成的点对,由 DFT 公式可知,其频率为 1 的分量结果为 0,与前述蝴蝶操作结果不一致。其中 a 2 = x 4 + x 12 a_2 = x_4 + x_{12} a2=x4+x12,因此无法直接执行简单的重复运算。

1 Hz 余弦分量:蓝线为频率 0 Hz 的余弦波,绿线为待分析信号。

相位平移与旋转因子的引入

为解决该问题,可对信号执行相位平移,使索引 4 与 12 处取值为 1 或 -1。该操作仅改变原始信号的相位,且可通过蝴蝶操作实现简化计算。

相位平移对最终结果的影响,将通过旋转因子进行补偿,该内容将在下一章中详细阐述。


彻底搞懂快速傅里叶变换 FFT------旋转因子

牙非涯 发布于 2022-02-28 20:03

上一篇文章引入蝴蝶操作完成样本对的 DFT 计算,实现分而治之策略中简单子问题的求解,同时引入信号相位改变的问题。为保证整体计算结果不变,采用旋转因子对相位平移后的信号进行补偿,所得结果作为下一阶段计算的输入。

组合计算流程

在引入旋转因子之前,首先对下一阶段的组合计算进行说明。

16 个样本点的 FFT

依据分而治之思想,DIVIDE 与 CONQUER 阶段已完成,后续进入 COMBINE 阶段,即对样本对的计算结果进行组合,形成新的样本序列。

按照计算顺序,将 2 点样本对合并为 4 点样本序列。对于长度为 4 的离散信号,依据 DFT 原理,需要对 4 个频率分量进行求解。

前期已完成 0 Hz 与 1 Hz 分量的计算,组合阶段需要补充求解 2 Hz 与 3 Hz 分量。

由正余弦函数的周期性可知,频率间隔为 2 Hz 时对应余弦波取值相等,即 0 Hz 与 2 Hz 的计算结果一致,1 Hz 与 3 Hz 的计算结果一致。

对由点 0、8、4、12 构成的 4 点信号,求解频率为 0 时的 DFT 结果,可表示为 a 0 + a 2 a_0 + a_2 a0+a2。

由于 a 2 a_2 a2 对应的信号已发生相位平移,需要乘以旋转因子 W 4 0 W_4^0 W40 进行补偿,再进行求和得到 b 0 b_0 b0,即为 4 点信号在频率 0 处的 DFT 结果。

同理可完成 b 1 b_1 b1、 b 2 b_2 b2、 b 3 b_3 b3 的求解。

旋转因子定义与性质

本章对旋转因子(亦称为相位因子)进行系统阐述。

旋转因子采用符号 W W W 表示,附带下标与上标:

  • 下标表示蝶形运算的点数,称为旋转因子的阶数
  • 上标表示旋转因子的索引

旋转因子为复数,在信号进入下一阶段蝶形运算之前施加,其作用为对相位平移后的信号进行补偿,保证整体 DFT 结果不变。

定义式如下:

在 4 点蝶形运算中,共需要 2 个旋转因子,仅第 3、第 4 个输入需要进行相位补偿,对应索引为 0 与 1。

旋转因子索引的取值范围为 0 至阶数的一半,该取值由初始样本对的计算顺序决定。

旋转因子与原始信号的关系

设原始信号为 x ( n ) x(n) x(n),分解形式可表示为:
x ( n ) = W ⋅ x ~ ( n ) x(n) = W\cdot \tilde{x}(n) x(n)=W⋅x~(n)

其中 x ~ ( n ) \tilde{x}(n) x~(n) 为经过相位平移后的信号,红圈标记对应蝴蝶操作的输出结果。

结果验证: b 0 b_0 b0 与 b 1 b_1 b1 计算

对组合结果进行验证,首先计算 4 点信号在频率 0 处的傅里叶级数。

4个点组合在频率为0的傅里叶级数

b 0 = x 0 + x 4 + x 8 + x 12 b_0 = x_0 + x_4 + x_8 + x_{12} b0=x0+x4+x8+x12

继续计算频率 1 对应的输出 b 1 b_1 b1。


b 1 = ( x 0 − x 8 ) + i ( x 4 − x 12 ) b_1 = (x_0 - x_8) + i(x_4 - x_{12}) b1=(x0−x8)+i(x4−x12)

计算表明, b 0 b_0 b0 与 b 1 b_1 b1 的结果与蝶形运算输出一致。

第二个旋转因子的计算结果为 − i -i −i。

旋转因子取值为 1 时,对应原始信号未发生相位平移;取值为 − i -i −i 时,对应信号向右平移 π / 2 \pi/2 π/2。

W 4 1 = cos ⁡ ( 2 π × 1 4 ) − i ⋅ sin ⁡ ( 2 π × 1 4 ) = cos ⁡ ( π 2 ) − i ⋅ sin ⁡ ( π 2 ) = 0 − i \begin{align*} W^{1}_{4} & = \cos\left(2\pi \times \frac{1}{4}\right) - i \cdot \sin\left(2\pi \times \frac{1}{4}\right) \\ & = \cos\left(\frac{\pi}{2}\right) - i \cdot \sin\left(\frac{\pi}{2}\right) \\ & = 0 - i \end{align*} W41=cos(2π×41)−i⋅sin(2π×41)=cos(2π)−i⋅sin(2π)=0−i

旋转因子的相位补偿机制

对旋转因子实现信号来回平移的机理进行说明。

原始信号 x ( n ) x(n) x(n) 经过相位平移得到 x ~ ( n ) \tilde{x}(n) x~(n)。

旋转因子取值为 1 时,信号不发生平移;取值为 − i -i −i 时,对应相位变化。

为适配蝴蝶操作,原始信号向左平移 4 个刻度,对应相位平移 π / 2 \pi/2 π/2;

完成初次蝴蝶运算后,乘以旋转因子 W W W,将信号向右平移 π / 2 \pi/2 π/2,实现相位补偿。

乘以 − i -i −i 与相位平移 π / 2 \pi/2 π/2 具有等效性,两种操作对信号产生的变换结果一致。

至此,蝴蝶操作与结果组合的基本流程已完成。将该结构扩展至完整信号并解释 FFT 最终输出,将在下一篇文章中给出。


彻底搞懂快速傅里叶变换 FFT------算法输出

牙非涯 发布于 2022-02-28 20:20

上一篇文章引入旋转因子,完成任意点对的蝶形运算,并实现 2 点样本到 4 点样本的组合。

在此基础上,可将 4 组 4 点蝶形组合为 2 组 8 点蝶形,再进一步组合为 1 组 16 点蝶形,得到最终输出。

FFT 算法的输出为对应 16 个不同频率的正弦波分量集合。

完整复现关键步骤的推导与计算,有助于理解算法机理。

4 点到 8 点的组合扩展

4 点蝶形运算包含 2 个旋转因子,8 点蝶形运算则包含 4 个旋转因子。

在 FFT 中,旋转因子的数量为对应蝶形点数的一半。

在 2 点蝶形阶段,样本 4 与 12 经过相位平移得到结果 a 2 a_2 a2、 a 3 a_3 a3;

在 4 点蝶形阶段,通过旋转因子补偿得到 b 2 b_2 b2、 b 3 b_3 b3;

该阶段前 4 个点 b 0 ∼ b 3 b_0 \sim b_3 b0∼b3 位于原始位置,不再需要旋转因子。

样本点 2、10 与 6、14 对应的 2 点蝶形输出 a 4 a_4 a4、 a 5 a_5 a5、 a 6 a_6 a6、 a 7 a_7 a7,在 4 点蝶形输出后仍存在相位偏移。

因此在 8 点蝶形阶段,需要引入额外旋转因子完成补偿。

最终将 8 点序列组合为 16 点序列,完成全部 FFT 计算。

FFT 算法输出形式

对完整 FFT 计算流程进行总结,各阶段输出可归纳为:

  • a a a:2 点蝶形运算结果
  • b b b:4 点蝶形运算结果
  • c c c:8 点蝶形运算结果
  • d d d:16 点蝶形运算结果,即 FFT 最终输出

FFT 输出为一组复数序列:

在 16 点信号示例中,共对 16 个频率分量进行求解,得到 16 组复数。

由该复数序列可求解对应正弦波的频率、幅度与相位,进而生成频谱图与相位图。

FFT 输出的幅度与相位计算

设 x [ n ] x[n] x[n] 为长度为 N N N 的时域离散信号, n = 0 , 1 , ... , N − 1 n = 0, 1, \ldots, N-1 n=0,1,...,N−1。其 N N N 点 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] \cdot e^{-j\frac{2\pi}{N}kn}, \quad k = 0, 1, \ldots, N-1 X[k]=n=0∑N−1x[n]⋅e−jN2πkn,k=0,1,...,N−1

其中 X [ k ] X[k] X[k] 为第 k k k 个频点对应的复数值, R e { X [ k ] } \mathrm{Re}\{X[k]\} Re{X[k]} 和 I m { X [ k ] } \mathrm{Im}\{X[k]\} Im{X[k]} 分别表示其实部与虚部。

幅度计算

各频点的幅度由复数模运算求得:

∣ X [ k ] ∣ = R e { X [ k ] } 2 + I m { X [ k ] } 2 |X[k]| = \sqrt{\mathrm{Re}\{X[k]\}^2 + \mathrm{Im}\{X[k]\}^2} ∣X[k]∣=Re{X[k]}2+Im{X[k]}2

相位计算

各频点的相位由复数辐角确定:

ϕ [ k ] = arctan ⁡ ( I m { X [ k ] } R e { X [ k ] } ) \phi[k] = \arctan\left(\frac{\mathrm{Im}\{X[k]\}}{\mathrm{Re}\{X[k]\}}\right) ϕ[k]=arctan(Re{X[k]}Im{X[k]})

实际计算中通常采用四象限反正切函数(如 atan2)以避免象限模糊问题。

真实信号的完整 FFT 流程

16 点信号在实际应用中不具备代表性,下面对更贴近实际的信号进行分析。

设一段时长为 10 秒的连续信号,对其进行离散化采样,样本点数 N = 1024 N = 1024 N=1024,采样率:
R = 1024 10 Hz R = \frac{1024}{10}\ \text{Hz} R=101024 Hz

频率索引 k k k 的取值范围为 0 ∼ N − 1 0 \sim N-1 0∼N−1,对应可分析的频率范围为 0 ∼ R 0 \sim R 0∼R。

在 DFT 框架下,频率间隔为 R / N R/N R/N,该间隔为可实现的最小频率分辨率。

连续真实信号 x ( t ) x(t) x(t)

FFT 计算结果

对该 1024 点信号执行 FFT,得到复数形式的输出,经转换可得到幅度与相位信息,据此生成频谱与相位谱。

傅里叶变换可将复杂周期信号分解为正弦波分量,FFT 则为计算机实现高效傅里叶变换的算法框架。

蝴蝶操作的结构便于计算机执行重复、规整的运算。


快速傅里叶变换 (FFT) 算法------蝶形变换的原理与实现

0小龙虾0 原创于 2019-12-09 22:21:15 发布

为实现基于 FFT 的海面模拟,需首先完成 FFT 算法的理论推导与工程实现。本文系统阐述 FFT 算法的数学构成,重点解析蝶形变换的数学逻辑。

离散傅里叶变换 (DFT)

在学习 FFT 算法前,需先掌握离散傅里叶变换(DFT)的基本定义。傅里叶变换用于实现时域信号到频域信号的转换,计算机无法直接处理连续信号,因此离散傅里叶变换(DFT)被提出以适配数字计算场景。

标准 DFT 变换的数学表达式为:
X ( k ) = ∑ n = 0 N − 1 x ( n ) e − i 2 π k N n , k ∈ { 0 , 1 , ... , N − 1 } X(k)=\sum_{n=0}^{N-1}x(n)e^{-i\frac{2\pi k}{N}n},\quad k\in \{0,1,\dots,N-1\} X(k)=n=0∑N−1x(n)e−iN2πkn,k∈{0,1,...,N−1}

为简化表达式,定义旋转因子:
W N k = e − i 2 π k N W_{N}^{k}=e^{-i\frac{2\pi k}{N}} WNk=e−iN2πk

旋转因子 W W W 的基本性质

性质 1:缩放性

W N k = W 2 N 2 k W_{N}^{k}=W_{2N}^{2k} WNk=W2N2k

证明过程

根据欧拉公式 e − i θ = cos ⁡ θ − i sin ⁡ θ e^{-i\theta} = \cos\theta - i\sin\theta e−iθ=cosθ−isinθ,将旋转因子展开:
W N k = e − i 2 π k N = cos ⁡ ( − 2 π k N ) + i sin ⁡ ( − 2 π k N ) = cos ⁡ ( − 2 π ( 2 k ) 2 N ) + i sin ⁡ ( − 2 π ( 2 k ) 2 N ) = W 2 N 2 k \begin{aligned} W_{N}^{k} &= e^{-i\frac{2\pi k}{N}} = \cos\left(-\frac{2\pi k}{N}\right)+i\sin\left(-\frac{2\pi k}{N}\right) \\ &= \cos\left(-\frac{2\pi(2k)}{2N}\right)+i\sin\left(-\frac{2\pi(2k)}{2N}\right) = W_{2N}^{2k} \end{aligned} WNk=e−iN2πk=cos(−N2πk)+isin(−N2πk)=cos(−2N2π(2k))+isin(−2N2π(2k))=W2N2k

性质 2:对称性

W N k + N 2 = − W N k W_{N}^{k+\frac{N}{2}}=-W_{N}^{k} WNk+2N=−WNk

性质 3:周期性

W N 0 = W N N W_{N}^{0}=W_{N}^{N} WN0=WNN

性质 2 与性质 3 的证明方法与性质 1 一致,均通过欧拉公式展开后进行代数变换即可验证。

快速傅里叶变换 (FFT) 的数学推导

将 DFT 变换结果 X ( k ) X(k) X(k) 按输入序列索引的奇偶性拆分。当 k ∈ { 0 , 1 , ... , N 2 − 1 } k\in \{0,1,\dots,\frac{N}{2}-1\} k∈{0,1,...,2N−1} 时,原式可改写为:
X ( k ) = ∑ n = 0 N − 1 x ( n ) e − i 2 π k N n X(k)=\sum_{n=0}^{N-1}x(n)e^{-i\frac{2\pi k}{N}n} X(k)=n=0∑N−1x(n)e−iN2πkn

按奇偶索引拆分求和项:
X ( k ) = ∑ n = 0 N 2 − 1 x ( 2 n ) e − i 2 π k N ( 2 n ) + ∑ n = 0 N 2 − 1 x ( 2 n + 1 ) e − i 2 π k N ( 2 n + 1 ) = ∑ n = 0 N 2 − 1 x ( 2 n ) e − i 2 π k N / 2 n + e − i 2 π k N ∑ n = 0 N 2 − 1 x ( 2 n + 1 ) e − i 2 π k N / 2 n \begin{aligned} X(k) &= \sum_{n=0}^{\frac{N}{2}-1}x(2n)e^{-i\frac{2\pi k}{N}(2n)} +\sum_{n=0}^{\frac{N}{2}-1}x(2n+1)e^{-i\frac{2\pi k}{N}(2n+1)} \\ &= \sum_{n=0}^{\frac{N}{2}-1}x(2n)e^{-i\frac{2\pi k}{N/2}n} +e^{-i\frac{2\pi k}{N}}\sum_{n=0}^{\frac{N}{2}-1}x(2n+1)e^{-i\frac{2\pi k}{N/2}n} \end{aligned} X(k)=n=0∑2N−1x(2n)e−iN2πk(2n)+n=0∑2N−1x(2n+1)e−iN2πk(2n+1)=n=0∑2N−1x(2n)e−iN/22πkn+e−iN2πkn=0∑2N−1x(2n+1)e−iN/22πkn

由于 e − i 2 π N e^{-i\frac{2\pi}{N}} e−iN2π 为与 n n n 无关的常数,可将 X ( k ) X(k) X(k) 表示为旋转因子的函数形式:
X ( e − i 2 π k N ) = ∑ n = 0 N − 1 x ( n ) e − i 2 π k N n X\left(e^{-i\frac{2\pi k}{N}}\right)=\sum_{n=0}^{N-1}x(n)e^{-i\frac{2\pi k}{N}n} X(e−iN2πk)=n=0∑N−1x(n)e−iN2πkn

代入旋转因子定义 W N k = e − i 2 π k N W_N^k = e^{-i\frac{2\pi k}{N}} WNk=e−iN2πk,可得:
X ( W N k ) = ∑ n = 0 N − 1 x ( n ) ( W N k ) n = ∑ n = 0 N 2 − 1 x ( 2 n ) ( W N 2 k ) n + W N k ∑ n = 0 N 2 − 1 x ( 2 n + 1 ) ( W N 2 k ) n , k ∈ { 0 , 1 , ... , N 2 − 1 } \begin{aligned} X(W_{N}^{k}) &= \sum_{n=0}^{N-1}x(n)\left(W_{N}^{k}\right)^{n} \\ &= \sum_{n=0}^{\frac{N}{2}-1}x(2n)\left(W_{\frac{N}{2}}^{k}\right)^{n} +W_{N}^{k}\sum_{n=0}^{\frac{N}{2}-1}x(2n+1)\left(W_{\frac{N}{2}}^{k}\right)^{n}, \quad k\in \{0,1,\dots,\tfrac{N}{2}-1\} \end{aligned} X(WNk)=n=0∑N−1x(n)(WNk)n=n=0∑2N−1x(2n)(W2Nk)n+WNkn=0∑2N−1x(2n+1)(W2Nk)n,k∈{0,1,...,2N−1}

定义两个子序列的 DFT 结果:
F ( W N 2 k ) = ∑ n = 0 N 2 − 1 x ( 2 n ) ( W N 2 k ) n G ( W N 2 k ) = ∑ n = 0 N 2 − 1 x ( 2 n + 1 ) ( W N 2 k ) n \begin{aligned} F\left(W_{\frac{N}{2}}^{k}\right) &= \sum_{n=0}^{\frac{N}{2}-1}x(2n)\left(W_{\frac{N}{2}}^{k}\right)^{n} \\ G\left(W_{\frac{N}{2}}^{k}\right) &= \sum_{n=0}^{\frac{N}{2}-1}x(2n+1)\left(W_{\frac{N}{2}}^{k}\right)^{n} \end{aligned} F(W2Nk)G(W2Nk)=n=0∑2N−1x(2n)(W2Nk)n=n=0∑2N−1x(2n+1)(W2Nk)n

则当 k ∈ { 0 , 1 , ... , N 2 − 1 } k\in \{0,1,\dots,\frac{N}{2}-1\} k∈{0,1,...,2N−1} 时, X ( W N k ) X(W_N^k) X(WNk) 可表示为:
X ( W N k ) = F ( W N 2 k ) + W N k   G ( W N 2 k ) X(W_{N}^{k})=F\left(W_{\frac{N}{2}}^{k}\right)+W_{N}^{k}\,G\left(W_{\frac{N}{2}}^{k}\right) X(WNk)=F(W2Nk)+WNkG(W2Nk)

接下来推导 k + N 2 k+\frac{N}{2} k+2N 处的结果 X ( W N k + N 2 ) X(W_N^{k+\frac{N}{2}}) X(WNk+2N),其中 k ∈ { 0 , 1 , ... , N 2 − 1 } k\in \{0,1,\dots,\frac{N}{2}-1\} k∈{0,1,...,2N−1}:
X ( W N k + N 2 ) = F ( W N 2 k + N 2 ) + W N k + N 2   G ( W N 2 k + N 2 ) = F ( W N 2 k + N ) + W N k + N 2   G ( W N 2 k + N ) = F ( W N 2 k W N N ) − W N k   G ( W N 2 k W N N ) = F ( W N 2 k ) − W N k   G ( W N 2 k ) \begin{aligned} X\left(W_{N}^{k+\frac{N}{2}}\right) &= F\left(W_{\frac{N}{2}}^{k+\frac{N}{2}}\right) +W_{N}^{k+\frac{N}{2}}\,G\left(W_{\frac{N}{2}}^{k+\frac{N}{2}}\right) \\ &= F\left(W_{N}^{2k+N}\right) +W_{N}^{k+\frac{N}{2}}\,G\left(W_{N}^{2k+N}\right) \\ &= F\left(W_{N}^{2k}W_{N}^{N}\right) -W_{N}^{k}\,G\left(W_{N}^{2k}W_{N}^{N}\right) \\ &= F\left(W_{\frac{N}{2}}^{k}\right) -W_{N}^{k}\,G\left(W_{\frac{N}{2}}^{k}\right) \end{aligned} X(WNk+2N)=F(W2Nk+2N)+WNk+2NG(W2Nk+2N)=F(WN2k+N)+WNk+2NG(WN2k+N)=F(WN2kWNN)−WNkG(WN2kWNN)=F(W2Nk)−WNkG(W2Nk)

综上,得到蝶形运算关系式:
{ X ( W N k ) = F ( W N 2 k ) + W N k G ( W N 2 k ) X ( W N k + N 2 ) = F ( W N 2 k ) − W N k G ( W N 2 k ) \left\{ \begin{aligned} X(W_{N}^{k}) &= F\left(W_{\frac{N}{2}}^{k}\right) + W_{N}^{k}G\left(W_{\frac{N}{2}}^{k}\right) \\ X\left(W_{N}^{k+\frac{N}{2}}\right) &= F\left(W_{\frac{N}{2}}^{k}\right) - W_{N}^{k}G\left(W_{\frac{N}{2}}^{k}\right) \end{aligned} \right. ⎩ ⎨ ⎧X(WNk)X(WNk+2N)=F(W2Nk)+WNkG(W2Nk)=F(W2Nk)−WNkG(W2Nk)

该组公式表明, N N N 点 DFT 结果的前半部分与后半部分可由其奇偶子序列的 N / 2 N/2 N/2 点 DFT 结果通过线性组合得到。

4 点 FFT 蝶形变换实例验证

令 N = 4 N=4 N=4,以 k = 0 k=0 k=0 为例展开计算,直观验证蝶形变换的计算逻辑。

首先计算 X ( W 4 0 ) X(W_4^0) X(W40):
X ( W 4 0 ) = F ( W 2 0 ) + W 4 0   G ( W 2 0 ) = ∑ n = 0 1 x ( 2 n ) ( W 2 0 ) n + W 4 0 ∑ n = 0 1 x ( 2 n + 1 ) ( W 2 0 ) n \begin{aligned} X(W_{4}^{0}) &= F(W_{2}^{0})+W_{4}^{0}\,G(W_{2}^{0}) \\ &= \sum_{n=0}^{1}x(2n)\left(W_{2}^{0}\right)^{n} +W_{4}^{0}\sum_{n=0}^{1}x(2n+1)\left(W_{2}^{0}\right)^{n} \end{aligned} X(W40)=F(W20)+W40G(W20)=n=0∑1x(2n)(W20)n+W40n=0∑1x(2n+1)(W20)n

其中子序列 DFT 结果 F ( W 2 0 ) F(W_2^0) F(W20) 与 G ( W 2 0 ) G(W_2^0) G(W20) 进一步递归拆分:
F ( W 2 0 ) = F f ( W 1 0 ) + W 2 0   G f ( W 1 0 ) = ∑ n = 0 0 x ( 4 n ) ( W 1 0 ) n + W 2 0 ∑ n = 0 0 x ( 4 n + 2 ) ( W 1 0 ) n = x ( 0 ) + x ( 2 )   W 2 0 \begin{aligned} F(W_{2}^{0}) &= F_{f}(W_{1}^{0})+W_{2}^{0}\,G_{f}(W_{1}^{0}) \\ &= \sum_{n=0}^{0}x(4n)\left(W_{1}^{0}\right)^{n} +W_{2}^{0}\sum_{n=0}^{0}x(4n+2)\left(W_{1}^{0}\right)^{n} \\ &= x(0)+x(2)\,W_{2}^{0} \end{aligned} F(W20)=Ff(W10)+W20Gf(W10)=n=0∑0x(4n)(W10)n+W20n=0∑0x(4n+2)(W10)n=x(0)+x(2)W20

G ( W 2 0 ) = F g ( W 1 0 ) + W 2 0   G g ( W 1 0 ) = ∑ n = 0 0 x ( 4 n + 1 ) ( W 1 0 ) n + W 2 0 ∑ n = 0 0 x ( 4 n + 3 ) ( W 1 0 ) n = x ( 1 ) + x ( 3 )   W 2 0 \begin{aligned} G(W_{2}^{0}) &= F_{g}(W_{1}^{0})+W_{2}^{0}\,G_{g}(W_{1}^{0}) \\ &= \sum_{n=0}^{0}x(4n+1)\left(W_{1}^{0}\right)^{n} +W_{2}^{0}\sum_{n=0}^{0}x(4n+3)\left(W_{1}^{0}\right)^{n} \\ &= x(1)+x(3)\,W_{2}^{0} \end{aligned} G(W20)=Fg(W10)+W20Gg(W10)=n=0∑0x(4n+1)(W10)n+W20n=0∑0x(4n+3)(W10)n=x(1)+x(3)W20

注: F f ,   G f F_f,\,G_f Ff,Gf 为 F F F 对应的递归子序列 DFT 结果; F g ,   G g F_g,\,G_g Fg,Gg 为 G G G 对应的递归子序列 DFT 结果。

因此 X ( W 4 0 ) X(W_4^0) X(W40) 可写为:
X ( W 4 0 ) = x ( 0 ) + x ( 2 )   W 2 0 + W 4 0 ( x ( 1 ) + x ( 3 )   W 2 0 ) X(W_{4}^{0})=x(0)+x(2)\,W_{2}^{0}+W_{4}^{0}\left(x(1)+x(3)\,W_{2}^{0}\right) X(W40)=x(0)+x(2)W20+W40(x(1)+x(3)W20)

4 点 FFT 的蝶形变换结构如下图所示:

上述计算过程的分步图解如下(其中 X [ i ] = X ( W 4 i ) X[i] = X(W_4^i) X[i]=X(W4i)):

子序列递归计算的图解:

完整的 4 点 FFT 蝶形变换图解:

通过蝶形变换,FFT 算法将 DFT 的计算复杂度从 O ( N 2 ) O(N^2) O(N2) 降低至 O ( N log ⁡ 2 N ) O(N\log_{2}N) O(Nlog2N),提升了计算效率。

位逆序(bitreverse)算法

FFT 算法可通过非递归方式实现,其前提是对输入序列进行位逆序重排。以 4 点 FFT 为例,最终参与计算的输入序列为 x [ 0 ] ,   x [ 2 ] ,   x [ 1 ] ,   x [ 3 ] x[0],\,x[2],\,x[1],\,x[3] x[0],x[2],x[1],x[3];8 点 FFT 的输入序列位置变化过程为:
0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 → 0 , 2 , 4 , 6 , 1 , 3 , 5 , 7 → 0 , 4 , 2 , 6 , 1 , 5 , 3 , 7 0,1,2,3,4,5,6,7 \to 0,2,4,6,1,3,5,7 \to 0,4,2,6,1,5,3,7 0,1,2,3,4,5,6,7→0,2,4,6,1,3,5,7→0,4,2,6,1,5,3,7

位逆序算法的规则为:对于 N N N 点 FFT,将输入索引 i i i 转换为 log ⁡ 2 N \log_2N log2N 位二进制数,对二进制位进行逆序操作后再转换为十进制数,该数值即为输入序列 x [ i ] x[i] x[i] 应处的目标位置。

示例 :在 8 点 FFT 中, x ( 4 ) x(4) x(4) 的索引 4 4 4 转换为 3 位二进制数为 100 100 100,逆序后为 001 001 001,对应十进制数 1 1 1,因此 x ( 4 ) x(4) x(4) 应放置在第 1 号位(索引从 0 开始)。

非递归 FFT 算法的工程实现

基于位逆序算法与蝶形变换,可编写迭代形式的 FFT 实现代码:

cpp 复制代码
// 复数类型定义(可替换为 C++ 标准库的 complex<double>)
using cp = complex<double>;
int n; // FFT 的长度,需为 2 的整数次幂

// FFT 迭代实现
// 参数说明:a 为输入输出的复数数组,omg 为预计算的旋转因子数组
void fft(cp *a, cp *omg){
    int lim = 0;
    while((1 << lim) < n) lim++; // 计算 log2(n),即二进制位数

    // 步骤 1:输入序列的位逆序重排
    for(int i = 0; i < n; i++){
        int t = 0;
        for(int j = 0; j < lim; j++){
            // 逐位提取 i 的二进制值,并映射到逆序位置
            if((i >> j) & 1)
                t |= (1 << (lim - j - 1));
        }
        if(i < t) swap(a[i], a[t]); // 避免重复交换
    }

    // 步骤 2:逐层执行蝶形变换
    for(int l = 2; l <= n; l *= 2){ // l 为当前蝶形单元的长度
        int m = l / 2; // 蝶形单元的半长
        for(cp *p = a; p != a + n; p += l){ // 遍历所有蝶形单元
            for(int i = 0; i < m; i++){ // 执行单个蝶形单元内的计算
                // 蝶形变换关系式
                cp t = omg[n / l * i] * p[i + m];
                p[i + m] = p[i] - t;
                p[i] += t;
            }
        }
    }
}

代码执行逻辑图解

  1. 第一层循环(蝶形单元长度 l l l 遍历)的分块计算逻辑:
  1. 第二层循环(蝶形单元遍历)的分块计算逻辑:
  1. 蝶形变换的计算逻辑:

迭代过程中,每一级的变换结果均可由当前级的计算结果自洽推导得出。完成上述实现后,即可将该 FFT 算法应用于海面模拟等工程场景。

总结

  1. FFT 算法通过拆分 DFT 为奇偶子序列的子问题,结合旋转因子的周期性、对称性与缩放性,建立蝶形运算关系式,将计算复杂度从 O ( N 2 ) O(N^2) O(N2) 降至 O ( N log ⁡ 2 N ) O(N\log_2N) O(Nlog2N)。
  2. 非递归 FFT 实现包含两个步骤:通过位逆序算法重排输入序列,按蝶形单元长度逐层执行蝶形变换。
  3. 蝶形运算关系式描述了 N N N 点 DFT 结果与 N / 2 N/2 N/2 点子序列 DFT 结果之间的线性组合关系,这一结构对应蝶形变换的物理含义。

FFT 原理------详细推导理解 FFT 变换

ZhangP.H 原创于 2020-05-14 20:48:05 发布

概要

FFT(Fast Fourier Transform,快速傅里叶变换)是离散傅里叶变换(DFT)的工程化实现方式。直接求解 DFT 的计算复杂度较高,FFT 方法利用 DFT 求解过程中旋转因子的固有性质,并引入分治算法的设计思想,显著简化了计算流程,该方法被广泛应用于频谱分析的工程实践中,如 MATLAB、C、C++、CUDA 等编程语言或框架的底层实现逻辑中。

一、DFT 简介

频谱分析是信号处理领域的重要组成部分,从傅里叶变换(FT)、拉普拉斯变换(LT)、离散时间傅里叶变换(DTFT)、Z 变换(ZT),到本文讨论的离散傅里叶变换(DFT),各类变换具有不同的适用场景与数学特征(其相互联系与区别可参考作者其他研究成果)。

相较于其他变换形式,DFT 得以广泛应用的原因在于其输入的时域信号为离散形式,输出的频域结果同样为离散形式。这一特性为基于计算机的频谱计算、存储与分析提供了便利,符合数字信号处理的发展趋势。

DFT 变换的数学表达式为:
X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j k 2 π K n , k = 0 , 1 , 2 , . . . , K − 1 X\left[ k \right]=\sum\limits_{n=0}^{N-1}{x\left[ n \right]{{e}^{-jk\frac{2\pi }{K}n}},\ k=0,1,2,...,K-1} X[k]=n=0∑N−1x[n]e−jkK2πn, k=0,1,2,...,K−1

与传统教材表述不同的是,此处 k k k 的取值范围不再与输入信号索引 n n n 的长度 0 ∼ N − 1 0 \sim N-1 0∼N−1 保持一致,而是可独立设定。这一设定旨在强调 k k k 的本质作用是对以 2 π 2\pi 2π 为周期的连续频谱进行离散化处理(DFT 是对 DTFT 连续频域结果进行离散化采样后的产物),即完成频谱的离散采样操作。

为便于分析,在 FFT 的计算过程中,通常选取 k = 0 ∼ N − 1 k = 0 \sim N-1 k=0∼N−1 的取值策略,此时 DFT 变换公式可表示为:
X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j k 2 π N n , k = 0 , 1 , 2 , . . . , N − 1 X\left[ k \right]=\sum\limits_{n=0}^{N-1}{x\left[ n \right]{{e}^{-jk\frac{2\pi }{N}n}},\ k=0,1,2,...,N-1} X[k]=n=0∑N−1x[n]e−jkN2πn, k=0,1,2,...,N−1

上述公式可直接求解,但计算量较大,需执行 N 2 N^2 N2 次复数乘法运算与 N ( N − 1 ) N(N-1) N(N−1) 次复数加法运算。为简化表达式,引入旋转因子 W N k n = e − j k 2 π N n W_N^{kn} = e^{-jk\frac{2\pi}{N}n} WNkn=e−jkN2πn,则 DFT 公式可改写为:
X [ k ] = ∑ n = 0 N − 1 x [ n ] e − j k 2 π N n = ∑ n = 0 N − 1 x [ n ] W N k n X\left[ k \right]=\sum\limits_{n=0}^{N-1}{x\left[ n \right]{{e}^{-jk\frac{2\pi }{N}n}}=\sum\limits_{n=0}^{N-1}{x\left[ n \right]W_{N}^{kn}}} X[k]=n=0∑N−1x[n]e−jkN2πn=n=0∑N−1x[n]WNkn

其中,旋转因子的完整定义为: W N k n = e − j k 2 π N n W_{N}^{kn} = {{e}^{-jk\frac{2\pi }{N}n}} WNkn=e−jkN2πn, W = e − j 2 π N W = {{e}^{-j\frac{2\pi }{N}}} W=e−jN2π。FFT 算法对 DFT 计算过程的简化,正是依托旋转因子 W W W 的若干基本性质实现的。

二、旋转因子 W W W 的性质

旋转因子具有以下数学性质,这些性质是简化 DFT 计算的关键:

  1. 周期性: W N a + N = W N a W_{N}^{a+N} = W_{N}^{a} WNa+N=WNa
  2. 对称性: W N a + N / 2 = − W N a W_{N}^{a+N/2} = -W_{N}^{a} WNa+N/2=−WNa
  3. 缩放性: W N 2 = W N / 2 1 W_{N}^{2} = W_{N/2}^{1} WN2=WN/21

上述性质可通过旋转因子的定义式直接展开推导,本质为基本的代数变换操作。这些性质表明,计算过程中存在大量重复的数值结果,无需重复计算,由此可有效降低 DFT 的计算复杂度。

三、FFT 蝶形计算推导

FFT 的计算流程融合了分治算法的设计思想,并结合旋转因子 W W W 的性质实现计算简化,具体推导过程如下:

步骤 1:输入信号的奇偶分解

将输入时域信号 x [ n ] , n = 0 , 1 , . . . , N − 1 x[n],\ n=0,1,...,N-1 x[n], n=0,1,...,N−1 按索引的奇偶性拆分为两个子序列:
f e v e n [ n ] = x [ 2 n ] f o d d [ n ] = x [ 2 n + 1 ] f_{even}\left[ n \right] = x\left[ 2n \right]\\f_{odd}\left[ n \right] = x\left[ 2n+1 \right] feven[n]=x[2n]fodd[n]=x[2n+1]

此时,子序列的索引范围为 n = 0 , 1 , 2 , . . . , N / 2 − 1 n=0,1,2,...,N/2-1 n=0,1,2,...,N/2−1。

步骤 2:DFT 公式的拆分与化简

对 DFT 公式 X [ k ] = ∑ n = 0 N − 1 x [ n ] W N k n , k = 0 , 1 , . . . , N − 1 X\left[ k \right]=\sum\limits_{n=0}^{N-1}{x\left[ n \right]W_{N}^{kn}},\ k=0,1,...,N-1 X[k]=n=0∑N−1x[n]WNkn, k=0,1,...,N−1 进行拆分,按索引奇偶性将求和项分为两部分:
X [ k ] = ∑ n 为偶数 x [ n ] W N k n + ∑ n 为奇数 x [ n ] W N k n , k = 0 , 1 , . . . , N − 1 X\left[ k \right]=\sum\limits_{n \text{ 为偶数}}{x\left[ n \right]W_{N}^{kn}}+\sum\limits_{n \text{ 为奇数}}{x\left[ n \right]W_{N}^{kn}},\ k=0,1,...,N-1 X[k]=n 为偶数∑x[n]WNkn+n 为奇数∑x[n]WNkn, k=0,1,...,N−1

该拆分过程的基本逻辑为将原求和序列按奇偶索引分离,如下图所示:

进一步展开可得:
X [ k ] = ∑ m = 0 ( N / 2 ) − 1 x [ 2 m ] W N k ⋅ 2 m + ∑ m = 0 ( N / 2 ) − 1 x [ 2 m + 1 ] W N k ⋅ ( 2 m + 1 ) , k = 0 , 1 , . . . , N − 1 X\left[ k \right]=\sum\limits_{m=0}^{(N/2)-1}{x\left[ 2m \right]W_{N}^{k\cdot 2m}}+\sum\limits_{m=0}^{(N/2)-1}{x\left[ 2m+1 \right]W_{N}^{k\cdot \left( 2m+1 \right)}},\ k=0,1,...,N-1 X[k]=m=0∑(N/2)−1x[2m]WNk⋅2m+m=0∑(N/2)−1x[2m+1]WNk⋅(2m+1), k=0,1,...,N−1

结合旋转因子的缩放性 W N 2 k m = W N / 2 k m W_N^{2km} = W_{N/2}^{km} WN2km=WN/2km,可将上式化简为:
X [ k ] = ∑ m = 0 ( N / 2 ) − 1 f e v e n [ m ] W N / 2 k ⋅ m + W N k ∑ m = 0 ( N / 2 ) − 1 f o d d [ m ] W N / 2 k ⋅ m , k = 0 , 1 , . . . , N − 1 X\left[ k \right]=\sum\limits_{m=0}^{(N/2)-1}{f_{even}\left[ m \right]W_{N/2}^{k\cdot m}}+W_{N}^{k}\sum\limits_{m=0}^{(N/2)-1}{f_{odd}\left[ m \right]W_{N/2}^{k\cdot m}},\ k=0,1,...,N-1 X[k]=m=0∑(N/2)−1feven[m]WN/2k⋅m+WNkm=0∑(N/2)−1fodd[m]WN/2k⋅m, k=0,1,...,N−1

令 F e v e n [ k ] F_{even}[k] Feven[k] 表示偶索引子序列 f e v e n [ n ] f_{even}[n] feven[n] 的 DFT 结果, F o d d [ k ] F_{odd}[k] Fodd[k] 表示奇索引子序列 f o d d [ n ] f_{odd}[n] fodd[n] 的 DFT 结果,则上式可简化为:
X [ k ] = F e v e n [ k ] + W N k F o d d [ k ] , k = 0 , 1 , . . . , N − 1 X\left[ k \right] = F_{even}\left[ k \right] + W_{N}^{k}F_{odd}\left[ k \right],\ k=0,1,...,N-1 X[k]=Feven[k]+WNkFodd[k], k=0,1,...,N−1

步骤 3:子序列 DFT 结果的周期性分析

F e v e n [ k ] F_{even}[k] Feven[k] 与 F o d d [ k ] F_{odd}[k] Fodd[k] 的时域输入长度均为 N / 2 N/2 N/2,但 k k k 的取值范围为 0 , 1 , ... , N − 1 0,1,...,N-1 0,1,...,N−1,是输入长度的 2 倍。这表明 F e v e n [ k ] F_{even}[k] Feven[k] 与 F o d d [ k ] F_{odd}[k] Fodd[k] 具有周期性特征(可理解为 N N N 个采样点包含了 2 个 2 π 2\pi 2π 周期的频谱采样),即:
F e v e n [ k + N / 2 ] = F e v e n [ k ] F o d d [ k + N / 2 ] = F o d d [ k ] F_{even}\left[ k+N/2 \right] = F_{even}\left[ k \right]\\F_{odd}\left[ k+N/2 \right] = F_{odd}\left[ k \right] Feven[k+N/2]=Feven[k]Fodd[k+N/2]=Fodd[k]

步骤 4:FFT 递推关系的推导

基于上述周期性,DFT 结果的前半部分可直接表示为:
X [ k ] = F e v e n [ k ] + W N k F o d d [ k ] , k = 0 , 1 , . . . , N / 2 − 1 X\left[ k \right] = F_{even}\left[ k \right] + W_{N}^{k}F_{odd}\left[ k \right],\ k=0,1,...,N/2-1 X[k]=Feven[k]+WNkFodd[k], k=0,1,...,N/2−1

结合旋转因子的对称性 W N k + N / 2 = − W N k W_N^{k+N/2} = -W_N^k WNk+N/2=−WNk,DFT 结果的后半部分可推导为:
X [ k + N / 2 ] = F e v e n [ k ] − W N k F o d d [ k ] , k = 0 , 1 , . . . , N / 2 − 1 X\left[ k+N/2 \right] = F_{even}\left[ k \right] - W_{N}^{k}F_{odd}\left[ k \right],\ k=0,1,...,N/2-1 X[k+N/2]=Feven[k]−WNkFodd[k], k=0,1,...,N/2−1

上述推导表明:一个 N N N 点的 DFT 结果可由其奇偶索引子序列的 N / 2 N/2 N/2 点 DFT 结果计算得到。例如,8 点 DFT 可由偶索引 4 点 DFT 结果与奇索引 4 点 DFT 结果推导得出;同理,4 点 DFT 可进一步分解为 2 点 DFT 结果的组合,以此类推,通过分治策略完成整个计算过程。

四、FFT 计算过程

步骤 1:输入序列的位逆序重排

通过二进制镜像(位逆序)的方式,对时域信号的索引进行二进制编码,并按逆序规则重新排列输入序列,如下表所示(最右侧列为逆序后的计算序列,与前述蝶形计算图对应):

二进制:对应计算序列 转换关系 原始索引:对应二进制
000: 0 0: 000
100: 4 1: 001
010: 2 2: 010
110: 6 3: 011
001: 1 4: 100
101: 5 5: 101
011: 3 6: 110
111: 7 7: 111

步骤 2:蝶形运算的逐级合并

按照奇偶分解的逆过程,从最小的子序列开始,逐级执行蝶形运算,合并奇偶子序列的 DFT 结果,最终得到完整的 N N N 点 FFT 计算结果。

五、补充说明

  1. 离散傅里叶逆变换(IDFT)的计算过程同样可采用上述分治与蝶形运算方法实现,仅需对旋转因子的符号与最终结果进行少量调整。
  2. 本文所阐述的方法为基 2 FFT 算法,除此之外,还存在基 4 等其他类型的 FFT 算法,其详细原理可参考《数字信号处理------原理、算法与应用(第四版)》第 380 页。

总结

  1. FFT 是 DFT 的高效实现方式,依托旋转因子的周期性、对称性、缩放性,结合分治算法降低计算复杂度。
  2. FFT 蝶形计算的逻辑是将 N N N 点 DFT 拆分为奇偶子序列的 N / 2 N/2 N/2 点 DFT 组合,通过递推实现计算简化。
  3. FFT 实际计算需先完成输入序列的位逆序重排,再通过逐级蝶形运算合并子序列结果。

参考文献

相关推荐
轻微的风格艾丝凡7 天前
MATLAB 电流/电压FFT谐波分析程序代码分析文档
算法·matlab·fft·thd
南檐巷上学12 天前
基于FPGA的音频信号监测识别系统
fpga开发·音频·verilog·fpga·傅立叶分析·fft·快速傅里叶变换
weiwei2284415 天前
深入理解傅里叶变换
fft·快速傅里叶变换·nnt
民乐团扒谱机2 个月前
【微实验】仿AU音频编辑器开发实践:从零构建音频可视化工具
算法·c#·仿真·audio·fft·频谱
bu_shuo2 个月前
simulink中使用fft进行频谱分析卡死可能的解决方法
matlab·simulink·fft·powergui
s09071362 个月前
Xilinx 7系列FPGA的FFT IP核简介
fpga开发·zynq·fft
硬汉嵌入式2 个月前
初步完成H7-TOOL的250M示波器功能自动频率测量
滤波·fft·频谱·h7-tool·250m示波器·自动频率测量
硬汉嵌入式3 个月前
H7-TOOL集成DSP数字信号量处理库,FFT注册添加成功
数字信号处理·dsp·fft·h7-tool
南檐巷上学4 个月前
Vivado调用FFT IP核进行数据频谱分析
fpga开发·fpga·vivado·fft·快速傅里叶变化