多项式算法——快速傅里叶变换FFT

本文详细介绍了快速傅里叶变换(FFT)算法,包括多项式加法、乘法、系数表示和点值表示。重点讨论了DFT与FFT的概念,阐述了单位复数根的性质,以及FFT的分治策略和时间复杂度。此外,还提供了FFT的代码实现,并举例说明其在高精度乘法中的应用。

多项式算法——快速傅里叶变换FFT

两个多项式函数相加的时间复杂度为 O ( n ) O(n) O(n),而相乘的时间复杂度为 O ( n 2 ) O(n^2) O(n2),即所有系数的笛卡尔积。傅里叶变换DFT将优化多项式相乘(以下简称卷积),而快速傅里叶变换则优化至 O ( n log ⁡ n ) O(n \log n) O(nlogn)

前置知识:

  1. 微积分(欧拉公式)
  2. 复变函数(单位元根)
  3. 线性代数(矩阵方程)

多项式

本章定义的多项式函数为定义在实数域上,关于变量 x x x形如:

A ( x ) = ∑ j = 0 n − 1 a j x j A(x) = \sum_{j=0}^{n-1} a_j x^j A(x)=j=0n1ajxj

n n n次多项式, a j a_j aj为多项式的系数,如果多项式非零最高次数项的系数为 a k a_k ak,那么我们说 A ( x ) A(x) A(x)的次数为 k k k,记作 d e g r e e ( A ) = k degree(A)=k degree(A)=k

任何一个严格大于多项式 A ( x ) A(x) A(x)的次数的整数都是多项式 A ( x ) A(x) A(x)的一个次数界。

多项式加法

两个次数界为 n n n的多项式 A ( x ) A(x) A(x) B ( x ) B(x) B(x)的多项式相加,仍是一个次数界为 n n n的多项式 C ( x ) C(x) C(x),点值满足 C ( x ) = A ( x ) + B ( x ) C(x)=A(x)+B(x) C(x)=A(x)+B(x),且系数满足:

C ( x ) = ∑ j = 0 n − 1 ( a j + b j ) x j C(x) = \sum_{j=0}^{n-1} (a_j + b_j) x^j C(x)=j=0n1(aj+bj)xj

多项式乘法

两个次数界为 n n n的多项式 A ( x ) A(x) A(x) B ( x ) B(x) B(x)的多项式相乘,其结果是一个次数界为 2 n − 1 2n-1 2n1的多项式 C ( x ) C(x) C(x)。点值满足 C ( x ) = A ( x ) B ( x ) C(x)=A(x)B(x) C(x)=A(x)B(x),且系数满足:

C ( x ) = ∑ j = 0 2 n − 1 ∑ i = 0 j a i b j − i x j C(x) = \sum_{j=0}^{2n-1} \sum_{i=0}^ja_i b_{j-i} x^j C(x)=j=02n1i=0jaibjixj

也称卷积

多项式表示法

系数表示

对于一个次数为 n n n的多项式 A ( x ) = ∑ j = 0 n − 1 a j x j A(x) = \sum_{j=0}^{n-1} a_j x^j A(x)=j=0n1ajxj而言,其系数表示法是一组由系数组成的 n n n维列向量 a ⃗ = ( a 0 , a 1 , … , a n − 1 ) \vec{a} = (a_0,a_1,\ldots,a_{n-1}) a =(a0,a1,,an1)

对于给定的一个系数表示法的多项式,我们可以通过霍纳法则(秦九韶算法)在 O ( n ) O(n) O(n)时间内计算出点值 A ( x 0 ) A(x_0) A(x0),即:

A ( x 0 ) = a 0 + x 0 ( a 1 + x 0 ( a 2 + … + x 0 ( a n − 1 ) ) … ) ) A(x_0) = a_0 + x_0 (a_1 +x_0(a_2+\ldots+x_0(a_{n-1}))\ldots)) A(x0)=a0+x0(a1+x0(a2++x0(an1))))

同时,我们对两个系数表示法的多项式只需要 O ( n ) O(n) O(n)的时间内就能完成,只需要做一次向量加法即可。

现在考虑系数表示法的多项式相乘,需要在 O ( n 2 ) O(n^2) O(n2)的时间内完成,因为需要做一次向量卷积(笛卡尔直积),记作 c ⃗ = a ⃗ ∗ b ⃗ \vec{c} = \vec{a} \ast \vec{b} c =a b

点值表示

一个次数界为 n n n的多项式的点值表示就是由一个 n n n个点值对所组成的集合:

{ ( x 0 , y 0 ) , … , ( x n − 1 , y n − 1 ) } \{(x_0,y_0),\ldots,(x_{n-1},y_{n-1})\} {(x0,y0),,(xn1,yn1)}

y k = A ( x k ) y_k = A(x_k) yk=A(xk),使得所有取值点的 x k x_k xk均不相同。

一个多项式的取值点的不同,表达也不同,故一个多项式的点值表示并不唯一。我们统一取值点为一个固定的点集 x 0 , … , x n − 1 x_0,\ldots,x_{n-1} x0,,xn1,称为基底

求值计算的逆(从点值表示法计算系数表示法的过程)叫做插值

定理:只有点值集合的大小和多项式的次数界相同,其插值才是唯一的。

证明:

点值和插值可以由如下矩阵表示:

[ 1 x 0 ⋯ x 0 n − 1 1 x 1 ⋯ x 1 n − 1 ⋮ ⋮ ⋱ ⋮ 1 x n − 1 ⋯ x n − 1 n − 1 ] [ a 0 a 1 ⋮ a n − 1 ] = [ y 0 y 1 ⋮ y n − 1 ] \begin{bmatrix} 1& x_{0}& \cdots & x_{0}^{n-1}\\ 1& x_{1}& \cdots & x_{1}^{n-1}\\ \vdots & \vdots & \ddots & \vdots \\ 1& x_{n-1}& \cdots & x_{n-1}^{n-1} \end{bmatrix} \begin{bmatrix} a_0 \\ a_1 \\ \vdots \\ a_n-1 \end{bmatrix} =\begin{bmatrix} y_0 \\ y_1 \\ \vdots \\ y_n-1 \end{bmatrix} 111x0x1xn1x0n1x1n1xn1n1 a0a1an1 =

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值