[EE261学习笔记] 15.快速傅里叶变换(FFT)原理

简单回顾

快速傅里叶变换,其实是离散傅里叶变换的一种改进算法

我们先来回忆一下离散傅里叶变换(DFT):

F f [ m ] ‾ = ∑ n = 0 N − 1 f [ n ] ‾ ω [ m ] ‾ − n (1) \underline{\mathscr{F}f[m]} = \sum_{n=0}^{N-1} \underline{f[n]} \underline{\omega[m]}^{-n} \tag1 Ff[m]=n=0N1f[n]ω[m]n(1)

其中 ω [ m ] ‾ = e 2 π i m N \underline{\omega[m]} = e^{2\pi i\frac{m}{N}} ω[m]=e2πiNm

对应的矩阵形式为:

[ F f [ 0 ] ‾ F f [ 1 ] ‾ ⋮ F f [ N − 1 ] ‾ ] = [ 1 1 ⋯ 1 1 ω ‾ − 1 ⋅ 1 ⋯ ω ‾ − 1 ⋅ ( N − 1 ) ⋮ ⋮ ⋱ ⋮ 1 ω ‾ − ( N − 1 ) ⋅ 1 ⋯ ω ‾ − ( N − 1 ) 2 ] [ f [ 0 ] ‾ f [ 1 ] ‾ ⋮ f [ N − 1 ] ‾ ] \begin{bmatrix} \underline{\mathscr{F}f[0]}\\ \underline{\mathscr{F}f[1]}\\ \vdots\\ \underline{\mathscr{F}f[N-1]} \end{bmatrix} = \begin{bmatrix} 1 & 1 & \cdots & 1 \\ 1 & \underline{\omega}^{-1 \cdot 1} & \cdots & \underline{\omega}^{- 1 \cdot (N-1)} \\ \vdots & \vdots & \ddots & \vdots \\ 1 & \underline{\omega}^{-(N-1) \cdot 1} & \cdots & \underline{\omega}^{-(N-1)^2} \end{bmatrix} \begin{bmatrix} \underline{f[0] } \\ \underline{f[1]} \\ \vdots\\ \underline{f[N-1]} \end{bmatrix} Ff[0]Ff[1]Ff[N1]=1111ω11ω(N1)11ω1(N1)ω(N1)2f[0]f[1]f[N1]

不难发现,如果要对 N N N 个采样点进行DFT,则时间复杂度为 o ( N 2 ) o \left( N^2\right) o(N2)

接下来,我们将讲解时间复杂度为 o ( N log ⁡ N ) o \left( N \log N \right) o(NlogN) 的FFT算法

为了书写方便,我们记

ω ‾ [ p , q ] = e 2 π i q p (2) \underline{\omega}[p, q] = e^{2\pi i \frac{q}{p}} \tag 2 ω[p,q]=e2πipq(2)

这样, ω [ m ] ‾ \underline{\omega[m]} ω[m]就可以改写为

ω [ m ] ‾ = e 2 π i m N = ω ‾ [ N , m ] \underline{\omega[m]} = e^{2\pi i \frac{m}{N}} = \underline{\omega}[N, m] ω[m]=e2πiNm=ω[N,m]

同时,不难发现,

ω ‾ [ N , n + m ] = e 2 π i n + m N = e 2 π i n N e 2 π i m N = ω ‾ [ N , n ] ω ‾ [ N , m ] \underline{\omega}[N, n+m] = e^{2\pi i \frac{n+m}{N}} = e^{2\pi i \frac{n}{N}}e^{2\pi i \frac{m}{N}} = \underline{\omega}[N, n]\underline{\omega}[N, m] ω[N,n+m]=e2πiNn+m=e2πiNne2πiNm=ω[N,n]ω[N,m]

ω ‾ [ N 2 , − n m ] = e − 2 π i n m N 2 = e − 2 π i 2 n m N = ω ‾ [ N , − 2 n m ] \underline{\omega}[\frac{N}{2}, -nm] = e^{-2\pi i \frac{nm}{\frac{N}{2}}} = e^{-2\pi i \frac{2nm}{N}} = \underline{\omega}[N, -2nm] ω[2N,nm]=e2πi2Nnm=e2πiN2nm=ω[N,2nm]


FFT推导

FFT的核心思想就是:将DFT的 N × N N \times N N×N矩阵该写为对几个 N 2 × N 2 \frac{N}{2} \times \frac{N}{2} 2N×2N的矩阵的操作,并用这种方式进行递归,最后得到FFT

首先,我们将 ( 1 ) (1) (1)式拆分为奇数、偶数两部分,即

