快速傅立叶变换(FFT)算法
已知多项式f(x)=a0+a1x+a2x2+...+am-1xm-1, g(x)=b0+b1x+b2x2+...+bn-1xn-1。利用卷积的蛮力算法,得到h(x)=f(x)g(x),这一过程的时间复杂度为O(n2)。但是,利用分治策略和插值法来求解h(x),可以将时间复杂度降低至O(nlogn),从而大幅提升算法的效率。此求值算法将被应用于FFT算法中。
一、多项式求值
首先,由lagrange插值法可以知道,对于一个n-1次多项式,只要给定n个不同的点(xi, yi),我们就可以计算出多项式的系数。因此,求解2n-1次多项式系数的问题,可以转化为多项式对1的复数域中所有2n次方根求值的问题。其中,1在复数域的2n次方根可以表示为

设f(x),g(x)为n-1次多项式,则插值法求多项式h(x)=f(x)g(x)的系数的步骤如下:
- 选择2n个不同的值xj(j=0,1,...,2n-1),求出算f(xj),g(xj)
- 计算所有h(xj)=f(xj)g(xj)
- 由于h(x)的次数不高于2n-1,利用lagrange插值公式求出h(x)的系数
在第一步多项式求值过程中,如果用蛮力算法,即直接计算每一个A(wj),那么时间复杂度为O(n3)。但事实上,设Ak(x)=an-k+an-k+1x+...+an-1xk-1,则存在关系:
Ak(x)=an-k+xAk-1(x)
利用这一递推关系式来求解A(x)=An(x),复杂度可以降低到O(n2)。这比蛮力算法已经有了很大的改进,但有没有更高效的求值算法呢?
采用分治策略,可以将多项式求值过程的时间复杂度降低至O(nlogn),从而大幅提升算法的效率。这一算法的思想如下:
设要求值的多项式为A(x)=a0+a1x+...+an-1xn-1,不妨设n为偶数,令
A0(x)=a0+a2x+a4x2+...+an-2x(n-2)/2
A1(x)=a1+a3x+a5x2+...+an-1x(n-2)/2
则
A(x)=A0(x2)+xA1(x2)
值得注意的是,根据复数域2n次单位根的性质,x2并不需要重新计算,只要在单位圆上间隔取值就可以了。下面给出用分治策略为多项式求值的算法伪码
算法1 Polyval(A, W) //分治策略多项式求值(假设n为偶数)
输入:n-1次多项式A的系数a0,a1,...,an-1,以及w0,w1,...,w2n-1
输出:A(w0),A(w1),...,A(w2n-1)
1. if A的长度=1 return A(W)
2. else do
3. 计算W1: W[0]2,W[1]2,...,W[2n-1]2
4. 计算A0: A[0],A[2],...A[n-2]
5. 计算A1: A[1],A[3],...A[n-1]
6. A0(W1)←Polyval(A0, W1)
7. A1(W1)←Polyval(A1, W1)
8. return A(W)=A0(W1)+WTA1(W1)
算法的递推方程为T(n) = 2T(n/2) + f(n), T(1) = O(1)。其中,f(n)为初始时计算所有2n次方根的时间,f(n) = O(n)。根据主定理,得到T(n) = O(nlogn)。
二、快速傅立叶变换
设f(x)=a0+a1x+a2x2+...+an-1xn-1, g(x)=b0+b1x+b2x2+...+bn-1xn-1,h(x)=f(x)g(x)。下面给出FFT算法的伪码:
算法2 FFT
1. 对x=wj(j=0,1,...,2n-1),分别计算f(wj),g(wj)
2. 利用步骤1的结果,计算所有dj=h(wj)
3. 构造多项式D(x)=d0+d1x+d2x2+...+d2n-1x2n-1
4. 对x=wj(j=0,1,...,2n-1),计算D(wj)
5. 设h(x)的系数为c0,c1,...,c2n-1,则有c0=D(1)/2n,c2n-1=D(w1)/2n,...,c1=D(w2n-1)/2n
不难分析,FFT算法时间复杂度为O(nlogn)。
快速傅立叶变换(FFT)算法的更多相关文章
- 快速傅立叶变换FFT模板
递归版 UOJ34多项式乘法 //容易暴栈,但是很好理解 #include <cmath> #include <iostream> #include <cstdio> ...
- 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换
写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!!一.傅立叶变换的由来关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶 ...
- 离散傅立叶变换与快速傅立叶变换(DFT与FFT)
自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...
- $\mathcal{FFT}$·$\mathcal{Fast \ \ Fourier \ \ Transformation}$快速傅立叶变换
\(2019.2.18upd:\) \(LINK\) 之前写的比较适合未接触FFT的人阅读--但是有几个地方出了错,大家可以找一下233 啊-本来觉得这是个比较良心的算法没想到这么抽搐这个算法真是将一 ...
- 快速傅立叶变换(FFT)
多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...
- BZOJ 2194 快速傅立叶变换之二 | FFT
BZOJ 2194 快速傅立叶变换之二 题意 给出两个长为\(n\)的数组\(a\)和\(b\),\(c_k = \sum_{i = k}^{n - 1} a[i] * b[i - k]\). 题解 ...
- 傅立叶变换—FFT
FFT(快速傅立叶变换)使用“分而治之”的策略来计算一个n阶多项式的n阶DFT系数的值.定义n为2的整数幂数,为了计算一个n阶多项式f(x),算法定义了连个新的n/2阶多项式,函数f[0](x)包含了 ...
- NVIDIA GPU的快速傅立叶变换
NVIDIA GPU的快速傅立叶变换 cuFFT库提供GPU加速的FFT实现,其执行速度比仅CPU的替代方案快10倍.cuFFT用于构建跨学科的商业和研究应用程序,例如深度学习,计算机视觉,计算物理, ...
- 傅立叶变换系列(五)快速傅立叶变换(FFT)
说明: 傅里叶级数.傅里叶变换.离散傅里叶变换.短时傅里叶变换...这些理解和应用都非常难,网上的文章有两个极端:“Esay” Or “Boring”!如果单独看一两篇文章就弄懂傅里叶,那说明你真 ...
随机推荐
- 用Eclipse在Weka中嵌入新算法
本文介绍添加一个新算法到Weka集成环境中的过程,并能在GUI中运行并显示其结果.想做到这一点有两种方法,一是用ANT命令生成新的weka.jar(稍后写教程),二是用IDE(Eclipse或NetB ...
- vscode plugins
├─ .obsolete├─ .wlck├─ .wtid├─ abeyuhang.vscode-lesslint-0.0.1├─ abierbaum.vscode-file-peek-1.0.1├─ ...
- doxygen
//commndline: doxygen Doxyfile /**comment /* /** time diff@pre precondition@post endcondition@throw ...
- Charles设置HTTPS抓包
1. 配置 Charles 根证书 点击 Help -> SSL Proxying -> Install Charles Root Certificate 之后会弹出钥匙串,如果不弹出,请 ...
- C#Mvc地址栏传值
A页面 location.href = "/Home/Bpage?names=" +names; B页面 var loc = location.href;var n1 = loc. ...
- 二十四. Python基础(24)--封装
二十四. Python基础(24)--封装 ● 知识结构 ● 类属性和__slots__属性 class Student(object): grade = 3 # 也可以写在__slots ...
- kafka 分区和副本以及kafaka 执行流程,以及消息的高可用
1.Kafka概览 Apache下的项目Kafka(卡夫卡)是一个分布式流处理平台,它的流行是因为卡夫卡系统的设计和操作简单,能充分利用磁盘的顺序读写特性.kafka每秒钟能有百万条消息的吞吐量,因此 ...
- django 分页出现 UnorderedObjectListWarning 错误
django 分页出现此错误: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unorde ...
- 解决启动vs2010 未能找到自动配置的设置文件
今天室友把固态拆掉,重新安上.打开vs2010出现 打开项目,出现 找了许多方法都无效. 发现c:user\Administer\documents\下,vs2010 .vs webset 那些文件点 ...
- Curl追踪请求延时问题
背景原因:测试环境发现一个连接内网访问和外网访问延迟差别很大,内网访问很快.外网访问很慢.于是我们用curl来诊断问题所在的区域! 命令如下: curl -o /dev/null -s -w %{ti ...