正文

基4FFT(DIF)代码2007-11-02 17:54:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/vfdff/30690.html

分享到:

/**** fft programe ***** Dev-C++ 4.9.9.2 ************/
// 02-11-07 17:51
/* 修改 radix 使循环控制完全取决于级数,为流水工作做准备 */
// 用不同的 RAM 存储中间结果 ,单此时仍旧是"原位",需要修改保证每次从不同的RAM读取一个数据

#include<math.h>
#include<stdio.h>
#include<stdlib.h>

#define STAGE 2
#define DISPLAY 1

#define Num (1<<STAGE*2)
#if DISPLAY
   int count = 0;
#endif
#define START 0   
#define END 8       
#define WINTH   ((1<<15)-1)
#define F(t)  ((int)(WINTH*t)&0xffff)
double result[Num];
double x[STAGE+1][Num],y[STAGE+1][Num];
double TAB[Num*2];

const double PI = 3.14159265358979323846;
const double EI = PI*2/Num;

void rad4(double x0[],double y0[],double x1[],double y1[],double TAB[],
                 int i,int n2,int adr1,int adr2,int adr3)
{
    int i1,i2,i3;
    double co1,co2,co3,si1,si2,si3;
    double r1,r2,r3,r4,s1,s2,s3,s4;
   
    i1=i+n2;i2=i1+n2;i3=i2+n2;                       /* 数据位置 */
    #if DISPLAY
        if(count>=START && count<END){
            printf("data: (%d)%.1f+%.1f, (%d)%.1f+%.1f, (%d)%.1f+%.1f, (%d)%.1f+%.1f\n",i,x0[i],y0[i],i1,x0[i1],y0[i1],i2,x0[i2],y0[i2],i3,x0[i3],y0[i3]);
        }
    #endif
    co1=TAB[2*adr1];co2=TAB[2*adr2];co3=TAB[2*adr3]; /* 旋转因子 */
    si1=TAB[2*adr1+1];si2=TAB[2*adr2+1];si3=TAB[2*adr3+1];
    #if DISPLAY
        if(count>=START && count<END){
            printf("factor: (%d)%4x+%xj, (%d)%4x+%xj, (%d)%4x+%xj\n",adr1,F(co1),F(si1),adr2,F(co2),F(si2),adr3,F(co3),F(si3));
        }
    #endif
    r1=x0[i]+x0[i2];r3=x0[i]-x0[i2];
    s1=y0[i]+y0[i2];s3=y0[i]-y0[i2];
    r2=x0[i1]+x0[i3];r4=x0[i1]-x0[i3];
    s2=y0[i1]+y0[i3];s4=y0[i1]-y0[i3];

    x1[i]=r1+r2; y1[i]=s1+s2; 
    r2=r1-r2; r1=r3-s4;r3=r3+s4;
    s2=s1-s2; s1=s3+r4;s3=s3-r4;
    x1[i1]=co1*r3+si1*s3;y1[i1]=co1*s3-si1*r3;
    x1[i2]=co2*r2+si2*s2;y1[i2]=co2*s2-si2*r2;
    x1[i3]=co3*r1+si3*s1;y1[i3]=co3*s1-si3*r1;
    #if DISPLAY
        if(count>=START & count<END){
            printf("result: (%d)%.1f+%.1f, (%d)%.1f+%.1f, (%d)%.1f+%.1f, (%d)%.1f+%.1f\n",i,x1[i],y1[i],i1,x1[i1],y1[i1],i2,x1[i2],y1[i2],i3,x1[i3],y1[i3]);
        }
    #endif
}

void switchadr(double x[],double y[],int n)
{
    double tempx,tempy;
    int i,j,k;
    for(i=0,j=0;i<=n-1;i++)
    {
        if(i<j)
        {
            tempx=x[j]; x[j]=x[i]; x[i]=tempx; 
            tempy=y[j]; y[j]=y[i]; y[i]=tempy;
        }
        k=n/4;
        while(3*k<(j+1)&&(j>0) )
        {
            j=j-3*k; k=k/4;
        }
        j=j+k;
    }
}

void radix4(double x0[],double y0[],double x1[],double y1[],double TAB[],int n,int L) // 只处理第L级
{
    int i,j,e,n1,n2;
    int a,b,c;
   
    n1 = n >> (2*L);       
    n2 = n1 >> 2;   
    e = 1 <<(2*L);
    for(j=0;j<n2;j++)
    {
        a=j*e;  b=a+a; c=a+b;
        a=a%n;  b=b%n; c=c%n;

        for(i=j;i<n;i+=n1)
        {
            #if DISPLAY
                if(count>=START & count<END)
                printf("Group : %d\n",count) ;
           #endif
           rad4(x0,y0,x1,y1,TAB,i,n2,a,b,c);
           #if DISPLAY
               count ++ ;
           #endif
        }
    }
}

/***************** ShowResult programe *****************/
/* 显示 0 -- 4^m-1 数据 */

void ShowResult(double x[],double y[],const int n)
{
    int i;
    double result[n];
    printf("n     real(n)      imag(n)      fabs(n)\n") ;
    for(i=0;i<n;i++)    
    {
        result[i]=sqrt( x[i]*x[i]+y[i]*y[i] ); /* 取模 */
        printf("%d     %f     %f     %f\n",i,x[i],y[i],result[i]) ;
    }
}

/*****************main programe********************/
int main(void)
{
    int i,k;
    /*******赋初值**********/
    for(i=0;i<Num;i++)
    {
        x[0][i]=i;   y[0][i]= 0 ;
    }

    /*******给表格赋初值**********/
    for(i=0;i<Num;i++)          /*计算NUM 点的FFT的旋转因子*/
    {
        TAB[i*2] = cos(EI*i);   /* 存余弦值 */
        TAB[i*2+1] = sin(EI*i); /* 存正弦值 */
    }

    for(k=0;k<STAGE;k++)    /*内部循环没有使用K值,只是用来控制循环次数而已*/
    {
        radix4(x[k],y[k],x[k+1],y[k+1],TAB,Num,k);
        #if !DISPLAY
            ShowResult(x[k+1],y[k+1],Num);
        #endif
    }

    switchadr(x[STAGE],y[STAGE],Num);
   
    getchar();
    return 0;
}

阅读(607) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册