快速傅里叶变换的递归实现

转载于:https://blog.csdn.net/a493823882/article/details/78731540

快速傅里叶变换算法原理简述 基于递归的fft实现

一、FFT:Fast Fourier Transform

按定义式计算DFT的复杂度为O(n^2),我们可以使用FFT将复杂度优化到O(nlog2N)。

长度为8的FFT的过程由如下图展示,称为蝶形运算:


对于长为N=2^n的序列x[n],根据DFT:



那么DFT可写为:


所以FFT的思想是每次都把序列分为奇序列与偶序列。

在接下来的程序中,把取x[n]的部分序列的编号称为index,如index=(4,3),即对应子序列x[4n+3]。

长度为8的序列分解如下图,每个都展示了index值:


这便是FFT算法


二、FFT的递归实现

1.核心代码:

采用C++实现,核心递归解释位于程序注释


 
 
  1. #include <iostream>
  2. #include <complex>
  3. #include <cmath>
  4. using namespace std;
  5. #define comp complex<double>
  6. #define PI acos(-1.0)
  7. #define I comp(0,1)
  8. const int N= 8; //设长度8
  9. int x[N];
  10. comp X[N];
  11. struct index{ //表示取x[n]的index,eg:mul=4,add=3,即取x[4n+3]
  12. int mul,add;
  13. index( int m, int a){
  14. mul=m;
  15. add=a;
  16. }
  17. index operator+( int a){
  18. return index(mul,add+a);
  19. }
  20. index operator*( int m){
  21. return index(mul*m,add);
  22. }
  23. };
  24. comp WN(double n,double N){ //旋转因子
  25. return exp( -1.0*I* 2.0*PI/N*n);
  26. }
  27. comp fft(int k,index i)
  28. {
  29. if(i.mul==N)
  30. return x[i.add];
  31. return fft(k,i* 2)+fft(k,i* 2+i.mul)*WN(i.mul*k,N);
  32. /* 核心递归:fft的思想是把序列分为奇与偶两部分,也就是相邻的分开,
  33. * 因为对于当前index为mul的序列,在x[n]中每隔一个mul取一个数,那么对于当前序列x[mul*n+add]
  34. * 每个数在x[n]中相邻mul,那么令mul=m, add=a,x[mn+a]=x[2*mn+a]+x[2*mn+a+m]
  35. */
  36. }
  37. int main()
  38. {
  39. for( int i= 0;i<N;i++)
  40. x[i]=i; //设序列为0,1,2,...,7
  41. for( int i= 0;i<N;i++)
  42. cout<<fft(i,index( 1, 0))<< endl;
  43. return 0;
  44. }
注:用complex类运行fft时间较长,只作为演示代码,不用于使用。

2.正确检验

长度为8的序列0~7的结果:


Matlab运行结果:



长度为16的序列0~15的结果:


Matlab运行结果:


可见程序可靠。


3.递归顺序展示:

展示了计算一次X[k]的值,每次程序输出的是当前递归的index值



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值