FFT算法学习心得

原创 2007年09月23日 09:57:00
 1。通常的FFT算法: 直接计算离散傅立叶变换具有n^2的复杂度,而cooley   和tukey在1965年发现了一种计算离散傅立叶变换的快速算法(即通常所说的FFT算法),这个算法在计算变换长度n=2^k的离散傅立叶变换时,具有   n*k   的复杂度,即O(n)=n*log2(n),   下面以此为例,讲讲快FFT的特点。  
      1)复数运算:傅立叶变换是基于复数的,因此首先知道复数的运算规则,在FFT算法中,只涉及复数的加、减和乘法三种运算。一个复数可表示为   c=(  x,yi),   x   为复数的实部,y为复数的虚部,i为虚数单位,等于-1的平方根。复数的运算规则是:若c1   表示为   (x1,y1),c2   表示为(x2,y2),   则   (x1+x2,y1+y2)和(x1-x2,y1-y2)分别等于c1+c2的和,c1-c2的差,复数的乘法相对复杂一些,c1*c2   的积为   (x1*x2-y1*y2,x1*y2+x2*y1).  
       
        2)蝶形变换:普通的FFT算法称为基2的FFT算法,这种算法的核心是蝶形变换   长度为n=2^k1的变换共需要做   k1   *   n/2   次蝶形变换,若需变换数据表示为一个复数数组c[],则每次蝶形变换有2个输入   c[i],c[i+s],两个输出:c[i],c[i+s],s成为翅间距。   每个变换的基本算法是:  
       
      t=wr   *   c[i+s];    
      c[i+s]=c[i]-t;  
      c[i]=c[i]+t;  
   
        前面说过,长度为n=2^k1的变换共需要做   k1   *   n/2次变换,实际的程序是一个3层循环,共需要k1*k2*(k3/2)次变换(k2*k3/2=n/2)。前面的wr是w的整数次方,w=e^(-2*PI/k3)   (k3=2,4,8,16...n,PI是圆周率),也成为旋转因子,例如n=32的变换需要log2(32)=5趟变换:  
        第1趟变换需要16*1次变换,翅间距是1,     若w=e^(-2*PI/2),   则wr=w^1  
        第2趟变换需要8*2次变换,   翅间距是2,     若w=e^(-2*PI/4),   则wr=w^1,w^2  
        第3趟变换需要4*2次变换,   翅间距是4,     若w=e^(-2*PI/8),   则wr=w^1,w^2,w^3,w^4    
        第4趟变换需要2*8次变换,   翅间距是8,     若w=e^(-2*PI/16),则wr=w^1,w^2,w^3,w^4,w^5,w^6,w^7,w^8  
        第5趟变换需要16*1次变换,翅间距是16,   若w=e^(-2*PI/32),则wr=w^1,w^2,w^3,w^4,w^5...w^15,w^16  
   
      3)w数组,w   的实部=cos(2*PI/k3),w的虚部=   -sin(2*PI/k3),计算出w,则wr数组就好求了,不断即相乘即可,当然也可以通过三角函数直接求。w^p   的实部=cos(2*PI/K3*p),虚部=-sin(2*PI/k3*p)  
   
    4)复数数组排序,在基2的蝶形变换中,复数数组需要重新排序,c[i]   要放置到数组c的第   reverse(c[i])   的位置,m=reverse(n)   函数的算法是这样的,若   n的   k位2进制的为b[],   b[k-1],B[k-2],...b[2],b[1],b[0],(   b[i]   等于1或者0,b[0]为最低bit).   则m=reverse(n)的2进制的为   b[0],b[1],b[2],b[3],...b[k-1]   (b[k-1]为最低bit).  
   
   2.更复杂的变换算法:基2的蝶形变换算法不止一种,它可分为2类,一类为基2时分傅立叶变换,另一类为基2频分傅立叶变换。上例的变为基2时分算法,在每一趟变换中,翅间距依次变大,第一趟为2,最后一趟为n/2,数组重排在变换之前进行,基2频分算法正好相反,翅间距依次缩小,起于n/2,止于2,数组重排在蝶形变换之后进行。   在<傅立叶变换>一书中,提到3种基2时分变换,3种基2频分变换。上述算法称为基2时分FFT第二种算法。我在看你的这个程序的同时,还看到朱志刚写的一个FFT程序,这个程序的算法是基2时分FFT第一种算法,它比经典的算法更复杂,需要对wr数组进行逆序排列。  
   
   3.更复杂的FFT算法,除了基2   的FFT算法外,还有更加复杂的基4算法,基8算法,甚至基3,基5算法,纯粹的基4算法只能计算长度为4^k的变换,但它比基2的算法速度更高。为了提高速度,很多FFT算法使用混合基算法。关于混合基FFT算法我还在学习中,希望有高手给予帮助。
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

FFT & NTT学习心得

FFT—快速傅里叶变换 基本功能 在O( (n+m)log(n+m) )的时间复杂度内计算:n次多项式乘m次多项式. 实现方式 欲求多项式A*多项式B, 对多项式A,B分别进行快速傅里叶变换...

从零开始学习FFT(快速傅里叶变换) 这也是我学习dft算法的心得,谢谢各位

本文是从最基础的知识开始讲解,力求用最通俗易懂的文字将问题将的通俗易懂,大神勿喷,多多指教啊,虽然说是从零学习FFT,但是基本的数学知识还是要有的,sin,cos,等。        FFT(快速傅里...

算法导论学习心得1-----插入排序及两种不同插入方法的效率比较

插入排序的思想不多说了,就和打扑克牌时一样,拿到一张牌时从左到右比较后插入,不同的地方在于我们插入扑克牌是不用考虑移动顺序的。 按照书上第一个算法的代码,插入排序的算法如下: 插入排序1: int...

Surf算法学习心得(二)——源码简析

说明:作为初学者,我对于源代码也只是简单的分析,开始和(一)中一样都叫做源码分析,后来感觉自己分析的质量不太好,还是都改为源码简析吧,结合起(一)及后面的心得来看估计效果会好点,呵呵。只是希望对于即将...

红黑树——《算法导论》学习心得(十四)

介绍另一种平衡二叉树:红黑树(Red Black Tree),红黑树由Rudolf Bayer于1972年发明,当时被称为平衡二叉B树(symmetric binary B-trees),1978年被...

SERPENT算法学习心得

本文原创,转载请注明出处。 douqingl@gmail.com 1. 概述         由于工作的原因,我学习了SERPENT算法(注释1),并进行了软件实现,抓取了每一轮、每一步操作的中间数据...

《算法导论》学习心得(八)—— 桶排序(JAVA)

桶排序:本身桶排序的概念就太确定,有的人把计数排序也称为桶排序(各个桶中元素的排序采用计数排序),得到数组C后直接从前往后遍历,输出数组值次数组下标,为0就不输出(或者存入原数组,不稳定),不过我认为...

《算法导论》学习心得(六)—— 计数排序(Java)

计数排序是一个非基于比较的排序算法,该算法于1954年由 Harold H. Seward 提出。它的优势在于在对一定范围内的整数排序时,它的复杂度为Ο(n+k)(其中k是整数的范围),快于任何比...

快速排序算法学习心得(Java实现)

先上代码: ​int AdjustArray(int s[], int l, int r) //返回调整后基准数的位置,传入的参数分别是:子数组,子数组的第一个数的下标,最后一个数的下标 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)