⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fft_gai.c

📁 标准C语言的高效的fft算法
💻 C
字号:
#include	<stdio.h>
#include	<math.h>
#include	<time.h>
#include	<malloc.h>

void Changeorder_1(float *R, int N);					//倒叙
void PowerM(int N);										//求幂			
void CaculateWn(int N);									//求旋转因子(半长FFT)
void CaculateWn1(int N);								//求旋转因子(对偶组合)			
void Displaydata( float *R, float *I, int N,int flag);	//显示输入输出
void FFT_r(float *R, float *I, int N,int M);			//实序列FFT 

int i=0,N=0,M=0,CT=0;									//循环变量i,序列长,幂,循环次数
clock_t before,after;									//初始时间,结束时间

#define MAX 2048										
const double PI=3.14159265;								

float R2[MAX];		//测试循环用实部
float I2[MAX];		//测试循环用虚部
float R[MAX];		//输入/输出序列的实部
float I[MAX];		//输入/输出序列的虚部
float WR[MAX];		//旋因子实部
float WI[MAX];		//旋因子虚部
float WR1[MAX];		//半长序列用旋因子实部
float WI1[MAX];
float R1[MAX];		//R的偶序列作为半长序列,记为x1
float I1[MAX];		//I的偶序列作为半长序列,记为x2
float xr[MAX];		//x1 FFT后的实部
float xi[MAX];		//x1 FFT后的虚部
float yr[MAX];		//
float yi1[MAX];		//
float or[MAX];		//半长序列实部
float oi[MAX];		//半长序列虚部
int   a[MAX]={0,1};	//记录倒序数下标



//////////////////////////////////////////////////////////////////////////MAIN
void main()
{
	
	int c=0;	//循环测试变量
	
	/////////////////////////////////////////////////////////////////读取信号
	FILE *fp  = NULL;
	char filename[20];
	float in1=0;
	float in2=0;
	
loop:printf("input file name:");
	 scanf("%s",filename);
	 fp=fopen(filename,"r");
	 if (fp==NULL)
	 {
		 printf("file is not exist! please input again:\n");
		 goto loop;
	 }
	 else
	 {
		 fscanf(fp,"%d\n",&N);
		 for (i=0;i<N;i++)
		 {
			 fscanf(fp,"%f\n",&in1);
			 R[i]=in1;
			 I[i]=0;
			 in1=0;
		 }
	 }
	 fclose(fp);	
	 
	 Displaydata(R,I,N,0);
	 printf("input cycle times:");
	 scanf("%d",&CT);
	 
	 ////////////////////////////////////////////////////////////////////////FFT运算
	 
	 before=clock();		//初始时间
	 PowerM(N);			    //求幂
	 Changeorder_1(R,N);	//求倒序数
	 
	 CaculateWn1(N);		//初始旋转因子表1
	 CaculateWn(N);		    //初始旋转因子表2
	 
	 for (c=CT;c>0;c--)
	 {
		 for (i=0;i<N;i++)	//保存并调整倒叙后的输入以循环
		 {	 
			 *(R2+i)=*(R+*(a+i));
			 *(I2+i)=*(I+*(a+i));		 
		 }
		 		 
		 FFT_r(R2,I2,N,M);	//求解FFT		 
	 }
	 
	 after=clock();		//计时结束
	 
	 ////////////////////////////////////////////////////////////////////输出结果
	 
	 Displaydata(R2,I2,N,1);	
	 printf("cycle:%d   time cost:%f\n",CT,(float)(after-before)/CLOCKS_PER_SEC);
	 
}


//////////////////////////////////////////////////////////////////////////

void PowerM(int N)
{
	M=0;
	while (N>1)
	{
		M++;
		N/=2;		
	}	
}

void Changeorder_1(float *R, int N)
{
	int i,j;
	
    for(i=2;i<N;i<<=1)
    {
        for(j=0;j<i;j++)
        {
			*(a+j)=*(a+j)<<1;
			*(a+j+i)=*(a+j)+1;			
        }
	}	
}


void CaculateWn(int N)
{	
	int n = N/4;
	for(i=0;i<n;i++){
		WI[i] =-(float)sin(PI/n*i);
		WR[i] = (float)cos(PI/n*i);
	}		
}


void CaculateWn1(int N)
{		
	int n = N/2;
	for(i=0;i<n;i++){
		WI1[i] =-(float)sin(PI/n*i);
		WR1[i] = (float)cos(PI/n*i);
	}
}


void FFT_r(float *R, float *I,int N, int M)
{	
	register int N1;
	int arg,cntr,pnt0,pnt1;
	int a,b,k;
	float pr,pi;//,tmp;
	
	register float temp1;
	register float temp2;
	
	int p;
	
    register float a1,b1;
	
	////////////分层计算初始化 
	a=8;
	b=4;
	
	N>>=1;
	M--;
	
	p=N/4;   
	
	
	
	///////////////////////////////////////////////////////////后倒叙再奇偶抽=先倒叙再前后分
    for (i=0;i<N;i++)
	{
		R1[i]=R[i];
		I1[i]=R[i+N];
	}
	
	////////////////////////////////////////////////////////////第一级蝶型运算 
	for(i=0;i<N;i=i+2)
	{		
		temp1=*(R1+i+1);
		*(R1+i+1)=*(R1+i)-temp1;
		*(R1+i)=*(R1+i)+temp1;
		
		temp2=*(I1+i+1);
		*(I1+i+1)=*(I1+i)-temp2;
		*(I1+i)=*(I1+i)+temp2;
	}
	
	/////////////////////////////////////////////////////////第二级蝶型运算 

    for(i=0;i<N;i=i+4)
    {	
		a1=WR[p];
		b1=WI[p];
        temp1=*(R1+i+2);
		*(R1+i+2)=*(R1+i)-temp1;
		*(R1+i)=*(R1+i)+temp1;
		
		temp2=*(I1+i+2);
		*(I1+i+2)=*(I1+i)-temp2;
		*(I1+i)=*(I1+i)+temp2;
		
        pr=*(R1+i+3)*a1-*(I1+i+3)*b1;
		pi=*(R1+i+3)*b1+*(I1+i+3)*a1;		
		
        *(R1+i+3)=*(R1+i+1)-pr;
        *(R1+i+1)=*(R1+i+1)+pr;
        *(I1+i+3)=*(I1+i+1)-pi;
        *(I1+i+1)=*(I1+i+1)+pi;	
    }
	
	
	///////////////////////////////////////////////////////////////三-M级正常运算 
	for(cntr=3;cntr<=M;++cntr){
		//pnt0=nfft/a;
		pnt0=N>>cntr;
		pnt1=0;
		for(k=0;k<=b-1;++k){
					
			i=k;
			while(i<N){  //以旋转因子为循环(与教材上实际一致)
				arg=i+b;    //b实际上是2^(cntr-1)的另一算法,pnt1是旋转因子指数
				//////////////////////////////////////////////////////////////////////////
				if(R1[arg]==0&&I1[arg]==0)
				{  if(R1[i]==0&&I1[i]==0)
				{i=i+a;continue;}
                else
                { R1[arg]=R1[i];I1[arg]=I1[i];i+=a;}
				}
				else
				{
					if (R1[i]==0 && I1[i]==0)
					{
						if(k==0){
							pr=R1[arg];
							pi=I1[arg];
						}
						
						else
						{
							register float wa=WR[pnt1];
							register float wb=WI[pnt1];
							pr=wa*R1[arg]-wb*I1[arg];
							pi=wa*I1[arg]+wb*R1[arg];
							
						}
						R1[arg]=-pr;
						I1[arg]=-pi;
						R1[i]=+pr;
						I1[i]=+pi;
						i=i+a;						
					}
					else
					{
						if(k==0){
							pr=R1[arg];
							pi=I1[arg];
						}						
						else
						{							
							register float wa=WR[pnt1];
							register float wb=WI[pnt1];
							pr=wa*R1[arg]-wb*I1[arg];
							pi=wa*I1[arg]+wb*R1[arg];							
						}
						R1[arg]=R1[i]-pr;
						I1[arg]=I1[i]-pi;
						R1[i]=R1[i]+pr;
						I1[i]=I1[i]+pi;
						i=i+a;						
					}				
				}   
			}
			//////////////////////////////////////////////////////////////////////			
			pnt1=pnt1+pnt0;
		}	
		a = a<<1;
		b = b<<1;
	}
	
	//////////////////////////////////////////////////////////////////////////
	
	
	for (i=0;i<N;i++)
	{
		or[i]=R1[i];
		oi[i]=I1[i];		
	}
	or[N]=or[0];
	oi[N]=oi[0];
	
	for (i=0;i<N;i++)
	{
		xr[i]=(or[i]+or[N-i])/2.0f;
		xi[i]=(oi[i]-oi[N-i])/2.0f;
		yr[i]=(oi[i]+oi[N-i])/2.0f;
		yi1[i]=-(or[i]-or[N-i])/2.0f;
	}
		
	xr[N]=xr[0];
	xi[N]=xi[0];
	yr[N]=yr[0];
	yi1[N]=yi1[0];
	
	for (i=0;i<=N;i++)		//全长序列前半(乘开)
	{
		R[i]=xr[i]+yr[i]*WR1[i]-yi1[i]*WI1[i];
		I[i]=xi[i]+yi1[i]*WR1[i]+yr[i]*WI1[i];		
	}
	N1=N<<1;
	for (i=N+1;i<N1;i++)	//全长后半=前半的共额
	{
		R[i]=R[N1-i];
		I[i]=-I[N1-i];
	}
}	




void Displaydata( float *R, float *I,int N,int flag)
{
	
	if (flag==0)
	{
		printf("\n ---------------input data is-------------------\n");
	}
	else
	{
		printf("\n ---------------the answer is-------------------\n");
	}	
	printf("the length of signal:%d\n",N);
	for ( i=0;i<N;i++)
	{
		printf("x[%d]=(%f,%f)\n",i,R[i],I[i]);		
	}
	
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -