快速傅里叶变换——FFT学习小记

问题

  • 给定两个一元多项式,快速求解它们的笛卡尔积。可以简单理解为多项式乘法。
  • 叙述算法前,先允许我介绍一下多项式。(不是你小学学的那种简单的

多项式

  • 对于多项式 A ( x ) = 2 x 3 5 x 2 + x 4 ,其次数界为4(最高次项的指数+1)。
  • 一个次数界为N的多项式可以记作: A ( x ) = j = 0 n 1 a j x j
  • 其中a为系数。

  • 回到多项式乘法。
  • 记多项式A(x)与B(x)的乘积为:C(x)=A(x)B(x),则C的次数界为A与B的次数界的和-1。
  • C(x)系数计算方法: c i = j = 0 i a j b i j
  • 朴素方法时间复杂度为 O ( n 2 )

点值

  • 对于一个多项式A(x),将x代入具体数值并求解出多项式的值y,则数对(x,y)为该多项式的点值对
  • 一个次数界为n的多项式的点值表达就是由n个点值对组成的集合:
    { ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n 1 , y n 1 ) }
  • 其中x互不相同。

插值

  • 插值运算点值运算的逆运算。
  • 假设我们得到了一个有n个点值对的点值表达,那我们可以确定唯一的一个次数界为n的多项式。

多项式乘法

  • 考虑使用点值与插值来完成多项式乘法。
  • 可以确定一组x,求得A与B的点值表达:
    A : { ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n 1 , y n 1 ) }
    B : { ( x 0 , y 0 ) , ( x 1 , y 1 ) , . . . , ( x n 1 , y n 1 ) }
  • 我们可以得到C的点值表达:
    C : { ( x 0 , y 0 y 0 ) , ( x 1 , y 1 y 1 ) , . . . , ( x n 1 , y n 1 y n 1 ) }
  • 注意:若A和B的次数界均为n,则C的次数界为2n-1。所以我们要找出2n-1个x来求点值表达,否则无法插值。

算法流程

  • 点值运算:分别构造A和B长度为2n-1的点值表达。
  • 逐点相乘:计算出C的点值表达。
  • 插值运算:通过C的点值表达求C每一项的系数。
  • 显然,若随便选2n-1个数,按照上述方法进行点值运算、插值运算,时间复杂度依然是 O ( n 2 ) 。而FFT的关键就在于优化点值运算、插值运算的时间。

复数

  • 复数应该妇孺皆知吧。复数z=a+bi的模长 l = a 2 + b 2 ,记作|z|。
    这里写图片描述
  • 如图,当Z不是原点时,其与x轴正方向的夹角称为复数Z的辐角,记作ArgZ。
  • Z可以表示成: Z = | Z | ( c o s ( ϕ ) + i s i n ( ϕ ) ) , p h i = A r g Z
  • 上述表示负数的形式我们称为复数的三角表示
    这里写图片描述
  • 由上图可得两个复数相乘的法则:模长相乘,辐角相加

N次单位复数根

这里写图片描述

  • 说句人话:解有n个,第j个解 x j = c o s 2 π j n + i s i n 2 π j n
  • 考虑证明一波。
  • 根据上述的三角表示,易知 x j 的模长为1,辐角为 2 π j n 。根据复数相乘的法则,n个 x j 相乘,模长依旧为1,辐角变为 2 π j ,而 c o s ( 2 π j ) = 1 , s i n ( 2 π j ) = 0 ,于是结果为 1 + i 0 = 1
  • 下图说明n次单位复数根均匀地分布在以复平面的原点为圆心的单位半径的圆周上。
    这里写图片描述
  • 我们称 ω n = ω n 1 主N次单位根
  • 注意到N次单位根均由主N次单位根顺时针旋转一定角度得到,且 ω n i = ω n i 1 ω n 。因此,N次单位根可视为公比为主N次单位根的等比数列。所以 ω n i + j = ω n i ω n j 。由此可推出下列三个引理:
  • 1.消去引理: ω d n d i = ω n i
  • 2.折半引理:如果n>0为偶数,那么n次单位复数根的平方的集合就是n/2次单位复数根的集合。
  • 3.求和引理: 对于n不整除k,有:
    j = 0 n 1 ( ω n k ) j = ( ω n k ) n 1 ω n k 1 = ( ω n n ) k 1 ω n k 1 = 1 k 1 ω n k 1 = 0
  • 对于n|k,显然有: j = 0 n 1 ( ω n k ) j = j = 0 n 1 1 j = n

DFT——离散傅里叶变换

  • 将A(x)中的x代入N次单位复数根(共N个),并定义结果y: y k = A ( ω n k ) = j = 0 n 1 a j ω n k j
  • y即为a的离散傅里叶变换(DFT)。记 y = D F T n ( a )

分治策略

  • 考虑对于单个数x,快速求出函数值A(x)。
  • 定义两个新的多项式:
    A 0 ( x ) = a 0 + a 2 x + a 4 x 2 + . . . + a n 2 x n 2 1
    A 1 ( x ) = a 1 + a 3 x + a 5 x 2 + . . . + a n 1 x n 2 1
  • 显然,它们的次数界都变为 n 2 (减了半),且有 y = A ( x ) = A 0 ( x 2 ) + x A 1 ( x 2 )

猜你喜欢

转载自blog.csdn.net/qq_36551189/article/details/81544620