快速傅里叶变换(FFT),真的很细

一、前言

在电赛中,使用FFT算法进行信号频谱分析极其常用,为了给大家科普FFT,本博客将从傅里叶级数到傅里叶变换,再到离散时间傅里叶变换、离散傅里叶变换,之后再简单讲解FFT中简单的按时间抽选的基 2–FFT 算法,主要目的在于为小白科普,如有不严谨或不正确的地方,还请大佬指出。本次博客大量参考其余大佬的博客,笔者只是拾人牙慧的小屁孩。

二、傅里叶变换的前世今生

傅里叶级数展开告诉我们,任何一个函数 f ( t ) f(t) f(t) ,都可以展开成如下形式的傅里叶级数:
f ( t ) = 1 2 a 0 + ∑ n = 1 + ∞ [ a n c o s ( n w t ) + b n s i n ( n w t ) ] w = 2 π T a n = 2 T ∫ − T 2 T 2 f ( t ) c o s ( n w t ) d t , n = 1 , 2 , 3... b n = 2 T ∫ − T 2 T 2 f ( t ) s i n ( n w t ) d t , n = 1 , 2 , 3... f(t) = \frac{1}{2}a_{0} + \sum^{+\infty}_{n=1}[a_{n}cos(nwt) + b_{n}sin(nwt)]\\ w = \frac{2\pi}{T}\\ a_{n} = \frac{2}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)cos(nwt)dt, n = 1, 2 ,3 ...\\ b_{n} = \frac{2}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)sin(nwt)dt, n = 1, 2 ,3 ... f(t)=21a0+n=1+[ancos(nwt)+bnsin(nwt)]w=T2πan=T22T2Tf(t)cos(nwt)dt,n=1,2,3...bn=T22T2Tf(t)sin(nwt)dt,n=1,2,3...
关于傅里叶级数待定系数的求解是利用的三角函数的正交性,详情可见这篇知乎。
我们利用欧拉公式得到(傅里叶变换里面有个 j j j,要考虑到这个复数和三角函数的关系):
c o s ( n w t ) = e j n w t + e − j n w t 2 s i n ( n w t ) = e j n w t − e − j n w t 2 j cos(nwt) = \frac{e^{jnwt}+e^{-jnwt}}{2}\\ sin(nwt) = \frac{e^{jnwt}-e^{-jnwt}}{2j} cos(nwt)=2ejnwt+ejnwtsin(nwt)=2jejnwtejnwt
代入傅里叶级数之中:
f ( t ) = 1 2 a 0 + ∑ n = 1 + ∞ [ a n c o s ( n w t ) + b n s i n ( n w t ) ] f ( t ) = 1 2 a 0 + ∑ n = 1 + ∞ ( a n e j n w t + e − j n w t 2 + b n e j n w t − e − j n w t 2 j ) f ( t ) = 1 2 a 0 + ∑ n = 1 + ∞ ( a n − j b n 2 e j n w t + a n + j b n 2 e − j n w t ) f(t) = \frac{1}{2}a_{0} + \sum^{+\infty}_{n=1}[a_{n}cos(nwt) + b_{n}sin(nwt)]\\ f(t) = \frac{1}{2}a_{0} + \sum^{+\infty}_{n=1}(a_{n} \frac{e^{jnwt}+e^{-jnwt}}{2}+ b_{n} \frac{e^{jnwt}-e^{-jnwt}}{2j})\\ f(t) = \frac{1}{2}a_{0} + \sum^{+\infty}_{n=1}( \frac{a_{n}-jb_{n}}{2}e^{jnwt}+ \frac{a_{n}+jb_{n}}{2}e^{-jnwt}) f(t)=21a0+n=1+[ancos(nwt)+bnsin(nwt)]f(t)=21a0+n=1+(an2ejnwt+ejnwt+bn2jejnwtejnwt)f(t)=21a0+n=1+(2anjbnejnwt+2an+jbnejnwt)
n = 0 n=0 n=0时,
a n − j b n 2 = a 0 − j b 0 2 = 1 2 ( 2 T ∫ − T 2 T 2 f ( t ) d t − 0 ) = 1 T ∫ − T 2 T 2 f ( t ) d t \frac{a_{n}-jb_{n}}{2} = \frac{a_{0}-jb_{0}}{2} = \frac{1}{2} (\frac{2}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)dt - 0) = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)dt 2anjbn=2a0jb0=21(T22T2Tf(t)dt0)=T12T2Tf(t)dt
c 0 = a 0 − j b 0 2 = 1 T ∫ − T 2 T 2 f ( t ) d t c_{0} = \frac{a_{0}-jb_{0}}{2} = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)dt c0=2a0jb0=T12T2Tf(t)dt
猜想 c n = a n − j b n 2 = 1 T ∫ − T 2 T 2 f ( t ) e − j n w t d t c_{n} = \frac{a_{n}-jb_{n}}{2} = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)e^{-jnwt}dt cn=2anjbn=T12T2Tf(t)ejnwtdt
假设我们猜想成立,
我们计算 c − n c_{-n} cn
c − n = 1 T ∫ − T 2 T 2 f ( t ) e j n w t d t = 1 T ∫ − T 2 T 2 f ( t ) [ c o s ( n w t ) + j s i n ( n w t ) ] d t = 1 2 [ 2 T ∫ − T 2 T 2 f ( t ) c o s ( n w t ) d t + 2 j T ∫ − T 2 T 2 f ( t ) s i n ( n w t ) d t ] = a n + j b n 2 \begin{align} c_{-n} &= \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)e^{jnwt}dt\\ &= \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)[cos(nwt) + jsin(nwt)]dt\\ &= \frac{1}{2} [\frac{2}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)cos(nwt)dt +\frac{2j}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)sin(nwt)dt ]\\ &= \frac{a_{n}+jb_{n}}{2}& \end{align} cn=T12T2Tf(t)ejnwtdt=T12T2Tf(t)[cos(nwt)+jsin(nwt)]dt=21[T22T2Tf(t)cos(nwt)dt+T2j2T2Tf(t)sin(nwt)dt]=2an+jbn
综上,
c − n = 1 T ∫ − T 2 T 2 f ( t ) e j n w t d t , n = 1 , 2 , 3... c_{-n} = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)e^{jnwt}dt, n = 1, 2 ,3 ... cn=T12T2Tf(t)ejnwtdt,n=1,2,3...
延拓为正整数 n n n
c n = 1 T ∫ − T 2 T 2 f ( t ) e − j n w t d t , n = 1 , 2 , 3... c_{n} = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)e^{-jnwt}dt, n = 1, 2 ,3 ... cn=T12T2Tf(t)ejnwtdt,n=1,2,3...
之后我们再将傅里叶级数的式子写成:
f ( t ) = 1 2 ( a 0 + 0 ) + ∑ n = 1 + ∞ ( a n − j b n 2 e j n w t + a n + j b n 2 e − j n w t ) f ( t ) = c 0 + ∑ n = 1 + ∞ ( c n e j n w t + c − n e − j n w t ) f ( t ) = ∑ n = − ∞ + ∞ c n e j n w t \begin{align} f(t) &= \frac{1}{2}(a_{0}+0) + \sum^{+\infty}_{n=1}( \frac{a_{n}-jb_{n}}{2}e^{jnwt}+ \frac{a_{n}+jb_{n}}{2}e^{-jnwt})\\ f(t) &= c_{0}+ \sum^{+\infty}_{n=1}( c_{n}e^{jnwt}+ c_{-n}e^{-jnwt})\\ f(t) &= \sum^{+\infty}_{n=-\infty}c_{n}e^{jnwt} \end{align} f(t)f(t)f(t)=21(a0+0)+n=1+(2anjbnejnwt+2an+jbnejnwt)=c0+n=1+(cnejnwt+cnejnwt)=n=+cnejnwt
又因为 c n = 1 T ∫ − T 2 T 2 f ( t ) e − j n w t d t c_{n} = \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(t)e^{-jnwt}dt cn=T12T2Tf(t)ejnwtdt
得到
f ( t ) = ∑ n = − ∞ + ∞ [ 1 T ∫ − T 2 T 2 f ( τ ) e − j n w τ d τ ] e j n w t f ( t ) = 1 T ∑ n = − ∞ + ∞ [ ∫ − T 2 T 2 f ( τ ) e − j n w τ d τ ] e j n w t \begin{align} f(t) & = \sum^{+\infty}_{n=-\infty}[ \frac{1}{T}\int^{\frac{T}{2}}_{-\frac{T}{2}}f(\tau)e^{-jnw\tau}d\tau]e^{jnwt}\\ f(t) & = \frac{1}{T} \sum^{+\infty}_{n=-\infty}[ \int^{\frac{T}{2}}_{-\frac{T}{2}}f(\tau)e^{-jnw\tau}d\tau]e^{jnwt} \end{align} f(t)f(t)=n=+[T12T2Tf(τ)ejnwτdτ]ejnwt=T1n=+[2T2Tf(τ)ejnwτdτ]ejnwt
请注意,这里的 n n n依然是一个整数,尽管它的范围为 − ∞ < n < ∞ -\infty < n < \infty <n<,所以接下来我们需要将其连续化。
傅里叶积分定理——当 T → + ∞ T \rightarrow +\infty T+,任何一个非周期函数 f ( t ) f(t) f(t)都可以看成某个周期函数 f T ( t ) f_{T}(t) fT(t)转换而来,数学表示即:
lim ⁡ T → + ∞ f T ( t ) = f ( t ) \lim_{T \rightarrow +\infty}f_{T}(t) = f(t) T+limfT(t)=f(t)
故,当我们取极限时,
lim ⁡ T → + ∞ Δ ( n w ) = lim ⁡ T → + ∞ [ n w − ( n − 1 ) w ] = lim ⁡ T → + ∞ w = lim ⁡ T → + ∞ 2 π T = 0 i . e .   lim ⁡ T → + ∞ Δ ( n w ) = 0 = lim ⁡ T → + ∞ d ( n w ) \lim_{T \rightarrow +\infty}\Delta(nw) =\lim_{T \rightarrow +\infty}[ nw - (n-1) w]=\lim_{T \rightarrow +\infty}w\\ = \lim_{T \rightarrow +\infty}\frac{2\pi}{T} = 0\\ i.e. \text{ } \lim_{T \rightarrow +\infty}\Delta(nw) = 0 = \lim_{T \rightarrow +\infty}d(nw) T+limΔ(nw)=T+lim[nw(n1)w]=T+limw=T+limT2π=0i.e. T+limΔ(nw)=0=T+limd(nw)
这样,只要 T → + ∞ T \rightarrow +\infty T+ Δ ( n w ) → d ( n w ) → 0 \Delta(nw) \rightarrow d(nw) \rightarrow 0 Δ(nw)d(nw)0,这样的话,岂不是 n w nw nw的间距就变得非常小了,离散的 Δ ( n w ) \Delta(nw) Δ(nw)就变成了连续的 d ( n w ) d(nw) d(nw),求和号就变成了积分号。
我们刚刚的式子也可以写成,
f ( t ) = 1 T ∑ n = − ∞ + ∞ [ ∫ − T 2 T 2 f ( τ ) e − j n w τ d τ ] e j n w t f ( t ) = lim ⁡ T → + ∞ 1 2 π d w ∫ − ∞ + ∞ [ ∫ − ∞ + ∞ f ( τ ) e − j w τ d τ ] e j w t f ( t ) = lim ⁡ T → + ∞ 1 2 π ∫ − ∞ + ∞ [ ∫ − ∞ + ∞ f ( τ ) e − j w τ d τ ] e j w t d w \begin{align} f(t) &= \frac{1}{T} \sum^{+\infty}_{n=-\infty}[ \int^{\frac{T}{2}}_{-\frac{T}{2}}f(\tau)e^{-jnw\tau}d\tau]e^{jnwt}\\ f(t) &= \lim_{T \rightarrow +\infty}\frac{1}{\frac{2 \pi}{dw}} \int^{+\infty}_{-\infty}[ \int^{+\infty}_{-\infty}f(\tau)e^{-jw\tau}d\tau]e^{jwt}\\ f(t) &= \lim_{T \rightarrow +\infty}\frac{1}{2 \pi} \int^{+\infty}_{-\infty}[ \int^{+\infty}_{-\infty}f(\tau)e^{-jw\tau}d\tau]e^{jwt}dw \end{align} f(t)f(t)f(t)=T1n=+[2T2Tf(τ)ejnwτdτ]ejnwt=T+limdw2π1+[+f(τ)ejwτdτ]ejwt=T+lim2π1+[+f(τ)ejwτdτ]ejwtdw
如果我们把 ∫ − T 2 T 2 f ( τ ) e − j w τ d τ \int^{\frac{T}{2}}_{-\frac{T}{2}}f(\tau)e^{-jw\tau}d\tau 2T2Tf(τ)ejwτdτ设为是傅里叶变换,那它可以得到一个含 w w w的式子,用于外层积分。于是我们把这个一个函数写成两步:
F ( w ) = ∫ − ∞ + ∞ f ( t ) e − j w t d t f ( t ) = 1 2 π ∫ − ∞ + ∞ F ( w ) e j w t d w F(w) = \int^{+\infty}_{-\infty}f(t)e^{-jwt}dt\\ f(t) = \frac{1}{2\pi} \int^{+\infty}_{-\infty}F(w)e^{jwt}dw F(w)=+f(t)ejwtdtf(t)=2π1+F(w)ejwtdw
这便是傅里叶变化和逆傅里叶变换。

三、DTFT和DTF

有了傅里叶变换
F ( w ) = ∫ − ∞ + ∞ f ( t ) e − j w t d t F(w) = \int^{+\infty}_{-\infty}f(t)e^{-jwt}dt F(w)=+f(t)ejwtdt
我们把时间离散化,便有了离散时间傅里叶变换(DTFT):
F ( w ) = ∫ − ∞ + ∞ f ( t ) e − j w n d n , n ∈ Z F(w) = \int^{+\infty}_{-\infty}f(t)e^{-jwn}dn, n \in Z F(w)=+f(t)ejwndn,nZ
不过,在这里的 n n n是从 − ∞ -\infty ∞ \infty 的整数,而且 w w w是连续的。该函数在时域上离散,在频域上则是周期的,它一般用来对离散时间信号进行频谱分析。

为了在科学计算和数字信号处理等领域使用计算机进行傅里叶变换,必须将函数定义在离散点上而非连续域内,且须满足有限性或周期性条件,即离散傅里叶变换(DFT)。
dft
0 0 0- N N N个点的波形,周期填充到 − ∞ -\infty ∞ \infty ,即为DFT的核心思想。

w t = 2 π f t = 2 π t T wt = 2\pi f t = 2\pi \frac{t}{T} wt=2πft=2πTt,这代表着 t t t 0 0 0 T T T中有一个周期的波形,

0 ≤ n N < 1 0 ≤ 2 π n N < 2 π  这代表着0-N中有一个周期的波形 0 ≤ 2 π k n N < 2 k π  这代表着0-N中有k个周期的波形 0 \leq \frac{n}{N} < 1\\ 0 \leq 2\pi \frac{n}{N} < 2\pi \text{ 这代表着0-N中有一个周期的波形}\\ 0 \leq 2\pi \frac{kn}{N} < 2k\pi \text{ 这代表着0-N中有k个周期的波形} 0Nn<102πNn<2π 这代表着0-N中有一个周期的波形02πNkn<2 这代表着0-N中有k个周期的波形
于是我们把DTFT的 w n wn wn改写成 2 π k n N \frac{2\pi kn}{N} N2πkn,它们都具有相同的含义。
于是我们感性的得到了DFT(本博客重点不是讲明如何严谨证明,而是通俗易懂解释):
F ( k ) = ∑ n = 0 N − 1 x n e − j 2 π k n / N F(k) = \sum^{N-1}_{n=0}x_{n}e^{-j2 \pi kn / N} F(k)=n=0N1xnej2πkn/N

四、FFT的蝶形变换

DFT 运算量从 N 2 N^2 N2,因为复数乘法的运算量为: ( a + j b ) ( c + j d ) = ( a b − b d ) + j ( b c + a d ) (a+jb)(c+jd)=(ab-bd)+j(bc+ad) (a+jb)(c+jd)=(abbd)+j(bc+ad)
在多点数的DFT运算中,常常会有很长的执行时间。
于是,在 1965 年Cooley 和 Tukey 在《计算机科学 》发表著名的《机器计算傅立叶级数的一种算法》论文后,FFT 开始大规模应用。
FFT也就是Fast Fourier Transform。FFT 充分利用了 DFT 运算中的对称性和周期性,从而将 DFT 运算量从 N 2 N^2 N2 减少到 log ⁡ 2 N \log_{2}{N} log2N

(一)对称性、周期性和可约性

在式子中,
F ( k ) = ∑ n = 0 N − 1 f ( n ) e − j 2 π k n / N F(k) = \sum^{N-1}_{n=0}f(n)e^{-j2 \pi kn / N} F(k)=n=0N1f(n)ej2πkn/N
我们一般将 e − j 2 π k n / N e^{-j2 \pi kn / N} ej2πkn/N写成 W N k n W^{kn}_{N} WNkn
DFT也可以写成
F ( k ) = ∑ n = 0 N − 1 f ( n ) W N k n F(k) = \sum^{N-1}_{n=0}f(n)W^{kn}_{N} F(k)=n=0N1f(n)WNkn
为什么要这么做,因为 W N k n W^{kn}_{N} WNkn具有很多性质,可以改善DFT 的运算效率,故为了我们方便研究 W N k n W^{kn}_{N} WNkn

对称性
( W N k n ) ∗ = ( cos ⁡ ( − 2 π k n / N ) + j sin ⁡ ( − 2 π k n / N ) ) ∗ = ( cos ⁡ ( 2 π k n / N ) − j sin ⁡ ( 2 π k n / N ) ) ∗ = cos ⁡ ( 2 π k n / N ) − j sin ⁡ ( 2 π k n / N ) = W N − k n (W^{kn}_{N})^{*} = (\cos{(-2 \pi kn / N)} + j\sin{(-2 \pi kn / N)})^{*} = (\cos{(2 \pi kn / N)} - j\sin{(2 \pi kn / N)})^{*} = \cos{(2 \pi kn / N)} - j\sin{(2 \pi kn / N)} = W^{-kn}_{N} (WNkn)=(cos(2πkn/N)+jsin(2πkn/N))=(cos(2πkn/N)jsin(2πkn/N))=cos(2πkn/N)jsin(2πkn/N)=WNkn
W N k n = W N k n × 1 = W N k n × cos ⁡ ( − 2 π k N / N ) + j sin ⁡ ( − 2 π k N / N ) = W N k n × W N k N = W N k ( n + N ) W^{kn}_{N} = W^{kn}_{N} \times 1 =W^{kn}_{N} \times \cos{(-2 \pi kN / N)} + j\sin{(-2 \pi kN / N)} = W^{kn}_{N} \times W^{kN}_{N}=W^{k(n+N)}_{N} WNkn=WNkn×1=WNkn×cos(2πkN/N)+jsin(2πkN/N)=WNkn×WNkN=WNk(n+N)
W N k n = W N k n × 1 = W N k n × cos ⁡ ( − 2 π N n / N ) + j sin ⁡ ( − 2 π N n / N ) = W N k n × W N N n = W N n ( k + N ) W^{kn}_{N} = W^{kn}_{N} \times 1 =W^{kn}_{N} \times \cos{(-2 \pi Nn / N)} + j\sin{(-2 \pi Nn / N)} = W^{kn}_{N} \times W^{Nn}_{N}=W^{n(k+N)}_{N} WNkn=WNkn×1=WNkn×cos(2πNn/N)+jsin(2πNn/N)=WNkn×WNNn=WNn(k+N)

