2D-FFT(二维快速傅里叶变换) 源码

2D-FFT(二维快速傅里叶变换)  



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


#define intsize sizeof(int)
#define complexsize sizeof(complex)
#define PI 3.1415926


int *a,*b;
int nLen,init_nLen,mLen,init_mLen,N,M;
FILE *dataFile;


typedef struct{
    float real;
    float image;
}complex;


complex *A,*A_In,*W;


complex Add(complex, complex);
complex Sub(complex, complex);
complex Mul(complex, complex);
int calculate_M(int);
void reverse(int,int);
void readData();
void fft(int,int);
void printResult();




int main()
{
    int i,j;


    readData();


    A = (complex *)malloc(complexsize*nLen);
    reverse(nLen,N);
    for(i=0; i<mLen; i++)
    {
        for(j=0; j<nLen; j++)
        {
            A[j].real = A_In[i*nLen+b[j]].real;
            A[j].image = A_In[i*nLen+b[j]].image;
        }
        
        fft(nLen,N);
        for(j=0; j<nLen; j++)
        {
            A_In[i*nLen+j].real = A[j].real;
            A_In[i*nLen+j].image = A[j].image;
        }
    }
    free(A);
 
    A = (complex *)malloc(complexsize*mLen);
    reverse(mLen,M);
    for(i=0; i<nLen; i++)
    {
        for(j=0; j<mLen; j++)
        {
            A[j].real = A_In[b[j]*nLen+i].real;
            A[j].image = A_In[b[j]*nLen+i].image;
        }


        fft(mLen,M);
        for(j=0; j<mLen; j++)
        {
            A_In[j*nLen+i].real = A[j].real;
            A_In[j*nLen+i].image = A[j].image;
        }
    }
    free(A);


    printResult();
 
    return 0;
}




