FFT算法学习

写在前面:

初学FFT算法移步:here
讲的真心不错,本文主要记录下自己的理解。
建议阅读的过程中,自己动手算一算需要仔细理解的地方!

overview

定义一个多项式: A(x)=Σj=0n1ajxj
计算

C(x)=A(x)B(x)

一般我们要计算两个 n 次多项式的乘积,直接计算的复杂度是 O(n2),利用 FFT 算法可以达到 O(nlogn) 的复杂度,其中利用到了傅里叶变换,周期性,还有分治策略。

大致的思路呢,就是先得到 A(x) B(x) 的点表示法(具体见下文),也就是利用 DFT 算法在 O(nlogn) 时间内得到点表示法,然后得到的两个点表示形式在对应位上直接相乘得到 C(x) 的点表示形式,最后就是逆 DFT 得到 C(x) 的多项式表示。

detail

一般我们将多项式表示为 A(x)=a0+a1x+a2x2+...+an1xn1 ,记为: a=(a1,a2,...an1)

实际上还有另外一种方法来唯一的表征一个多项式 ,即点值法,也就是找出多项式在 n 个不同的点上的取值,记为:{(x0,y0),(x1,y1),...,(xn1,yn1)},具体证明略。
现在我们的目的是得到 A(x) 的点值表示,直接代入 n 个数,计算的时间复杂度为 O(n2),所以现在就用到了 傅里叶变换 去优化这个过程。

我们选用n个特殊的值,用处后面自然会感受到:

ω0n,ω1n,...,ωn1nωn=e2iπn

你会发现上面的取值 ωin 的周期是 n ,也就是 i=n+k i=k 时候的值是一样的。
现在我们对 A(x) 作一些变换:
A(x)=A[0](x2)+xA[1](x2)

A[0](x)=a0+a2x+a4x2+...+an2xn21

A[1](x)=a1+a3x1+a5x2+...+an1xn21

现在我们需要分别去计算 A[0](x),A[1](x) 在 上述 n 个数上的取值,即计算 (ωin)2,你会发现这个式子的周期是 n/2 ,所以这个 n 个数的序列的 前后半段完全相同 (聪明的你是否想到了优化的地方呢)!

也就是我们计算A[0](x),A[1](x) 的时候,其实只需代入计算 前 n/2 个数,这样问题的规模就缩小了一半,假设我们得到了上述两者的取值结果:

v0,v1,...vn/2  t0,t1,...tn/2

为什么取负号?自己想一想!(^_^
最后就是递归的计算下去,但是每次计算问题的规模都会为上一次的一半,所以整体的复杂度变为 nlogn


接下来就是逆 DFT :
其实逆DFT与DFT的计算过程类似,只需看看我们之前计算 yi 序列的过程:
ss
那么我们只需要在等式两边分别左乘一个逆矩阵就OK了,如何求上面那个矩阵的逆矩阵呢?
直接给出了矩阵的:

C(j,k)=ωkjnn

具体证明略。
所以要计算 ai 序列,就是一个类似的过程,用逆矩阵去乘我们先前得到的 yi 序列,方法类似嘛,只不过:
aj=1nΣk=0n1ykωkjn

把之前的 w 替换为 w1 ,最后除以 n 就完成啦!复杂度也是 nlogn

all

有错误的话,欢迎指出哦!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值