#include "genfft.h" #include "pfaconst.h" /* Copyright (c) Colorado School of Mines, 1995.*/ /* All rights reserved. */ // stolen by Joerg Arndt from the cwplib ... // // Original author: Dave Hale, Colorado School of Mines, 04/27/89 // // edited by Joerg Arndt (july 96): // C++ only // changed float to REAL // replaced 'magic numbers' (P120 etc), they moved to pfaconst.h // // see pfafft.doc ! int npfa (int nmin) { int i; for (i=0; i<NTAB-1 && nctab[i].n<nmin; ++i); return nctab[i].n; } int npfao (int nmin, int nmax) { 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 2*npfa((nmin+1)/2); } int npfaro (int nmin, int nmax) { return 2*npfao((nmin+1)/2,(nmax+1)/2); } void pfacc (int isign, int n, complex cz[]) { static int kfax[] = { 16,13,11,9,8,7,5,4,3,2 }; REAL *z=(REAL*)cz; int j0,j1,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; REAL 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; j0 = 0; j1 = j0+jinc; /* if factor is 2 */ if (ifac==2) { for (l=0; l<m; l++) { t1r = z[j0]-z[j1]; t1i = z[j0+1]-z[j1+1]; z[j0] = z[j0]+z[j1]; z[j0+1] = z[j0+1]+z[j1+1]; z[j1] = t1r; z[j1+1] = t1i; jt = j1+2; j1 = j0+2; j0 = jt; } continue; } j2 = j1+jinc; if (j2>=jmax) j2 = j2-jmax; /* if factor is 3 */ if (ifac==3) { if (mu==1) c1 = P866; else c1 = -P866; for (l=0; l<m; l++) { t1r = z[j1]+z[j2]; t1i = z[j1+1]+z[j2+1]; y1r = z[j0]-0.5*t1r; y1i = z[j0+1]-0.5*t1i; y2r = c1*(z[j1]-z[j2]); y2i = c1*(z[j1+1]-z[j2+1]); z[j0] = z[j0]+t1r; z[j0+1] = z[j0+1]+t1i; z[j1] = y1r-y2i; z[j1+1] = y1i+y2r; z[j2] = y1r+y2i; z[j2+1] = y1i-y2r; jt = j2+2; j2 = j1+2; j1 = j0+2; j0 = 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[j0]+z[j2]; t1i = z[j0+1]+z[j2+1]; t2r = z[j1]+z[j3]; t2i = z[j1+1]+z[j3+1]; y1r = z[j0]-z[j2]; y1i = z[j0+1]-z[j2+1]; y3r = c1*(z[j1]-z[j3]); y3i = c1*(z[j1+1]-z[j3+1]); z[j0] = t1r+t2r; z[j0+1] = t1i+t2i; z[j1] = y1r-y3i; z[j1+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 = j1+2; j1 = j0+2; j0 = 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[j1]+z[j4]; t1i = z[j1+1]+z[j4+1]; t2r = z[j2]+z[j3]; t2i = z[j2+1]+z[j3+1]; t3r = z[j1]-z[j4]; t3i = z[j1+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[j0]-0.25*t5r; t7i = z[j0+1]-0.25*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[j0] = z[j0]+t5r; z[j0+1] = z[j0+1]+t5i; z[j1] = y1r-y4i; z[j1+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 = j1+2; j1 = j0+2; j0 = 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[j1]+z[j6]; t1i = z[j1+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[j1]-z[j6]; t4i = z[j1+1]-z[j6+1]; t5r = z[j2]-z[j5]; t5i = z[j2+1]-z[j5+1]; t6r = z[j3]-z[j4]; t6i = z[j3+1]-z[j4+1]; t7r = z[j0]-0.5*t3r; t7i = z[j0+1]-0.5*t3i; t8r = t1r-t3r; t8i = t1i-t3i; t9r = t2r-t3r; t9i = t2i-t3i; y1r = t7r+c1*t8r+c2*t9r; y1i = t7i+c1*t8i+c2*t9i; y2r = t7r+c2*t8r+c3*t9r; y2i = t7i+c2*t8i+c3*t9i; y3r = t7r+c3*t8r+c1*t9r; y3i = t7i+c3*t8i+c1*t9i; y4r = c6*t4r-c4*t5r+c5*t6r; y4i = c6*t4i-c4*t5i+c5*t6i; y5r = c5*t4r-c6*t5r-c4*t6r; y5i = c5*t4i-c6*t5i-c4*t6i; y6r = c4*t4r+c5*t5r+c6*t6r; y6i = c4*t4i+c5*t5i+c6*t6i; z[j0] = z[j0]+t1r+t2r+t3r; z[j0+1] = z[j0+1]+t1i+t2i+t3i; z[j1] = y1r-y6i; z[j1+1] = y1i+y6r; z[j2] = y2r-y5i; z[j2+1] = y2i+y5r; z[j3] = y3r-y4i; z[j3+1] = y3i+y4r; z[j4] = y3r+y4i; z[j4+1] = y3i-y4r; z[j5] = y2r+y5i; z[j5+1] = y2i-y5r; z[j6] = y1r+y6i; z[j6+1] = y1i-y6r; jt = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } j7 = j6+jinc; if (j7>=jmax) j7 = j7-jmax; /* if factor is 8 */ if (ifac==8) { if (mu==1) { c1 = 1.0; c2 = P707; } else if (mu==3) { c1 = -1.0; c2 = -P707; } else if (mu==5) { c1 = 1.0; c2 = -P707; } else { c1 = -1.0; c2 = P707; } c3 = c1*c2; for (l=0; l<m; l++) { t1r = z[j0]+z[j4]; t1i = z[j0+1]+z[j4+1]; t2r = z[j0]-z[j4]; t2i = z[j0+1]-z[j4+1]; t3r = z[j1]+z[j5]; t3i = z[j1+1]+z[j5+1]; t4r = z[j1]-z[j5]; t4i = z[j1+1]-z[j5+1]; t5r = z[j2]+z[j6]; t5i = z[j2+1]+z[j6+1]; t6r = c1*(z[j2]-z[j6]); t6i = c1*(z[j2+1]-z[j6+1]); t7r = z[j3]+z[j7]; t7i = z[j3+1]+z[j7+1]; t8r = z[j3]-z[j7]; t8i = z[j3+1]-z[j7+1]; t9r = t1r+t5r; t9i = t1i+t5i; t10r = t3r+t7r; t10i = t3i+t7i; t11r = c2*(t4r-t8r); t11i = c2*(t4i-t8i); t12r = c3*(t4r+t8r); t12i = c3*(t4i+t8i); y1r = t2r+t11r; y1i = t2i+t11i; y2r = t1r-t5r; y2i = t1i-t5i; y3r = t2r-t11r; y3i = t2i-t11i; y5r = t12r-t6r; y5i = t12i-t6i; y6r = c1*(t3r-t7r); y6i = c1*(t3i-t7i); y7r = t12r+t6r; y7i = t12i+t6i; z[j0] = t9r+t10r; z[j0+1] = t9i+t10i; z[j1] = y1r-y7i; z[j1+1] = y1i+y7r; z[j2] = y2r-y6i; z[j2+1] = y2i+y6r; z[j3] = y3r-y5i; z[j3+1] = y3i+y5r; z[j4] = t9r-t10r; z[j4+1] = t9i-t10i; z[j5] = y3r+y5i; z[j5+1] = y3i-y5r; z[j6] = y2r+y6i; z[j6+1] = y2i-y6r; z[j7] = y1r+y7i; z[j7+1] = y1i-y7r; jt = j7+2; j7 = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } j8 = j7+jinc; if (j8>=jmax) j8 = j8-jmax; /* if factor is 9 */ if (ifac==9) { if (mu==1) { c1 = P866; c2 = P766; c3 = P642; c4 = P173; c5 = P984; } else if (mu==2) { c1 = -P866; c2 = P173; c3 = P984; c4 = -P939; c5 = P342; } else if (mu==4) { c1 = P866; c2 = -P939; c3 = P342; c4 = P766; c5 = -P642; } else if (mu==5) { c1 = -P866; c2 = -P939; c3 = -P342; c4 = P766; c5 = P642; } else if (mu==7) { c1 = P866; c2 = P173; c3 = -P984; c4 = -P939; c5 = -P342; } else { c1 = -P866; c2 = P766; c3 = -P642; c4 = P173; c5 = -P984; } c6 = c1*c2; c7 = c1*c3; c8 = c1*c4; c9 = c1*c5; for (l=0; l<m; l++) { t1r = z[j3]+z[j6]; t1i = z[j3+1]+z[j6+1]; t2r = z[j0]-0.5*t1r; t2i = z[j0+1]-0.5*t1i; t3r = c1*(z[j3]-z[j6]); t3i = c1*(z[j3+1]-z[j6+1]); t4r = z[j0]+t1r; t4i = z[j0+1]+t1i; t5r = z[j4]+z[j7]; t5i = z[j4+1]+z[j7+1]; t6r = z[j1]-0.5*t5r; t6i = z[j1+1]-0.5*t5i; t7r = z[j4]-z[j7]; t7i = z[j4+1]-z[j7+1]; t8r = z[j1]+t5r; t8i = z[j1+1]+t5i; t9r = z[j2]+z[j5]; t9i = z[j2+1]+z[j5+1]; t10r = z[j8]-0.5*t9r; t10i = z[j8+1]-0.5*t9i; t11r = z[j2]-z[j5]; t11i = z[j2+1]-z[j5+1]; t12r = z[j8]+t9r; t12i = z[j8+1]+t9i; t13r = t8r+t12r; t13i = t8i+t12i; t14r = t6r+t10r; t14i = t6i+t10i; t15r = t6r-t10r; t15i = t6i-t10i; t16r = t7r+t11r; t16i = t7i+t11i; t17r = t7r-t11r; t17i = t7i-t11i; t18r = c2*t14r-c7*t17r; t18i = c2*t14i-c7*t17i; t19r = c4*t14r+c9*t17r; t19i = c4*t14i+c9*t17i; t20r = c3*t15r+c6*t16r; t20i = c3*t15i+c6*t16i; t21r = c5*t15r-c8*t16r; t21i = c5*t15i-c8*t16i; t22r = t18r+t19r; t22i = t18i+t19i; t23r = t20r-t21r; t23i = t20i-t21i; y1r = t2r+t18r; y1i = t2i+t18i; y2r = t2r+t19r; y2i = t2i+t19i; y3r = t4r-0.5*t13r; y3i = t4i-0.5*t13i; y4r = t2r-t22r; y4i = t2i-t22i; y5r = t3r-t23r; y5i = t3i-t23i; y6r = c1*(t8r-t12r); y6i = c1*(t8i-t12i); y7r = t21r-t3r; y7i = t21i-t3i; y8r = t3r+t20r; y8i = t3i+t20i; z[j0] = t4r+t13r; z[j0+1] = t4i+t13i; z[j1] = y1r-y8i; z[j1+1] = y1i+y8r; z[j2] = y2r-y7i; z[j2+1] = y2i+y7r; z[j3] = y3r-y6i; z[j3+1] = y3i+y6r; z[j4] = y4r-y5i; z[j4+1] = y4i+y5r; z[j5] = y4r+y5i; z[j5+1] = y4i-y5r; z[j6] = y3r+y6i; z[j6+1] = y3i-y6r; z[j7] = y2r+y7i; z[j7+1] = y2i-y7r; z[j8] = y1r+y8i; z[j8+1] = y1i-y8r; jt = j8+2; j8 = j7+2; j7 = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } j9 = j8+jinc; if (j9>=jmax) j9 = j9-jmax; j10 = j9+jinc; if (j10>=jmax) j10 = j10-jmax; /* if factor is 11 */ if (ifac==11) { if (mu==1) { c1 = P841; c2 = P415; c3 = -P142; c4 = -P654; c5 = -P959; c6 = P540; c7 = P909; c8 = P989; c9 = P755; c10 = P281; } else if (mu==2) { c1 = P415; c2 = -P654; c3 = -P959; c4 = -P142; c5 = P841; c6 = P909; c7 = P755; c8 = -P281; c9 = -P989; c10 = -P540; } else if (mu==3) { c1 = -P142; c2 = -P959; c3 = P415; c4 = P841; c5 = -P654; c6 = P989; c7 = -P281; c8 = -P909; c9 = P540; c10 = P755; } else if (mu==4) { c1 = -P654; c2 = -P142; c3 = P841; c4 = -P959; c5 = P415; c6 = P755; c7 = -P989; c8 = P540; c9 = P281; c10 = -P909; } else if (mu==5) { c1 = -P959; c2 = P841; c3 = -P654; c4 = P415; c5 = -P142; c6 = P281; c7 = -P540; c8 = P755; c9 = -P909; c10 = P989; } else if (mu==6) { c1 = -P959; c2 = P841; c3 = -P654; c4 = P415; c5 = -P142; c6 = -P281; c7 = P540; c8 = -P755; c9 = P909; c10 = -P989; } else if (mu==7) { c1 = -P654; c2 = -P142; c3 = P841; c4 = -P959; c5 = P415; c6 = -P755; c7 = P989; c8 = -P540; c9 = -P281; c10 = P909; } else if (mu==8) { c1 = -P142; c2 = -P959; c3 = P415; c4 = P841; c5 = -P654; c6 = -P989; c7 = P281; c8 = P909; c9 = -P540; c10 = -P755; } else if (mu==9) { c1 = P415; c2 = -P654; c3 = -P959; c4 = -P142; c5 = P841; c6 = -P909; c7 = -P755; c8 = P281; c9 = P989; c10 = P540; } else { c1 = P841; c2 = P415; c3 = -P142; c4 = -P654; c5 = -P959; c6 = -P540; c7 = -P909; c8 = -P989; c9 = -P755; c10 = -P281; } for (l=0; l<m; l++) { t1r = z[j1]+z[j10]; t1i = z[j1+1]+z[j10+1]; t2r = z[j2]+z[j9]; t2i = z[j2+1]+z[j9+1]; t3r = z[j3]+z[j8]; t3i = z[j3+1]+z[j8+1]; t4r = z[j4]+z[j7]; t4i = z[j4+1]+z[j7+1]; t5r = z[j5]+z[j6]; t5i = z[j5+1]+z[j6+1]; t6r = z[j1]-z[j10]; t6i = z[j1+1]-z[j10+1]; t7r = z[j2]-z[j9]; t7i = z[j2+1]-z[j9+1]; t8r = z[j3]-z[j8]; t8i = z[j3+1]-z[j8+1]; t9r = z[j4]-z[j7]; t9i = z[j4+1]-z[j7+1]; t10r = z[j5]-z[j6]; t10i = z[j5+1]-z[j6+1]; t11r = z[j0]-0.5*t5r; t11i = z[j0+1]-0.5*t5i; t12r = t1r-t5r; t12i = t1i-t5i; t13r = t2r-t5r; t13i = t2i-t5i; t14r = t3r-t5r; t14i = t3i-t5i; t15r = t4r-t5r; t15i = t4i-t5i; y1r = t11r+c1*t12r+c2*t13r+c3*t14r+c4*t15r; y1i = t11i+c1*t12i+c2*t13i+c3*t14i+c4*t15i; y2r = t11r+c2*t12r+c4*t13r+c5*t14r+c3*t15r; y2i = t11i+c2*t12i+c4*t13i+c5*t14i+c3*t15i; y3r = t11r+c3*t12r+c5*t13r+c2*t14r+c1*t15r; y3i = t11i+c3*t12i+c5*t13i+c2*t14i+c1*t15i; y4r = t11r+c4*t12r+c3*t13r+c1*t14r+c5*t15r; y4i = t11i+c4*t12i+c3*t13i+c1*t14i+c5*t15i; y5r = t11r+c5*t12r+c1*t13r+c4*t14r+c2*t15r; y5i = t11i+c5*t12i+c1*t13i+c4*t14i+c2*t15i; y6r = c10*t6r-c6*t7r+c9*t8r-c7*t9r+c8*t10r; y6i = c10*t6i-c6*t7i+c9*t8i-c7*t9i+c8*t10i; y7r = c9*t6r-c8*t7r+c6*t8r+c10*t9r-c7*t10r; y7i = c9*t6i-c8*t7i+c6*t8i+c10*t9i-c7*t10i; y8r = c8*t6r-c10*t7r-c7*t8r+c6*t9r+c9*t10r; y8i = c8*t6i-c10*t7i-c7*t8i+c6*t9i+c9*t10i; y9r = c7*t6r+c9*t7r-c10*t8r-c8*t9r-c6*t10r; y9i = c7*t6i+c9*t7i-c10*t8i-c8*t9i-c6*t10i; y10r = c6*t6r+c7*t7r+c8*t8r+c9*t9r+c10*t10r; y10i = c6*t6i+c7*t7i+c8*t8i+c9*t9i+c10*t10i; z[j0] = z[j0]+t1r+t2r+t3r+t4r+t5r; z[j0+1] = z[j0+1]+t1i+t2i+t3i+t4i+t5i; z[j1] = y1r-y10i; z[j1+1] = y1i+y10r; z[j2] = y2r-y9i; z[j2+1] = y2i+y9r; z[j3] = y3r-y8i; z[j3+1] = y3i+y8r; z[j4] = y4r-y7i; z[j4+1] = y4i+y7r; z[j5] = y5r-y6i; z[j5+1] = y5i+y6r; z[j6] = y5r+y6i; z[j6+1] = y5i-y6r; z[j7] = y4r+y7i; z[j7+1] = y4i-y7r; z[j8] = y3r+y8i; z[j8+1] = y3i-y8r; z[j9] = y2r+y9i; z[j9+1] = y2i-y9r; z[j10] = y1r+y10i; z[j10+1] = y1i-y10r; jt = j10+2; j10 = j9+2; j9 = j8+2; j8 = j7+2; j7 = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } j11 = j10+jinc; if (j11>=jmax) j11 = j11-jmax; j12 = j11+jinc; if (j12>=jmax) j12 = j12-jmax; /* if factor is 13 */ if (ifac==13) { if (mu==1) { c1 = P885; c2 = P568; c3 = P120; c4 = -P354; c5 = -P748; c6 = -P970; c7 = P464; c8 = P822; c9 = P992; c10 = P935; c11 = P663; c12 = P239; } else if (mu==2) { c1 = P568; c2 = -P354; c3 = -P970; c4 = -P748; c5 = P120; c6 = P885; c7 = P822; c8 = P935; c9 = P239; c10 = -P663; c11 = -P992; c12 = -P464; } else if (mu==3) { c1 = P120; c2 = -P970; c3 = -P354; c4 = P885; c5 = P568; c6 = -P748; c7 = P992; c8 = P239; c9 = -P935; c10 = -P464; c11 = P822; c12 = P663; } else if (mu==4) { c1 = -P354; c2 = -P748; c3 = P885; c4 = P120; c5 = -P970; c6 = P568; c7 = P935; c8 = -P663; c9 = -P464; c10 = P992; c11 = -P239; c12 = -P822; } else if (mu==5) { c1 = -P748; c2 = P120; c3 = P568; c4 = -P970; c5 = P885; c6 = -P354; c7 = P663; c8 = -P992; c9 = P822; c10 = -P239; c11 = -P464; c12 = P935; } else if (mu==6) { c1 = -P970; c2 = P885; c3 = -P748; c4 = P568; c5 = -P354; c6 = P120; c7 = P239; c8 = -P464; c9 = P663; c10 = -P822; c11 = P935; c12 = -P992; } else if (mu==7) { c1 = -P970; c2 = P885; c3 = -P748; c4 = P568; c5 = -P354; c6 = P120; c7 = -P239; c8 = P464; c9 = -P663; c10 = P822; c11 = -P935; c12 = P992; } else if (mu==8) { c1 = -P748; c2 = P120; c3 = P568; c4 = -P970; c5 = P885; c6 = -P354; c7 = -P663; c8 = P992; c9 = -P822; c10 = P239; c11 = P464; c12 = -P935; } else if (mu==9) { c1 = -P354; c2 = -P748; c3 = P885; c4 = P120; c5 = -P970; c6 = P568; c7 = -P935; c8 = P663; c9 = P464; c10 = -P992; c11 = P239; c12 = P822; } else if (mu==10) { c1 = P120; c2 = -P970; c3 = -P354; c4 = P885; c5 = P568; c6 = -P748; c7 = -P992; c8 = -P239; c9 = P935; c10 = P464; c11 = -P822; c12 = -P663; } else if (mu==11) { c1 = P568; c2 = -P354; c3 = -P970; c4 = -P748; c5 = P120; c6 = P885; c7 = -P822; c8 = -P935; c9 = -P239; c10 = P663; c11 = P992; c12 = P464; } else { c1 = P885; c2 = P568; c3 = P120; c4 = -P354; c5 = -P748; c6 = -P970; c7 = -P464; c8 = -P822; c9 = -P992; c10 = -P935; c11 = -P663; c12 = -P239; } for (l=0; l<m; l++) { t1r = z[j1]+z[j12]; t1i = z[j1+1]+z[j12+1]; t2r = z[j2]+z[j11]; t2i = z[j2+1]+z[j11+1]; t3r = z[j3]+z[j10]; t3i = z[j3+1]+z[j10+1]; t4r = z[j4]+z[j9]; t4i = z[j4+1]+z[j9+1]; t5r = z[j5]+z[j8]; t5i = z[j5+1]+z[j8+1]; t6r = z[j6]+z[j7]; t6i = z[j6+1]+z[j7+1]; t7r = z[j1]-z[j12]; t7i = z[j1+1]-z[j12+1]; t8r = z[j2]-z[j11]; t8i = z[j2+1]-z[j11+1]; t9r = z[j3]-z[j10]; t9i = z[j3+1]-z[j10+1]; t10r = z[j4]-z[j9]; t10i = z[j4+1]-z[j9+1]; t11r = z[j5]-z[j8]; t11i = z[j5+1]-z[j8+1]; t12r = z[j6]-z[j7]; t12i = z[j6+1]-z[j7+1]; t13r = z[j0]-0.5*t6r; t13i = z[j0+1]-0.5*t6i; t14r = t1r-t6r; t14i = t1i-t6i; t15r = t2r-t6r; t15i = t2i-t6i; t16r = t3r-t6r; t16i = t3i-t6i; t17r = t4r-t6r; t17i = t4i-t6i; t18r = t5r-t6r; t18i = t5i-t6i; y1r = t13r+c1*t14r+c2*t15r+c3*t16r+c4*t17r+c5*t18r; y1i = t13i+c1*t14i+c2*t15i+c3*t16i+c4*t17i+c5*t18i; y2r = t13r+c2*t14r+c4*t15r+c6*t16r+c5*t17r+c3*t18r; y2i = t13i+c2*t14i+c4*t15i+c6*t16i+c5*t17i+c3*t18i; y3r = t13r+c3*t14r+c6*t15r+c4*t16r+c1*t17r+c2*t18r; y3i = t13i+c3*t14i+c6*t15i+c4*t16i+c1*t17i+c2*t18i; y4r = t13r+c4*t14r+c5*t15r+c1*t16r+c3*t17r+c6*t18r; y4i = t13i+c4*t14i+c5*t15i+c1*t16i+c3*t17i+c6*t18i; y5r = t13r+c5*t14r+c3*t15r+c2*t16r+c6*t17r+c1*t18r; y5i = t13i+c5*t14i+c3*t15i+c2*t16i+c6*t17i+c1*t18i; y6r = t13r+c6*t14r+c1*t15r+c5*t16r+c2*t17r+c4*t18r; y6i = t13i+c6*t14i+c1*t15i+c5*t16i+c2*t17i+c4*t18i; y7r = c12*t7r-c7*t8r+c11*t9r-c8*t10r+c10*t11r-c9*t12r; y7i = c12*t7i-c7*t8i+c11*t9i-c8*t10i+c10*t11i-c9*t12i; y8r = c11*t7r-c9*t8r+c8*t9r-c12*t10r-c7*t11r+c10*t12r; y8i = c11*t7i-c9*t8i+c8*t9i-c12*t10i-c7*t11i+c10*t12i; y9r = c10*t7r-c11*t8r-c7*t9r+c9*t10r-c12*t11r-c8*t12r; y9i = c10*t7i-c11*t8i-c7*t9i+c9*t10i-c12*t11i-c8*t12i; y10r = c9*t7r+c12*t8r-c10*t9r-c7*t10r+c8*t11r+c11*t12r; y10i = c9*t7i+c12*t8i-c10*t9i-c7*t10i+c8*t11i+c11*t12i; y11r = c8*t7r+c10*t8r+c12*t9r-c11*t10r-c9*t11r-c7*t12r; y11i = c8*t7i+c10*t8i+c12*t9i-c11*t10i-c9*t11i-c7*t12i; y12r = c7*t7r+c8*t8r+c9*t9r+c10*t10r+c11*t11r+c12*t12r; y12i = c7*t7i+c8*t8i+c9*t9i+c10*t10i+c11*t11i+c12*t12i; z[j0] = z[j0]+t1r+t2r+t3r+t4r+t5r+t6r; z[j0+1] = z[j0+1]+t1i+t2i+t3i+t4i+t5i+t6i; z[j1] = y1r-y12i; z[j1+1] = y1i+y12r; z[j2] = y2r-y11i; z[j2+1] = y2i+y11r; z[j3] = y3r-y10i; z[j3+1] = y3i+y10r; z[j4] = y4r-y9i; z[j4+1] = y4i+y9r; z[j5] = y5r-y8i; z[j5+1] = y5i+y8r; z[j6] = y6r-y7i; z[j6+1] = y6i+y7r; z[j7] = y6r+y7i; z[j7+1] = y6i-y7r; z[j8] = y5r+y8i; z[j8+1] = y5i-y8r; z[j9] = y4r+y9i; z[j9+1] = y4i-y9r; z[j10] = y3r+y10i; z[j10+1] = y3i-y10r; z[j11] = y2r+y11i; z[j11+1] = y2i-y11r; z[j12] = y1r+y12i; z[j12+1] = y1i-y12r; jt = j12+2; j12 = j11+2; j11 = j10+2; j10 = j9+2; j9 = j8+2; j8 = j7+2; j7 = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } j13 = j12+jinc; if (j13>=jmax) j13 = j13-jmax; j14 = j13+jinc; if (j14>=jmax) j14 = j14-jmax; j15 = j14+jinc; if (j15>=jmax) j15 = j15-jmax; /* if factor is 16 */ if (ifac==16) { if (mu==1) { c1 = 1.0; c2 = P923; c3 = P382; c4 = P707; } else if (mu==3) { c1 = -1.0; c2 = P382; c3 = P923; c4 = -P707; } else if (mu==5) { c1 = 1.0; c2 = -P382; c3 = P923; c4 = -P707; } else if (mu==7) { c1 = -1.0; c2 = -P923; c3 = P382; c4 = P707; } else if (mu==9) { c1 = 1.0; c2 = -P923; c3 = -P382; c4 = P707; } else if (mu==11) { c1 = -1.0; c2 = -P382; c3 = -P923; c4 = -P707; } else if (mu==13) { c1 = 1.0; c2 = P382; c3 = -P923; c4 = -P707; } else { c1 = -1.0; c2 = P923; c3 = -P382; c4 = P707; } c5 = c1*c4; c6 = c1*c3; c7 = c1*c2; for (l=0; l<m; l++) { t1r = z[j0]+z[j8]; t1i = z[j0+1]+z[j8+1]; t2r = z[j4]+z[j12]; t2i = z[j4+1]+z[j12+1]; t3r = z[j0]-z[j8]; t3i = z[j0+1]-z[j8+1]; t4r = c1*(z[j4]-z[j12]); t4i = c1*(z[j4+1]-z[j12+1]); t5r = t1r+t2r; t5i = t1i+t2i; t6r = t1r-t2r; t6i = t1i-t2i; t7r = z[j1]+z[j9]; t7i = z[j1+1]+z[j9+1]; t8r = z[j5]+z[j13]; t8i = z[j5+1]+z[j13+1]; t9r = z[j1]-z[j9]; t9i = z[j1+1]-z[j9+1]; t10r = z[j5]-z[j13]; t10i = z[j5+1]-z[j13+1]; t11r = t7r+t8r; t11i = t7i+t8i; t12r = t7r-t8r; t12i = t7i-t8i; t13r = z[j2]+z[j10]; t13i = z[j2+1]+z[j10+1]; t14r = z[j6]+z[j14]; t14i = z[j6+1]+z[j14+1]; t15r = z[j2]-z[j10]; t15i = z[j2+1]-z[j10+1]; t16r = z[j6]-z[j14]; t16i = z[j6+1]-z[j14+1]; t17r = t13r+t14r; t17i = t13i+t14i; t18r = c4*(t15r-t16r); t18i = c4*(t15i-t16i); t19r = c5*(t15r+t16r); t19i = c5*(t15i+t16i); t20r = c1*(t13r-t14r); t20i = c1*(t13i-t14i); t21r = z[j3]+z[j11]; t21i = z[j3+1]+z[j11+1]; t22r = z[j7]+z[j15]; t22i = z[j7+1]+z[j15+1]; t23r = z[j3]-z[j11]; t23i = z[j3+1]-z[j11+1]; t24r = z[j7]-z[j15]; t24i = z[j7+1]-z[j15+1]; t25r = t21r+t22r; t25i = t21i+t22i; t26r = t21r-t22r; t26i = t21i-t22i; t27r = t9r+t24r; t27i = t9i+t24i; t28r = t10r+t23r; t28i = t10i+t23i; t29r = t9r-t24r; t29i = t9i-t24i; t30r = t10r-t23r; t30i = t10i-t23i; t31r = t5r+t17r; t31i = t5i+t17i; t32r = t11r+t25r; t32i = t11i+t25i; t33r = t3r+t18r; t33i = t3i+t18i; t34r = c2*t29r-c6*t30r; t34i = c2*t29i-c6*t30i; t35r = t3r-t18r; t35i = t3i-t18i; t36r = c7*t27r-c3*t28r; t36i = c7*t27i-c3*t28i; t37r = t4r+t19r; t37i = t4i+t19i; t38r = c3*t27r+c7*t28r; t38i = c3*t27i+c7*t28i; t39r = t4r-t19r; t39i = t4i-t19i; t40r = c6*t29r+c2*t30r; t40i = c6*t29i+c2*t30i; t41r = c4*(t12r-t26r); t41i = c4*(t12i-t26i); t42r = c5*(t12r+t26r); t42i = c5*(t12i+t26i); y1r = t33r+t34r; y1i = t33i+t34i; y2r = t6r+t41r; y2i = t6i+t41i; y3r = t35r+t40r; y3i = t35i+t40i; y4r = t5r-t17r; y4i = t5i-t17i; y5r = t35r-t40r; y5i = t35i-t40i; y6r = t6r-t41r; y6i = t6i-t41i; y7r = t33r-t34r; y7i = t33i-t34i; y9r = t38r-t37r; y9i = t38i-t37i; y10r = t42r-t20r; y10i = t42i-t20i; y11r = t36r+t39r; y11i = t36i+t39i; y12r = c1*(t11r-t25r); y12i = c1*(t11i-t25i); y13r = t36r-t39r; y13i = t36i-t39i; y14r = t42r+t20r; y14i = t42i+t20i; y15r = t38r+t37r; y15i = t38i+t37i; z[j0] = t31r+t32r; z[j0+1] = t31i+t32i; z[j1] = y1r-y15i; z[j1+1] = y1i+y15r; z[j2] = y2r-y14i; z[j2+1] = y2i+y14r; z[j3] = y3r-y13i; z[j3+1] = y3i+y13r; z[j4] = y4r-y12i; z[j4+1] = y4i+y12r; z[j5] = y5r-y11i; z[j5+1] = y5i+y11r; z[j6] = y6r-y10i; z[j6+1] = y6i+y10r; z[j7] = y7r-y9i; z[j7+1] = y7i+y9r; z[j8] = t31r-t32r; z[j8+1] = t31i-t32i; z[j9] = y7r+y9i; z[j9+1] = y7i-y9r; z[j10] = y6r+y10i; z[j10+1] = y6i-y10r; z[j11] = y5r+y11i; z[j11+1] = y5i-y11r; z[j12] = y4r+y12i; z[j12+1] = y4i-y12r; z[j13] = y3r+y13i; z[j13+1] = y3i-y13r; z[j14] = y2r+y14i; z[j14+1] = y2i-y14r; z[j15] = y1r+y15i; z[j15+1] = y1i-y15r; jt = j15+2; j15 = j14+2; j14 = j13+2; j13 = j12+2; j12 = j11+2; j11 = j10+2; j10 = j9+2; j9 = j8+2; j8 = j7+2; j7 = j6+2; j6 = j5+2; j5 = j4+2; j4 = j3+2; j3 = j2+2; j2 = j1+2; j1 = j0+2; j0 = jt; } continue; } } } void pfacr (int isign, int n, complex cz[], REAL rz[]) { int i,ir,ii,jr,ji,no2; REAL *z,tempr,tempi,sumr,sumi,difr,difi; REAL wr,wi,wpr,wpi,wtemp,theta; /* copy input to output and fix dc and nyquist */ z = (REAL*)cz; for (i=2; i<n; i++) rz[i] = z[i]; rz[1] = z[0]-z[n]; rz[0] = z[0]+z[n]; z = rz; /* initialize cosine-sine recurrence */ theta = 2.0*M_PI/(REAL)n; if (isign>0) theta = -theta; wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0+wpr; wi = wpi; /* twiddle */ no2 = n/2; for (ir=2,ii=3,jr=n-2,ji=n-1; ir<=no2; ir+=2,ii+=2,jr-=2,ji-=2) { sumr = z[ir]+z[jr]; sumi = z[ii]+z[ji]; difr = z[ir]-z[jr]; difi = z[ii]-z[ji]; tempr = wi*difr-wr*sumi; tempi = wi*sumi+wr*difr; z[ir] = sumr+tempr; z[ii] = difi+tempi; z[jr] = sumr-tempr; z[ji] = tempi-difi; wtemp = wr; wr += wr*wpr-wi*wpi; wi += wi*wpr+wtemp*wpi; } /* do complex to complex transform */ pfacc(isign,n/2,(complex*)z); } void pfarc (int isign, int n, REAL rz[], complex cz[]) { int i,ir,ii,jr,ji,no2; REAL *z,tempr,tempi,sumr,sumi,difr,difi; REAL wr,wi,wpr,wpi,wtemp,theta; /* copy input to output while scaling */ z = (REAL*)cz; for (i=0; i<n; i++) z[i] = 0.5*rz[i]; /* do complex to complex transform */ pfacc(isign,n/2,cz); /* fix dc and nyquist */ z[n] = 2.0*(z[0]-z[1]); z[0] = 2.0*(z[0]+z[1]); z[n+1] = 0.0; z[1] = 0.0; /* initialize cosine-sine recurrence */ theta = 2.0*M_PI/(REAL)n; if (isign<0) theta = -theta; wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0+wpr; wi = wpi; /* twiddle */ no2 = n/2; for (ir=2,ii=3,jr=n-2,ji=n-1; ir<=no2; ir+=2,ii+=2,jr-=2,ji-=2) { sumr = z[ir]+z[jr]; sumi = z[ii]+z[ji]; difr = z[ir]-z[jr]; difi = z[ii]-z[ji]; tempr = wi*difr+wr*sumi; tempi = wi*sumi-wr*difr; z[ir] = sumr+tempr; z[ii] = difi+tempi; z[jr] = sumr-tempr; z[ji] = tempi-difi; wtemp = wr; wr += wr*wpr-wi*wpi; wi += wi*wpr+wtemp*wpi; } } void pfamcc (int isign, int n, int nt, int k, int kt, complex cz[]) { static int kfax[] = { 16,13,11,9,8,7,5,4,3,2 }; REAL *z=(REAL*)cz; int j0,j1,j2,j3,j4,j5,j6,j7,j8,j9,j10,j11,j12,j13,j14,j15; int nleft,jfax,ifac,jfac,iinc,imax,ndiv,m,mm=0,mu=0,l,istep,jstep, jt,i0,i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,i13,i14,i15,it; REAL 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; /* determine step within and between transforms */ istep = 2*k; jstep = 2*kt; /* 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 */ iinc = istep*mm; imax = istep*n; i0 = 0; i1 = i0+iinc; /* if factor is 2 */ if (ifac==2) { for (l=0; l<m; l++) { j0 = i0; j1 = i1; for (jt=0; jt<nt; jt++) { t1r = z[j0]-z[j1]; t1i = z[j0+1]-z[j1+1]; z[j0] = z[j0]+z[j1]; z[j0+1] = z[j0+1]+z[j1+1]; z[j1] = t1r; z[j1+1] = t1i; j0 += jstep; j1 += jstep; } it = i1+istep; i1 = i0+istep; i0 = it; } continue; } i2 = i1+iinc; if (i2>=imax) i2 = i2-imax; /* if factor is 3 */ if (ifac==3) { if (mu==1) c1 = P866; else c1 = -P866; for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; for (jt=0; jt<nt; jt++) { t1r = z[j1]+z[j2]; t1i = z[j1+1]+z[j2+1]; y1r = z[j0]-0.5*t1r; y1i = z[j0+1]-0.5*t1i; y2r = c1*(z[j1]-z[j2]); y2i = c1*(z[j1+1]-z[j2+1]); z[j0] = z[j0]+t1r; z[j0+1] = z[j0+1]+t1i; z[j1] = y1r-y2i; z[j1+1] = y1i+y2r; z[j2] = y1r+y2i; z[j2+1] = y1i-y2r; j0 += jstep; j1 += jstep; j2 += jstep; } it = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i3 = i2+iinc; if (i3>=imax) i3 = i3-imax; /* if factor is 4 */ if (ifac==4) { if (mu==1) c1 = 1.0; else c1 = -1.0; for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; for (jt=0; jt<nt; jt++) { t1r = z[j0]+z[j2]; t1i = z[j0+1]+z[j2+1]; t2r = z[j1]+z[j3]; t2i = z[j1+1]+z[j3+1]; y1r = z[j0]-z[j2]; y1i = z[j0+1]-z[j2+1]; y3r = c1*(z[j1]-z[j3]); y3i = c1*(z[j1+1]-z[j3+1]); z[j0] = t1r+t2r; z[j0+1] = t1i+t2i; z[j1] = y1r-y3i; z[j1+1] = y1i+y3r; z[j2] = t1r-t2r; z[j2+1] = t1i-t2i; z[j3] = y1r+y3i; z[j3+1] = y1i-y3r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; } it = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i4 = i3+iinc; if (i4>=imax) i4 = i4-imax; /* 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++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; for (jt=0; jt<nt; jt++) { t1r = z[j1]+z[j4]; t1i = z[j1+1]+z[j4+1]; t2r = z[j2]+z[j3]; t2i = z[j2+1]+z[j3+1]; t3r = z[j1]-z[j4]; t3i = z[j1+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[j0]-0.25*t5r; t7i = z[j0+1]-0.25*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[j0] = z[j0]+t5r; z[j0+1] = z[j0+1]+t5i; z[j1] = y1r-y4i; z[j1+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; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; } it = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i5 = i4+iinc; if (i5>=imax) i5 = i5-imax; i6 = i5+iinc; if (i6>=imax) i6 = i6-imax; /* 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++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; for (jt=0; jt<nt; jt++) { t1r = z[j1]+z[j6]; t1i = z[j1+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[j1]-z[j6]; t4i = z[j1+1]-z[j6+1]; t5r = z[j2]-z[j5]; t5i = z[j2+1]-z[j5+1]; t6r = z[j3]-z[j4]; t6i = z[j3+1]-z[j4+1]; t7r = z[j0]-0.5*t3r; t7i = z[j0+1]-0.5*t3i; t8r = t1r-t3r; t8i = t1i-t3i; t9r = t2r-t3r; t9i = t2i-t3i; y1r = t7r+c1*t8r+c2*t9r; y1i = t7i+c1*t8i+c2*t9i; y2r = t7r+c2*t8r+c3*t9r; y2i = t7i+c2*t8i+c3*t9i; y3r = t7r+c3*t8r+c1*t9r; y3i = t7i+c3*t8i+c1*t9i; y4r = c6*t4r-c4*t5r+c5*t6r; y4i = c6*t4i-c4*t5i+c5*t6i; y5r = c5*t4r-c6*t5r-c4*t6r; y5i = c5*t4i-c6*t5i-c4*t6i; y6r = c4*t4r+c5*t5r+c6*t6r; y6i = c4*t4i+c5*t5i+c6*t6i; z[j0] = z[j0]+t1r+t2r+t3r; z[j0+1] = z[j0+1]+t1i+t2i+t3i; z[j1] = y1r-y6i; z[j1+1] = y1i+y6r; z[j2] = y2r-y5i; z[j2+1] = y2i+y5r; z[j3] = y3r-y4i; z[j3+1] = y3i+y4r; z[j4] = y3r+y4i; z[j4+1] = y3i-y4r; z[j5] = y2r+y5i; z[j5+1] = y2i-y5r; z[j6] = y1r+y6i; z[j6+1] = y1i-y6r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; } it = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i7 = i6+iinc; if (i7>=imax) i7 = i7-imax; /* if factor is 8 */ if (ifac==8) { if (mu==1) { c1 = 1.0; c2 = P707; } else if (mu==3) { c1 = -1.0; c2 = -P707; } else if (mu==5) { c1 = 1.0; c2 = -P707; } else { c1 = -1.0; c2 = P707; } c3 = c1*c2; for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; j7 = i7; for (jt=0; jt<nt; jt++) { t1r = z[j0]+z[j4]; t1i = z[j0+1]+z[j4+1]; t2r = z[j0]-z[j4]; t2i = z[j0+1]-z[j4+1]; t3r = z[j1]+z[j5]; t3i = z[j1+1]+z[j5+1]; t4r = z[j1]-z[j5]; t4i = z[j1+1]-z[j5+1]; t5r = z[j2]+z[j6]; t5i = z[j2+1]+z[j6+1]; t6r = c1*(z[j2]-z[j6]); t6i = c1*(z[j2+1]-z[j6+1]); t7r = z[j3]+z[j7]; t7i = z[j3+1]+z[j7+1]; t8r = z[j3]-z[j7]; t8i = z[j3+1]-z[j7+1]; t9r = t1r+t5r; t9i = t1i+t5i; t10r = t3r+t7r; t10i = t3i+t7i; t11r = c2*(t4r-t8r); t11i = c2*(t4i-t8i); t12r = c3*(t4r+t8r); t12i = c3*(t4i+t8i); y1r = t2r+t11r; y1i = t2i+t11i; y2r = t1r-t5r; y2i = t1i-t5i; y3r = t2r-t11r; y3i = t2i-t11i; y5r = t12r-t6r; y5i = t12i-t6i; y6r = c1*(t3r-t7r); y6i = c1*(t3i-t7i); y7r = t12r+t6r; y7i = t12i+t6i; z[j0] = t9r+t10r; z[j0+1] = t9i+t10i; z[j1] = y1r-y7i; z[j1+1] = y1i+y7r; z[j2] = y2r-y6i; z[j2+1] = y2i+y6r; z[j3] = y3r-y5i; z[j3+1] = y3i+y5r; z[j4] = t9r-t10r; z[j4+1] = t9i-t10i; z[j5] = y3r+y5i; z[j5+1] = y3i-y5r; z[j6] = y2r+y6i; z[j6+1] = y2i-y6r; z[j7] = y1r+y7i; z[j7+1] = y1i-y7r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; j7 += jstep; } it = i7+istep; i7 = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i8 = i7+iinc; if (i8>=imax) i8 = i8-imax; /* if factor is 9 */ if (ifac==9) { if (mu==1) { c1 = P866; c2 = P766; c3 = P642; c4 = P173; c5 = P984; } else if (mu==2) { c1 = -P866; c2 = P173; c3 = P984; c4 = -P939; c5 = P342; } else if (mu==4) { c1 = P866; c2 = -P939; c3 = P342; c4 = P766; c5 = -P642; } else if (mu==5) { c1 = -P866; c2 = -P939; c3 = -P342; c4 = P766; c5 = P642; } else if (mu==7) { c1 = P866; c2 = P173; c3 = -P984; c4 = -P939; c5 = -P342; } else { c1 = -P866; c2 = P766; c3 = -P642; c4 = P173; c5 = -P984; } c6 = c1*c2; c7 = c1*c3; c8 = c1*c4; c9 = c1*c5; for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; j7 = i7; j8 = i8; for (jt=0; jt<nt; jt++) { t1r = z[j3]+z[j6]; t1i = z[j3+1]+z[j6+1]; t2r = z[j0]-0.5*t1r; t2i = z[j0+1]-0.5*t1i; t3r = c1*(z[j3]-z[j6]); t3i = c1*(z[j3+1]-z[j6+1]); t4r = z[j0]+t1r; t4i = z[j0+1]+t1i; t5r = z[j4]+z[j7]; t5i = z[j4+1]+z[j7+1]; t6r = z[j1]-0.5*t5r; t6i = z[j1+1]-0.5*t5i; t7r = z[j4]-z[j7]; t7i = z[j4+1]-z[j7+1]; t8r = z[j1]+t5r; t8i = z[j1+1]+t5i; t9r = z[j2]+z[j5]; t9i = z[j2+1]+z[j5+1]; t10r = z[j8]-0.5*t9r; t10i = z[j8+1]-0.5*t9i; t11r = z[j2]-z[j5]; t11i = z[j2+1]-z[j5+1]; t12r = z[j8]+t9r; t12i = z[j8+1]+t9i; t13r = t8r+t12r; t13i = t8i+t12i; t14r = t6r+t10r; t14i = t6i+t10i; t15r = t6r-t10r; t15i = t6i-t10i; t16r = t7r+t11r; t16i = t7i+t11i; t17r = t7r-t11r; t17i = t7i-t11i; t18r = c2*t14r-c7*t17r; t18i = c2*t14i-c7*t17i; t19r = c4*t14r+c9*t17r; t19i = c4*t14i+c9*t17i; t20r = c3*t15r+c6*t16r; t20i = c3*t15i+c6*t16i; t21r = c5*t15r-c8*t16r; t21i = c5*t15i-c8*t16i; t22r = t18r+t19r; t22i = t18i+t19i; t23r = t20r-t21r; t23i = t20i-t21i; y1r = t2r+t18r; y1i = t2i+t18i; y2r = t2r+t19r; y2i = t2i+t19i; y3r = t4r-0.5*t13r; y3i = t4i-0.5*t13i; y4r = t2r-t22r; y4i = t2i-t22i; y5r = t3r-t23r; y5i = t3i-t23i; y6r = c1*(t8r-t12r); y6i = c1*(t8i-t12i); y7r = t21r-t3r; y7i = t21i-t3i; y8r = t3r+t20r; y8i = t3i+t20i; z[j0] = t4r+t13r; z[j0+1] = t4i+t13i; z[j1] = y1r-y8i; z[j1+1] = y1i+y8r; z[j2] = y2r-y7i; z[j2+1] = y2i+y7r; z[j3] = y3r-y6i; z[j3+1] = y3i+y6r; z[j4] = y4r-y5i; z[j4+1] = y4i+y5r; z[j5] = y4r+y5i; z[j5+1] = y4i-y5r; z[j6] = y3r+y6i; z[j6+1] = y3i-y6r; z[j7] = y2r+y7i; z[j7+1] = y2i-y7r; z[j8] = y1r+y8i; z[j8+1] = y1i-y8r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; j7 += jstep; j8 += jstep; } it = i8+istep; i8 = i7+istep; i7 = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i9 = i8+iinc; if (i9>=imax) i9 = i9-imax; i10 = i9+iinc; if (i10>=imax) i10 = i10-imax; /* if factor is 11 */ if (ifac==11) { if (mu==1) { c1 = P841; c2 = P415; c3 = -P142; c4 = -P654; c5 = -P959; c6 = P540; c7 = P909; c8 = P989; c9 = P755; c10 = P281; } else if (mu==2) { c1 = P415; c2 = -P654; c3 = -P959; c4 = -P142; c5 = P841; c6 = P909; c7 = P755; c8 = -P281; c9 = -P989; c10 = -P540; } else if (mu==3) { c1 = -P142; c2 = -P959; c3 = P415; c4 = P841; c5 = -P654; c6 = P989; c7 = -P281; c8 = -P909; c9 = P540; c10 = P755; } else if (mu==4) { c1 = -P654; c2 = -P142; c3 = P841; c4 = -P959; c5 = P415; c6 = P755; c7 = -P989; c8 = P540; c9 = P281; c10 = -P909; } else if (mu==5) { c1 = -P959; c2 = P841; c3 = -P654; c4 = P415; c5 = -P142; c6 = P281; c7 = -P540; c8 = P755; c9 = -P909; c10 = P989; } else if (mu==6) { c1 = -P959; c2 = P841; c3 = -P654; c4 = P415; c5 = -P142; c6 = -P281; c7 = P540; c8 = -P755; c9 = P909; c10 = -P989; } else if (mu==7) { c1 = -P654; c2 = -P142; c3 = P841; c4 = -P959; c5 = P415; c6 = -P755; c7 = P989; c8 = -P540; c9 = -P281; c10 = P909; } else if (mu==8) { c1 = -P142; c2 = -P959; c3 = P415; c4 = P841; c5 = -P654; c6 = -P989; c7 = P281; c8 = P909; c9 = -P540; c10 = -P755; } else if (mu==9) { c1 = P415; c2 = -P654; c3 = -P959; c4 = -P142; c5 = P841; c6 = -P909; c7 = -P755; c8 = P281; c9 = P989; c10 = P540; } else { c1 = P841; c2 = P415; c3 = -P142; c4 = -P654; c5 = -P959; c6 = -P540; c7 = -P909; c8 = -P989; c9 = -P755; c10 = -P281; } for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; j7 = i7; j8 = i8; j9 = i9; j10 = i10; for (jt=0; jt<nt; jt++) { t1r = z[j1]+z[j10]; t1i = z[j1+1]+z[j10+1]; t2r = z[j2]+z[j9]; t2i = z[j2+1]+z[j9+1]; t3r = z[j3]+z[j8]; t3i = z[j3+1]+z[j8+1]; t4r = z[j4]+z[j7]; t4i = z[j4+1]+z[j7+1]; t5r = z[j5]+z[j6]; t5i = z[j5+1]+z[j6+1]; t6r = z[j1]-z[j10]; t6i = z[j1+1]-z[j10+1]; t7r = z[j2]-z[j9]; t7i = z[j2+1]-z[j9+1]; t8r = z[j3]-z[j8]; t8i = z[j3+1]-z[j8+1]; t9r = z[j4]-z[j7]; t9i = z[j4+1]-z[j7+1]; t10r = z[j5]-z[j6]; t10i = z[j5+1]-z[j6+1]; t11r = z[j0]-0.5*t5r; t11i = z[j0+1]-0.5*t5i; t12r = t1r-t5r; t12i = t1i-t5i; t13r = t2r-t5r; t13i = t2i-t5i; t14r = t3r-t5r; t14i = t3i-t5i; t15r = t4r-t5r; t15i = t4i-t5i; y1r = t11r+c1*t12r+c2*t13r+c3*t14r+c4*t15r; y1i = t11i+c1*t12i+c2*t13i+c3*t14i+c4*t15i; y2r = t11r+c2*t12r+c4*t13r+c5*t14r+c3*t15r; y2i = t11i+c2*t12i+c4*t13i+c5*t14i+c3*t15i; y3r = t11r+c3*t12r+c5*t13r+c2*t14r+c1*t15r; y3i = t11i+c3*t12i+c5*t13i+c2*t14i+c1*t15i; y4r = t11r+c4*t12r+c3*t13r+c1*t14r+c5*t15r; y4i = t11i+c4*t12i+c3*t13i+c1*t14i+c5*t15i; y5r = t11r+c5*t12r+c1*t13r+c4*t14r+c2*t15r; y5i = t11i+c5*t12i+c1*t13i+c4*t14i+c2*t15i; y6r = c10*t6r-c6*t7r+c9*t8r-c7*t9r+c8*t10r; y6i = c10*t6i-c6*t7i+c9*t8i-c7*t9i+c8*t10i; y7r = c9*t6r-c8*t7r+c6*t8r+c10*t9r-c7*t10r; y7i = c9*t6i-c8*t7i+c6*t8i+c10*t9i-c7*t10i; y8r = c8*t6r-c10*t7r-c7*t8r+c6*t9r+c9*t10r; y8i = c8*t6i-c10*t7i-c7*t8i+c6*t9i+c9*t10i; y9r = c7*t6r+c9*t7r-c10*t8r-c8*t9r-c6*t10r; y9i = c7*t6i+c9*t7i-c10*t8i-c8*t9i-c6*t10i; y10r = c6*t6r+c7*t7r+c8*t8r+c9*t9r+c10*t10r; y10i = c6*t6i+c7*t7i+c8*t8i+c9*t9i+c10*t10i; z[j0] = z[j0]+t1r+t2r+t3r+t4r+t5r; z[j0+1] = z[j0+1]+t1i+t2i+t3i+t4i+t5i; z[j1] = y1r-y10i; z[j1+1] = y1i+y10r; z[j2] = y2r-y9i; z[j2+1] = y2i+y9r; z[j3] = y3r-y8i; z[j3+1] = y3i+y8r; z[j4] = y4r-y7i; z[j4+1] = y4i+y7r; z[j5] = y5r-y6i; z[j5+1] = y5i+y6r; z[j6] = y5r+y6i; z[j6+1] = y5i-y6r; z[j7] = y4r+y7i; z[j7+1] = y4i-y7r; z[j8] = y3r+y8i; z[j8+1] = y3i-y8r; z[j9] = y2r+y9i; z[j9+1] = y2i-y9r; z[j10] = y1r+y10i; z[j10+1] = y1i-y10r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; j7 += jstep; j8 += jstep; j9 += jstep; j10 += jstep; } it = i10+istep; i10 = i9+istep; i9 = i8+istep; i8 = i7+istep; i7 = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i11 = i10+iinc; if (i11>=imax) i11 = i11-imax; i12 = i11+iinc; if (i12>=imax) i12 = i12-imax; /* if factor is 13 */ if (ifac==13) { if (mu==1) { c1 = P885; c2 = P568; c3 = P120; c4 = -P354; c5 = -P748; c6 = -P970; c7 = P464; c8 = P822; c9 = P992; c10 = P935; c11 = P663; c12 = P239; } else if (mu==2) { c1 = P568; c2 = -P354; c3 = -P970; c4 = -P748; c5 = P120; c6 = P885; c7 = P822; c8 = P935; c9 = P239; c10 = -P663; c11 = -P992; c12 = -P464; } else if (mu==3) { c1 = P120; c2 = -P970; c3 = -P354; c4 = P885; c5 = P568; c6 = -P748; c7 = P992; c8 = P239; c9 = -P935; c10 = -P464; c11 = P822; c12 = P663; } else if (mu==4) { c1 = -P354; c2 = -P748; c3 = P885; c4 = P120; c5 = -P970; c6 = P568; c7 = P935; c8 = -P663; c9 = -P464; c10 = P992; c11 = -P239; c12 = -P822; } else if (mu==5) { c1 = -P748; c2 = P120; c3 = P568; c4 = -P970; c5 = P885; c6 = -P354; c7 = P663; c8 = -P992; c9 = P822; c10 = -P239; c11 = -P464; c12 = P935; } else if (mu==6) { c1 = -P970; c2 = P885; c3 = -P748; c4 = P568; c5 = -P354; c6 = P120; c7 = P239; c8 = -P464; c9 = P663; c10 = -P822; c11 = P935; c12 = -P992; } else if (mu==7) { c1 = -P970; c2 = P885; c3 = -P748; c4 = P568; c5 = -P354; c6 = P120; c7 = -P239; c8 = P464; c9 = -P663; c10 = P822; c11 = -P935; c12 = P992; } else if (mu==8) { c1 = -P748; c2 = P120; c3 = P568; c4 = -P970; c5 = P885; c6 = -P354; c7 = -P663; c8 = P992; c9 = -P822; c10 = P239; c11 = P464; c12 = -P935; } else if (mu==9) { c1 = -P354; c2 = -P748; c3 = P885; c4 = P120; c5 = -P970; c6 = P568; c7 = -P935; c8 = P663; c9 = P464; c10 = -P992; c11 = P239; c12 = P822; } else if (mu==10) { c1 = P120; c2 = -P970; c3 = -P354; c4 = P885; c5 = P568; c6 = -P748; c7 = -P992; c8 = -P239; c9 = P935; c10 = P464; c11 = -P822; c12 = -P663; } else if (mu==11) { c1 = P568; c2 = -P354; c3 = -P970; c4 = -P748; c5 = P120; c6 = P885; c7 = -P822; c8 = -P935; c9 = -P239; c10 = P663; c11 = P992; c12 = P464; } else { c1 = P885; c2 = P568; c3 = P120; c4 = -P354; c5 = -P748; c6 = -P970; c7 = -P464; c8 = -P822; c9 = -P992; c10 = -P935; c11 = -P663; c12 = -P239; } for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; j7 = i7; j8 = i8; j9 = i9; j10 = i10; j11 = i11; j12 = i12; for (jt=0; jt<nt; jt++) { t1r = z[j1]+z[j12]; t1i = z[j1+1]+z[j12+1]; t2r = z[j2]+z[j11]; t2i = z[j2+1]+z[j11+1]; t3r = z[j3]+z[j10]; t3i = z[j3+1]+z[j10+1]; t4r = z[j4]+z[j9]; t4i = z[j4+1]+z[j9+1]; t5r = z[j5]+z[j8]; t5i = z[j5+1]+z[j8+1]; t6r = z[j6]+z[j7]; t6i = z[j6+1]+z[j7+1]; t7r = z[j1]-z[j12]; t7i = z[j1+1]-z[j12+1]; t8r = z[j2]-z[j11]; t8i = z[j2+1]-z[j11+1]; t9r = z[j3]-z[j10]; t9i = z[j3+1]-z[j10+1]; t10r = z[j4]-z[j9]; t10i = z[j4+1]-z[j9+1]; t11r = z[j5]-z[j8]; t11i = z[j5+1]-z[j8+1]; t12r = z[j6]-z[j7]; t12i = z[j6+1]-z[j7+1]; t13r = z[j0]-0.5*t6r; t13i = z[j0+1]-0.5*t6i; t14r = t1r-t6r; t14i = t1i-t6i; t15r = t2r-t6r; t15i = t2i-t6i; t16r = t3r-t6r; t16i = t3i-t6i; t17r = t4r-t6r; t17i = t4i-t6i; t18r = t5r-t6r; t18i = t5i-t6i; y1r = t13r+c1*t14r+c2*t15r+c3*t16r+c4*t17r+c5*t18r; y1i = t13i+c1*t14i+c2*t15i+c3*t16i+c4*t17i+c5*t18i; y2r = t13r+c2*t14r+c4*t15r+c6*t16r+c5*t17r+c3*t18r; y2i = t13i+c2*t14i+c4*t15i+c6*t16i+c5*t17i+c3*t18i; y3r = t13r+c3*t14r+c6*t15r+c4*t16r+c1*t17r+c2*t18r; y3i = t13i+c3*t14i+c6*t15i+c4*t16i+c1*t17i+c2*t18i; y4r = t13r+c4*t14r+c5*t15r+c1*t16r+c3*t17r+c6*t18r; y4i = t13i+c4*t14i+c5*t15i+c1*t16i+c3*t17i+c6*t18i; y5r = t13r+c5*t14r+c3*t15r+c2*t16r+c6*t17r+c1*t18r; y5i = t13i+c5*t14i+c3*t15i+c2*t16i+c6*t17i+c1*t18i; y6r = t13r+c6*t14r+c1*t15r+c5*t16r+c2*t17r+c4*t18r; y6i = t13i+c6*t14i+c1*t15i+c5*t16i+c2*t17i+c4*t18i; y7r = c12*t7r-c7*t8r+c11*t9r-c8*t10r+c10*t11r-c9*t12r; y7i = c12*t7i-c7*t8i+c11*t9i-c8*t10i+c10*t11i-c9*t12i; y8r = c11*t7r-c9*t8r+c8*t9r-c12*t10r-c7*t11r+c10*t12r; y8i = c11*t7i-c9*t8i+c8*t9i-c12*t10i-c7*t11i+c10*t12i; y9r = c10*t7r-c11*t8r-c7*t9r+c9*t10r-c12*t11r-c8*t12r; y9i = c10*t7i-c11*t8i-c7*t9i+c9*t10i-c12*t11i-c8*t12i; y10r = c9*t7r+c12*t8r-c10*t9r-c7*t10r+c8*t11r+c11*t12r; y10i = c9*t7i+c12*t8i-c10*t9i-c7*t10i+c8*t11i+c11*t12i; y11r = c8*t7r+c10*t8r+c12*t9r-c11*t10r-c9*t11r-c7*t12r; y11i = c8*t7i+c10*t8i+c12*t9i-c11*t10i-c9*t11i-c7*t12i; y12r = c7*t7r+c8*t8r+c9*t9r+c10*t10r+c11*t11r+c12*t12r; y12i = c7*t7i+c8*t8i+c9*t9i+c10*t10i+c11*t11i+c12*t12i; z[j0] = z[j0]+t1r+t2r+t3r+t4r+t5r+t6r; z[j0+1] = z[j0+1]+t1i+t2i+t3i+t4i+t5i+t6i; z[j1] = y1r-y12i; z[j1+1] = y1i+y12r; z[j2] = y2r-y11i; z[j2+1] = y2i+y11r; z[j3] = y3r-y10i; z[j3+1] = y3i+y10r; z[j4] = y4r-y9i; z[j4+1] = y4i+y9r; z[j5] = y5r-y8i; z[j5+1] = y5i+y8r; z[j6] = y6r-y7i; z[j6+1] = y6i+y7r; z[j7] = y6r+y7i; z[j7+1] = y6i-y7r; z[j8] = y5r+y8i; z[j8+1] = y5i-y8r; z[j9] = y4r+y9i; z[j9+1] = y4i-y9r; z[j10] = y3r+y10i; z[j10+1] = y3i-y10r; z[j11] = y2r+y11i; z[j11+1] = y2i-y11r; z[j12] = y1r+y12i; z[j12+1] = y1i-y12r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; j7 += jstep; j8 += jstep; j9 += jstep; j10 += jstep; j11 += jstep; j12 += jstep; } it = i12+istep; i12 = i11+istep; i11 = i10+istep; i10 = i9+istep; i9 = i8+istep; i8 = i7+istep; i7 = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } i13 = i12+iinc; if (i13>=imax) i13 = i13-imax; i14 = i13+iinc; if (i14>=imax) i14 = i14-imax; i15 = i14+iinc; if (i15>=imax) i15 = i15-imax; /* if factor is 16 */ if (ifac==16) { if (mu==1) { c1 = 1.0; c2 = P923; c3 = P382; c4 = P707; } else if (mu==3) { c1 = -1.0; c2 = P382; c3 = P923; c4 = -P707; } else if (mu==5) { c1 = 1.0; c2 = -P382; c3 = P923; c4 = -P707; } else if (mu==7) { c1 = -1.0; c2 = -P923; c3 = P382; c4 = P707; } else if (mu==9) { c1 = 1.0; c2 = -P923; c3 = -P382; c4 = P707; } else if (mu==11) { c1 = -1.0; c2 = -P382; c3 = -P923; c4 = -P707; } else if (mu==13) { c1 = 1.0; c2 = P382; c3 = -P923; c4 = -P707; } else { c1 = -1.0; c2 = P923; c3 = -P382; c4 = P707; } c5 = c1*c4; c6 = c1*c3; c7 = c1*c2; for (l=0; l<m; l++) { j0 = i0; j1 = i1; j2 = i2; j3 = i3; j4 = i4; j5 = i5; j6 = i6; j7 = i7; j8 = i8; j9 = i9; j10 = i10; j11 = i11; j12 = i12; j13 = i13; j14 = i14; j15 = i15; for (jt=0; jt<nt; jt++) { t1r = z[j0]+z[j8]; t1i = z[j0+1]+z[j8+1]; t2r = z[j4]+z[j12]; t2i = z[j4+1]+z[j12+1]; t3r = z[j0]-z[j8]; t3i = z[j0+1]-z[j8+1]; t4r = c1*(z[j4]-z[j12]); t4i = c1*(z[j4+1]-z[j12+1]); t5r = t1r+t2r; t5i = t1i+t2i; t6r = t1r-t2r; t6i = t1i-t2i; t7r = z[j1]+z[j9]; t7i = z[j1+1]+z[j9+1]; t8r = z[j5]+z[j13]; t8i = z[j5+1]+z[j13+1]; t9r = z[j1]-z[j9]; t9i = z[j1+1]-z[j9+1]; t10r = z[j5]-z[j13]; t10i = z[j5+1]-z[j13+1]; t11r = t7r+t8r; t11i = t7i+t8i; t12r = t7r-t8r; t12i = t7i-t8i; t13r = z[j2]+z[j10]; t13i = z[j2+1]+z[j10+1]; t14r = z[j6]+z[j14]; t14i = z[j6+1]+z[j14+1]; t15r = z[j2]-z[j10]; t15i = z[j2+1]-z[j10+1]; t16r = z[j6]-z[j14]; t16i = z[j6+1]-z[j14+1]; t17r = t13r+t14r; t17i = t13i+t14i; t18r = c4*(t15r-t16r); t18i = c4*(t15i-t16i); t19r = c5*(t15r+t16r); t19i = c5*(t15i+t16i); t20r = c1*(t13r-t14r); t20i = c1*(t13i-t14i); t21r = z[j3]+z[j11]; t21i = z[j3+1]+z[j11+1]; t22r = z[j7]+z[j15]; t22i = z[j7+1]+z[j15+1]; t23r = z[j3]-z[j11]; t23i = z[j3+1]-z[j11+1]; t24r = z[j7]-z[j15]; t24i = z[j7+1]-z[j15+1]; t25r = t21r+t22r; t25i = t21i+t22i; t26r = t21r-t22r; t26i = t21i-t22i; t27r = t9r+t24r; t27i = t9i+t24i; t28r = t10r+t23r; t28i = t10i+t23i; t29r = t9r-t24r; t29i = t9i-t24i; t30r = t10r-t23r; t30i = t10i-t23i; t31r = t5r+t17r; t31i = t5i+t17i; t32r = t11r+t25r; t32i = t11i+t25i; t33r = t3r+t18r; t33i = t3i+t18i; t34r = c2*t29r-c6*t30r; t34i = c2*t29i-c6*t30i; t35r = t3r-t18r; t35i = t3i-t18i; t36r = c7*t27r-c3*t28r; t36i = c7*t27i-c3*t28i; t37r = t4r+t19r; t37i = t4i+t19i; t38r = c3*t27r+c7*t28r; t38i = c3*t27i+c7*t28i; t39r = t4r-t19r; t39i = t4i-t19i; t40r = c6*t29r+c2*t30r; t40i = c6*t29i+c2*t30i; t41r = c4*(t12r-t26r); t41i = c4*(t12i-t26i); t42r = c5*(t12r+t26r); t42i = c5*(t12i+t26i); y1r = t33r+t34r; y1i = t33i+t34i; y2r = t6r+t41r; y2i = t6i+t41i; y3r = t35r+t40r; y3i = t35i+t40i; y4r = t5r-t17r; y4i = t5i-t17i; y5r = t35r-t40r; y5i = t35i-t40i; y6r = t6r-t41r; y6i = t6i-t41i; y7r = t33r-t34r; y7i = t33i-t34i; y9r = t38r-t37r; y9i = t38i-t37i; y10r = t42r-t20r; y10i = t42i-t20i; y11r = t36r+t39r; y11i = t36i+t39i; y12r = c1*(t11r-t25r); y12i = c1*(t11i-t25i); y13r = t36r-t39r; y13i = t36i-t39i; y14r = t42r+t20r; y14i = t42i+t20i; y15r = t38r+t37r; y15i = t38i+t37i; z[j0] = t31r+t32r; z[j0+1] = t31i+t32i; z[j1] = y1r-y15i; z[j1+1] = y1i+y15r; z[j2] = y2r-y14i; z[j2+1] = y2i+y14r; z[j3] = y3r-y13i; z[j3+1] = y3i+y13r; z[j4] = y4r-y12i; z[j4+1] = y4i+y12r; z[j5] = y5r-y11i; z[j5+1] = y5i+y11r; z[j6] = y6r-y10i; z[j6+1] = y6i+y10r; z[j7] = y7r-y9i; z[j7+1] = y7i+y9r; z[j8] = t31r-t32r; z[j8+1] = t31i-t32i; z[j9] = y7r+y9i; z[j9+1] = y7i-y9r; z[j10] = y6r+y10i; z[j10+1] = y6i-y10r; z[j11] = y5r+y11i; z[j11+1] = y5i-y11r; z[j12] = y4r+y12i; z[j12+1] = y4i-y12r; z[j13] = y3r+y13i; z[j13+1] = y3i-y13r; z[j14] = y2r+y14i; z[j14+1] = y2i-y14r; z[j15] = y1r+y15i; z[j15+1] = y1i-y15r; j0 += jstep; j1 += jstep; j2 += jstep; j3 += jstep; j4 += jstep; j5 += jstep; j6 += jstep; j7 += jstep; j8 += jstep; j9 += jstep; j10 += jstep; j11 += jstep; j12 += jstep; j13 += jstep; j14 += jstep; j15 += jstep; } it = i15+istep; i15 = i14+istep; i14 = i13+istep; i13 = i12+istep; i12 = i11+istep; i11 = i10+istep; i10 = i9+istep; i9 = i8+istep; i8 = i7+istep; i7 = i6+istep; i6 = i5+istep; i5 = i4+istep; i4 = i3+istep; i3 = i2+istep; i2 = i1+istep; i1 = i0+istep; i0 = it; } continue; } } } void pfa2cc (int isign, int idim, int n1, int n2, complex cz[]) { int n,nt,k,kt; /* determine transform length, number of transforms, and strides */ if (idim==1) { n = n1; nt = n2; k = 1; kt = n1; } else { n = n2; nt = n1; k = n1; kt = 1; } /* do multiple complex to complex transforms */ pfamcc(isign,n,nt,k,kt,cz); } void pfa2cr (int isign, int idim, int n1, int n2, complex cz[], REAL rz[]) { int i1,i2,j,k,it,jt,kt,n,nt,itmul,itinc; REAL *z,*temp,tempr,tempi,sumr,sumi,difr,difi; REAL wr,wi,wpr,wpi,wtemp,theta; /* if transforming dimension 1 */ if (idim==1) { /* copy input to output and fix dc and nyquist */ z = (REAL*)cz; for (i2=0,jt=0,kt=0; i2<n2; i2++,jt+=n1,kt+=(n1+2)) { rz[jt+1] = z[kt]-z[kt+n1]; rz[jt] = z[kt]+z[kt+n1]; for (i1=2,j=jt+2,k=kt+2; i1<n1; i1++,j++,k++) rz[j] = z[k]; } z = rz; /* set transform length, number of transforms and strides */ n = n1; nt = n2; itmul = 1; itinc = n1; /* else, if transforming dimension 2 */ } else { /* copy input to output and fix dc and nyquist */ z = (REAL*)cz; for (i2=1; i2<n2/2; i2++) { for (i1=0,j=i2*n1*2; i1<n1*2; i1++,j++) rz[j] = z[j]; } for (i1=0,j=n1*n2; i1<n1*2; i1+=2,j+=2) { rz[i1+1] = z[i1]-z[j]; rz[i1] = z[i1]+z[j]; } z = rz; /* set transform length, number of transforms and strides */ n = n2; nt = n1; itmul = n1; itinc = 2; } /* initialize cosine-sine recurrence */ theta = 2.0*M_PI/(REAL)n; if (isign>0) theta = -theta; wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0+wpr; wi = wpi; /* twiddle transforms simultaneously */ for (j=2,k=n-2; j<=n/2; j+=2,k-=2) { jt = j*itmul; kt = k*itmul; for (it=0; it<nt; it++) { sumr = z[jt]+z[kt]; sumi = z[jt+1]+z[kt+1]; difr = z[jt]-z[kt]; difi = z[jt+1]-z[kt+1]; tempr = wi*difr-wr*sumi; tempi = wi*sumi+wr*difr; z[jt] = sumr+tempr; z[jt+1] = difi+tempi; z[kt] = sumr-tempr; z[kt+1] = tempi-difi; jt += itinc; kt += itinc; } wtemp = wr; wr += wr*wpr-wi*wpi; wi += wi*wpr+wtemp*wpi; } /* if transforming dimension 1 */ if (idim==1) { /* transform as complex elements */ pfa2cc(isign,1,n1/2,n2,(complex*)z); /* else, if transforming dimension 2 */ } else { /* transform as complex elements */ pfa2cc(isign,2,n1,n2/2,(complex*)z); /* unmerge even and odd vectors */ temp = (REAL*)malloc(n1*sizeof(REAL)); for (i2=0; i2<n2; i2+=2) { for (i1=0,j=i2*n1+1; i1<n1; i1++,j+=2) temp[i1] = z[j]; for (i1=0,j=i2*n1,k=i2*n1; i1<n1; i1++,j+=2,k++) z[k] = z[j]; for (i1=0,j=(i2+1)*n1; i1<n1; i1++,j++) z[j] = temp[i1]; } free(temp); } } void pfa2rc (int isign, int idim, int n1, int n2, REAL rz[], complex cz[]) { int i1,i2,j,k,it,jt,kt,n,nt,itmul,itinc; REAL *z,*temp,tempr,tempi,sumr,sumi,difr,difi; REAL wr,wi,wpr,wpi,wtemp,theta; /* copy input to output while scaling */ z = (REAL*)cz; for (i2=0,j=0; i2<n2; i2++) for (i1=0; i1<n1; i1++,j++) z[j] = 0.5*rz[j]; /* if transforming dimension 1 */ if (idim==1) { /* transform as complex elements */ pfa2cc(isign,1,n1/2,n2,cz); /* shift rows to make room for nyquist */ z = (REAL*)cz; for (i2=n2-1; i2>0; i2--) { jt = i2*n1+n1-1; kt = jt+i2*2; for (i1=n1-1,j=jt,k=kt; i1>=0; i1--,j--,k--) z[k] = z[j]; } /* set transform length, number of transforms and strides */ n = n1; nt = n2; itmul = 1; itinc = n1+2; /* else, if transforming dimension 2 */ } else { /* merge even and odd vectors */ temp = z+n1*n2; for (i2=0; i2<n2; i2+=2) { for (i1=0,j=i2*n1; i1<n1; i1++,j++) temp[i1] = z[j]; for (i1=0,j=(i2+1)*n1,k=i2*n1+1; i1<n1; i1++,j++,k+=2) z[k] = z[j]; for (i1=0,j=i2*n1; i1<n1; i1++,j+=2) z[j] = temp[i1]; } /* transform as complex elements */ pfa2cc(isign,2,n1,n2/2,cz); /* set transform length, number of transforms and strides */ n = n2; nt = n1; itmul = n1; itinc = 2; } /* fix dc and nyquist for each transform */ for (it=0,j=0,k=n*itmul; it<nt; it++,j+=itinc,k+=itinc) { z[k] = 2.0*(z[j]-z[j+1]); z[j] = 2.0*(z[j]+z[j+1]); z[k+1] = 0.0; z[j+1] = 0.0; } /* initialize cosine-sine recurrence */ theta = 2.0*M_PI/(REAL)n; if (isign<0) theta = -theta; wtemp = sin(0.5*theta); wpr = -2.0*wtemp*wtemp; wpi = sin(theta); wr = 1.0+wpr; wi = wpi; /* twiddle transforms simultaneously */ for (j=2,k=n-2; j<=n/2; j+=2,k-=2) { jt = j*itmul; kt = k*itmul; for (it=0; it<nt; it++) { sumr = z[jt]+z[kt]; sumi = z[jt+1]+z[kt+1]; difr = z[jt]-z[kt]; difi = z[jt+1]-z[kt+1]; tempr = wi*difr+wr*sumi; tempi = wi*sumi-wr*difr; z[jt] = sumr+tempr; z[jt+1] = difi+tempi; z[kt] = sumr-tempr; z[kt+1] = tempi-difi; jt += itinc; kt += itinc; } wtemp = wr; wr += wr*wpr-wi*wpi; wi += wi*wpr+wtemp*wpi; } } #if defined TEST /* #include "cwp.h" */ main() { int nmin,n,no,nfft,nffto; REAL cpu,total; complex c[720720]; int npfao2 (int nmin, int nmax); for (n=0; n<720720; ++n) c[n].r = c[n].i = 0.0; for (nmin=npfa(100); nmin<=10000; nmin=npfa(nmin+1)) { n = npfa(nmin); for (nfft=0,total=0.0; total<1.0; ++nfft) { cpu = cpusec(); pfacc(1,n,c); total += cpusec()-cpu+FLT_EPSILON; } no = npfao(nmin,2*nmin); for (nffto=0,total=0.0; total<1.0; ++nffto) { cpu = cpusec(); pfacc(1,no,c); total += cpusec()-cpu+FLT_EPSILON; } printf("valid n=%d cost=%g optimal n=%d cost=%g\n", n,1.0/nfft,no,1.0/nffto); } } #endif /* TEST */