2022年C语言实现FFT .pdf

上传人:Che****ry 文档编号:27262079 上传时间:2022-07-23 格式:PDF 页数:18 大小:135.48KB
返回 下载 相关 举报
2022年C语言实现FFT .pdf_第1页
第1页 / 共18页
2022年C语言实现FFT .pdf_第2页
第2页 / 共18页
点击查看更多>>
资源描述

《2022年C语言实现FFT .pdf》由会员分享,可在线阅读,更多相关《2022年C语言实现FFT .pdf(18页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、#include #include /* 快速福利叶变换C 函数函数简介:此函数是通用的快速傅里叶变换C 语言函数,移植性强,以下部分不依赖硬件。此函数采用联合体的形式表示一个复数,输入为自然顺序的复数(输入实数是可令复数虚部为0) ,输出为经过FFT 变换的自然顺序的复数使用说明:使用此函数只需更改宏定义FFT_N 的值即可实现点数的改变,FFT_N 的应该为 2 的 N 次方,不满足此条件时应在后面补0 函数调用: FFT(s); 时间: 2010-2-20 版本: Ver1.0 参考文献:*/ #include #define PI 3.1415926535897932384626433

2、832795028841971 /定义圆周率值#define FFT_N 128 / 定义福利叶变换的点数struct compx float real,imag; /定义一个复数结构struct compx sFFT_N; /FFT 输入和输出:从 S1 开始存放,根据大小自己定义/* 函数原型: struct compx EE(struct compx b1,struct compx b2) 函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b 输出参数: a 和 b 的乘积,以联合体的形式输出*/ struct compx EE(struct compx a,struc

3、t compx b) struct compx c; c.real=a.real*b.real-a.imag*b.imag; c.imag=a.real*b.imag+a.imag*b.real; return(c); /* 函数原型: void FFT(struct compx *xin,int N) 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 18 页 - - - - - - - - - 函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数: *xin 复

4、数结构体组的首地址指针,struct 型*/ void FFT(struct compx *xin) int f,m,nv2,nm1,i,k,l,j=0; struct compx u,w,t; nv2=FFT_N/2; /变址运算,即把自然顺序变成倒位序,采用雷德算法nm1=FFT_N-1; for(i=0;inm1;i+) if(ij) /如果 ij, 即进行变址 t=xinj; xinj=xini; xini=t; k=nv2; /求 j 的下一个倒位序while(k=j) /如果 k=j,表示 j 的最高位为1 j=j-k; /把最高位变成0 k=k/2; /k/2,比较次高位,依次类

5、推,逐个比较,直到某个位为0 j=j+k; /把 0 改为 1 int le,lei,ip; /FFT 运算核,使用蝶形运算完成FFT 运算f=FFT_N; for(l=1;(f=f/2)!=1;l+) /计算 l 的值,即计算蝶形级数; for(m=1;m=l;m+) / 控制蝶形结级数 /m 表示第m 级蝶形, l 为蝶形级总数l=log(2) N le=2(m-1); /le 蝶形结距离,即第m 级蝶形的蝶形结相距 le 点lei=le/2; /同一蝶形结中参加运算的两点的距离u.real=1.0; /u 为蝶形结运算系数,初始值为1 u.imag=0.0; w.real=cos(PI/

6、lei); /w 为系数商,即当前系数与前一个系数的商w.imag=-sin(PI/lei); for(j=0;j=lei-1;j+) /控制计算不同种蝶形结,即计算系数不同的名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 18 页 - - - - - - - - - 蝶形结 for(i=j;i=FFT_N-1;i=i+le) /控制同一蝶形结运算,即计算系数相同蝶形结 ip=i+lei; /i,ip 分别表示参加蝶形运算的两个节点t=EE(xinip,u); /蝶形运算

7、,详见公式xinip.real=xini.real-t.real; xinip.imag=xini.imag-t.imag; xini.real=xini.real+t.real; xini.imag=xini.imag+t.imag; u=EE(u,w); /改变系数,进行下一个蝶形运算 /* 函数原型: void main() 函数功能:测试FFT 变换,演示函数使用方法输入参数:无输出参数:无*/ void main() int i; for(i=0;iFFT_N;i+) /给结构体赋值 si.real=sin(2*3.141592653589793*i/FFT_N); /实部为正弦波F

8、FT_N 点采样,赋值为1 si.imag=0; /虚部为 0 FFT(s); /进行快速福利叶变换for(i=0;iFFT_N;i+) /求变换后结果的模值,存入复数的实部部分si.real=sqrt(si.real*si.real+si.imag*si.imag); while(1); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 18 页 - - - - - - - - - #include #include /* 快速福利叶变换C 程序包函数简介:此程序包是通用

9、的快速傅里叶变换C 语言函数,移植性强,以下部分不依赖硬件。此程序包采用联合体的形式表示一个复数,输入为自然顺序的复数(输入实数是可令复数虚部为0) ,输出为经过FFT 变换的自然顺序的复数 .此程序包可在初始化时调用create_sin_tab()函数创建正弦函数表,以后的可采用查表法计算耗时较多的sin 和 cos 运算,加快可计算速度使用说明:使用此函数只需更改宏定义FFT_N 的值即可实现点数的改变,FFT_N 的应该为 2 的 N 次方,不满足此条件时应在后面补0。若使用查表法计算sin 值和cos 值,应在调用FFT 函数前调用create_sin_tab()函数创建正弦表函数调用

10、: FFT(s); 时间: 2010-2-20 版本: Ver1.1 参考文献:*/ #include #define FFT_N 128 / 定义福利叶变换的点数#define PI 3.1415926535897932384626433832795028841971 /定义圆周率值struct compx float real,imag; /定义一个复数结构struct compx sFFT_N; /FFT 输入和输出:从S0开始存放,根据大小自己定义float SIN_TABFFT_N/2; /定义正弦表的存放空间/* 函数原型: struct compx EE(struct compx

11、 b1,struct compx b2) 函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b 输出参数: a 和 b 的乘积,以联合体的形式输出*/ struct compx EE(struct compx a,struct compx b) struct compx c; c.real=a.real*b.real-a.imag*b.imag; c.imag=a.real*b.imag+a.imag*b.real; return(c); /* 函数原型: void create_sin_tab(float *sin_t) 名师资料总结 - - -精品资料欢迎下载 - - -

12、 - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 4 页,共 18 页 - - - - - - - - - 函数功能:创建一个正弦采样表,采样点数与福利叶变换点数相同输入参数: *sin_t 存放正弦表的数组指针输出参数:无*/ void create_sin_tab(float *sin_t) int i; for(i=0;i=0&n=FFT_N/2&n2*PI) pi2-=2*PI; a=sin_tab(pi2); return a; /* 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - -

13、 - - - - - 名师精心整理 - - - - - - - 第 5 页,共 18 页 - - - - - - - - - 函数原型: void FFT(struct compx *xin,int N) 函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数: *xin 复数结构体组的首地址指针,struct 型输出参数:无*/ void FFT(struct compx *xin) int f,m,nv2,nm1,i,k,l,j=0; struct compx u,w,t; nv2=FFT_N/2; /变址运算,即把自然顺序变成倒位序,采用雷德算法nm1=FFT_N-1; for(i

14、=0;inm1;i+) if(ij) /如果 ij, 即进行变址 t=xinj; xinj=xini; xini=t; k=nv2; /求 j 的下一个倒位序while(k=j) /如果 k=j,表示 j 的最高位为1 j=j-k; /把最高位变成0 k=k/2; /k/2,比较次高位,依次类推,逐个比较,直到某个位为0 j=j+k; /把 0 改为 1 int le,lei,ip; /FFT 运算核,使用蝶形运算完成FFT 运算f=FFT_N; for(l=1;(f=f/2)!=1;l+) /计算 l 的值,即计算蝶形级数; for(m=1;m=l;m+) / 控制蝶形结级数 /m 表示第