周期性
W N k n = W N ( n + N ) k W^{kn}_{N} = W^{(n + N)k}_{N} WNkn=WN(n+N)k

可约性
W N k n = W m N m k n W^{kn}_{N} = W^{mkn}_{mN} WNkn=WmNmkn

特殊点
W N 0 = 1 W^{0}_{N} = 1 WN0=1
W N N / 2 = − 1 W^{N/2}_{N} = -1 WNN/2=1
W N k + N / 2 = − W N k W^{k+N/2}_{N} = -W^{k}_{N} WNk+N/2=WNk

(二)FFT的核心思想

FFT 算法的基本思想:
➢ 利用 DFT 系数的特性,合并 DFT 运算中的某些项。
➢ 把长序列 DFT→短序列 DFT,从而减少运算量。
将一个大点数 N 的 DFT 能分解为若干小点数 DFT 的组合,则显然可以达到减少运算工作量的效果。
fft

(三)按时间抽选的基 2–FFT 算法

设输入序列长度为 N = 2 M 2^M 2M(M 为正整数),将该序列按时间顺序的奇偶分解为越来越短的子序列,称为基 2 按时间抽取的 FFT 算法。也称为 Coolkey-Tukey 算法。
其中基 2 表示:N = 2 M 2^M 2M,M 为整数。若不满足这个条件,可以人为地加上若干零值(加零补长)使其达到 N = 2 M 2^M 2M
下面我们来细说,
F ( k ) = D F T [ f ( n ) ] = ∑ n = 0 N − 1 f ( n ) W N k n = ∑ r = 0 N / 2 − 1 f ( 2 r ) W N k 2 r + ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N k ( 2 r + 1 ) \begin{align} F(k) = &DFT[f(n)] \\ = &\sum^{N-1}_{n=0}f(n)W^{kn}_{N}\\ = &\sum^{N/2-1}_{r=0}f(2r)W^{k2r}_{N} + \sum^{N/2-1}_{r=0}f(2r +1)W^{k(2r+1)}_{N}\\ \end{align} F(k)===DFT[f(n)]n=0N1f(n)WNknr=0N/21f(2r)WNk2r+r=0N/21f(2r+1)WNk(2r+1)
把式子分成奇数项和偶数项,接着开始变换,
= ∑ r = 0 N / 2 − 1 f ( 2 r ) W N k 2 r + ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N k ( 2 r + 1 ) = ∑ r = 0 N / 2 − 1 f ( 2 r ) W N k 2 r + W N k ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N k 2 r = ∑ r = 0 N / 2 − 1 f ( 2 r ) W N / 2 k r + W N k ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N / 2 k r = F 1 ( k ) + W N k F 2 ( k ) \begin{align} = &\sum^{N/2-1}_{r=0}f(2r)W^{k2r}_{N} + \sum^{N/2-1}_{r=0}f(2r +1)W^{k(2r+1)}_{N}\\ = &\sum^{N/2-1}_{r=0}f(2r)W^{k2r}_{N} + W^{k}_{N} \sum^{N/2-1}_{r=0}f(2r +1)W^{k2r}_{N}\\ = &\sum^{N/2-1}_{r=0}f(2r)W^{kr}_{N/2} + W^{k}_{N} \sum^{N/2-1}_{r=0}f(2r +1)W^{kr}_{N/2}\\ = &F_{1}(k) +W^{k}_{N}F_{2}(k) \end{align} ====r=0N/21f(2r)WNk2r+r=0N/21f(2r+1)WNk(2r+1)r=0N/21f(2r)WNk2r+WNkr=0N/21f(2r+1)WNk2rr=0N/21f(2r)WN/2kr+WNkr=0N/21f(2r+1)WN/2krF1(k)+WNkF2(k)
我们便将一个DFT拆分成了两个DFT运算的相加。

