FFT算法是由J.W. Cooley和J. W. Tukey在论文”Analgorithm for the machine calculation of complex Fourier Series”中提出的。FFT是基于ComplexDFT来实现的。
通过ComplexDFT来计算Real DFT
尽管FFT算法是基于ComplexDFT实现的,但我们仍可以用其来计算RealDFT,因为RealDFT可以方便地转换为ComplexDFT。从图2-1中可以看出RealDFT和Complex DFT的区别。在RealDFT中,时间域是一个包含N个点的信号,频率域则包括实数部分和虚数部分两个长度为N/2+1的信号;在ComplexDFT中,时间域也有两个部分,分别是实数部分和虚数部分,长度为N。频率域的实数部分和虚数部分则长度增至N。
如图2-1所示,RealDFT和ComplexDFT的区别仅在于后者在时间域增加了一个虚数部分,频率域长度的变化正是由这个虚数部分引起的。
图2-1 Real DFT和ComplexDFT的区别
产生这个区别的原因是实数的虚数部分为0,因此将实数表达为虚数很简单,加上一个系数为0的虚数部分即可。例如在图2-1中的ComplexDFT,若将时间域的虚数部分设为0,频率域中多出的部分也置为0,那么图2-1中的RealDFT和ComplexDFT就相等了。当包含负频率时,DFT的频率域会具有周期性。在ComplexDFT中,频率域中0到N/2为正频率,N/2+1到N-1为负频率。
与使用ComplexDFT计算Real DFT相比,使用ComplexInverse DFT计算Real InverseDFT更为困难。这是因为频率域中N/2+1到N-1部分的系数需要计算。其计算过程也不复杂,系数N/2+1对应系数N/2-1的相反数,N/2+2对应N/2-2的相反数,即:
系数(N/2+1)=—系数(N/2-1)
系数(N/2+2)=—系数(N/2-2)
注意,0与N/2没有相应的点与之对应。进行RealInverse DFT计算时,首先将0到N/2复制到complexDFT的系数0到N/2,然后使用一个子过程来计算系数N/2+1到N-1。这个子过程的伪代码实现如下:
6000'NEGATIVE FREQUENCY GENERATION
6010'This subroutine creates the complex frequency domain from the realfrequency domain.
6020'Upon entry to this subroutine, N% contains the number of points in thesignals, and
6030'REX[ ] and IMX[ ] contain the real frequency domain in samples 0 toN/2.
6040'On return, REX[ ] and IMX[ ] contain the complex frequency domainin samples 0 to N-1.
6050 '
6060FOR K% = (N%/2+1) TO (N%-1)
6070REX[K%] = REX[N%-K%]
6080IMX[K%] = -IMX[N%-K%]
6090NEXT K%
6100 '
6110RETURN
FFT的实现原理
FFT算法很复杂,本文不讨论细节,只描述其实现原理。在虚数域中,时间域和频率域表达的都是由N个虚数点组成的信号,每个虚数点都由实数部分和虚数部分的两个数字来表达。例如虚数点X[6],就是由实数部分ReX[6]和虚数部分Im X[6]组成。
FFT算法的核心思想是将时间域中一个包含N个点的信号分解为N个包含一个点的信号。然后分别计算这N个信号的频率域对应值,最后将这N个频率域的信号综合为频率域中的一个信号。
图2-2描述了一个包含12个点的示例信号在FFT中的分解过程。
图2-2 FFT中的分解(decompose)过程
图2-2中的过程看似复杂,实际上可以通过如图2-3所示的位反转算法(bitreversal sorting)来实现。算法将各点的二进制位反转为对称的形式,即可完成N个点的信号到N个单点信号的分解过程。
图2-3位反转排序