15、m 级蝶形, l 为蝶形级总数l=log(2)N le=2(m-1); /le 蝶形结距离,即第m 级蝶形的蝶形结相距le 点lei=le/2; /同一蝶形结中参加运算的两点的距离u.real=1.0; /u 为蝶形结运算系数,初始值为1 u.imag=0.0; /w.real=cos(PI/lei); /不适用查表法计算sin 值和 cos 值/ w.imag=-sin(PI/lei); w.real=cos_tab(PI/lei); /w 为系数商,即当前系数与前一个系数的商w.imag=-sin_tab(PI/lei); 名师资料总结 - - -精品资料欢迎下载 - - - - - -

16、- - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 18 页 - - - - - - - - - for(j=0;j=lei-1;j+) /控制计算不同种蝶形结,即计算系数不同的蝶形结 for(i=j;i=FFT_N-1;i=i+le) /控制同一蝶形结运算,即计算系数相同蝶形结 ip=i+lei; /i,ip 分别表示参加蝶形运算的两个节点t=EE(xinip,u); /蝶形运算,详见公式xinip.real=xini.real-t.real; xinip.imag=xini.imag-t.imag; xini.real=xini.rea

17、l+t.real; xini.imag=xini.imag+t.imag; u=EE(u,w); /改变系数,进行下一个蝶形运算 /* 函数原型: void main() 函数功能:测试FFT 变换,演示函数使用方法输入参数:无输出参数:无*/ void main() int i; create_sin_tab(SIN_TAB); for(i=0;iFFT_N;i+) /给结构体赋值 si.real=sin(2*3.141592653589793*i/FFT_N); /实部为正弦波FFT_N 点采样,赋值为1 si.imag=0; /虚部为 0 FFT(s); /进行快速福利叶变换for(i=

18、0;iFFT_N;i+) /求变换后结果的模值,存入复数的实部部分si.real=sqrt(si.real*si.real+si.imag*si.imag); while(1); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 7 页,共 18 页 - - - - - - - - - #include #include /* 快速福利叶变换C 程序包函数简介:此程序包是通用的快速傅里叶变换C 语言函数,移植性强,以下部分不依赖硬件。此程序包采用联合体的形式表示一个复数,输入为自然顺序

19、的复数(输入实数是可令复数虚部为0) ,输出为经过FFT 变换的自然顺序的复数 .此程序包可在初始化时调用create_sin_tab()函数创建正弦函数表,以后的可采用查表法计算耗时较多的sin 和 cos 运算,加快可计算速度.与Ver1.1 版相比较, Ver1.2 版在创建正弦表时只建立了1/4 个正弦波的采样值,相比之下节省了FFT_N/4 个存储空间使用说明:使用此函数只需更改宏定义FFT_N 的值即可实现点数的改变,FFT_N 的应该为 2 的 N 次方,不满足此条件时应在后面补0。若使用查表法计算sin 值和cos 值,应在调用FFT 函数前调用create_sin_tab()

20、函数创建正弦表函数调用: FFT(s); 时间: 2010-2-20 版本: Ver1.2 参考文献:*/ #include #define FFT_N 128 /定义福利叶变换的点数#define PI 3.1415926535897932384626433832795028841971 / 定义圆周率值struct compx float real,imag; /定义一个复数结构struct compx sFFT_N; /FFT 输入和输出:从S0开始存放,根据大小自己定义float SIN_TABFFT_N/4+1; /定义正弦表的存放空间/* 函数原型: struct compx EE

21、(struct compx b1,struct compx b2) 函数功能:对两个复数进行乘法运算输入参数:两个以联合体定义的复数a,b 输出参数: a 和 b 的乘积,以联合体的形式输出*/ struct compx EE(struct compx a,struct compx b) struct compx c; c.real=a.real*b.real-a.imag*b.imag; c.imag=a.real*b.imag+a.imag*b.real; return(c); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - -

22、 名师精心整理 - - - - - - - 第 8 页,共 18 页 - - - - - - - - - /* 函数原型: void create_sin_tab(float *sin_t) 函数功能:创建一个正弦采样表,采样点数与福利叶变换点数相同输入参数: *sin_t 存放正弦表的数组指针输出参数:无*/ void create_sin_tab(float *sin_t) int i; for(i=0;i=0&nFFT_N/4&n=FFT_N/2&n=3*FFT_N/4&n2*PI) pi2-=2*PI; a=sin_tab(pi2); return a; /* 函数原型: void F

23、FT(struct compx *xin,int N) 函数功能:对输入的复数组进行快速傅里叶变换(FFT)输入参数: *xin 复数结构体组的首地址指针,struct 型输出参数:无*/ void FFT(struct compx *xin) int f,m,nv2,nm1,i,k,l,j=0; struct compx u,w,t; nv2=FFT_N/2; /变址运算,即把自然顺序变成倒位序,采用雷德算法nm1=FFT_N-1; for(i=0;inm1;i+) if(ij) /如果 ij, 即进行变址 t=xinj; xinj=xini; xini=t; k=nv2; /求 j 的下一

24、个倒位序while(k=j) /如果 k=j,表示 j 的最高位为1 j=j-k; /把最高位变成0 k=k/2; /k/2,比较次高位,依次类推,逐个比较,直到某个位为0 j=j+k; /把 0 改为 1 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 18 页 - - - - - - - - - int le,lei,ip; /FFT 运算核,使用蝶形运算完成FFT 运算f=FFT_N; for(l=1;(f=f/2)!=1;l+) /计算 l 的值,即计算蝶形级数

25、; for(m=1;m=l;m+) / 控制蝶形结级数 /m 表示第m 级蝶形, l 为蝶形级总数l=log(2) N le=2(m-1); /le 蝶形结距离,即第m 级蝶形的蝶形结相距 le 点lei=le/2; /同一蝶形结中参加运算的两点的距离u.real=1.0; /u 为蝶形结运算系数,初始值为1 u.imag=0.0; /w.real=cos(PI/lei); /不适用查表法计算sin 值和 cos 值/ w.imag=-sin(PI/lei); w.real=cos_tab(PI/lei); /w 为系数商,即当前系数与前一个系数的商w.imag=-sin_tab(PI/lei

26、); for(j=0;j=lei-1;j+) /控制计算不同种蝶形结,即计算系数不同的蝶形结 for(i=j;i=FFT_N-1;i=i+le) /控制同一蝶形结运算,即计算系数相同蝶形结 ip=i+lei; /i,ip 分别表示参加蝶形运算的两个节点t=EE(xinip,u); /蝶形运算,详见公式xinip.real=xini.real-t.real; xinip.imag=xini.imag-t.imag; xini.real=xini.real+t.real; xini.imag=xini.imag+t.imag; u=EE(u,w); /改变系数,进行下一个蝶形运算 /* 函数原型:

27、 void main() 函数功能:测试FFT 变换,演示函数使用方法输入参数:无输出参数:无名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 18 页 - - - - - - - - - */ void main() int i; create_sin_tab(SIN_TAB); for(i=0;iFFT_N;i+) /给结构体赋值 si.real=sin(2*3.141592653589793*i/FFT_N); /实部为正弦波FFT_N 点采样,赋值为1 si.im

28、ag=0; /虚部为 0 FFT(s); /进行快速福利叶变换for(i=0;iFFT_N;i+) /求变换后结果的模值,存入复数的实部部分si.real=sqrt(si.real*si.real+si.imag*si.imag); while(1); #include struct compx float real ; float imag ; /* 定义一个复数结构struct compx s257; /*FFT 输入,输出均从 s1开始1.struct compx EE( struct compx, struct compx); 2.void FFT(struct compx * ,in

29、t) 3.4.struct compx EE( struct compx b1, struct compx b2) 5. struct compx b3; 6.b3.real =b1.real*b2.real-b1.imag*b2.imag; 7. b3.imag=b1.real*b2.imag+b1.imag*b2.real; 8. return( b3); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 12 页,共 18 页 - - - - - - - - - 9. 10./*

30、输入 xin 的实部,虚部,输出:xin(实部,虚部)N 为 FFT 点数11.12.void FFT( struct compx *xin ,N) 13. 14.int f,m,nv2,nm1,i,k,j=1,l; 15.int le,lei,ip; 16.float pi,x,y; 17.struct compx v,w,t; 18.nv2=N/2; 19.f=N; 20.for(m=1;(f=f/2)!=1;m+) ; /*求 N 为 2 的多少次幂放入m 21.nm1=N-1; 22. /* 变变址运算,实现数据运算前的位倒序*/ 23.for(i=1;i=nm1;i+)24. if(

31、ij) t=xinj;xinj=xini;xini=t; 25. k=nv2; 26. while(kj) j=j-k;k=k/2; 27. j=j+k; 28. 29./* FFT*/ 30.for(l=1;lm;l+) 31. 32.le=pow(2,l); 33.lei=le/2; 34.pi=3.14159265; 35.v.real=1.0;v.imag=0.0; 36.w.real=cos(pi/lei);w.imag=-sin(pi/lei); 37. for(j=1;j=lei;i+) 38. 39. for(i=j;i=N;i=i+le) ip=i+lei; 40. t=EE

32、(xinip,v); 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 13 页,共 18 页 - - - - - - - - - 41. xinip.real=xini.real-t.real; 42. xinip.imag=xini.imag-t.imag; 43. xini.real=xini.real+t.real; 44. xini.imag=xini.imag+t.imag; 45. v=EE(v,w); 46. 47.48. 49. 注意(用的是基二时域算法)且点数是的n

33、 次方#include math.h #include stdio.hstruct compx double real; double imag; ;struct compx EE(struct compx b1,struct compx b2) struct compx b3; b3.real=b1.real*b2.real-b1.imag*b2.imag; b3.imag=b1.real*b2.imag+b1.imag*b2.real; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - -

34、 第 14 页,共 18 页 - - - - - - - - - return(b3); FFT 运算函数void FFT(struct compx *xin,int N) int f,m,LH,nm,i,k,j,L; double p , ps ; int le,B,ip; float pi; struct compx v,w,t; LH=N/2; f=N; for(m=1;(f=f/2)!=1;m+); nm=N-2; j=N/2; for(i=1;i=nm;i+) if(i=k)j=j-k;k=k/2; j=j+k; for(L=1;L=m;L+) le=pow(2,L); B=le/2

35、; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 15 页,共 18 页 - - - - - - - - - pi=3.14159; for(j=0;j=B-1;j+) p=pow(2,m-L)*j; ps=2*pi/N*p; w.real=cos(ps); w.imag=-sin(ps); for(i=j;i=N-1;i=i+le) ip=i+B; t=EE(xinip,w); xinip.real=xini.real-t.real; xinip.imag=xini.imag-t

36、.imag; xini.real=xini.real+t.real; xini.imag=xini.imag+t.imag; return ; 主函数#include #include #include float result257; struct compx s257; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 16 页,共 18 页 - - - - - - - - - int Num= ; const float pp=3.14159; main() int i; for

37、(i=0;i ;i+) si.real=sin(pp*i/16); si.imag=0; FFT(s,Num); for(i=0;i ;i+) printf(%.4f,si.real); printf(+%.4fjn,si.imag); resulti=sqrt(pow(si.real,2)+pow(si.imag,2); 其函数中取的是个点for(i=0;i ;i+)如果要改变点数或者函数只需在主函数中改变for(i=0;i ;i+)si.real=sin(pp*i/16)名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 17 页,共 18 页 - - - - - - - - - 便可名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 18 页,共 18 页 - - - - - - - - -

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 高考资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