傅里叶变换
一个欠了一年的帐,今天终于还上了
我根本不知道录音的基本原理
内求解多项式乘法
算法导论上的傅里叶变换,是为了在
如果直接让两个多项式卷积,那么朴素方法复杂度显然是
如何降复杂度呢?使用点值计算
线性代数上可以证明,一个n-1次多项式,可以在其图像上使用n个点唯一确定(插值方法)
也就是说,一个多项式
那么两个均为
显然从一个
其中第i个点
画在图上也就是:
普通乘法是我们之前使用的lowB方法,下面曲线救国nb,就求值和插值这两步是真nb,求值和插值为何是

使用之前学过的方法,这两步都是
求值时需要将
插值时需要使用拉格朗日插值法,也是
拉格朗日插值公式:
其中 是多项式 的点值表示 最外层这个求和已经是
用二维数组
预处理分母, 分子预先先直接求出
那么对于一个给定的k,分母就是n个数的积,
分子就是
, 乘上最外圈的
得到 也就是说,之前使用的方法是
的
但是使用快速傅里叶变换这种吊法,就能给他降到
怎么降的?选点值的时候有讲究
任意n个不同的点就可以确定一个n-1次表达式.
如果选n个单位复根,然后对系数向量
单位复根儿
"n次单位复根"就是指满足
欧拉公式
显然
n次单位复根儿恰好有n个,也就是
这n个画在复平面儿上是很整齐的,比如8次复根就长这样:
任何两个相邻的单位复根之间的角度都是固定的,

都落在复平面单位元上
显然8次复根只有8个,如果非要写第九个
然后书上就说这是加法群
DFT
求n-1次多项式的点值表示时,就需要选取n个点
如果选取的n个点是n个富哥儿,那么此时有
记作
笑死,这看上去不就是带入求值吗,选n个富哥有屁用啊?
如果用普通的带入求值,找n个富哥儿和找n个普通人儿没有区别.
富哥儿的作用不能浪费喽,他们和普通值又有啥区别呢?
这就是单位复根儿的几个性质
这几个性质在计算时会体现群论的对称性,这意味着,这n个富哥确实能够比n个普通值携带更多的信息
FFT
fast Fourier transform,快速傅里叶变换
在
也就是说,DFT并不是一个求解方法,只是娶了n个富哥作为点值表示
仍然可以使用带入求值这种
而FFT就是一种吊法
他这样变形:
首先n向上取整到最近的2的幂次,这样做是为了保证能够一直二分直到剩1项,反正多取点不会降低精度
后面的n默认就认为是2的幂次了
我们现在已知的是
要求的是
现在可以这样算了:
而现在对于一个
以此递归,总会有个时候,
写出伪代码:
注意FFT函数的输入是目标多项式的系数向量,不是富哥,因为富哥是作为常数使用的,不需要参数传递
FFT函数输出的是
一定注意函数不是y=A(x),而是y=FFT(a)
一定要清楚函数在干什么
1 | vector<int> FFT(vector<int> a){//a是系数,返回y向量 |
这里面有一个y[n/2+i]=y0[i]-pow(omega_n,i)*y1[i]
,怎么得到的呢?
从上面的伪代码可以看出,最底层的递归和自变量无关.
加速发生在这里,将工程量直接缩减到一半
1 | for(int i=0;i<n/2;i++){//一定注意此处上界是n/2 |
每次递归都将工程量缩减一半,因此总工程量直接对n取对数
好了到此FFT的思路有了,求值结束,也就是我们求得了
举个例子,
,正好有 项,n=4 4次单位复根
1
2
3
4
5
6
7
8
9
10
11
12
13
14 FFT(<1,2,1,1>){
n=<1,2,1,1>.length()=4;
a0=<1,1>;
a1=<2,1>;
w1;
y0=FFT(<1,1>){
n=<1,1>.length()=2;
a0=<1>;
a1=<1>;
y0=FFT(<1>)=<1>;
y1=FFT(<1>)=<1>;
y[0]=y[0]+w1
}
}
下面考虑如何从点值形式倒回去,也就是如何在
现在已知的是
显然可以待定系数法设n个系数,然后带入自变量和因变量,解一元n次方程组.
高斯消元法是
写成矩阵形式

也就是说,一眼顶针,鉴定为范德蒙矩阵,必然可逆且逆矩阵唯一
现在要用尽可能快的方法求解这个范德蒙矩阵
这有个定理
怎么得出来的,我线性代数忘了,不会解,但是
由于
共有n个
回忆正向的FFT是干啥的来着
是求解
其中
类比一下
令单位富哥变成单位负哥,就可以直接带入FFT函数求解了
解出来都除以n就得到了
因此又在
回到多项式求积
卷积定理:
对于两个长度为n的向量