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

📄 fft.c

📁 实现对信号进行傅立叶变化的程序
💻 C
字号:
#define Pi 3.141592653589793238462643

void FFT_ArraySetValue(double *s1, double *s2, int numdat)
{
	int i;
	for(i=0;i<numdat;i++){s2[i]=s1[i];}
}

void FFT_swap(double *s1, double *s2)
{
	double temp;
	temp=(*s1);
	(*s1)=(*s2);
	(*s2)=temp;
}

double windfunc(double t, double h,int numdat,int PP)
{
	double y;
	switch(PP)
	{
	case 1: 
		y=(1+cos(Pi*t/(double)numdat/h));
		break;
	case 2: 
		y=2./3.*(1+cos(Pi*t/(double)numdat/h))*(1+cos(Pi*t/(double)numdat/h));
		break;
	case 3: 
		y=2./5.*pow((1+cos(Pi*t/(double)numdat/h)),3.);
		break;
	case 4: 
		y=8./35.*pow((1+cos(Pi*t/(double)numdat/h)),4.);
		break;
	case 5: 
		y=8./63.*pow((1+cos(Pi*t/(double)numdat/h)),5.);
		break;
	case 6: 
		y=16./231.*pow((1+cos(Pi*t/(double)numdat/h)),6.);
		break;
	}
	return y;
	
}




void WindData(double *xreal,double *yimag,
			  double h, int numdat,int PP)
{
	int i;
	for(i=0;i<numdat;i++)
	{
		xreal[i]=xreal[i]*windfunc(i*h,h,numdat,PP);
		yimag[i]=yimag[i]*windfunc(i*h,h,numdat,PP);
	}
	
}



void FFT(double *xreal, double *yimag, 
		 double *freq, double *ampl,
		 double h, int numdat, int flag,int PP)
{
	int maxpower,arg,cntr,pnt0,pnt1,i;
	int j,a,b,k;
	double sign,prodreal,prodimag,harm;
	double *cosary;
	double *sinary;
	double *tempx;
	double *tempy;
	
	cosary=(double *) calloc(numdat,sizeof(double));
	if(cosary==NULL) exit(1);
	sinary=(double *) calloc(numdat,sizeof(double));
	if(sinary==NULL) exit(1);
	tempx=(double *) calloc(numdat,sizeof(double));
	if(tempx==NULL) exit(1);
	tempy=(double *) calloc(numdat,sizeof(double));
	if(tempy==NULL) exit(1);
	
	FFT_ArraySetValue(xreal,tempx,numdat);
	FFT_ArraySetValue(yimag,tempy,numdat);
	
	WindData(xreal,yimag,h,numdat,PP);
	
	j=0;
	if(flag!=0)
	{
		sign=1.0;
		for(i=0;i<=numdat-1;i++)
		{
			xreal[i]=xreal[i]/numdat;
			yimag[i]=yimag[i]/numdat;
		}
	}
	else
	{
		sign=-1.0;
	}
	
	for(i=0;i<=numdat-2;i++)
	{
		if(i<j)
		{
			FFT_swap(&xreal[i],&xreal[j]);
			FFT_swap(&yimag[i],&yimag[j]);
		}
		
		k=numdat/2;
		while(k<=j)
		{
			j=j-k;
			k=k/2;
			
		}
		j=j+k;
	}
	maxpower=0;
	i=numdat;
	while(i!=1)
	{
		maxpower=maxpower+1;
		i=i/2;
	}
	harm=2*Pi/numdat;
	for(i=0;i<=numdat-1;i++)
	{
		sinary[i]=sign*sin(harm*i);
		cosary[i]=cos(harm*i);
	}
	a=2;
	b=1;
	for(cntr=1;cntr<=maxpower;cntr++)
	{
		pnt0=numdat/a;
		pnt1=0;
		for(k=0;k<=b-1;k++)
		{
			i=k;
			while(i<numdat)
			{
				arg=i+b;
				if(k==0)
				{
					prodreal=xreal[arg];
					prodimag=yimag[arg];
				}
				else
				{
					prodreal=xreal[arg]*cosary[pnt1]-yimag[arg]*sinary[pnt1];
					prodimag=xreal[arg]*sinary[pnt1]+yimag[arg]*cosary[pnt1];
				}
				xreal[arg]=xreal[i]-prodreal;
				yimag[arg]=yimag[i]-prodimag;
				xreal[i]=xreal[i]+prodreal;
				yimag[i]=yimag[i]+prodimag;
				i=i+a;
			}
			pnt1=pnt1+pnt0;
		}
		a=2*a;
		b=b*2;
	} 
	for(i=0;i<numdat/2;i++)
	{ 
		FFT_swap(&xreal[i],&xreal[i+numdat/2]);
		FFT_swap(&yimag[i],&yimag[i+numdat/2]);
	}
	
	FFT_ArraySetValue(xreal,freq,numdat);
	FFT_ArraySetValue(yimag,ampl,numdat);
	FFT_ArraySetValue(tempx,xreal,numdat);
	FFT_ArraySetValue(tempy,yimag,numdat);
	
	
	free(cosary);
	free(sinary);
	free(tempx);
	free(tempy);
}

void FFTClac(double *xreal, double *yimag,
			 double *freq, double *ampl,
			 double h, int numdat,int PP)
{
	FFT(xreal,yimag,freq,ampl,h,numdat,0,PP);
}

void FFTClacFreqAmplPhase(double *xreal, double *yimag, 
						  double *freq, double *ampl,
						  double h,int numdat,int PP)
{
	int i;
	
	FFTClac(xreal,yimag,freq,ampl,h,numdat,PP);
	for(i=0;i<numdat;i++)
	{
		ampl[i]=sqrt(freq[i]*freq[i]+ampl[i]*ampl[i])/numdat;
		freq[i]=(double)(i-numdat/2.)*2.*Pi/(double)numdat/h; 
	}
	
}

⌨️ 快捷键说明

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