F f [ m ] ‾ = ∑ n = 0 N − 1 f [ n ] ‾ ω [ m ] ‾ − n = ( f [ 0 ] ‾ ω [ m ] ‾ − 0 + f [ 2 ] ‾ ω [ m ] ‾ − 2 + ⋯ + f [ N − 2 ] ‾ ω [ m ] ‾ − ( N − 2 ) ) + ( f [ 1 ] ‾ ω [ m ] ‾ − 1 + f [ 3 ] ‾ ω [ m ] ‾ − 3 + ⋯ + f [ N − 1 ] ‾ ω [ m ] ‾ − ( N − 1 ) ) = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω [ m ] ‾ − 2 n + ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω [ m ] ‾ − ( 2 n + 1 ) \begin{aligned} \underline{\mathscr{F}f[m]} &= \sum_{n=0}^{N-1} \underline{f[n]} \underline{\omega[m]}^{-n}\\ & = \left( \underline{f[0]} \underline{\omega[m]}^{-0} + \underline{f[2]} \underline{\omega[m]}^{-2} + \dots + \underline{f[N-2]} \underline{\omega[m]}^{-\left(N-2 \right)} \right) + \left( \underline{f[1]} \underline{\omega[m]}^{-1} + \underline{f[3]} \underline{\omega[m]}^{-3} + \dots + \underline{f[N-1]} \underline{\omega[m]}^{-\left(N-1 \right)} \right)\\ &=\sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega[m]}^{-2n} + \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega[m]}^{-(2n+1)} \end{aligned} Ff[m]=n=0N1f[n]ω[m]n=(f[0]ω[m]0+f[2]ω[m]2++f[N2]ω[m](N2))+(f[1]ω[m]1+f[3]ω[m]3++f[N1]ω[m](N1))=n=02N1f[2n]ω[m]2n+n=02N1f[2n+1]ω[m](2n+1)

利用 ( 2 ) (2) (2) 式,可将上式改写为

F f [ m ] ‾ = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N , − 2 n m ] + ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N , − ( 2 n + 1 ) m ] = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N , − 2 n m ] + ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N , − 2 n m ] ω ‾ [ N , − m ] = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N 2 , − n m ] + ω ‾ [ N , − m ] ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N 2 , − n m ] (3) \begin{aligned} \underline{\mathscr{F}f[m]} &=\sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[N, -2nm] + \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[N, -(2n+1)m]\\ &=\sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[N, -2nm] + \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[N, -2nm]\underline{\omega}[N, -m]\\ &=\sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[\frac{N}{2}, -nm] + \underline{\omega}[N, -m] \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[\frac{N}{2}, -nm]\tag 3 \end{aligned} Ff[m]=n=02N1f[2n]ω[N,2nm]+n=02N1f[2n+1]ω[N,(2n+1)m]=n=02N1f[2n]ω[N,2nm]+n=02N1f[2n+1]ω[N,2nm]ω[N,m]=n=02N1f[2n]ω[2N,nm]+ω[N,m]n=02N1f[2n+1]ω[2N,nm](3)

注意我们要使用递归来计算的话,必须把式子写成矩阵形式,那么 ( 3 ) (3) (3)式就可以写为:

F ‾ N f [ m ] ‾ = F N 2 f even [ m ] ‾ + ω ‾ [ N , − m ] F N 2 f odd [ m ] ‾ (4) \underline\mathscr{F}_N \underline{f[m]} = \underline{\mathscr{F}_{\frac{N}{2}}f_\text{even}[m]} + \underline{\omega}[N, -m]\underline{\mathscr{F}_{\frac{N}{2}}f_\text{odd}[m]} \tag4 FNf[m]=F2Nfeven[m]+ω[N,m]F2Nfodd[m](4)

我们仔细看看从 ( 3 ) (3) (3) 式的求和形式到 ( 4 ) (4) (4) 的矩阵矩阵形式, ( 3 ) (3) (3) 式完全是没有问题的,但是 ( 4 ) (4) (4) 式却有问题: ( 4 ) (4) (4) 式中的 F ‾ N 2 \underline\mathscr{F}_{\frac{N}{2}} F2N N 2 × N 2 \frac{N}{2} \times \frac{N}{2} 2N×2N 的矩阵,那么与之相乘的矩阵必然有 N 2 \frac{N}{2} 2N 行,也就是说 m ≤ N 2 − 1 m \leq \frac{N}{2}-1 m2N1。换句话说, ( 4 ) (4) (4) 式计算出的其实是 F ‾ N \underline\mathscr{F}_N FN 的前半部分。

那么对于 m ∈ [ N 2 , N − 1 ] m \in [\frac{N}{2}, N-1] m[2N,N1] 的情况,应该如何写出相应的矩阵形式呢?我们将 ( 3 ) (3) (3) 式左边的系数写成 m + N 2 m+\frac{N}{2} m+2N,这样一来, m m m 的取值依然是 [ 0 , N 2 − 1 ] [0, \frac{N}{2}-1] [0,2N1]。于是就有:

F f [ m + N 2 ] ‾ = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N 2 , − n ( m + N 2 ) ] + ω ‾ [ N , − ( m + N 2 ) ] ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N 2 , − n ( m + N 2 ) ] = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N 2 , − n m ] ω ‾ [ N 2 , − n N 2 ] + ω ‾ [ N , − m ] ω ‾ [ N , − N 2 ] ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N 2 , − n m ] ω ‾ [ N 2 , − n N 2 ] (5) \begin{aligned} \underline{\mathscr{F}f[m+\frac{N}{2}]} & = \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[\frac{N}{2}, -n \left(m+\frac{N}{2}\right) ] \\ & +\underline{\omega}[N, -\left(m+\frac{N}{2}\right)] \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[\frac{N}{2}, -n\left(m+\frac{N}{2}\right)] \\ & = \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[\frac{N}{2}, -nm ] \underline{\omega}[\frac{N}{2}, -n \frac{N}{2}]\\ &+\underline{\omega}[N, -m] \underline{\omega}[N, -\frac{N}{2}] \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[\frac{N}{2}, -nm] \underline{\omega}[\frac{N}{2}, -n\frac{N}{2}] \tag5 \end{aligned} Ff[m+2N]=n=02N1f[2n]ω[2N,n(m+2N)]+ω[N,(m+2N)]n=02N1f[2n+1]ω[2N,n(m+2N)]=n=02N1f[2n]ω[2N,nm]ω[2N,n2N]+ω[N,m]ω[N,2N]n=02N1f[2n+1]ω[2N,nm]ω[2N,n2N](5)

注意到,

ω ‾ [ N 2 , − n N 2 ] = e − 2 π i n = 1 \underline{\omega}[\frac{N}{2}, -n\frac{N}{2}] = e^{-2\pi in} = 1 ω[2N,n2N]=e2πin=1

ω ‾ [ N , − N 2 ] = e − π i = − 1 \underline{\omega}[N, -\frac{N}{2}] = e^{-\pi i} = -1 ω[N,2N]=eπi=1

带入 ( 5 ) (5) (5) 式,有:

F f [ m + N 2 ] ‾ = ∑ n = 0 N 2 − 1 f [ 2 n ] ‾ ω ‾ [ N 2 , − n m ] − ω ‾ [ N , − m ] ∑ n = 0 N 2 − 1 f [ 2 n + 1 ] ‾ ω ‾ [ N 2 , − n m ] \underline{\mathscr{F}f[m+\frac{N}{2}]} = \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n]} \underline{\omega}[\frac{N}{2}, -nm ] - \underline{\omega}[N, -m] \sum_{n=0}^{\frac{N}{2}-1} \underline{f[2n+1]} \underline{\omega}[\frac{N}{2}, -nm] Ff[m+2N]=n=02N1f[2n]ω[2N,nm]ω[N,m]n=02N1f[2n+1]ω[2N,nm]

写成矩阵的形式,即

F ‾ N f [ m + N 2 ] ‾ = F N 2 f e v e n [ m ] ‾ − ω ‾ [ N , − m ] F N 2 f o d d [ m ] ‾ (6) \underline\mathscr{F}_N \underline{f[m+\frac{N}{2}]} = \underline{\mathscr{F}_{\frac{N}{2}}f_{even}[m]} - \underline{\omega}[N, -m]\underline{\mathscr{F}_{\frac{N}{2}}f_{odd}[m]} \tag6 FNf[m+2N]=F2Nfeven[m]ω[N,m]F2Nfodd[m](6)

结合 ( 4 ) (4) (4) ( 6 ) (6) (6) 两式,我们可以得到FFT的矩阵递归式:

F ‾ N f [ m ] ‾ = F N 2 f even [ m ] ‾ + ω ‾ [ N , − m ] F N 2 f odd [ m ] ‾ \huge\underline\mathscr{F}_N \underline{f[m]} = \underline{\mathscr{F}_{\frac{N}{2}}f_\text{even}[m]} + \underline{\omega}[N, -m]\underline{\mathscr{F}_{\frac{N}{2}}f_\text{odd}[m]} FNf[m]=F2Nfeven[m]+ω[N,m]F2Nfodd[m]

F ‾ N f [ m + N 2 ] ‾ = F N 2 f e v e n [ m ] ‾ − ω ‾ [ N , − m ] F N 2 f odd [ m ] ‾ \huge\underline\mathscr{F}_N \underline{f[m+\frac{N}{2}]} = \underline{\mathscr{F}_{\frac{N}{2}}f_{even}[m]} - \underline{\omega}[N, -m]\underline{\mathscr{F}_{\frac{N}{2}}f_\text{odd}[m]} FNf[m+2N]=F2Nfeven[m]ω[N,m]F2Nfodd[m]

