快速傅里叶变换(FTT)计算多项式乘法

1.多项式运算

设 A ( x ) = a 0 + a 1 x + a 2 x 2 + ⋯ + a n − 1 x n − 1 B ( x ) = b 0 + b 1 x + b 2 x 2 + ⋯ + b n − 1 x n − 1 设A(x) = a_0+a_1x+a_2x^2+\dots+a_{n-1}x^{n-1}\\ B(x) = b_0+b_1x+b_2x^2+\dots+b_{n-1}x^{n-1}\\ A(x)=a0+a1x+a2x2++an1xn1B(x)=b0+b1x+b2x2++bn1xn1

  • 加法
    A ( x ) + B ( x ) = ( a 0 + b 0 ) + ( a 1 + b 1 ) x + ⋯ + ( a n − 1 + b n − 1 ) x x − 1 A(x)+B(x) = \\(a_0+b_0)+(a_1+b_1)x+\dots+(a_{n-1}+b{n-1})x^{x-1} A(x)+B(x)=(a0+b0)+(a1+b1)x++(an1+bn1)xx1

  • 求值

    • 普通算法 复杂度为 O ( n 2 ) O(n^2) O(n2)

    • 霍尔算法(秦九韶算法) 复杂度为 O ( n ) O(n) O(n)
      A 1 ( x ) = a n − 1 A 2 ( x ) = a n − 2 + x A 1 ( x ) = a n − 2 + a n − 1 x A 3 ( x ) = a n − 3 + x A 3 ( x ) = a n − 3 + a n − 2 x + a n − 2 x 2 … A n ( x ) = a 0 + x A n − 1 ( x ) = A ( x ) A_1(x) = a_{n-1}\\ A_2(x) = a_{n-2}+xA_1(x) = a_{n-2}+a_{n-1}x\\ A_3(x) = a_{n-3}+xA_3(x) = a_{n-3}+a_{n-2}x+a_{n-2}x^2\\ \dots\\ A_n(x) = a_0+xA_{n-1}(x) =A(x) A1(x)=an1A2(x)=an2+xA1(x)=an2+an1xA3(x)=an3+xA3(x)=an3+an2x+an2x2An(x)=a0+xAn1(x)=A(x)

  • 乘法
    C ( x ) = A ( x ) B ( x ) = ∑ k = 0 m + n − 2 c k x k 其中 c k = ∑ i + j = k a i b j C(x) = A(x)B(x) = \sum_{k=0}^{m+n-2}c_kx^k\\ 其中c_k = \sum_{i+j=k}a_ib_j\\ C(x)=A(x)B(x)=k=0m+n2ckxk其中ck=i+j=kaibj
    蛮力算法为 O ( n 2 ) O(n^2) O(n2)(以乘法为基本操作)

    用图形表示如下,在下述矩阵中,每个斜线的和恰好是乘法中的各个分量。

    pSJBNx1.jpg

2.多项式的点值表示法

  • 引理
    一个系数在复数域上的 n − 1 度的多项式有 n 个复数根 一个系数在复数域上的n-1度的多项式有n个复数根 一个系数在复数域上的n1度的多项式有n个复数根
    推论
    度数为 n − 1 的多项式 A ( x ) 由 n 个不同的 x 值唯一确定。 即 : n 个点确定一个 n − 1 次幂的多项式 度数为n-1的多项式A (x)由n个不同的x值唯一确定。\\ 即:n个点确定一个n-1次幂的多项式 度数为n1的多项式A(x)n个不同的x值唯一确定。:n个点确定一个n1次幂的多项式

  • 点值表示法
    A ( x ) = ( x 0 , y 0 ) , … , ( x n − 1 , y n − 1 ) B ( x ) = ( x 0 , z 0 ) , … , ( x n − 1 , z n − 1 ) A(x) = (x_0,y_0),\dots,(x_{n-1},y_{n-1})\\ B(x) = (x_0,z_0),\dots,(x_{n-1},z_{n-1})\\ A(x)=(x0,y0),,(xn1,yn1)B(x)=(x0,z0),,(xn1,zn1)

  • 点值表示法中的加法
    A ( x ) + B ( x ) : ( x 0 , y 0 + z 0 ) , … , ( x n − 1 , y n − 1 + z n − 1 ) A(x)+B(x) :(x_0,y_0+z_0),\dots,(x_{n-1},y_{n-1}+z_{n-1}) A(x)+B(x):(x0,y0+z0),,(xn1,yn1+zn1)

  • 点值表示法中的求值
    A ( x ) = ∑ k = 0 n − 1 y k ∏ j ≠ k ( x − x j ) ∏ j ≠ k ( x k − x j ) ( L a g r a n g e f o r m u l a ) A(x) = \sum_{k=0}^{n-1} y_k\frac{\prod_{j\neq k}(x-x_j)}{\prod_{j\neq k}(x_k-x_j)}(Lagrange formula)\\ A(x)=k=0n1ykj=k(xkxj)j=k(xxj)(Lagrangeformula)
    以乘法为基本运算,复杂度为 O ( n 2 ) O(n^2) O(n2)

  • 点值表示法中的乘法
    A ( x ) ∗ B ( x ) : ( x 0 , y 0 ∗ z 0 ) , … , ( x n − 1 , y n − 1 ∗ z n − 1 ) A(x)*B(x):(x_0,y_0*z_0),\dots,(x_{n-1},y_{n-1}*z_{n-1}) A(x)B(x):(x0,y0z0),,(xn1,yn1zn1)
    在点值表示法中,若以乘法为基本运算,则复杂度为 O ( n ) O(n) O(n),但是需要2n-1个点

