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