📄 pfafft.c
字号:
{ 10296, 0.065502f },{ 10920, 0.068182f },{ 11088, 0.065217f },{ 11440, 0.075000f },{ 12012, 0.078534f },{ 12870, 0.087719f },{ 13104, 0.081081f },{ 13860, 0.084270f },{ 15015, 0.102740f },{ 16016, 0.106383f },{ 16380, 0.105634f },{ 17160, 0.119048f },{ 18018, 0.123967f },{ 18480, 0.119048f },{ 20020, 0.137615f },{ 20592, 0.140187f },{ 21840, 0.154639f },{ 24024, 0.168539f },{ 25740, 0.180723f },{ 27720, 0.180723f },{ 30030, 0.220588f },{ 32760, 0.241935f },{ 34320, 0.254237f },{ 36036, 0.254237f },{ 40040, 0.288462f },{ 45045, 0.357143f },{ 48048, 0.357143f },{ 51480, 0.384615f },{ 55440, 0.384615f },{ 60060, 0.454545f },{ 65520, 0.517241f },{ 72072, 0.576923f },{ 80080, 0.625000f },{ 90090, 0.833333f },{ 102960, 0.789474f },{ 120120, 1.153846f },{ 144144, 1.153846f },{ 180180, 1.875000f },{ 240240, 2.500000f },{ 360360, 3.750000f },{ 720720, 7.500000f },};int npfa (int nmin)/*****************************************************************************Return smallest valid n not less than nmin for prime factor fft.******************************************************************************Input:nmin lower bound on returned value (see notes below)Returned: valid n for prime factor fft******************************************************************************Notes:The returned n will be composed of mutually prime factors fromthe set {2,3,4,5,7,8,9,11,13,16}. Because n cannot exceed720720 = 5*7*9*11*13*16, 720720 is returned if nmin exceeds 720720.******************************************************************************Author: Dave Hale, Colorado School of Mines, 04/28/89Modified: Dave Hale, Colorado School of Mines, 08/05/91 For efficiency, use pre-computed table of valid n and costs.*****************************************************************************/{ int i; for (i=0; i<NTAB-1 && nctab[i].n<nmin; ++i); return nctab[i].n;}int npfao (int nmin, int nmax)/*****************************************************************************Return optimal n between nmin and nmax for prime factor fft.******************************************************************************Input:nmin lower bound on returned value (see notes below)nmax desired (but not guaranteed) upper bound on returned valueReturned: valid n for prime factor fft******************************************************************************Notes:The returned n will be composed of mutually prime factors fromthe set {2,3,4,5,7,8,9,11,13,16}. Because n cannot exceed720720 = 5*7*9*11*13*16, 720720 is returned if nmin exceeds 720720.If nmin does not exceed 720720, then the returned n will not be less than nmin. The optimal n is chosen to minimize the estimatedcost of performing the fft, while satisfying the constraint, ifpossible, that n not exceed nmax.******************************************************************************Author: Dave Hale, Colorado School of Mines, 06/13/89Modified: Dave Hale, Colorado School of Mines, 08/05/91 For efficiency, use pre-computed table of valid n and costs.*****************************************************************************/{ int i,j; for (i=0; i<NTAB-1 && nctab[i].n<nmin; ++i); for (j=i+1; j<NTAB-1 && nctab[j].n<=nmax; ++j) if (nctab[j].c<nctab[i].c) i = j; return nctab[i].n;}int npfar (int nmin)/*****************************************************************************Return smallest valid n not less than nmin for real-to-fcomplex or fcomplex-to-real prime factor ffts.******************************************************************************Input:nmin lower bound on returned valueReturned: valid n for real-to-fcomplex/fcomplex-to-real prime factor fft******************************************************************************Notes:Current implemenations of real-to-fcomplex and fcomplex-to-real prime factor ffts require that the transform length n be even and that n/2 be a valid length for a fcomplex-to-fcomplex prime factor fft. The value returned by npfar satisfies these conditions. Also, see notes for npfa.******************************************************************************Author: Dave Hale, Colorado School of Mines, 06/16/89*****************************************************************************/{ return 2*npfa((nmin+1)/2);}int npfaro (int nmin, int nmax)/*****************************************************************************Return optimal n between nmin and nmax for real-to-fcomplex or fcomplex-to-real prime factor ffts******************************************************************************Input:nmin lower bound on returned valuenmax desired (but not guaranteed) upper bound on returned valueReturned: valid n for real-to-fcomplex/fcomplex-to-real prime factor fft******************************************************************************Notes:Current implemenations of real-to-fcomplex and fcomplex-to-real prime factor ffts require that the transform length n be even and that n/2 be a valid length for a fcomplex-to-fcomplex prime factor fft. The value returned by npfaro satisfies these conditions. Also, see notes for npfao.******************************************************************************Author: Dave Hale, Colorado School of Mines, 06/16/89*****************************************************************************/{ return 2*npfao((nmin+1)/2,(nmax+1)/2);}#define P120 0.120536680f#define P142 0.142314838f#define P173 0.173648178f#define P222 0.222520934f#define P239 0.239315664f#define P281 0.281732557f#define P342 0.342020143f#define P354 0.354604887f#define P382 0.382683432f#define P415 0.415415013f#define P433 0.433883739f#define P464 0.464723172f#define P540 0.540640817f#define P559 0.559016994f#define P568 0.568064747f#define P587 0.587785252f#define P623 0.623489802f#define P642 0.642787610f#define P654 0.654860734f#define P663 0.663122658f#define P707 0.707106781f#define P748 0.748510748f#define P755 0.755749574f#define P766 0.766044443f#define P781 0.781831482f#define P822 0.822983866f#define P841 0.841253533f#define P866 0.866025404f#define P885 0.885456026f#define P900 0.900968868f#define P909 0.909631995f#define P923 0.923879533f#define P935 0.935016243f#define P939 0.939692621f#define P951 0.951056516f#define P959 0.959492974f#define P970 0.970941817f#define P974 0.974927912f#define P984 0.984807753f#define P989 0.989821442f#define P992 0.992708874f#define NFAX 10void pfacc (int isign, int n, fcomplex cz[])/*****************************************************************************Prime factor fft: fcomplex to fcomplex transform, in place******************************************************************************Input:isign sign of isign is the sign of exponent in fourier kerneln length of transform (see notes below)z array[n] of fcomplex numbers to be transformed in placeOutput:z array[n] of fcomplex numbers transformed******************************************************************************Notes:n must be factorable into mutually prime factors taken from the set {2,3,4,5,7,8,9,11,13,16}. in other words, n = 2**p * 3**q * 5**r * 7**s * 11**t * 13**uwhere 0 <= p <= 4, 0 <= q <= 2, 0 <= r,s,t,u <= 1is required for pfa to yield meaningful results. thisrestriction implies that n is restricted to the range 1 <= n <= 720720 (= 5*7*9*11*13*16)******************************************************************************References: Temperton, C., 1985, Implementation of a self-sortingin-place prime factor fft algorithm: Journal ofComputational Physics, v. 58, p. 283-299.Temperton, C., 1988, A new set of minimum-add rotatedrotated dft modules: Journal of Computational Physics,v. 75, p. 190-198.******************************************************************************Author: Dave Hale, Colorado School of Mines, 04/27/89*****************************************************************************/{ static int kfax[] = { 16,13,11,9,8,7,5,4,3,2 }; register float *z=(float*)cz; register int j00,j01,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15,jt; int nleft,jfax,ifac,jfac,jinc,jmax,ndiv,m,mm=0,mu=0,l; float t1r,t1i,t2r,t2i,t3r,t3i,t4r,t4i,t5r,t5i, t6r,t6i,t7r,t7i,t8r,t8i,t9r,t9i,t10r,t10i, t11r,t11i,t12r,t12i,t13r,t13i,t14r,t14i,t15r,t15i, t16r,t16i,t17r,t17i,t18r,t18i,t19r,t19i,t20r,t20i, t21r,t21i,t22r,t22i,t23r,t23i,t24r,t24i,t25r,t25i, t26r,t26i,t27r,t27i,t28r,t28i,t29r,t29i,t30r,t30i, t31r,t31i,t32r,t32i,t33r,t33i,t34r,t34i,t35r,t35i, t36r,t36i,t37r,t37i,t38r,t38i,t39r,t39i,t40r,t40i, t41r,t41i,t42r,t42i, y1r,y1i,y2r,y2i,y3r,y3i,y4r,y4i,y5r,y5i, y6r,y6i,y7r,y7i,y8r,y8i,y9r,y9i,y10r,y10i, y11r,y11i,y12r,y12i,y13r,y13i,y14r,y14i,y15r,y15i, c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12; /* keep track of n left after dividing by factors */ nleft = n; /* begin loop over possible factors (from biggest to smallest) */ for (jfax=0; jfax<NFAX; jfax++) { /* skip if not a mutually prime factor of n */ ifac = kfax[jfax]; ndiv = nleft/ifac; if (ndiv*ifac!=nleft) continue; /* update n left and determine n divided by factor */ nleft = ndiv; m = n/ifac; /* determine rotation factor mu and stride mm */ for (jfac=1; jfac<=ifac; jfac++) { mu = jfac; mm = jfac*m; if (mm%ifac==1) break; } /* adjust rotation factor for sign of transform */ if (isign<0) mu = ifac-mu; /* compute stride, limit, and pointers */ jinc = 2*mm; jmax = 2*n; j00 = 0; j01 = j00+jinc; /* if factor is 2 */ if (ifac==2) { for (l=0; l<m; l++) { t1r = z[j00]-z[j01]; t1i = z[j00+1]-z[j01+1]; z[j00] = z[j00]+z[j01]; z[j00+1] = z[j00+1]+z[j01+1]; z[j01] = t1r; z[j01+1] = t1i; jt = j01+2; j01 = j00+2; j00 = jt; } continue; } j2 = j01+jinc; if (j2>=jmax) j2 = j2-jmax; /* if factor is 3 */ if (ifac==3) { if (mu==1) c1 = (float)P866; else c1 = (float)(-P866); for (l=0; l<m; l++) { t1r = z[j01]+z[j2]; t1i = z[j01+1]+z[j2+1]; y1r = z[j00]-0.5f*t1r; y1i = z[j00+1]-0.5f*t1i; y2r = c1*(z[j01]-z[j2]); y2i = c1*(z[j01+1]-z[j2+1]); z[j00] = z[j00]+t1r; z[j00+1] = z[j00+1]+t1i; z[j01] = y1r-y2i; z[j01+1] = y1i+y2r; z[j2] = y1r+y2i; z[j2+1] = y1i-y2r; jt = j2+2; j2 = j01+2; j01 = j00+2; j00 = jt; } continue; } j3 = j2+jinc; if (j3>=jmax) j3 = j3-jmax; /* if factor is 4 */ if (ifac==4) { if (mu==1) c1 = 1.0; else c1 = -1.0; for (l=0; l<m; l++) { t1r = z[j00]+z[j2]; t1i = z[j00+1]+z[j2+1]; t2r = z[j01]+z[j3]; t2i = z[j01+1]+z[j3+1]; y1r = z[j00]-z[j2]; y1i = z[j00+1]-z[j2+1]; y3r = c1*(z[j01]-z[j3]); y3i = c1*(z[j01+1]-z[j3+1]); z[j00] = t1r+t2r; z[j00+1] = t1i+t2i; z[j01] = y1r-y3i; z[j01+1] = y1i+y3r; z[j2] = t1r-t2r; z[j2+1] = t1i-t2i; z[j3] = y1r+y3i; z[j3+1] = y1i-y3r; jt = j3+2; j3 = j2+2; j2 = j01+2; j01 = j00+2; j00 = jt; } continue; } j4 = j3+jinc; if (j4>=jmax) j4 = j4-jmax; /* if factor is 5 */ if (ifac==5) { if (mu==1) { c1 = P559; c2 = P951; c3 = P587; } else if (mu==2) { c1 = -P559; c2 = P587; c3 = -P951; } else if (mu==3) { c1 = -P559; c2 = -P587; c3 = P951; } else { c1 = P559; c2 = -P951; c3 = -P587; } for (l=0; l<m; l++) { t1r = z[j01]+z[j4]; t1i = z[j01+1]+z[j4+1]; t2r = z[j2]+z[j3]; t2i = z[j2+1]+z[j3+1]; t3r = z[j01]-z[j4]; t3i = z[j01+1]-z[j4+1]; t4r = z[j2]-z[j3]; t4i = z[j2+1]-z[j3+1]; t5r = t1r+t2r; t5i = t1i+t2i; t6r = c1*(t1r-t2r); t6i = c1*(t1i-t2i); t7r = z[j00]-0.25f*t5r; t7i = z[j00+1]-0.25f*t5i; y1r = t7r+t6r; y1i = t7i+t6i; y2r = t7r-t6r; y2i = t7i-t6i; y3r = c3*t3r-c2*t4r; y3i = c3*t3i-c2*t4i; y4r = c2*t3r+c3*t4r; y4i = c2*t3i+c3*t4i; z[j00] = z[j00]+t5r; z[j00+1] = z[j00+1]+t5i; z[j01] = y1r-y4i; z[j01+1] = y1i+y4r; z[j2] = y2r-y3i; z[j2+1] = y2i+y3r; z[j3] = y2r+y3i; z[j3+1] = y2i-y3r; z[j4] = y1r+y4i; z[j4+1] = y1i-y4r; jt = j4+2; j4 = j3+2; j3 = j2+2; j2 = j01+2; j01 = j00+2; j00 = jt; } continue; } j5 = j4+jinc; if (j5>=jmax) j5 = j5-jmax; j6 = j5+jinc; if (j6>=jmax) j6 = j6-jmax; /* if factor is 7 */ if (ifac==7) { if (mu==1) { c1 = P623; c2 = -P222; c3 = -P900; c4 = P781; c5 = P974; c6 = P433; } else if (mu==2) { c1 = -P222; c2 = -P900; c3 = P623; c4 = P974; c5 = -P433; c6 = -P781; } else if (mu==3) { c1 = -P900; c2 = P623; c3 = -P222; c4 = P433; c5 = -P781; c6 = P974; } else if (mu==4) { c1 = -P900; c2 = P623; c3 = -P222; c4 = -P433; c5 = P781; c6 = -P974; } else if (mu==5) { c1 = -P222; c2 = -P900; c3 = P623; c4 = -P974; c5 = P433; c6 = P781; } else { c1 = P623; c2 = -P222; c3 = -P900; c4 = -P781; c5 = -P974; c6 = -P433; } for (l=0; l<m; l++) { t1r = z[j01]+z[j6]; t1i = z[j01+1]+z[j6+1]; t2r = z[j2]+z[j5]; t2i = z[j2+1]+z[j5+1]; t3r = z[j3]+z[j4]; t3i = z[j3+1]+z[j4+1]; t4r = z[j01]-z[j6]; t4i = z[j01+1]-z[j6+1]; t5r = z[j2]-z[j5]; t5i = z[j2+1]-z[j5+1];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -