博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
快速傅氏变换之旅(二) 七种FFT算法速度比较(含代码)
阅读量:2397 次
发布时间:2019-05-10

本文共 7623 字,大约阅读时间需要 25 分钟。

转载请标明是引用于

 例子代码:(编译工具:VS2005)

由于公司要做FFT算法,具体是做高尔夫球的弹道分析,至今还没把算法敲定。

今天网上看了算法,自己建立工程,进行了比较。

现在按算法速度从快到慢的顺序介绍:(先搭个框架,具体算法解释,请听下回分解)

1、

//*******************************************************************// 将data[]中的元素进行快速傅立叶变换,当变换长度大于L2 cache,有较快的速度BOOL FFT2(CMPL data[], size_t n)//*******************************************************************{	unsigned long i;	//------------------------------------	if (n<4)	{		printf("too small transpos length\n");		return FALSE;	}			Init_OMAGE_ARRAY(n);	if (g_w.arr==NULL)	{		printf("no enough memory\n");		return FALSE;	}	reverseOrder(data,n,Log2(n)); //反序    	if (n<=MAX_IN_CACHE_TRANS_LEN)	{		fft_sub(data,n,2,n);		return TRUE;	}		for (i=0;i

 

//*******************************************************************// 将data[]中的元素进行快速傅立叶变换BOOL FFT1(CMPL data[], size_t n)//*******************************************************************{	unsigned long i,i1,i2,j1,j2,d;	unsigned long groupBase,groupLen,omageBase;	CMPL t,t1,t2;	double *pW=NULL;	char fileName[3209];	if (n<4)	{		printf("too small transpos length\n");		return FALSE;	}			Init_OMAGE_ARRAY(n);	if (g_w.arr==NULL)	{		printf("no enough memory\n");		return FALSE;	}		reverseOrder(data,n,Log2(n)); //反序    	for (i=0;i
=4, buffterfly group length >=8 ,group number =n/group length for (groupLen=8;groupLen<=n;groupLen*=2 ) { d=groupLen/2; //d: 翅间距 omageBase=g_w.tabIndex[Log2(groupLen)-2].offset; pW= (double *)(g_w.arr)+omageBase; //omage array address for ( groupBase = 0; groupBase

2、

void fft(int n, double xRe[], double xIm[],                double yRe[], double yIm[]){    int   sofarRadix[maxFactorCount],           actualRadix[maxFactorCount],           remainRadix[maxFactorCount];    int   nFactor;    int   count;    pi = 4*atan(1);        transTableSetup(sofarRadix, actualRadix, remainRadix, &nFactor, &n);    permute(n, nFactor, actualRadix, remainRadix, xRe, xIm, yRe, yIm);    for (count=1; count<=nFactor; count++)      twiddleTransf(sofarRadix[count], actualRadix[count], remainRadix[count],                     yRe, yIm);}   /* fft */

 

3、

void four1(double data[], int nn, int isign){    int n,j,i,m,mmax,istep;    double tempr,tempi,theta,wpr,wpi,wr,wi,wtemp;    n = 2 * nn;    j = 1;    for (i = 1; i<=n; i=i+2)    {        if(j > i)        {            tempr = data[j];            tempi = data[j + 1];            data[j] = data[i];            data[j + 1] = data[i + 1];            data[i] = tempr;            data[i + 1] = tempi;        }        m = n / 2;        while (m >= 2 && j > m)        {            j = j - m;            m = m / 2;        }        j = j + m;    }    mmax = 2;    while(n > mmax)    {        istep = 2 * mmax;        theta = 6.28318530717959 / (isign * mmax);        wpr = -2.0 * sin(0.5 * theta)*sin(0.5 * theta);        wpi = sin(theta);        wr = 1.0;        wi = 0.0;        for(m = 1; m<=mmax; m=m+2)        {            for (i = m; i<=n; i=i+istep)            {                j = i + mmax;                tempr=double(wr)*data[j]-double(wi)*data[j+1];                tempi=double(wr)*data[j+1]+double(wi)*data[j];                data[j] = data[i] - tempr;                data[j + 1] = data[i + 1] - tempi;                data[i] = data[i] + tempr;                data[i + 1] = data[i + 1] + tempi;            }            wtemp = wr;            wr = wr * wpr - wi * wpi + wr;            wi = wi * wpr + wtemp * wpi + wi;        }        mmax = istep;    }}

4、

void fft(COMPLEX in[],COMPLEX out[], COMPLEX omega[],int n){	int s,k,m,l,nv,t,j;	COMPLEX podd,ret;	k = (int)(log(n) / log(2) + 0.5);	nv = n;	m = 1;	for ( l = k-1 ; l >= 0 ; l-- )	{		for ( t = 0 ; t < m * nv ; t+=nv )			for ( j = 0 ; j < nv/2 ; j++ )			{				s = (t+j) / (int)pow(2,l);				s = reverse(s,k);				ret = omega[s];				mul(&ret,&in[t+j+nv/2],&podd);				sub(&in[t+j],&podd,&in[t+j+nv/2]);				add(&in[t+j],&podd,&in[t+j]);			}		m *= 2;		nv /= 2;	}	for ( t = 0 ; t < n ; t++ )	{		s = reverse(t,k);		out[t] = in[s];	}}

5、

void cdft(int n, int isgn, double *a){    void cftfsub(int n, double *a);    void cftbsub(int n, double *a);        if (isgn >= 0) {        cftfsub(n, a);    } else {        cftbsub(n, a);    }}

 

void cftfsub(int n, double *a){    void bitrv2(int n, double *a);    void bitrv216(double *a);    void bitrv208(double *a);    void cftmdl1(int n, double *a);    void cftrec4(int n, double *a);    void cftleaf(int n, int isplt, double *a);    void cftfx41(int n, double *a);    void cftf161(double *a);    void cftf081(double *a);    void cftf040(double *a);    void cftx020(double *a);#ifdef USE_CDFT_THREADS    void cftrec4_th(int n, double *a);#endif /* USE_CDFT_THREADS */        if (n > 8) {        if (n > 32) {            cftmdl1(n, a);#ifdef USE_CDFT_THREADS            if (n > CDFT_THREADS_BEGIN_N) {                cftrec4_th(n, a);            } else #endif /* USE_CDFT_THREADS */            if (n > 512) {                cftrec4(n, a);            } else if (n > 128) {                cftleaf(n, 1, a);            } else {                cftfx41(n, a);            }            bitrv2(n, a);        } else if (n == 32) {            cftf161(a);            bitrv216(a);        } else {            cftf081(a);            bitrv208(a);        }    } else if (n == 8) {        cftf040(a);    } else if (n == 4) {        cftx020(a);    }}void cftbsub(int n, double *a){    void bitrv2conj(int n, double *a);    void bitrv216neg(double *a);    void bitrv208neg(double *a);    void cftb1st(int n, double *a);    void cftrec4(int n, double *a);    void cftleaf(int n, int isplt, double *a);    void cftfx41(int n, double *a);    void cftf161(double *a);    void cftf081(double *a);    void cftb040(double *a);    void cftx020(double *a);#ifdef USE_CDFT_THREADS    void cftrec4_th(int n, double *a);#endif /* USE_CDFT_THREADS */        if (n > 8) {        if (n > 32) {            cftb1st(n, a);#ifdef USE_CDFT_THREADS            if (n > CDFT_THREADS_BEGIN_N) {                cftrec4_th(n, a);            } else #endif /* USE_CDFT_THREADS */            if (n > 512) {                cftrec4(n, a);            } else if (n > 128) {                cftleaf(n, 1, a);            } else {                cftfx41(n, a);            }            bitrv2conj(n, a);        } else if (n == 32) {            cftf161(a);            bitrv216neg(a);        } else {            cftf081(a);            bitrv208neg(a);        }    } else if (n == 8) {        cftb040(a);    } else if (n == 4) {        cftx020(a);    }}

6、

//*************************************************************************// *// * 函数名称:// *   FFT()// *// * 参数:// *   complex
* TD- 指向时域数组的指针// * complex
* FD- 指向频域数组的指针// * r-2的幂数,即迭代次数// *// * 返回值:// * 无。// *// * 说明:// * 该函数用来实现快速付立叶变换。// *// ************************************************************************/void FFT( complex
*TD, complex
*FD, complex
*X1, complex
*X2, complex
*Omega, int r){ // 付立叶变换点数 long count; // 循环变量 int i,j,k; // 中间变量 int bfsize,p; // 角度 double angle; complex
*X; // 计算付立叶变换点数 count = 1 << r; // 分配运算所需存储器 //Omega = new complex
[count / 2]; //X1 = new complex
[count]; //X2 = new complex
[count]; // 计算加权系数 for(i = 0; i < count / 2; i++) { angle = -i * 3.1415926 * 2 / count; Omega[i] = complex
(cos(angle), sin(angle)); } // 将时域点写入X1 memcpy(X1, TD, sizeof(complex
) * count); // 采用蝶形算法进行快速付立叶变换 for(k = 0; k < r; k++) { for(j = 0; j < 1 << k; j++) { bfsize = 1 << (r-k); for(i = 0; i < bfsize / 2; i++) { p = j * bfsize; X2[i + p] = X1[i + p] + X1[i + p + bfsize / 2]; X2[i + p + bfsize / 2] = (X1[i + p] - X1[i + p + bfsize / 2]) * Omega[i * (1<

 

你可能感兴趣的文章
linux下用户与组管理-组管理与帐户文件介绍
查看>>
linux下文件权限管理介绍
查看>>
linux下常用网络操作(重点)
查看>>
linux在下软件安装-jdk和tomcat安装
查看>>
java框架基础 静态代理和动态代理
查看>>
jQuery ajax开发基于json
查看>>
oracle数据库
查看>>
oracle中间的数据类型
查看>>
论文划分
查看>>
vscode利用cmake调试
查看>>
zcash挖矿
查看>>
zcash挖矿指南
查看>>
区块链术语解释
查看>>
./configure,make,make install的作用
查看>>
学术论文录用结果通知(Notification)
查看>>
Theorem等数学化的论述
查看>>
使用HttpClient爬取国内疫情数据
查看>>
引用传递和值传递有什么区别
查看>>
C++从入门到放肆!
查看>>
C++是什么?怎么学?学完了能得到什么?
查看>>