目录
开场白
最近研究数字滤波器的时候接触到了离散傅里叶变换(DFT),它的实现非常简单但是使用非常不便,时间复杂度很高,对于性能一般且不带FPU的辣鸡单片机直接求解难度很大,在点数较少( N⩽8 N ⩽ 8 )时勉强可用,点数再高计算几乎登天。因此需要一种能够快速计算DFT的算法减少时间复杂度,此快速傅里叶变换(FFT)的初衷是也。虽然现在有相当多的FFT库可以使用,这些库性能都相对不错,敲起代码来得心应手,丝毫没有无知的羞耻(^_^)。但作为一只好奇心甚重的小白,还是希望亲自实现一把,于是乎趁晚上散步的几个小时找来书研究了一下,推了一遍公式,敲了一遍代码,也算是搞懂了FFT的实现。
基础数学
在涉及傅里叶变换的核心算法之前,先对其中的基础数学简要归纳
复数由实部和虚部构成,形如( a+bi a + b i ),这里 i i 为单位虚数(
)
单位虚数的性质: i×i=−1 i × i = − 1
复数也有四则运算,这里我们用到其中两种:复乘、复加
1.复数运算
对于两个复数 a+bi a + b i 、 c+di c + d i ,其乘积满足
对于两个复数 a+bi a + b i 、 c+di c + d i ,其和
2.欧拉公式
对于复指数形式,欧拉大人为我们指了一条明路,这就是著名的欧拉公式
这条公式将奠定快速傅里叶变换的理论基础
基础信号论
奈奎斯特采样定理
奈奎斯特采样定理(又名香农采样定理)是对信号离散化的准则,为了获取信号更多的信息,其必须满足
采样速率 fs f s 必须大于信号最高频率的两倍,这个频率称为奈奎斯特频率 fN f N ,即
fs>2⋅fN f s > 2 ⋅ f N
从解方程到傅里叶变换
1.何方神圣
法国大数学家傅里叶提出,任何一个函数都可以化为由正弦函数构成的无穷级数,简而言之,表现任何一个复杂的信号(如声音),只需要足够多的正弦函数相加。例如信号 f(x) f ( x ) 可以写为
这里每一个小的正弦函数都包含属于自己的幅值、频率、相位,这样一个庞大的组合体构成了任意的 f(x) f ( x ) ,也构成我们能看到、听到的信息,狭义的说,傅里叶变换正是将一个完整的 f(x) f ( x ) 打散为正弦之和的手段,每一个正弦代表了信号在该频率的分量,于是我们说xx信号200KHz的分量是…
2.分量求解:从方程开始
在上面我们提到任意信号都可以由不同频率的分量合成,也就是
如果我们换一个角度看上式,看成一个方程,结果如何?为了简单起见,我们先抛弃令人不舒服的相位 φ φ
这里,每一个正弦函数我们都抽象地将其看作一个种频率,即 fn=2πnω f n = 2 π n ω ,我们把这些频率看作已知,也就是统统都存在(大不了幅值为0嘛)
于是我们需要求解上述方程。经验告诉我们一个方程式不够嘀,有多少个未知数就有多少个方程组成方程组,否则方程组就是欠定,解可能不唯一。很不幸这里 n n 的取值为无穷大,也就是说我们需要找到无穷多个方程联立才能求解每一个频率分量,但这无疑为我们解决问题找到了一个途径。
事实上我们真的需要知道每一个频率分量吗?
世界上漂亮的女孩子千千万万,难道….
在信号论基础里面俺特意放了一条奈奎斯特采样定律,可见我们能获得的信号细节(也就是频率的种数吧)是有条件限制的,至少受采样速率的限制,采样速率又受产品要求、器件工艺、人民币张数等等的限制….
假若以200Hz的速率采样,能准确看清的信号频率最高也就100Hz吧?200Hz总得有个分辨率,分辨率为1Hz,就需要201个正弦函数。对!201个正弦函数,到此问题可解:为了在采样频率为200Hz时得到分辨率为1Hz的分量信息,需要求解未知数为201的方程: