2D-FFT(二维快速傅里叶变换)
#include
#include
#include
#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 {
for(j=0; 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 {
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 {
for(j=0; 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 {
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 {
for(j=0; j {
fscanf(dataFile,"%f",&A_In[i*nLen+j].real);
A_In[i*nLen+j].image = 0.0;
}
}
fclose(dataFile);
for(i=0; i {
for(j=init_nLen; j {
A_In[i*nLen+j].real = 0.0;
A_In[i*nLen+j].image = 0.0;
}
}
for(i=init_mLen; i {
for(j=0; 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 {
for(j=0; 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 {
for(j=0; 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 {
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 {
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 {
for(j=0; 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 {
a[i] = 0;
}
b[0] = 0;
for(i=1; i {
j = 0;
while(a[j] != 0)
{
a[j] = 0;
j++;
}
a[j] = 1;
b[i] = 0;
for(j=0; 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