Introduction to "FFT"

Introduction to "FFT"

首先,我构思了一会儿,希望通过比较好的方式,阐述FFT. 开源,分享.

... ...

回答,什么FFT?

FFT,Fast Fourier Transform. 它是一种快速的DFT(Discret Fourier Transform),由于人们在利用DFT的时候,算法速度很慢,计算时间长,(长的你根本受不了,等的天都黑了~它还没计算出结果),于是牛人就想办法在算法上改进传统的DFT. 改进的结果就是FFT。它不是一种新的变换,而是对DFT的改进,而由于快速的特性,得到广泛的应用~

DFT:

对于复数序列,离散傅里叶变换公式为:

实现DFT也是要花点时间的

我之前做DFT的笔记在这里,要搞懂FFT,必须先明白DFT

http://blog.csdn.net/cinmyheart/article/details/21050119

Get start with "FFT" (基于时间抽选的基-2 FFT 算法)

算法原理:

按照输入的信号顺序的奇偶数来把原来一个部分的DFT分成两个部分的DFT

最后原来的DFT[x(n)] 被恒等的化做两个部分相加.

注意事项:

一.       W2N = exp(-2*pi*j*2/N) == exp(-2*pi*j/(N/2));这是极其重要的恒等变形!累加的范围从原来的0~N-1, 降低到了0~N/2 -1 !!!

二.  exp(-2*pi*j* (r*k)/(N/2)) == exp(-2*pi*j *( r*(k+N/2)) / (N/2) ) 这里利用了 exp(-2*pi*j * X)的周期性

利用这个周期性,可以推理得到,

这是很重要的性质,利用这种周期性,我知道前面一般,就可以算出后面的一半数据了,因为相同的!

X1(N/2 + k) = X1(k)

三.

k  = 0,1,2,3 ... (N/2 -1)

利用

W_(N/2 + k)_N == exp(-2*pi*j*(N/2 + k)/N )

== W_(N/2)_N* W_(k)_N == exp(-2*pi*j*(N/2 )/N ) * exp(-2*pi*j*(k)/N )

== - W_(k)_N == - exp(-2*pi*j *(k/N))

于是!W_(N/2 + k)_N == -W_(k)_N

上面等式的左边+N/2 得到的是后半部分的X1(k) [注意k的取值范围已经不是0 ~N-1咯]

最后我们完成了一件很漂亮的事情,简直“算命先生”哈哈利用“一半的数据,我们可以获得全部的数据”

为什么这么说呢?

看这个图

X1 和X2是输入数据

X(k)是输出,

X(k)         ==前半部分 = X1(k) + W_k_N * X2(k);

X(k+N/2) ==后半部分 = X1(k) -  W_k_N * X2(k);

k是0~N/2,此时我们利用N/2的输入数据,能够得到N的输出数据.

正是基于以上的几点原因,才会有速度的提升!!!

想法虽好,怎么实现呢?

Butter fly

看这里,

X(k)         ==前半部分 = X1(k) + W_k_N * X2(k);

X(k+N/2) ==后半部分 = X1(k) -  W_k_N * X2(k);

有没有很像一只蝴蝶~

这里是基于N/2 点的DFT,于是只有一次奇偶重排序,

前面四个点是奇数顺序点,后面四个是偶数顺序点(注意计数从0开始,而不是1,所以0是奇数顺序点)

上图得到的其实是4对 蝶形,: )

这里N == 8,可以在N/2 中有4个点,还可以进行奇偶重排序,直到只有两个点,不需要再进行奇偶重排序

程序实现的注意事项

1. 奇偶重排序——实现方式 Bits reversal,在之后的link中会以C语言代码demo的方式给出

2.  在第一层,W_0_N 第二层 W_0_N,W_2_N, 第三层W_0_N W_1_N W_2_N W_3_N

这个W_r_N的系数r和层数的关系,用C 语言的形式表述为

tmp = k << (bits - m);

然后取低的m个有效位,即可以得到r

r =  tmp & ((1<<m) - 1);

3. It‘s time to implement yourown FFT !

http://blog.csdn.net/cinmyheart/article/details/39042623

时间: 2024-08-22 22:46:58

Introduction to "FFT"的相关文章

[学习笔记] 多项式与快速傅里叶变换(FFT)基础

引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积(或者多项式乘法/高精度乘法), 而代码量却非常小. 博主一年半前曾经因COGS的一道叫做"神秘的常数 $\pi$"的题目而去学习过FFT, 但是基本就是照着板子打打完并不知道自己在写些什么鬼畜的东西OwO 不过...博主这几天突然照着算法导论自己看了一遍发现自己似乎突然意识到了什么OwO然后就打了一道板子题还1A了OwO再加上午考试差点AK

XJTUOJ wmq的A&#215;B Problem FFT

wmq的A×B Problem 发布时间: 2017年4月9日 17:06   最后更新: 2017年4月9日 17:07   时间限制: 3000ms   内存限制: 512M 描述 这是一个非常简单的问题. wmq如今开始学习乘法了!他为了训练自己的乘法计算能力,写出了n个整数,并且对每两个数a,b都求出了它们的乘积a×b.现在他想知道,在求出的n(n−1)2个乘积中,除以给定的质数m余数为k(0≤k<m)的有多少个. 输入 第一行为测试数据的组数. 对于每组测试数据,第一行为2个正整数n,

对AM信号FFT的matlab仿真

普通调幅波AM的频谱,大信号包络检波频谱分析 u(t)=Ucm(1+macos ?t)cos ?ct ma称为调幅系数 它的频谱由载波,上下边频组成 , 包络检波中二极管截去负半周再用电容低通滤波,可以得到基带信号,那么,截去负半周后的AM信号必定包含基带信号的频谱.我们可以通过matlab来验证. %已知基带信号为1hz,载波为64hz,调制系数ma=0.3,采样频率1024hz,FFT变换区间N为2048 clear; fs=1024; f=1; %1hz基带信号 fc=64; %64hz载

Spring AOP之Introduction(@DeclareParents)简介

Spring的文档上对Introduction这个概念和相关的注解@DeclareParents作了如下介绍: Introductions (known as inter-type declarations in AspectJ) enable an aspect to declare that advised objects implement a given interface, and to provide an implementation of that interface on be

多项式FFT相关模板

自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <stdlib.h> #include <algorithm> #include <vector> using namespace std; #de

Introduction and Basic concepts

1 Network Edge The device such as computers and mobiles connect to the Internet. So they are referred as end systems(who run the application programs) sitting at the edge of the Internet. And we use host and end system interchangeably, that is host=e

多项式艺术:浅谈FFT和NTT算法(未完待续)

什么是多项式? 百度百科说:“由若干个单项式相加组成的代数式叫做多项式.多项式中每个单项式叫做多项式的项,这些单项式中的最高次数,就是这个多项式的次数.” 也就是说,形如的式子,就叫做多项式.这样的式子,也能写作.很显然,多项式加上(或是减上)多项式也是多项式,复杂度是的.但是,如果多项式想要乘上一个多项式,那么也可以,最简单的方法却是的. 不过,FFT算法会告诉你,就够了. 多项式乘法 我们说的,多项式想要乘上一个多项式,那就是多项式乘法,人称“卷积”.我们方才所看到的,被称为多项式的“系数表

FFT模板(From MG)

1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 using namespace std; 5 struct cp{double x,y;}; 6 int n1,n2,n,m; 7 double pi=acos(-1); 8 cp a[500010],b[500010],cur[500010]; 9 cp operator *(cp x,cp y){return (cp){x.x*y.x-x.y*y

Bzoj2179 FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3079  Solved: 1581 Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output 12 数据范围: n<=60000 HINT Source FFT FFT真