void readData()
{
     int i,j;


     dataFile = fopen("dataIn.txt","r");
     fscanf(dataFile,"%d %d",&init_mLen,&init_nLen);
     M = calculate_M(init_mLen);
     N = calculate_M(init_nLen);
     nLen = (int)pow(2,N);
     mLen = (int)pow(2,M);
    
     A_In = (complex *)malloc(complexsize*nLen*mLen);


     for(i=0; i<init_mLen; i++)
     {
         for(j=0; j<init_nLen; j++)
         {
             fscanf(dataFile,"%f",&A_In[i*nLen+j].real);
             A_In[i*nLen+j].image = 0.0;
         }
     }
     fclose(dataFile);


     for(i=0; i<mLen; i++)
     {
         for(j=init_nLen; j<nLen; j++)
         {
             A_In[i*nLen+j].real = 0.0;
             A_In[i*nLen+j].image = 0.0;
         }
     }


     for(i=init_mLen; i<mLen; i++)
     {
         for(j=0; j<init_nLen; j++)
         {
             A_In[i*nLen+j].real = 0.0;
             A_In[i*nLen+j].image = 0.0;
         }
     }


     printf("Reading initial datas:\n");
     for(i=0; i<init_mLen; i++)
     {
         for(j=0; j<init_nLen; j++)
         {
             if(A_In[i*nLen+j].image < 0)
             { 
                 printf("%f%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
             else
             {
                 printf("%f+%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
         }
         printf("\n");
     }
  
     printf("\n");
  
     printf("Reading formal datas:\n");
     for(i=0; i<mLen; i++)
     {
         for(j=0; j<nLen; j++)
         {
             if(A_In[i*nLen+j].image < 0)
             { 
                 printf("%f%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
             else
             {
                 printf("%f+%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
         }
         printf("\n");
     }
}




void fft(int fft_nLen, int fft_M)
{
     int i;
     int lev,dist,p,t;
     complex B;


     W = (complex *)malloc(complexsize*fft_nLen/2);


     for(lev=1; lev<=fft_M; lev++)
     {
         dist = (int)pow(2,lev-1);
         for(t=0; t<dist; t++)
         {
             p = t*(int)pow(2,fft_M-lev);
             W[p].real = (float)cos(2*PI*p/fft_nLen);
             W[p].image = (float)(-1*sin(2*PI*p/fft_nLen));
             for(i=t; i<fft_nLen; i=i+(int)pow(2,lev))
             {
                 B = Add(A[i],Mul(A[i+dist],W[p]));
                 A[i+dist] = Sub(A[i],Mul(A[i+dist],W[p]));
                 A[i].real = B.real;
                 A[i].image = B.image;
             }
         }
     }


     free(W);
}




void printResult()
{
     int i,j;
 
     printf("Output results:\n");
     for(i=0; i<mLen; i++)
     {
         for(j=0; j<nLen; j++)
         {
             if(A_In[i*nLen+j].image < 0)
             {
                 printf("%f%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
             else
             {
                 printf("%f+%fi\t",A_In[i*nLen+j].real,A_In[i*nLen+j].image);
             }
         }
         printf("\n");
     }
 
     free(A_In);
}


int calculate_M(int len)
{
    int i;
    int k;
 
    i = 0;
    k = 1;
    while(k < len)
    {
        k = k*2;
        i++;
    }
 
    return i;
}


void reverse(int len, int M)
{
    int i,j;
 
    a = (int *)malloc(intsize*M);
    b = (int *)malloc(intsize*len);
 
    for(i=0; i<M; i++)
    {
        a[i] = 0;
    }
 
    b[0] = 0;
    for(i=1; i<len; i++)
    {
        j = 0;
        while(a[j] != 0)
        {
            a[j] = 0;
            j++;
        }
  
        a[j] = 1;
        b[i] = 0;
        for(j=0; j<M; j++)
        {
            b[i] = b[i]+a[j]*(int)pow(2,M-1-j);
        }
    }
}


complex Add(complex c1, complex c2)
{
    complex c;
    c.real = c1.real+c2.real;
    c.image = c1.image+c2.image;
    return c;
}


complex Sub(complex c1, complex c2)
{
    complex c;
    c.real = c1.real-c2.real;
    c.image = c1.image-c2.image;
    return c;
}


complex Mul(complex c1, complex c2)
{
    complex c;
    c.real = c1.real*c2.real-c1.image*c2.image;
    c.image = c1.real*c2.image+c2.real*c1.image;
    return c;
}


测试:


dataIn.txt文件的内容如下:


5 6
1 2 3 4 4 5
3 2 1 2 4 5
2 3 4 5 1 2
2 4 5 2 1 2
3 2 4 8 9 0


结果:


Reading initial datas:
1.000000+0.000000i 2.000000+0.000000i 3.000000+0.000000i 4.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i
3.000000+0.000000i 2.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i
2.000000+0.000000i 3.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i
2.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 2.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i
3.000000+0.000000i 2.000000+0.000000i 4.000000+0.000000i 8.000000+0.000000i 9.000000+0.000000i 0.000000+0.000000i


Reading formal datas:
1.000000+0.000000i 2.000000+0.000000i 3.000000+0.000000i 4.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




3.000000+0.000000i 2.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




2.000000+0.000000i 3.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




2.000000+0.000000i 4.000000+0.000000i 5.000000+0.000000i 2.000000+0.000000i 1.000000+0.000000i 2.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




3.000000+0.000000i 2.000000+0.000000i 4.000000+0.000000i 8.000000+0.000000i 9.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i 0.000000+0.000000i




Output results:
95.000000+0.000000i  -23.556349-31.142136i  13.000000-6.000000i 7.556350+2.857865i


-1.000000+0.000000i 7.556349-2.857865i   13.000000+6.000000i  -23.556351+31.142136i




-6.292893-40.334526i -15.606602+17.020815i  -6.707107-11.535534i 7.292892-1.292893i


-9.707107+3.707107i 2.292893-11.363961i   6.020815+7.878680i   12.363961-8.363960i




28.000000-1.000000i  -8.828428-1.000000i 10.000000-5.000000i -4.100504-2.071068i 


6.000000+1.000000i  -3.171573-1.000000i  12.000000-11.000000i -23.899494+12.071068i




-7.707106-6.334524i  8.707107+2.707107i  -18.020817-12.121321i 5.606601+7.020816i


-8.292893-2.292893i -0.363960-4.363961i  -5.292893+4.464466i  3.707107-1.363961i




29.000000+0.000000i  -16.485281-14.899494i  5.000000+12.000000i  0.485282-4.899495i 


 1.000000+0.000000i  0.485281+4.899495i   5.000000-12.000000i  -16.485283+14.899494i




-7.707106+6.334524i  3.707107+1.363961i   -5.292893-4.464466i  -0.363961+4.363961i 


-8.292893+2.292893i  5.606602-7.020816i   -18.020815+12.121321i  8.707107-2.707106i




28.000000+1.000000i  -23.899496-12.071068i 12.000000+11.000000i -3.171573+1.000000i 


 6.000000-1.000000i  -4.100505+2.071068i  10.000000+5.000000i  -8.828426+1.000000i




-6.292895+40.334526i 12.363961+8.363962i  6.020816-7.878679i 2.292892+11.363961i  


-9.707107-3.707107i   7.292893+1.292893i  -6.707107+11.535534i  -15.606600-17.020817i
Press any key to continue
  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值