数字信号处理算法(3)-实序列快速傅立叶变换
admin 于 2014年05月30日 发表在 数字信号处理
1. 功能
用N点复序列快速傅立叶变换来计算2N点的实序列离散傅立叶变换。
2. 方法简介
3. 算法r1fft.h
#ifndef R1FFT_H_ #define R1FFT_H_ /*形参介绍: * x——双精度实型一位数组,长度为n。 * 开始时存放要变换的实数据,最后存放变换结果的前n/2+1个值, * 其存储顺序为[Re(0),Re(1),...Re[n/2],Im(n/2-1),...,Im(1)], * 其中Re(0)=X(0),Re(n/2)=X(n/2),根据共轭对称性,很容易写出后半部分的值。 * n——整型变量,数据长度,必须是2的整数次幂. */ #include "fft.h" void r1fft( double x[], int n); void r1fft( double x[], int n) { int i,n1; double a,c,e,s,fr,fi,gr,gi,*f,*g; f=malloc(n/2*sizeof(double)); g=malloc(n/2*sizeof(double)); n1=n/2; e=3.141592653589793/n1; for(i=0;i<n1;i++) { f[i]=x[2*i]; g[i]=x[2*i+1]; } fft(f,g,n1,1); x[0]=f[0]+g[0]; x[n1]=f[0]-g[0]; for(i=1;i<n1;i++) { fr=(f[i]+f[n1-i])/2; fi=(g[i]-g[n1-i])/2; gr=(g[n1-i]+g[i])/2; gi=(f[n1-i]-f[i])/2; a=i*e; c=cos(a); s=sin(a); x[i]=fr+c*gr+s*gi; x[n-i]=fi+c*gi-s*gr; } free(f); free(g); } #endif /* R1FFT_H_ */
4. 例程实现
具体实现main.c函数如下:
/* * main.c * * Created on: 2014年5月27日 * Author: lu */ #include <stdio.h> #include <math.h> #include "r1fft.h" int main(void) { int i,n; double x[64]; FILE *fp; n=64; for(i=0;i<10;i++) { x[i]=0; } for(i=10;i<n;i++) { x[i]=exp(-(i-10)/15.0)*sin(6.2831853*(i-10)/16.0); } r1fft(x,n); printf("\n离散傅立叶变换:\n"); printf(" %10.7f\t\t",x[0]); printf(" \t%10.7f+J %10.7f\n",x[1],x[n-1]); for(i=2;i<n/2;i+=2) { printf("%10.7f+J %10.7f\t",x[i],x[n-i]); printf("\t%10.7f+J %10.7f\t",x[i+1],x[n-i-1]); printf("\n"); } printf("%10.7f",x[n/2]); for(i=1;i<n/2;i++) { x[i]=sqrt(x[i]*x[i]+x[n-i]*x[n-i]); } x[n/2]=fabs(x[n/2]); fp=fopen("r1fft.dat","w"); for(i=0;i<=n/2;i++) { fprintf(fp,"%d\t%f\n",i,x[i]); } fclose(fp); }
5. 离散傅立叶变换X(k)(k=0,1,..32)
6. 输入序列x(n)的频谱