3.粗略的系数表示和点值表示的转换

我们既想要快速的求值(O(n)),又想要快速的乘法(O(n))。能否在两种表示方法之间快速转换,借此满足要求。

  • 从系数表示到点值表示

    • 直接代值 -需要n个点,n次霍尔运算,复杂度为 O ( n 2 ) O(n^2) O(n2)

    • 矩阵计算 -复杂度同样为 O ( n 2 ) O(n^2) O(n2)

      pSwwECT.jpg

  • 从点值表示到系数表示 复杂度为 O ( n 3 ) O(n^3) O(n3)

    pSwwZ2F.jpg

4.从系数表示到点表示(利用分治算法求n个点的取值)

我们强调,利用分治算法不是为了在单个点上提高效率,单个点上霍尔算法已经最优,而是为了在n个点时提高效率。

  • 两种划分子问题方法

    • 按照幂次高低

      pS0eLPx.jpg

    • 按照奇偶幂次

      pS0e7Z9.jpg

  • 减少复杂度的方法

    简而易见,如果依然计算n个点,那么求值的复杂度不会有任何提高。如果能用n/2点代替n个点呢

    设 n 个点为 ± x 0 , … , ± x n − 1 则 A ( x i ) = A e v e n ( x i 2 ) + x i A o d d ( x i 2 ) A ( − x i ) = A e v e n ( x i 2 ) − x i A o d d ( x i 2 ) 设n个点为\pm x_0,\dots,\pm x_n-1\\ 则A(x_i) = A_{even}(x_i^2)+x_iA_{odd}(x_i^2)\\ A(-x_i)= A_{even}(x_i^2)-x_iA_{odd}(x_i^2) n个点为±x0,,±xn1A(xi)=Aeven(xi2)+xiAodd(xi2)A(xi)=Aeven(xi2)xiAodd(xi2)

    现在只需要计算n/2个点的 A e v e n ( x i 2 ) 、 A o d d ( x i 2 ) A_{even}(x_i^2)、A_{odd}(x_i^2) Aeven(xi2)Aodd(xi2)即可。

    但是, x 2 x^2 x2相等的技巧只在递归树的最顶层有效,无法形成递归。怎么样使得 x 0 2 , x 1 2 , x 2 2 . . x_0^2,x_1^2,x_2^2.. x02,x12,x22..也互为相反数呢?

    毫无疑问,我们需要复数。我们可以从底向上缔造满足条件的一个树,如下图

    pS0mLwj.png

    我们可以发现,第n层节点满足 x n = 1 x^n=1 xn=1。可以借助下面的定理来求解x的值
    若 ω n = 1 , 则 ω = e 2 π i / n = c o s 2 π n + i s i n 2 π n 推论 1 :若 n 为偶数,那么 n 个根互为相反数,即 ω n 2 + j = − ω j 推论 2 : 将 n 平方,产生 n / 2 个根,即 w 2 = e 4 π i / n = { v 0 , … , v n / 2 − 1 } 推论 3 : ω 1 0 = ω 0 , ω 1 k = ω k 若\omega^n=1,则\omega = e^{2\pi i/n} = cos\frac {2\pi}n+isin\frac{2\pi}n\\ 推论1:若n为偶数,那么n个根互为相反数,即\omega ^{\frac n2+j} = -\omega^{j}\\ 推论2:将n平方,产生n/2个根,即w^2 = e^{4\pi i/n} = \{v^0,\dots,v^{n/2-1}\}\\ 推论3:\omega_1^0 = \omega_0,\omega_1^k = \omega_k ωn=1,ω=e2πi/n=cosn2π+isinn2π推论1:若n为偶数,那么n个根互为相反数,即ω2n+j=ωj推论2:n平方,产生n/2个根,即w2=e4πi/n={v0,,vn/21}推论3:ω10=ω0,ω1k=ωk
    n = 2 k n=2^k n=2k,那么在递归的第i层,我们有 n / 2 i n/2^i n/2i个节点,由于 n / 2 i n/2^i n/2i恒为偶数,由上述"推论1"可知,这 n / 2 i n/2^i n/2i个节点互为相反数。

    以n=8为例,8个根的分布如下图。

    pS0u0xK.png

    因此,若 n = 2 k n=2^k n=2k,在递归树的每一层,节点之间两两都互为相反数。递归得以进行。

    那么有
    T ( n ) = T ( n 2 ) + O ( n ) T ( n ) = Θ ( n log ⁡ n ) T(n) = T(\frac n2)+O(n)\\ T(n) = \Theta(n\log n) T(n)=T(2n)+O(n)T(n)=Θ(nlogn)
    至此,我们将求n个点的值的复杂度从 O ( n 2 ) O(n^2) O(n2)降到了 O ( n log ⁡ n ) O(n\log n) O(nlogn)

5.FFT伪代码

思路如“4”中所说

  • 算法:FFT(A,n, ω \omega ω)

  • 输入:n为2的幂。n-1阶多项式A,n个根 ω i \omega^i ωi,其中 ω i = e 2 π i / n \omega^i = e^{2\pi i/n} ωi=e2πi/n

  • 输出: A ( ω i ) , i ∈ [ 0 , n − 1 ] A(\omega ^i),i\in[0,n-1] A(ωi),i[0,n1]

  • 伪代码

    1. if n=1 then return a_0
    2.express A(x) = A_even(x^2)+x*A_odd(x^2)
    3.FFT(A_even,n/2,w^2)
    4.FFT(A_odd,n/2,w^2)
    5.for j=0 to n-1 do
    6.	A(w^j) = A_even(w^2j)+w_j*A_odd(w^2j)
    7.return A(w^0)..A(w^n-1)
    
  • 复杂度如‘4’中的分析

有了FFT算法,我们可以以 Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn)的复杂度将多项式的系数表示法转换为点表示法。

6.从点表示到系数表示(逆FFT)

  • 傅里叶矩阵

    • 正向矩阵

      如下图, a i a_i ai代表多项式的系数。利用该矩阵,可以求出n个( ω i , y i \omega _i,y_i ωi,yi)点对。(DFT算法)

      pS0lAWn.png

    • 逆矩阵

      给定n个点对,通过下述矩阵可以求出多项式的系数

      pS0lmLT.png

    • 解逆矩阵

      将傅里叶逆矩阵化为 F n ( ω ) F_n(\omega) Fn(ω)的形式(根据“4”中的推论3得出),并求出 F n ( ω ) F_n(\omega) Fn(ω)的逆,如下图

      pS0lMo4.png

      我们有 1 n F n ( ω − 1 ) = F n ( ω ) − 1 \frac 1n F_n(\omega^{-1}) =F_n(\omega)^{-1} n1Fn(ω1)=Fn(ω)1。其中 w − 1 = e − 2 π i / n w^{-1} = e^{-2\pi i/n} w1=e2πi/n

      因此

      pS0lR0S.png

  • 逆FFT算法

    若按照上述矩阵计算,那么复杂度仍为 O ( n 2 ) O(n^2) O(n2),因此,依然需要用到FFT。只需将 ω \omega ω换成 − ω -\omega ω,将 a i a_i ai的位置和 y i y_i yi的位置互换,即为逆FTT。可以用逆FFT实现从点表示到系数表示的转换,复杂度为 Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn)

    PS:因为 n = 2 k n=2^k n=2k,故n个根之间互为相反数。因此将 ω \omega ω换成 − ω -\omega ω之后,依然可以调用分治算法计算。

7.多项式乘法

  • 利用FFT和逆FFT,我们可以成功的把多项式乘法的复杂度降到 Θ ( n log ⁡ n ) \Theta(n\log n) Θ(nlogn),过程如下图。

    pS01EAe.png

8.多项式乘法的应用与扩展

  • 应用:可以应用在整数乘法中,可以将两个乘数转换为二进制多项式的形式(令x = 2,系数为0或1),即可利用FFT计算乘法
  • 扩展:FFT是在复数域上的运算,精度难免会有损失,有时我们需要在有限域上计算。那么当n|p-1时, ω n = 1 m o d p \omega ^n=1modp ωn=1modp有n个根。NTT算法:通过将离散傅里叶专门化到有限域F中得到。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值