/**** 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;
}
正文
基4FFT(DIF)代码2007-11-02 17:54:00
【评论】 【打印】 【字体:大 中 小】 本文链接:http://blog.pfan.cn/vfdff/30690.html
阅读(742) | 评论(0)
版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!
评论