快速傅里叶变换fft_快速傅里叶变换(FFT)求解多项式乘法

本篇笔记的目的是尽量通过简洁的方式说明FFT算法的过程,各种概念能不用就不用,也不涉及其物理意义,仅仅局限于算法这一块来讨论FFT

求解多项式乘法,那么首先明确,多项式是什么,例如下面一个多项式:

这是一个n-1次多项式(最高次项是

),
是它各项的系数,该多项式也可以写成以下形式:

不过无论是哪种形式,一个多项式都可以通过一组系数所确定,而这组系数所组成的向量也叫做系数向量(例如上面

的系数向量为:
),通过系数向量表示一个多项的方式也叫做
系数表示法

上面简单介绍一下多项式,接下来回到问题:多项式乘法。例如,已知两个多项式

,分别是n-1次多项式和m-1次多项式(n和m可以相等):

现在将这两个多项式相乘,得到一个最高n+m-1次多项式:

那么要求解

也就是求出它的
系数向量

问题是怎么求?如果直接遍历

的每一项去计算就太慢了,时间复杂度最好也是
,所以需要更快的算法,也就是下面要讨论的:快速傅里叶变换(FFT)算法

关于下面这一节介绍的概念,与FFT并没有直接的联系,可以顺带看一下就当是从不同的角度去理解,当然也可以直接跳过去


点值表示法

对于一个已知的多项式

,将
代进去可以得到一个确定的值
,如:
,并且,可以将
看作是坐标系上的一个点。进一步的,可以将任意多(互不相等)的自变量(
)代入到
中,从而得到更多的点:

我们知道,通过两个(不同的)点,可以解析一次多项式(如

),通过三个不同的点可以解析二次多项式(
),所以可以进一步的推出,通过n+1个不同的点,可以解析n次多项式

通过n+1个不同的点

,唯一确定一个n次多项式,该方式也叫做
多项式的点值表示法

在详细讨论FFT的具体步骤之前,先从整体上概括一下。FFT主要使用了两种数学方法,离散傅里叶变换(DFT)以及离散傅里叶变换逆变换(IDFT),公式如下:

(DFT)

(IDFT)

上面两个式子中

是虚数根(即
),关于这两个式子的证明这里就不展开了,可以参见附录

回到我们的问题,可以通过设置一些变量,将这两个公式代入到我们之前的问题中。首先,设

其中

,关于变量
的性质会在后面详细讨论,这里不展开,然后令

将这些变量代入到DFT的公式中,得到:

通过上式将DFT与我们的目标多项式

关联起来了,自然也就可以通过IDFT来计算多项式的系数

但是,由于不知道

的具体值(知道问题就解决了),所以也就无法使用DFT计算

不过,我们知道:

,而且多项式
的系数是已知的,所以可以“曲线救国”:

通过该式计算

,然后再使用IDFT计算
。以上是FFT的概括,下面详细的展开来讨论

N次单位根

为了更好的讨论

,还是先从
欧拉公式开始说起(很久很久以前,有一个……):

关于该公式的证明详见结尾附录,

是一个
复数,它 实部的值为
虚部的值为
,所以,
对应到
复数平面上的点与原点之间的距离恒为1,如下图所示:

28babdbaecb071cb1d39f92bed23820e.png

因为

周期函数(周期为
),所以可以得出:

并且,无论

取何值,
都是分布在复平面的
单位圆

07ec7182506dc4653d5f0a337450d7d0.png

由于是单位圆,所以

此时就等于是从1(起点)到
在圆上的
弧长

279b2300960ecbd9dd4aa30dc9962491.png

以上简要的介绍了欧拉公式,下面回到我们定义的变量:

,需要说明的一点就是,前面的概述中,为了简单起见,
没有加任何上下标,所以更清楚的表示会给
加一个下标:

从前面欧拉公式的讨论中可以知道,

,相当于在单位圆上绕了一圈又回到了起点,而
相当于是将这个单位圆分成了
n等分,而
就对应单位圆上第
等分点

c38f43850230f96dc198d12898de352c.png
n=18

上图是一个n=18的例子,并使用大红色标注了三个值

。通过前面的讨论以及这个栗子,应该对
有了一个比较直观的认识,说了这么多,应该能猜到N次单位根就是指的它了,关于N次单位根的就不展开了,下面介绍一下它的几个性质:

性质一:

性质二:

性质三:

上面的性质一叫做消去引理,性质二叫做折半引理,性质三。。。还没找到名字,希望知道的大佬能告诉一声。这些性质如果光看公式感觉不够直观的话,可以对照前面的那个图例来理解

计算

首先,定义

分别是多项式
的系数数量)。前面已经说过,无法直接使用DFT计算
,需要先计算

但是如果直接把

朴(cu)素(bao)的代进去的话,时间复杂度还是
,所以后面的计算再怎么快,也无法降低整个算法的复杂度了,因此,需要使用一些方法,来降低计算
的时间花费

先来看一个栗子,假设有这样一个多项式:

我们可以将它的奇数项与偶数项分开,并化简为下面的形式:

并且

还可以递归的计算下去,将该方法用到
上就是:

这样时间复杂度就变成了:

除此之外,还可以利用前面讨论的单位根的性质来降低计算量,例如,

这样,仅仅计算

一半的取值范围就可以得到其整个取值范围的结果,这样,将
计算完毕之后,就可以通过简单的乘法来计算

求解

系数

计算到这一步基本已经完成一大半了,只需要使用IDFT公式来求解

的各项系数就可以了:

上面式子中

。另外,为了表示更方便,同时也为了代码的复用,通常还会再构建一个N-1次多项式
,它的系数就是各个
的值:

所以,最终

的计算公式可以写成:

上式第二步使用了单位根的性质三,并且特别的交代一下:

总结

  1. 取N个单位根:
  2. 将它们分别代入到多项式
  3. 计算
  4. 构造一个新的多项式
  5. 计算
  6. 计算多项式
    的系数

附录

  • 欧拉公式证明

首先,构造一个函数

, 然后,对该函数求导:

一个函数的导数为0,说明这个函数是一个常数函数,所以随便代一个

的值(例如0)进去就可以解析该函数:

以上是使用求导的证明方法,简单直接,还有一种方法是使用了

麦克劳林公式来证明的,下面简单的贴一下公式:

  • DFT与IDFT的证明

首先,还是令

(上面为了方便
并没有加下标
,这里加上以便下面证明的可读性),然后离散傅里叶公(逆)变换式:

为了证明(1)(2)式成立,接下来把它们写成矩阵形式:

其中

的矩阵,同样(2)式:

结合(3)(4),可以得到:

(5)式说明只要

(N阶单位矩阵),(1)(2)式就成立,下面来证明这里一点

,有

(即
)时,显然这是一个等比数列,由等比数列求和公式得到:

而当

(即
)时:

综合(7)(8)得到:

(1)(2)式成立,证毕

参考资料:

[1] 算法设计与分析(北京大学)

[2] 从多项式乘法到快速傅里叶变换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值