我们再利用对称性 W N k n = W N k ( n + N ) W^{kn}_{N} = W^{k(n+N)}_{N} WNkn=WNk(n+N),可以得到,
= ∑ r = 0 N / 2 − 1 f ( 2 r ) W N / 2 k r + W N k ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N / 2 k r = ∑ r = 0 N / 2 − 1 f ( 2 r ) W N / 2 k ( r + N / 2 ) + W N k ∑ r = 0 N / 2 − 1 f ( 2 r + 1 ) W N / 2 k ( r + N / 2 ) = F 1 ( k + N / 2 ) + W N k F 2 ( k + N / 2 ) \begin{align} = &\sum^{N/2-1}_{r=0}f(2r)W^{kr}_{N/2} + W^{k}_{N} \sum^{N/2-1}_{r=0}f(2r +1)W^{kr}_{N/2}\\ = &\sum^{N/2-1}_{r=0}f(2r)W^{k(r+N/2)}_{N/2} + W^{k}_{N} \sum^{N/2-1}_{r=0}f(2r +1)W^{k(r+N/2)}_{N/2}\\ = &F_{1}(k+N/2) +W^{k}_{N}F_{2}(k+N/2) \end{align} ===r=0N/21f(2r)WN/2kr+WNkr=0N/21f(2r+1)WN/2krr=0N/21f(2r)WN/2k(r+N/2)+WNkr=0N/21f(2r+1)WN/2k(r+N/2)F1(k+N/2)+WNkF2(k+N/2)
做一些变换,
F ( k ) = F 1 ( k + N / 2 ) + W N k F 2 ( k + N / 2 ) F ( k + N / 2 ) = F 1 ( k + N ) + W N k + N / 2 F 2 ( k + N ) F ( k + N / 2 ) = F 1 ( k ) + W N k × W N N / 2 F 2 ( k )  周期性 F ( k + N / 2 ) = F 1 ( k ) − W N k F 2 ( k )  特殊点 \begin{align} F(k) = & F_{1}(k+N/2) +W^{k}_{N}F_{2}(k+N/2) \\ F(k + N/2) = & F_{1}(k+N) +W^{k + N/2}_{N}F_{2}(k+N) \\ F(k + N/2) = & F_{1}(k) +W^{k}_{N} \times W^{ N/2}_{N} F_{2}(k) \text{ 周期性}\\ F(k + N/2) = & F_{1}(k) -W^{k}_{N} F_{2}(k) \text{ 特殊点} \end{align} F(k)=F(k+N/2)=F(k+N/2)=F(k+N/2)=F1(k+N/2)+WNkF2(k+N/2)F1(k+N)+WNk+N/2F2(k+N)F1(k)+WNk×WNN/2F2(k) 周期性F1(k)WNkF2(k) 特殊点
于是我们有了两个计算结果,分别结算FFT的前半部分和后半部分
F ( k ) = F 1 ( k ) + W N k F 2 ( k ) F ( k + N / 2 ) = F 1 ( k ) − W N k F 2 ( k ) F(k) = F_{1}(k) +W^{k}_{N}F_{2}(k) \\ F(k + N/2) = F_{1}(k) -W^{k}_{N} F_{2}(k) F(k)=F1(k)+WNkF2(k)F(k+N/2)=F1(k)WNkF2(k)
有了上面的计算结果后,我们可以得到如下的蝶形运算流图符号:
fly

  1. 1 个蝶形运算需要 1 次复乘,2 次复加。(加减都叫复加,这里的复乘和复加意为复数运算)
  2. 左边两路为输入,右边两路为输出。
  3. 中间以一个小圆表示加减运算(右上路为相加输出,右下路为相减输出)。

