本文参考文献:
Polynomial Multiplication (Vector Convolution) and FFT
前言
通常两个多项式相乘所需的时间复杂度是 Θ(n^2),使用FFT算法可以将多项式乘法的时间复杂度降为。
1.多项式表示方法
这节介绍两种表示多项式的方法:系数表达和点值表达。
1.3.1. 系数表达
对一个次数界为 n 的多项式 而言,其系数表达是一个由系数组成的向量 。
采用系数表达对于多项式的某些运算是很方便的。例如,对多项式 f(x) 在给定点的求值运算就是计算 的值。使用霍纳法则,我们可以在 Θ(n) (n-1次乘法和n-1次加法)时间复杂度内完成求值运算:
1.3.1.1多项式的运算
假设有多项式f(x)和g(x):
的系数是 ,
的系数是 ,
1.加法运算:
在系数表示形式下,求两个多项式的加法是很容易的。
令,假设的系数是 ,显然有
因此计算的计算复杂度是 Θ(n) 。
2.乘法运算
令,则,
因此计算复杂度是 Θ(n^2) (需要进行次乘法)
本文的主要目标就是 讨论如何降低多项式乘法的时间复杂度。
1.3.2. 点值表达
一个次数界为 n 的多项式 f(x) 的点值表达就是一个由 n 个不同的点值对组成的集合:
, 其中,且各不相同。
1.3.2.1 点值表达式的运算
假设已知f(x)的n-1个点:
假设已知g(x)的n-1个点:
由霍纳法则知,求多项式的一个点需要的时间是n,则求n个点需要的时间是n*n,即时间复杂度是
1.加法运算:
令,则的n个点为:
计算的计算复杂度是 Θ(n) 。
2.乘法运算
令,
由于h(x)的次数是n-2,因此f(x)和g(x)需要各选取2n-1个点,
假设已知f(x)的2n-1个点:
假设已知g(x)的2n-1个点:
则h(x)的点值表达为:
计算h(x)计算复杂度是 Θ(n) 。
1.3.3. 系数表达和点值表达的相互转换
- 从系数表示法转为点值表示法称为 求值(Evaluation)。
- 从点值表示法转为系数表示法称为 插值(Interpolation)。
1.3.3.1 求值法
左侧矩阵就是著名的 范德蒙德矩阵。
当 m=n时为范德蒙德方阵,互不相同时其逆存在,帮助我们快速从点值表示法转回系数表示法。m>n时任取 xi 互不相同的 n+1 行可以求逆。m<n 时无法还原系数。这体现出 n+1个点值唯一确定最高次数不超过 n 的多项式。
朴素计算求值的复杂度为 O(nm),因为带入求值一次的复杂度为 O(n)。快速傅里叶变换即在离散傅里叶变换基础上通过选取合适的 xi,使得可以快速求值。
1.3.3.2拉格朗日插值法
从一个多项式的“点值表达”确定其“系数表达”形式称为“插值”。目前最常使用的插值方法即为拉格朗日插值法。
假设已知f(x)的n-1个点:。则根据拉格朗日插值定理知,f(x)的多项式如下:
扩展:
我们称为拉格朗日基,其特点是:
当且仅当时,值为1,为其他值时,值为0。
我们可以用这一性质对多项式进行约束。
假设某个多项式a(x)在处的值是,则要求a(x)满足下面等式:
,对于任意成立
1.3.4 总结
根据上面分析,可以发现两种形式的多项式乘法,算法复杂度均为。
可以看出点值表示法的大部分计算时间在于求值和插值方法。如果这两部分可以提速,那么点值法的计算复杂度变可以降低。
很幸运,我们通过在特殊点对多项式进行取值,可以将求值和插值部分,分别使用FFT和IFFT运算,从而将计算复杂度变降为。
2.单位根
由于FFT会用到单位根,因此在介绍FFT之前,先介绍一下单位根。
如果,则g成为n次单位根。本定义通常用于复数域和有限域。
下面的介绍均为复数域范畴。
欧拉公式:.
(cos为点在x轴上的坐标,sin为点在y轴上的坐标)
即单位圆上从 (1,0)开始旋转 x度得到的复数。
由于.
故有
故是n次单位根,可记为。另外均为n次单位根。
由于,
故
故单位根有如下性质:
3.FFT
3.1 DFT
在介绍 FFT 之前,我们先给出离散傅里叶变换(Discrete Fourier Transform,DFT)的概念。
DFT 在工程中是将离散信号从时域转为频域的过程。碰巧的是,其表达式刚好可以用来对多项式进行多点求值,只不过这些点值是固定的 单位根 处的点值,但对于求值做多项式乘法已经足够了。
DFT即为对f(x)在n个n次单位根处求值。如下:
设,
则
3.2 FFT算法详解
3.2.1 简化情况
首先我们得搞清楚,DFT 是一个变换,而 FFT 是用于实现 DFT 的算法。
FFT的巧妙之处在于通过将函数拆分为奇函数和偶函数,将函数的次数降低了,如此可以迭代次,最终将算法复杂度降低到
下面将具体讲解这个过程。
任意多项式f(x)可以拆分为偶函数和奇函数之和,则:
和的系数均n/2个,次数也为n/2,分别计算和在n/2个点处的值,就可以得到f(x)在n个点上的取值(因为可以同时计算出f(x)和f(-x)两个点)。
因此对于这两个多项式中的任意一个求一个点的复杂度为,求n/2个点的复杂度是。则对2个多项式均求n/2个点的复杂度是。
3.2.2 引入单位根
上面的式子拆分奇偶可以一直迭代的关键是,每次迭代都要找到互为相反数的两个x坐标。但是每次迭代,新的变量u都是原变量x的平方,在实数域中,平方是没有复数的。
由于单位根始终有如下性质:,
故始终有互为相反数的一组数据存在,所以此时可以引入单位复根。
因此,FFT的范德蒙方阵如下:
3.2.3 递归公式
3.2.3 蝴蝶变换
递归处理比较慢,我们希望像位运算卷积一样通过递推实现整个过程。具体方法为蝴蝶变换,此处不具体介绍,可参考多项式 I:拉格朗日插值与快速傅里叶变换 - 洛谷专栏 的4.3.4
3.3 IFFT
从点值变为多项式形式时,可以使用IFFT。
已知FFT的范德蒙方阵为:
只需要计算即可:
则多项式系数为:
同样使用上述迭代拆分奇偶项的方式,在时间范围内完成。
参考文献: