FFT从入门到使用(ACM/OI)

(首先膜一发高中生qwq亏我学了信号处理原理专业课了竟然是看高中生的博客才能看懂qwq。。。大概断断续续看了几十篇吧。。。

序言

可能是许久以来写的最认真的一篇了吧,加上今天感觉不太舒服,但是觉得要开始扎实的学点什么,所以,就从现在开始吧。感谢所有认真写博客的人的帮助!!!希望我也能贡献点什么qwq。。。

一直想学FFT,之前牛客的多小有一道组合数学就用FFT写的,而且当时还傻乎乎的用唯一分解定理,但是自己好久没静下心学什么了,而且自己的数学功底又不好,导致一直学不会。看了很多人的博客也没看明白,尤其是原根。但是看了一个OIer的博客,顿时明白了。。。然后赶紧记录下来。

另外,本文的代码实现全部参考匡斌(kuangbin)的模板(2018.7更新)

前言

你搜索这个关键词就已经知道这一是个数学的东西了。只想学会用很简单,但是这远远不够。所以在看这个博客之前应该先学一下复数的基本知识。

好了下面进入正文。

1.DFT IDFT FFT官方定义?

离散傅里叶变换(Discrete Fourier Transform,缩写为DFT),是傅里叶变换时域频域上都呈离散的形式,将信号的时域采样变换为其DTFT的频域采样。

FFT是一种DFT的高效算法,称为快速傅立叶变换(fast Fourier transform)。

                                              ——百度百科

在百度百科上能找到DFT和FFT这两个定义。正如定义,FFT和DFT实际上按照结果来看的话是一样的,但是FFT比较快的计算DFT和IDFT(离散反傅里叶变换·)。

快速数论变换(NTT)是快速傅里叶变换(FFT)在数论基础上的实现。

是不是有点迷QAQ?既然是官方定义那肯定不能让你看懂才对嘛~下面我们一一解释~

2.为什么要使用FFT?

我们在这里引入一个例子:求多项式乘积的朴素算法。

大家平时求    f(x) = a^{_{1}}f(x) = a_{1}x^2 + b_{1}x + c_{1}   与  g(x) = a_{2}x^2 + b_{2}x + c_{2}  的乘积时候,是怎么进行的呢?

我们令

K(x) = f(x)*g(x) = a_{1}x^2 *a_{2}x^2 + a_{1}x^2*b_{2}x + a_{1}x^2*c_{2} + b_{1}x *b_{2}x^2 + b_{1}x*b_{2}x + b_{1}x*c_{2} + c_{1} *a_{2}x^2 + c_{1}*b_{2}x + c_{1}*c_{2}

那么很显然我们进行了9次运算,复杂度是O(n^2).(具体代码实现不再展开)

但是如果数字足够大呢?比如100000?那朴素算法可太慢啦(;′⌒`),

3.学习FFT

3.1 在学习FFT之前...

3.1.1什么是FFT

FFT,即为快速傅氏变换,是离散傅氏变换的快速算法,它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。它对傅氏变换的理论并没有新的发现,但是对于在计算机系统或者说数字系统中应用离散傅立叶变换,可以说是进了一大步。——360百科

如果上一个例子用朴素算法太慢啦!所以我们要用FFT进行优化,复杂度会降为O(nlog(n))

3.1.2项式的系数表示法与点值表示法

一个多项式,我们可以怎样来表示呢?

系数表示法就是用一个多项式的各个项系数来表达这个多项式。比如:

f(x) = a_{1}x^2 + b_{1}x + c_{1}\Leftrightarrow f(x) = \{a_{1},b_{1},c_{1}\}

点值表示法是把这个多项式看成一个函数,从上面选取n+1个点,从而利用这n+1个点来唯一的表示这个函数。为什么用(n+1)个点就能唯一的表示这个函数了呢?想一下高斯消元法,两点确定一条直线。再来一个点,能确定这个直线中的另一个参数,那么也就是说(n+1)个点能确定n个参数(不考虑倍数点之类的没用点)。如下:

\\f_{1}(x) = y_{1} = a_{0} + a_{1}x _{1}+ a_{2}x_{1}^2 + a_{3}x_{1}^3+...+a_{n}x_{1}^n\\ f_{2}(x) = y_{2} = a_{0} + a_{1}x_{2} + a_{2}x_{2}^2 + a_{3}x_{2}^3+...+a_{n}x_{2}^n\\ f_{3}(x) = y_{3} = a_{0} + a_{1}x_{3} + a_{2}x^2_{3} + a_{3}x_{3}^3+...+a_{n}x_{3}^n\\ f_{4}(x) = y_{4} = a_{0} + a_{1}x_{4} + a_{2}x_{4}^2 + a_{3}x_{4}^3+...+a_{n}x_{4}^n\\..\\ f_{n}(x) = y_{n} = a_{0} + a_{1}x_{n} + a_{2}x_{n}^2 + a_{3}x_{n}^3+...+a_{n}x_{n}^n\\

多项式由系数表示法转为点值表示法的过程,就成为DFT;

相对地,把一个多项式的点值表示法转化为系数表示法的过程,就是IDFT。

而FFT就是通过取某些特殊的x的点值来加速DFT和FFT的过程。

3.1.3复数的引入

复数分为实数和虚数。实数就是我们日

  • 18
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值