DFT和FFT之间有什么区别使FFT如此之快?

时间:2017-06-08 18:39:54

标签: algorithm audio fft waveform spectrum

我正在尝试理解FFT,这是我到目前为止所做的:

为了找到波形中的频率大小,必须通过将波与它们搜索的频率相乘,在两个不同的相位(sin和cos)中对每个进行探测,并对每个相位进行平均。通过它与两者的关系找到阶段,并且代码就是这样的:

//simple pseudocode
var wave = [...];                //an array of floats representing amplitude of wave
var numSamples = wave.length;
var spectrum = [1,2,3,4,5,6...]  //all frequencies being tested for.  

function getMagnitudesOfSpectrum() {
   var magnitudesOut = [];
   var phasesOut = [];

   for(freq in spectrum) {
       var magnitudeSin = 0;
       var magnitudeCos = 0;

       for(sample in numSamples) {
          magnitudeSin += amplitudeSinAt(sample, freq) * wave[sample];
          magnitudeCos += amplitudeCosAt(sample, freq) * wave[sample];
       }

       magnitudesOut[freq] = (magnitudeSin + magnitudeCos)/numSamples;
       phasesOut[freq] = //based off magnitudeSin and magnitudeCos
   }

   return magnitudesOut and phasesOut;
}

为了非常快速地为很多频率执行此操作,FFT会使用许多技巧。

用于使FFT比DFT快得多的快捷方式有哪些?

P.S。我已经尝试在网上查看完整的FFT算法,但所有的技巧往往被压缩成一段漂亮的代码而没有太多解释。在我能够理解整个事物之前,我首先需要的是将这些有效变化作为概念进行介绍。

谢谢。

1 个答案:

答案 0 :(得分:2)

请参阅How to compute Discrete Fourier Transform?

这个想法是N - 点 DFT 离散和积分可以分成2 N/2 - 点的两半,其中两半可以表示为{{1的函数} - 点 DFT 和一些小调整将它们组合成最终结果。这导致每个整个数据集需要几乎一半的操作。如果您以递归方式应用此方法,则会以天真的方式获得N/2而不是O(n.log2(n))

有两种众所周知的方法可以将方程式划分为两个相似的半和,一个称为时间抽取,另一个称为抽取频率。 Booth以代数方式分割原始和(利用O(n^2)权重矩阵的对称性),只需google。

调整通常涉及拆分数据集的偶数奇数条目,或者使用 butterfly shuffle 对其进行重新排序,其中涉及位反转的索引顺序,可以快速硬连线...用于 HW DFFT 实现...有关详细信息,请参阅Wiki Butterfly diagram