网上关于FFT在信号处理中应用的文章并不少,这里尽量少说废话,直接说如何用FFT实现多项式乘法。
多项式乘法,通常是用系数乘积的方式完成,这样的时间复杂度是O(n^2) n为多项式项数。系数乘法可以满足大多数的乘法需求,然而当位数大于1000时,此法用起来就显得捉襟见肘
通过引入FFT,我们可以将这个复杂度降到O(nlogn)
基本概念
1.多项式的两种表示法
系数表示法:即平时看到的多项式:Σi=0~n-1 a[i]*(x^i)
点值表示法:一个最高次为n-1次的多项式f(x),可以表示为n个其图像上点(x,y),例如2x^2+3x+1可以表示为(0,1) (1,6) (2,15)
两种方法可以互相转换,而点值表示法下两多项式相乘是非常方便的,只要将同一个x对应的两式y值相乘,就是新多项式对应的点值,当然,所取点值数量需要与结果多项式相符,例如:
(x+1)*(2x+1) = 2x^2+3x+1
x+1 -> (0,1) (1,2) (2,3)
2x+1 -> (0,1) (1,3) (2,5)
{(0,1) (1,2) (2,3)}*{(0,1) (1,3) (2,5)} -> (0,1) (1,6) (2,15) -> 2x^2+3x+1
而两种表示法的转换就是DFT(离散傅里叶变换,Discrete Fourier Transform)和IDFT(逆离散傅里叶变换,Inversed Discrete Fourier Transform),但是基于实数的DFT和IDFT效率仍为n^2,在此不做累述
2.复根
既然实数不行,那么我们就用性质特殊的虚数。如果读者不知道虚数,也许问题也不大,把i当成一个具有特别性质的数学符号来理解吧
在本文中,我们定义n次复根为满足x^n=1的复数x,其中n为正整数。如4次复根有4个,分别是 1,i,-1,-i。
由欧拉公式
e^(ix)=(cos x+isin x),我们可以得到e^(2πi)=1。那么若k为整数,e^(2kπi/n)就是一个n次复根。为方便表述,我们定义w(n,k)=e^(2kπi/n)。通过欧拉公式,我们也可以将e的指数幂形式转化为我们熟知的a+bi形式(后文并不需要这个转化&#