《1228.DFT快速算法的研究.doc》由会员分享,可在线阅读,更多相关《1228.DFT快速算法的研究.doc(21页珍藏版)》请在三一办公上搜索。
1、 目录摘要.1第一部分 FFT的回顾2第一节 DFT与FFT的过渡.2第二节 按时间抽取以2为基的算法(FFT-DIT2)(库利-图基算法).2第三节 按频率抽取以2为基的算法(FFT-DIT2)(桑德-图基算法).6第二部分 混合基与分裂基的研究.7第一节 混合基的相关知识7第二节 分裂基的相关知识9第三部分 FFT算法改进.12第四部分 FFT实例运行结果及比较14第五部分 总结与感想.18参考文献 .19摘要快速傅立叶变换FFT是离散傅立叶变换DFT的一种快速算法,我们知道有限长序列的主要特点是其频域也可以离散化成有限长序列,即能进行DFT变换。DFT广泛应用于信号的频谱分析、滤波器的设
2、计以及系统的分析、设计和实现中。而在相当长时间中由于N值大时,计算量大。无法达到实时处理的要求。1965年,库利(cooley)和图基(Tukey)首先提出FFT算法.对于N点DFT,仅需(N/2)log2N 次复数乘法运算。大大提高了计算效率。后来又有桑德快速算法以及一些算法改进。FFT是DFT的一种快速计算机算法,无任何近似,无精度损失。本论文主要介绍基本FFT算法与实现,以及混合基、分裂基等一些先进算法,最后附有方案改进和算法程序设计。第一部分 FFT的算法回顾第一节 DFT与FFT的过渡 N点有限长序列x(n)的DFT为二者仅有一符号之差和一个常熟因子1/N。由DFT可知完成整个DFT
3、运算共需N2次复数乘法和N(N-1)次复数加法。由复数知识可知,此运算4N2次实数乘法和 2N(N-1)次实数加法运算。因此DFT 正比于N2,当N很大时,其运算量很可观。为此我们对此加以改进。 在DFT中我们知道WNnk具有一些特定性质:可得出由此可对DFT中的一些项合并,将其分解为短序列DFT,FFT就是由此而得出的。 第二节 按时间抽取以2为基的算法(FFT-DIT2)(库利-图基算法)设序列点数N=2L,LZ。如条件不满足可人为加上若干个0,N=2L序列n的奇偶分两组 于是得经过WNnk的性质转换使X(k)前后分离如下:对X(k)的前一半(k=0,1, ,N/2-1),由DFT定义:对
4、X(k)的后一半(k=N/2, N/2+1, ,N-1)由此我们只需求0N/21区间的,就可求出X(k)。其算法流图如下图一。 X1(0)N/2 点 DFT x(0) X(0) X1(1) WN0x(2) X(1) X1(2) WN1 x(4) X(2) X1(3) WN2x(6) X(3) Y1(0) WN4 WN3N/2 点 DFTx(1) X(4) Y1(1) WN5x(3) X(5) Y1(2) WN6x(5) X(6) Y1(3) WN7x(7) X(7) 图一 N点离散傅立叶变换的计算化为两个N/2点离散傅立叶变换的计算(N=8)由以上流图可见,其FFT的运算量大大减少。直接计算D
5、FT与FFT算法的计算量比值见下表1。表1NN2N22414.041644.0864125.416256328.03210248012.864409619221.41281638444836.625665536102464.0由流图可知,输入为顺序,而输出为倒位序,其完成是通过变址运算来实现的。下表2是N=8时的顺序二进制数以及相应的倒位序二进制数。 表2自然数二进制数倒位序二进制数倒位序顺序0000000010011004201001023011110641000011510110156110011371111117通过上面的推导可以看出,N点DFT可以分解为两个N/2点的DFT,每个N/2
6、点的DFT又可以分解为两个N/4点的DFT。依此类推,当N为2的整数次幂时(N=2M),由于每分解一次降低一阶幂次,所以通过M次的分解,最后全部成为一系列2点DFT运算。以上就是按时间抽取的快速傅立叶变换(FFT)算法。序列X(k)的离散傅立叶变换的区别在于将WN改变为WN-1,并多了一个除仪N的运算。因为WN 和WN-1对于推导按时间抽取的快速傅立叶变换算法并无实质性区别,因为可将FFT和快速傅立叶反变换(IFFT)算法合并在同一个程序中。如下语句(C语言): 1. 子函数语句void srfft(x,y,n,sign)2. 形参说明 x双精度实型一维数组,长度为n。开始时存放要变换数据的实
7、部,最后存放变换结果的实部。 y双精度实型一维数组,长度为n。开始时存放要变换数据的虚部,最后存放变换结果的虚部。 n整型变量。数据长度必须是2 的整数次幂,即n2m。sign整型变量。当sign时,子函数fft( )计算离散傅立叶正变换(DFT);当sign时,子函数计算离散傅立叶反变换(DFT)。3、子函数程序(文件名:srfftc)#includemath.hvoid fft(x,y,n,sign);int n, sign;double x ,y ; int i,j,k,l,m ,n1,n2,;double c,c1,e,s,s1t,tr;ti;for(j=1,i=1;i16;i+) m
8、=i; j=2*j; if(j=n)break; n1=n-1;for(j=0,i=0;in;i+) if(ij) tr=xj;ti=yj;xj=xi;yj=yi;xi=tr;yi=ti; k=n/2; while(k(j+1)j=j-k; k=k/2; j=j+k; n1=1;for(l=1;l=m;l+)n1=2*n1; n2=n1/2; e=3.14159265359/n2; c=1.0; s=0.0; c1=cos(e); s1=-sign*sin(e); for(j=0;jn2;j+)for(i=j;in;i+=n1) k=i+n2; tr=c*xk-s*xk; xk=xi-tr;
9、yk=yi-ti; xi=xi+tr; yi+yi+ti; t=c;c=c*c1-s*s1;s=t*s1+s*c1; if(sign=-1) for(i=0;in;i+) xi/=n; yi/=n; 第三节 按频率抽取以2为基的算法(FFT-DIT2)(桑德-图基算法)算法原理:对时域有限长序列x(n),设N(可补零)。1)按频率抽取以2为基的FFT算法(FFT-DIF2)是以频域奇偶分组方式将X(k)不断二分为一系列短序列,减小了DFT的基数。2)在每个短序列的计算中,利用对称性和周期性,以蝶形运算来合并相同项,从而降低计算量,提高了计算速度。由的性质可知按k的奇数和偶数可将X(K)分为两部
10、分。X(2k)X(2k)这样,我们就把一个N点DFT分解为两个N/2点的DFT了。其分解过程如下图二所示。X(0)X(1)X(2)X(3)X(4)X(5)X(6)X(7)X(0)X(2)X(4)X(6)X(1)X(3)X(5)X(7)vN/2点DFTN/2点DFT 图二按频率抽取以2为基的FFT算法(FFT-DIF2)与按时间抽取以2为基的FFT算法的特点和程序基本类似,这里不在介绍。第二部分 混合基与分裂基的研究第一节 混合基的相关知识混合基算法:混合基算法主要应用于当序列值N为复合数时的快速傅立叶变换。它是将复合数N分解成一系列因子乘积的整数情况的FFT算法。当N=ab,计算DFT如下:
11、(1)其中N=ab=ba将十进制数n表示为b进制数,n0末位,n1进位,得n=n1b+n0, n1=0,1,n-1, n0=0,1,b-1 (2)同理将频率变量k表示为a进制,k1为进位,k0为末位。得k=k1a+k0, k1=0,1,b-1, k0=0,1,a-1 (3)将(2),(3)代入(1)式中,得 由以上过程中得 , k00,1,a-1 (4) (5) k10,1,b-1 (6) (7)以上是N为复合数的FFT算法得全过程,从中我们归纳出它的一般计算步骤如下:a) 将N分为两个因子,例如N=ab,将序列变换为:x(n)=x(bn1+n0 )=x(n1,n0) n1=0,1,a-1 n
12、00,1,b-1;b) 利用式(4)求c) 利用式(5)求d) 利用式(6)求e) 利用式(7)求整序,的傅立叶变换以N428为例,得其混合基FFT算法流程图,如图三所示:X(n)=x(n1,n0) X1(k0,n0) X2(k0,k1)=X(k) X1(k1,k0)=X(k) 0 00 00 00 0 00 0 1 01 01 WN0 01 4 01 1 -12 10 -j10 10 1 02 2 -1 3 11 j 11 WN1 11 5 03 3 -14 20 -1 20 20 2 10 4 1 -1 5 21 21 WN2 21 6 11 5 j -1 -16 30 -1 30 30
13、3 12 6 -j7 31 31 WN3 31 7 13 7 -1 图三 N=4X2=8的FFT运算流程图上面讨论的是将N分解为两个素数的情况,当N为高组合素数是,同样可按以上步骤进行计算,如NaM,Mcd,根据以上流程同样可以得到其DFT。以此类推可以到任意基的DFT,课堂中学的基2FFT混合基运算里的一个特例。第二节 分裂基的相关知识1. 分裂基概述:自从基2快速算法出现后,人们再不断探求更快的算法。1984年,法国的P.Dohamel和H.Hollmann将基2分解和基4分解糅合在一起,提出了分裂基FFT算法。该算法的基本想法是对偶序号使用基2FFT算法,对奇序号使用基4算法。其运算量比
14、前诉几种算法都有所减少,运算流程图却于基2FF很接近。它在FFT算法中是一种实用的高效率新算法。2. 方法简介序列x(n)的离散傅立叶变换为将X(k)按序列号k的奇偶分成两组。当k为偶数时,进行基2频率抽取分解,X(k)可表示为X(2k)当k为奇数时,进行基4频率抽取分解,X(k)可表示为 由此可见,一个N点的DFT可以分解为一个N2点的DFT和两个N4点的DFT。这种分解既有基2的部分,又有基4的部分,因此称为分裂基分解。上面的N2点DFT又可分解为一个N8点的DFT和两个N8点的DFT,而两个N4点的DFT也可以分解为一个N8点的DFT和两个N16点的DFT。依次类推,直至分解到最后一级为
15、止。这就是按频率抽取的分裂基快速傅立叶变换算法。3. 分裂基算法的优点:a) 在已知的N2M的各种算法中,所需的乘法数是最少的,并接近理论上的最小值;b) 分裂基算法有着和基4、基2算法一样的规则结构,可以同址运算,这在用IC芯片来实现这些算法时特别重要;c) 若把基2,基4和分裂基算法中无关紧要的旋转因子都考虑进去,那么三者所需的计算量是一样的。分裂基算法的特点时合理安排了算法结构,使无关紧要的旋转因子最大程度地减少。4. 分裂基C语言程序: 一。程序说明:1 子函数语句void srfft(x,y,n)2,形参说明 x双精度实型一维数组,长度为n。开始时存放要变换数据的实部,最后存放变换结
16、果的实部。 y双精度实型一维数组,长度为n。开始时存放要变换数据的虚部,最后存放变换结果的虚部。 n整型变量。数据长度必须是2 的整数次幂,即n2m。二。子函数程序(文件名:srfft。c)#include”math.h”void strfft(x,y,z)int n;double x,y;int I,j,k,m,i1,i2,i3,n1,n2,n4,id,is;double a,b,c,e,a3,r1,r2,r3,r4;double c1,c3,s1,s2,s3,cc1,cc3,ss1,ss3;for(j=1,i=1;i16;i+)m=i; j=2*j; if(j=n)break; n2=2*
17、n; for(k=1;km;k+) n2=n2/2;n4=n2/4;e=6.28318530718/n2;a=0;for(j=0;jn4;j+)a3=3*a;cc1=cos(a);ss1=sin(a);cc3=cos(a3);ss3=sin(a3);a=(j+1)*e;is=j;id=2*n2;do for(i=is;i(n-1);i=i+id) i1=i+n4;i2=i1+n4;i3=i2+n4;r1=xi-xi2;xi=xi+xi2;r2=xi1-xi3;xi1=xi1+xi3;s1=yi-yi2;yi=yi+yi2;s2=yi1-yi3;yi1=yi1+yi3;s3=r1-s2;r1=r
18、1+s2;s2=r2-s1;r2=r2+s1;xi2=r1*cc1-s2*ss1;yi2=-s2*cc1-r1*ss1;xi3=s3*cc3+r2*ss3;yi3=r2*cc3-s3*ss3; is=2*id-n2+j;id=4*id; while(is(n-1);is=0;id=4;dofor(i=is;in;i=i+id) i1=i+1;r1=xi;r2=yi;xi=r1+xi1;yi=r2+yi1;xi1=r1-xi1;yi1=r2-yi1; is=2*id-2; id=4*id;while(is(n-1);n1=n-1;for(j=0,i=0;in1;i+)if(ij) r1=xj;s
19、1=yj; xj =xi; yj=yi; xi=r1; yi=s1;k=n/2;while(k(j+1) j=j-k;k=k/2;j=j+k;)第三部分 FFT算法改进自1965年重新发现快速傅立叶变换算法以来,寻求更快的算法的努力从来未停止过。从理论上讲,用更大的基数可以进一步的缩减实数运算的次数,但随之而来的程序的复杂程度和长度都必须付出代价,甚至于得不偿失。除了基8算法尚可实用外,基数取得更高是没有多大意义的。我们知道,DFT的计算同周期褶积的计算有着密切的关系。有了FFT算法,就可以快速地计算周期褶积。但是也可以直接寻求快速计算周期褶积地算法,甚至也可以用某些快速计算周期褶积地方法反过
20、来用于计算DFT。在七十年代中期,上诉两方面都有所进展。前者是所谓数论变换(NTT),用有限整数环取代了复数域,跟DFT一样可以将周期褶积变换为乘积。数论变换可以避免运算误差,这在DFT地三角函数地有关运算是不可避免的,但变换的有关参数受到数论上的要求而严格的限制。策二种是所谓的Winograd傅立叶变换算法,它将较长点数的DFT分解为许多短点数的DFT。每种短点数的DFT用短周期褶积来算出来,各个短周期褶积的计算则用多项式理论设计出具有尽可能少的乘法次数的算法。虽然在不断的实践中,这两种算法都不理想,但也促进了人们不断进行研究探索!以下是最新的离散傅立叶变换的改良方法:SIFT:离散傅立叶变
21、换ASIC/FPGA设计的新方法傅立叶变换是数字时代的核心,在数字信号处理中扮演着重要的角色。自傅立叶变换理论提出以来,其计算方法一直是研究的重要课题。离散傅立叶变换是中更为可行和行之有效的傅立叶变换的实际应用。目前已有多种离散傅立叶变换的计算方法。如Goertzel的递归算法,Bluestein Chrip Z变换算法,Rader算法,Winograd 算法,Hartly变换等。1965年后,Cooley及Tukey提出的FFT算法成为傅立叶变换计算方法的主流。FFTW(Fastest Fourier Transform in the West)是FFT最新的算法之一。FFT提出之后,傅立叶
22、变换技术的进步更多地来自于微电子工艺的改进。快速傅立叶变换-FFT 离散傅立叶变换的基本公式为: 其中 FFT的核心是蝶型单元,其设计也是 FFT实现的重点,在FPGA实现中,是较为复杂的部分,其性能也决定了整个设计的性能。FFT需要对样本或输出系数次序做特别的处理。FFT使基本的DFT计算量由2N2减少到2Nlog(N),计算量大大降低,成为傅立叶变换的关键因素。我们可以注意到,FFT算法中,采样点对计算结果是彼此相关的,因此,也需要采集全部采样周期内的样本数据后,才开始运算。FFT的计算过程是批处理过程,基本的流程是收集数据、开始计算、输出结果。典型的数据处理流程如图1所示。 FFT算法的
23、FPGA/ASIC实现,有很多的研究文献可供参考。 采样积分傅立叶变换 SIFTSIFT(SAMPLE INTEGRATED FOURIER TRANSFORM)是以傅立叶变换基本算法为基础的新的离散傅立叶变换实现方法。SIFT方法中,当采样点对系数的贡献可以独立计算,计算完成后,不需要保存这些样本数据。数据处理是透明型的。由此得到的一个明显的好处在于,在FPGA/ASIC设计中,可以实现无延迟傅立叶变换,全部采样数据输入完即可输出系数。SIFT处理数据的流程如图2所示.第四部分 FFT实例运行结果及比较一、基2FFT算法程序运行结果设输入序列x(i)为 x(i)=Qi,I=0,1,n-1其离
24、散傅立叶变换为X(k)= (1-Qn)/(1-QWk), k=0,1,2,31这里W=e-j2p/n.选取Q=0.9+j0.3,n=32,计算离散傅立叶变换X=(k)和离散傅立叶反变换x(i),并和理论值比较。主函数程序(文件名:fft.m):#include #include main() inti,j,n; double a1,a2,c,c1,c2,d1,d2,q1,q2,w,w1,w2; double x32,y32,a32,b32; n=32;a1=0.9;a2=0.3;x0=1.0;y0=0.0;for(i=1;in;i+) xi=a1*xi-1-a2*yi-1; yi=a2*xi-
25、1+a1*yi-1; printf(n COMPLEX INPUT SEQUENCEn); for(i=0;in/2;i+) for(j=0;j2;j+) printf(%10.7f+j%10.7f,x2*i+j,y2*I+j); printf(n)q1=xn-1;q2=yn-2;for(i=1;in;i+)w=6.28318530718/n*I; w1=cos(w); w2=-sin(w); c1=1.0-a1*w1+a2*w2; c2=a1*w2+a2*w1; c=c1*c1+c2*c2; d1=1.0-a1*q1+a2*q2; d2=a1*q2+a2*q1; ai=(c1*d1+c28d
26、2)/c; bi=(c2*d1-c1*d2)c; printf(n THEORETICAL DFTn); for(i=0;in/2;i+) for(j=0;j2;j+) printf(%10.7f+j%10.7f,x2*i+j,y2*I+j); printf(n) fft(x,y,n,l);printf(n DISCRETE FOURIER TRANSFORMn); for(i=0;in/2;i+) for(j=0;j2;j+) printf(%10.7f+j%10.7f,x2*i+j,y2*I+j); printf(n) fft(x,y,n,-l);printf(n INVERSE DISC
27、RETE FOURIER TRANSFORMn); for(i=0;in/2;i+) for(j=0;j2;j+) printf(%10.7f+j%10.7f,x2*i+j,y2*I+j); printf(n) 运行结果为:输入序列x(i)为1.0000000 +J 0.0000000 0.9000000 +J 0.30000000.7200000 +J 0.5400000 0.4860000 +J 0.70200000.2268000 +J 0.7776000 -0.0291600 +J 0.7678800- 0.2566080 +J 0.6823440 -0.4356504 +J -0.5
28、371272- 0.5532235 +J 0.3527194 -0.6037170 +J 0.1514804- 0.5887894 +J - 0.0447828 -0.5164756 +J -0.2169413- 0.3997457 +J - 0.3501899 -0.2547141 +J -0.4350946- 0.0987144 +J - 0.4679994 0.0515569 +J - 0.4508137 0.1816453 +J - 0.3902653 0.2805604 +J - 0.2967452 0.3415279 +J - 0.1829025 0.3622459 +J - 0.
29、0621539 0.3446674 +J 0.0527352 0.2943801 +J 0.1508619 0.2196835 +J 0.2240898 0.1304882 +J 0.2675859 0.0371637 +J 0.2799738 -0.0505448 +J 0.2631255- 0.1244280 +J 0.2216495 -0.1784800 +J 0.1621561- 0.2092789 +J 0.0923965 -0.2160699 +J 0.0.203732- 0.2005749 +J - 0.0464851 -0.1665719 +J - 0.1020091x(i)离
30、散傅立叶变换X(k)(k=0,1,2,31)的理论值为 0.6939728 +J 3.4997157 2.7922679 +J 8.0504557 9.4029646 +J -9.1350136 1.8664455 +J -3.8338328 1.131827 +J -2.2341573 0.9047939 +J -1.5346293 0.7995572 +J -1.1396094 0.7396056 +J -0.8823144 0.7008616 +J -0.6985654 0.6735758 +J -0.5584785 0.6531094 +J -0.4462450 0.6369913 +
31、J -0.3526891 0.6237884 +J -0.2720860 0.6126129 +J -0.2006419 0.6028833 +J -0.1357032 0.5942004 +J -0.0753137 0.5862775 +J -0.0179492 0.5788996 +J 0.0376517 0.5718985 +J 0.0926070 0.5651358 +J 0.1479833 0.5584921 +J 0.2048808 0.5518591 +J 0.2645222 0.5451336 +J 0.3283649 0.5382144 +J 0.3982571 0.5310015 +J 0.4766778 0.5234037 +J 0.5671323 0.5153625 +J 0.6748500 0.5069258 +J