FFT算法的优化——提高FFT算法一倍的时空效率

前言

由于本人学习FFT时第一份代码并不是从普通的FFT学起的,而是直接从一个经过优化的版本开始学。

这是一个利用到共轭复数性质的优化,出自myy的论文,但在网上缺乏关于这个优化的文章,有写的都是大神,没有很细致的讲解。因此我决定自己总结一下。

本文是在默认读者了解并掌握了FFT算法的情况下写的。没有学过FFT的同学可以先去学一下。

FFT的基本运算

ω N \omega_N ωN 表示 e 2 π i N e^{\frac {2\pi i} {N}} eN2πi
对于给定的多项式函数

f ( x ) = ∑ i = 0 n a i x i f(x)=\sum_{i=0}^{n}a_ix^i f(x)=i=0naixi

X X X f f f D F T DFT DFT ,则有

X i = ∑ j = 0 N − 1 a j ω N i j , a i = 1 N ∑ j = 0 N − 1 X j ω N − i j X_i=\sum_{j=0}^{N-1}a_j \omega_{N}^{ij},a_i=\frac{1}{N}\sum_{j=0}^{N-1}X_j \omega_{N}^{-ij} Xi=j=0N1ajωNij,ai=N1j=0N1XjωNij

以及我们知道的卷积定理

D F T ( f ⋅ g ) = D F T ( f ) ⋅ D F T ( g ) DFT(f\cdot g)=DFT(f)\cdot DFT(g) DFT(fg)=DFT(f)DFT(g) D F T ( f + g ) = D F T ( f ) + D F T ( g ) DFT(f+g)=DFT(f)+DFT(g) DFT(f+g)=DFT(f)+DFT(g)

还有各种各样的复数运算法则,都是本文的前置技能。
其中复数运算法则中有一条性质:
z 1 z 2 ‾ = z ˉ 1 ⋅ z ˉ 2 \overline {z_1z_2}=\bar z_1 \cdot \bar z_2 z1z2=zˉ1zˉ2
其中 a ˉ \bar a aˉ 表示 a a a 的共轭复数。
这是我们优化FFT算法需要用到的重要性质。

如何优化?

考虑到 D F T DFT DFT 的对称性,我们来比较一下 X i X_i Xi 以及 X N − i X_{N-i} XNi

X i = ∑ j = 0 N − 1 a j ω N i j X_i=\sum_{j=0}^{N-1}a_j \omega_{N}^{ij} Xi=j=0N1ajωNij X N − i = ∑ j = 0 N − 1 a j ω N ( N − i ) j = ∑ j = 0 N − 1 a j ω N − i j = X i ‾ X_{N-i}=\sum_{j=0}^{N-1}a_j \omega_{N}^{(N-i)j}=\sum_{j=0}^{N-1}a_j \omega_{N}^{-ij}=\overline {X_i} XNi=j=0N1ajωN(Ni)j=j=0N1ajωNij=Xi

咦??求出 X i X_i Xi 就知道 X N − i X_{N-i} XNi 了?那用 N N N 的长度做岂不是很浪费??
为什么 X n − i = X i X_{n-i}=X_i Xni=Xi 呢?实际上这是由于我们的多项式函数的系数并没有虚部造成的。我们换一个系数有虚部的函数看看。

f ( x ) = ∑ i = 0 n ( a i + i b i ) x i f(x)=\sum_{i=0}^{n}(a_i+ib_i)x^i f(x)=i=0n(ai+ibi)xi

这里可能变量名重了= =,考虑到惯用的表达方式,我们约定此文以下部分中上下标的 i i i 表示变量,其余位置表示虚数单位。

X i = ∑ j = 0 N − 1 ( a j + i b j ) ω N i j X_i=\sum_{j=0}^{N-1}(a_j+ib_j)\omega_{N}^{ij}

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值