其中 m ∈ [ 0 , N 2 − 1 ] m\in [0, \frac{N}{2}-1] m[0,2N1],第一个等式为前 N 2 \frac{N}{2} 2N 项,第二个等式为后 N 2 \frac{N}{2} 2N

这个式子很明确地告诉我们:

FFT实际上就是将DFT的矩阵,通过一定的方式进行拆分,从而降低时间复杂度的一种算法


FFT的时间复杂度

有了递归式,我们就可以来算时间复杂度。

方便起见,我们将矩阵写成 [ n × m ] \left[ n \times m \right] [n×m],其中 n n n m m m 分别表示行列数。并设 N = 2 k N = 2^k N=2k

  1. 那么前 N 2 \frac{N}{2} 2N 项就可以写成

[ N 2 × N 2 ] + C N [ N 2 × N 2 ] \left[ \frac{N}{2} \times \frac{N}{2} \right] + C_N \left[ \frac{N}{2} \times \frac{N}{2} \right] [2N×2N]+CN[2N×2N]

其中 C N C_N CN 为一常数,该式花费的时间为 o ( [ N 2 × N 2 ] ) + 1 + o ( [ N 2 × N 2 ] ) o\left( \left[ \frac{N}{2} \times \frac{N}{2} \right] \right) + 1 + o\left( \left[ \frac{N}{2} \times \frac{N}{2} \right] \right) o([2N×2N])+1+o([2N×2N]),其中 1 1 1 就是常数相乘的操作

对于后 N 2 \frac{N}{2} 2N 项,由于对应的矩阵、常数都是相同的,因此只需要额外进行 1 1 1 次操作即可

  1. 我们把 n × n n \times n n×n 的矩阵记为 [ n ] [n] [n],并把 m m m 个不同的常数相乘记为 C m C^m Cm,则如下图

[EE261学习笔记] 15.快速傅里叶变换(FFT)原理_第1张图片

注意图中 1 + 2 ⋯ + 2 k − 1 1+2 \dots + 2^{k-1} 1+2+2k1 是前文提到的后 N 2 \frac{N}{2} 2N 项的计算量,需要进行累加计算。到最后一项时,它的累积值为 2 n − 1 2^n-1 2n1

不难发现,递归至最后一项时,总计算次数应为(图中最后一行以及虚线框内):

0 ⋅ ( 0 k ) + 1 ⋅ ( 1 k ) + ⋯ + k ⋅ ( k k ) + ( 2 k ) + ( 2 k − 1 ) + ( 2 k ) (7) 0\cdot\binom{0}{k} + 1\cdot\binom{1}{k} + \dots + k\cdot \binom{k}{k} + (2^k) + (2^k-1) +(2^k)\tag7 0(k0)+1(k1)++k(kk)+(2k)+(2k1)+(2k)(7)

简单解释一下上式

  • 前面的各项排列组合表示的是各个常数 C x C^x Cx 所需的计算时间,如系数 C k C^k Ck 只在最后一个一阶矩阵前出现,计算量为 k ⋅ ( k k ) = k k\cdot \binom{k}{k}=k k(kk)=k 次,又如系数 C 1 C^1 C1 必然会出现 ( 1 k ) \binom{1}{k} (k1) 次,因此计算量为 1 ⋅ ( 1 k ) = k 1\cdot \binom{1}{k}=k 1(k1)=k
  • 第一个 2 n 2^n 2n 表示的是所有 1 1 1 阶矩阵的计算时间总和;
  • 2 n − 1 2^n-1 2n1 表示的是后 N 2 \frac{N}{2} 2N 项的计算量;
  • 第二个 2 n 2^n 2n 表示的是计算所有加号花费的时间

( 7 ) (7) (7) 式不容易计算,但是我们可以直观地估计一下,对于前面的阶乘项,最多用时为 k k k 次,最少为 1 1 1 次,那么不严格地估计一下,我们取平均 k + 1 2 \frac{k+1}{2} 2k+1 次,这样共需要计算 N N N 次(有 N N N [ 1 ] [1] [1]),因此时间复杂度应为:

o ( ( N k 2 ) + 3 N − 1 ) = o ( 1 2 N log ⁡ 2 N + 3 N − 1 ) = o ( N log ⁡ 2 N ) o\left( \left( N\frac{k}{2} \right) +3N-1 \right) = o\left( \frac{1}{2} N \log _2 N +3N-1 \right) = o\left( N \log _2 N \right) o((N2k)+3N1)=o(21Nlog2N+3N1)=o(Nlog2N)

因此,FFT的时间复杂度就是

o ( N lg ⁡ N ) o\left( N \lg N \right) o(NlgN)

你可能感兴趣的:(学习笔记-傅里叶变换,FFT,快速傅里叶变换,快速傅里叶变换原理)