已知多项式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)的系数的步骤如下:

  1. 选择2n个不同的值xj(j=0,1,...,2n-1),求出算f(xj),g(xj)
  2. 计算所有h(xj)=f(xj)g(xj)
  3. 由于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)算法的更多相关文章

  1. 快速傅立叶变换FFT模板

    递归版 UOJ34多项式乘法 //容易暴栈,但是很好理解 #include <cmath> #include <iostream> #include <cstdio> ...

  2. 为什么要进行傅立叶变换?傅立叶变换究竟有何意义?如何用Matlab实现快速傅立叶变换

    写在最前面:本文是我阅读了多篇相关文章后对它们进行分析重组整合而得,绝大部分内容非我所原创.在此向多位原创作者致敬!!!一.傅立叶变换的由来关于傅立叶变换,无论是书本还是在网上可以很容易找到关于傅立叶 ...

  3. 离散傅立叶变换与快速傅立叶变换(DFT与FFT)

    自从去年下半年接触三维重构以来,听得最多的词就是傅立叶变换,后来了解到这个变换在图像处理里面也是重点中的重点. 本身自己基于高数知识的理解是傅立叶变换是将一个函数变为一堆正余弦函数的和的变换.而图像处 ...

  4. $\mathcal{FFT}$·$\mathcal{Fast \ \ Fourier \ \ Transformation}$快速傅立叶变换

    \(2019.2.18upd:\) \(LINK\) 之前写的比较适合未接触FFT的人阅读--但是有几个地方出了错,大家可以找一下233 啊-本来觉得这是个比较良心的算法没想到这么抽搐这个算法真是将一 ...

  5. 快速傅立叶变换(FFT)

    多项式 系数表示法 设\(f(x)\)为一个\(n-1\)次多项式,则 \(f(x)=\sum\limits_{i=0}^{n-1}a_i*x_i\) 其中\(a_i\)为\(f(x)\)的系数,用这 ...

  6. BZOJ 2194 快速傅立叶变换之二 | FFT

    BZOJ 2194 快速傅立叶变换之二 题意 给出两个长为\(n\)的数组\(a\)和\(b\),\(c_k = \sum_{i = k}^{n - 1} a[i] * b[i - k]\). 题解 ...

  7. 傅立叶变换—FFT

    FFT(快速傅立叶变换)使用“分而治之”的策略来计算一个n阶多项式的n阶DFT系数的值.定义n为2的整数幂数,为了计算一个n阶多项式f(x),算法定义了连个新的n/2阶多项式,函数f[0](x)包含了 ...

  8. NVIDIA GPU的快速傅立叶变换

    NVIDIA GPU的快速傅立叶变换 cuFFT库提供GPU加速的FFT实现,其执行速度比仅CPU的替代方案快10倍.cuFFT用于构建跨学科的商业和研究应用程序,例如深度学习,计算机视觉,计算物理, ...

  9. 傅立叶变换系列(五)快速傅立叶变换(FFT)

    说明: 傅里叶级数.傅里叶变换.离散傅里叶变换.短时傅里叶变换...这些理解和应用都非常难,网上的文章有两个极端:“Esay”  Or  “Boring”!如果单独看一两篇文章就弄懂傅里叶,那说明你真 ...

随机推荐

  1. .Net Core2.1 部署到IIS

    1. 发布网站,和.net framework MVC一样 2.安装WindowsHosting和.Net Core SDK 下载地址:https://www.microsoft.com/net/do ...

  2. dubbo 异步回调

    dubbo 异步回调的使用 业务接口: public interface HelloService { String sayHello(); void sayHi(String name); } 回调 ...

  3. php7 数据导出Excel office 2011中文乱码问题

    public function test(){ $data = array( array( 'name' => '对对对', 'score' => 80, 'grade' => '急 ...

  4. C#图解第七章:类和继承

    1.类继承 通过继承我们可以定义一个新类,新类纳入一个已经声明的类并进行扩展. 1.可以使用- 一个已经存在的类作为新类的基础..已存在的类称为基类(baseclass),新类称为派生类(derive ...

  5. C++ 抽象类与接口

    1. 抽象类  在面向对象编程中,抽象类是一种只能定义类型,不能生成对象的类,它是对一系列看上去不同,但是本质相同的具体概念的抽象.最典型的的抽象类就是”图形”,三角形.矩形.梯形都是图形,它们都具有 ...

  6. python笔记17-全局变量、局部变量

    在函数里面定义变量叫局部变量,它只能在函数里面用出了该函数外,就不能使用了在函数外面定义的变量,是全局变量,在函数内也可以使用 如果想在函数里面修改全局变量的值,那么要先用global关键字声明 要修 ...

  7. Linux修改日期、时间,系统与硬件时间

    Linux的时间分为两种,硬件时间和系统时间两种: 一.查看与修改系统时间 查看系统时间:date # date Fri Nov 26 15:20:18 CST 1999 用指定的格式显示系统时间:  ...

  8. yarn依赖管理工具的使用

    Yarn是Facebook发布的一款依赖管理工具,它比npm更快.更高效. 与NPM命令对照 npm install => yarn install npm install --save [pa ...

  9. java基础(1)IntelliJ IDEA入门和数组操作 解决idea启动速度慢--配置JVM

    一. IntelliJ IDEA入门 1 快捷键和技巧 智能补全代码,比如只写首字母按回车: psvm+Enter :public stactic void main(String[] args) s ...

  10. 使用selenium爬取网站动态数据

    处理页面动态加载的爬取 selenium selenium是python的一个第三方库,可以实现让浏览器完成自动化的操作,比如说点击按钮拖动滚轮等 环境搭建: 安装:pip install selen ...