分解后的运算量减少了近一半。

我们举个例子:
N= 2 3 2^3 23=8,
我们如果只分两组,
2组
确实能得到答案,不过还可以继续分下去,提高性能。
再继续分下去的时候,要注意新的奇偶次序,
奇偶
理清次序之后,我们分四组,进行2点DFT:
四组

下图是按 8 点抽取的 FFT 运算流图:
答案
和我们绘制的本质一致,我们只需增加第一级蝶形即可。
至此,我们成功完成了按时间抽选的基 2–FFT 算法的8点FFT。

四、FFT变换的应用

(一)获取信号的频率幅值相位

一个模拟信号,经过 ADC 采样之后,就变成了数字信号。采样定理告诉我们,采样频率要大于信号频率的两倍(要满足奈奎斯特采样定律)。
现在ADC的采样率为Fs,对峰值为A的信号进行采样,采样点个数为N,我们得到的数字信号就是一个N点数数组。我们对其进行FFT变换,获得N点数FFT结果。(为了方便FFT 运算,通常 N 取 2 的整数次方)
现在我们必须知道FFT 变换结果的物理意义:

  1. FFT 的结果的每个点的模值就是 A 的 N/2 倍,第一个点就是直流分量,它的模值就是直流分量的 N 倍。
  2. 每个点的相位呢,就是在该频率下的信号的相位——计算的话,非常简单直接将该点对应的实数和虚数求出角度即可。
  3. 第一个点表示直流分量(即 0Hz),而最后一个点 N-1的再下一个点N(这个点在数组上不存在的)表示采样频率 Fs,故某点n的频率可以表示为 f n = ( n − 1 ) × F s N f_n = \frac{(n-1) \times F_s}{N} fn=N(n1)×Fs。(含义为0-Fs被分成了N份)
  4. 按照3所说,分辨率则为 f n = F s N f_n = \frac{F_s}{N} fn=NFs。(例如采样频率 Fs为 1024Hz,采样点数为1024 点,则可以分辨到 1Hz。)

可以得出结论,采样时间越长,点数越多,分辨率越高。
但请注意要满足奈奎斯特采样定律(采样频率要大于信号
频率的两倍),当然实际应用中,往往高于两倍。

fft的物理含义

(二)频谱泄漏

还记得我们计算信号频率时,是将0-Fs被分成了N份,而每个数组下标对应的频率是一个Fs/N的整数倍。
但是实际中没有这么巧合的情况,我们在进行离散化处理的时候,难免会出现截断。

对于频率为 fs 的正弦序列,它的频谱应该只是在 fs 处有离散谱。但是,在利用 DFT 求它的频谱做了截短,结果使信号的频谱不只是在 fs 处有离散谱,而是在以 fs 为中心的频带范围内都有谱线出现,它们可以理解为是从 fs 频率上“泄露”出去的,这种现象称 为频谱“泄露"。

所以在刚刚的图中,正弦的频谱应该是一条直线,但笔者却绘制了一个粗粗的刺,这就是频谱泄露的体现之一。
在实际问题中遇到的离散时间序列f(n)通常是无限长序列(前文提到的DTFT),因而处理这个序列的时候需要将它截断(计算器无法处理无限长序列)。截断相当于将序列乘以窗函数 w(n)。(时域中 f(n)和 w(n)相乘对应于频域中它们的离散傅立叶变换 F(jw)和 W(jw)的卷积)
为了减小频谱“泄露”的影响,往往在 FFT 处理中采用加窗技术,典型的加窗序列有 Hamming、Blackman、Gaussian 等窗序列。此外,增加窗序列的长度(增加采样个数)也可以减少频谱“泄露”。
基础知识补充链接——什么是窗函数?
时域上乘上窗函数,相当于频域进行卷积。长度为无穷长的常数窗函数,频域为 delta 函数,卷积后的结果和原来一样。窗的频谱,越像 delta 函数(主瓣越窄,旁瓣越小),频谱的还原度越高。加窗就不可避免频谱泄漏,典型的加权序列有 Hamming、Blackman、Gaussian 等窗序列主要是为了降低降低旁瓣,对于降低频谱泄漏效果远不如增加窗序列的长度明显。

参考资料

  1. 从傅里叶级数到傅里叶变换
  2. 傅里叶系列(一)傅里叶级数的推导
  3. 安富莱_STM32-V7开发板_第2版DSP数字信号处理教程(V2.7)
  4. 什么是窗函数?
  • 24
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值