关于《算法的乐趣》傅立叶变换一章的补充

一些热心读者反馈在介绍快速傅立叶变换(FFT)部分的描述和代码不一致,比如某位读者反馈前面正文介绍的是DIT-FFT,但是给出的代码实现确是DIF-FFT,让人困惑,本文准备补充一下相关的内容。

DIT-FFT和DIF-FFT,一个是按时间抽取计算(Decimation-In-Time),一个是按频率抽取计算(Decimation-In-Frequency),是两种等价的FFT算法,本章内容主要集中在离散傅立叶变换算法的使用实例,比如频谱和均衡器,因此并没有具体描述这二者的差异,只是在242页中间一段文字中做了说明,原文如下:

“FFT算法对这个位置关系的处理有两种方式,一种是如图15-4所示,在开始蝶形运算之前就对原始数据按照码位关系进行排序,则计算后可直接得到与原始序列一致的输出。这种方式又称为原位运算方式。另一种方式是直接进行蝶形运算,然后按照码位关系对运算后的输出结果重新排序。”

这段文字其实存一个错误,在此需要更正一下,实际上无论是DIT-FFT还是DIF-FFT,都可以实现为原位运算方式。

DIT-FFT和DIF-FFT的主要差异就是蝶形运算的方式,有的资料说属否需要对输入数据倒序重排也是DIT-FFT和DIF-FFT的差异,这一点是仁者见仁,智者见智了,许多高效的算法都可以通过巧妙的循环控制避免这个重排操作,因此这应该不算是DIT和DIF的主要差异。蝶形运算的差异主要体现在参与蝶形运算的两个点的数据与旋转因子的乘法是在减法之前还是在减法之后,这句话理解起来有点困难,可以通过蝶形运算关系图来理解。书中的图15-3是DIT-FFT的蝶形运算关系图,,可以看出。

图(1) DIF蝶形运算示意图

根据以上分析,本文补充一个DIT_FFT的算法实现,大家可以对比一下书中给出的DIF_FFT算法,可以看到蝶形运算部分的明显区别。

void DIT_FFT(FFT_HANDLE *hfft, COMPLEX *TD2FD){int power = NumberOfBits(hfft->count); //power为蝶形运算级数//重新排序ResortSequence(TD2FD, hfft->count, power);for(int k = 0; k < power; k++) //第k级蝶形运算{int butterfly = 1 << (k + 1);int wtp = 1 << (power – k – 1);for(int j = 0; j < (1 << k); j++) //蝶形运算分组{for(int i = j; i < hfft->count; i += butterfly){int b = i + butterfly / 2;COMPLEX t = TD2FD[b]*hfft->wt[j * wtp];TD2FD[b] = TD2FD[i] – t;TD2FD[i] = TD2FD[i] + t;}}}}

如果前世五百次眸回,才换来今生的擦肩而过。

关于《算法的乐趣》傅立叶变换一章的补充

相关文章:

你感兴趣的文章:

标签云: