C语言实现FFT(非递归蝶形运算版)

19 篇文章 1 订阅

蝶形算法可参考链接
代码如下:

#include<iostream>
#include<complex.h>
#include<math.h>
#define PI 3.14159
#define N 32
#define STAGE ((int)(log(N)/log(2)))
using namespace std;
typedef complex<double> data_t;

void FFT(data_t Xin[N],data_t Xout[N]){
        //旋转因子计算
        data_t W[N/2];
        for(int i=0;i<N/2;i++){
               W[i].real(cos(2*PI*i/N));
               W[i].imag(-sin(2*PI*i/N));
        }
        //中间变量
        data_t Xtmp[STAGE+1][N];
        for(int i=0;i<N;i++)
        {
            Xtmp[0][i]=Xin[i];
        }
        //计算
        for(int i=0;i<STAGE;i++)                             //共i个stage
        {
              //第i个stage,根据Xtmp[i]计算Xtmp[i+1]
              int span=1<<i;                                    //跨度=蝶形单元大小的一半
              int group_num=(int)N/(2*span);        //蝶形单元数目
              int group_size=(int)N/group_num;    //蝶形单元大小
              for(int k=0;k<group_num;k++){
                    for(int t=0;t<group_size/2;t++){                //需要group_size次单位根的t次方
                            data_t w={cos(2*PI*t/group_size),-sin(2*PI*t/group_size)};
                            Xtmp[i+1][k*group_size+t] = Xtmp[i][k*group_size+t]+w*Xtmp[i][k*group_size+t+span];
                            Xtmp[i+1][k*group_size+t+group_size/2] = Xtmp[i][k*group_size+t]-w*Xtmp[i][k*group_size+t+span];
                    }
              }
        }
        for(int i=0;i<N;i++){
            Xout[i]=Xtmp[STAGE][i];
        }
}

void bit_reverse(data_t* Xin,int n){
         int fft8table[8]={0,4,2,6,1,5,3,7};
        int fft16table[16]={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
        int fft32table[32]={0,16,8,24,4,20,12,28,2,18,10,26,6,22,14,30,1,17,9,25,5,21,13,29,3,19,11,27,7,23,15,31};
        data_t *Tmp=new data_t[n];
        switch(n){
            case 8:{
                for(int i=0;i<8;i++)
                    Tmp[i]=Xin[fft8table[i]];
                for(int i=0;i<8;i++)
                    Xin[i]=Tmp[i];
                break;
            }
            case 16:{
                for(int i=0;i<16;i++)
                    Tmp[i]=Xin[fft16table[i]];
                for(int i=0;i<16;i++)
                    Xin[i]=Tmp[i];
                break;
            }
            case 32:{
                for(int i=0;i<32;i++)
                    Tmp[i]=Xin[fft32table[i]];
                for(int i=0;i<32;i++)
                    Xin[i]=Tmp[i];
                break;
            }
            default:
                cout<<"error value of n"<<endl;
        }
}

int main(){
    //支持8,16,32点FFT
    complex<double> X[N];
    complex<double> Y[N];
    for(int i=0;i<N;i++){
        X[i].real(i);
        X[i].imag(0);
    }
    bit_reverse(X,N);
    FFT(X,Y);
    for(int i=0;i<N;i++)
        cout<<Y[i]<<endl;
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA硅农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值