/* fftpack.c : A set of FFT routines in C. Algorithmically based on Fortran-77 FFTPACK by Paul N. Swarztrauber (Version 4, 1985). */ /* isign is +1 for backward and -1 for forward transforms */ #include #include #define DOUBLE #ifdef DOUBLE #define Treal double #else #define Treal float #endif #define ref(u,a) u[a] #define MAXFAC 13 /* maximum number of factors in factorization of n */ #define NSPECIAL 4 /* number of factors for which we have special-case routines */ #ifdef __cplusplus extern "C" { #endif /* ---------------------------------------------------------------------- passf2, passf3, passf4, passf5, passf. Complex FFT passes fwd and bwd. ---------------------------------------------------------------------- */ static void passf2(int ido, int l1, const Treal cc[], Treal ch[], const Treal wa1[], int isign) /* isign==+1 for backward transform */ { int i, k, ah, ac; Treal ti2, tr2; if (ido <= 2) { for (k=0; k= l1) { for (j=1; j idp) idlj -= idp; war = wa[idlj - 2]; wai = wa[idlj-1]; for (ik=0; ik= l1) { for (j=1; j= l1) { for (k=0; k= l1) { for (j=1; j= l1) { for (k=0; k= l1) { for (j=1; j= l1) { for (j=1; j 5) { wa[i1-1] = wa[i-1]; wa[i1] = wa[i]; } } l1 = l2; } } /* cffti1 */ void cffti(int n, Treal wsave[]) { int iw1, iw2; if (n == 1) return; iw1 = 2*n; iw2 = iw1 + 2*n; cffti1(n, wsave+iw1, (int*)(wsave+iw2)); } /* cffti */ /* ---------------------------------------------------------------------- rfftf1, rfftb1, rfftf, rfftb, rffti1, rffti. Treal FFTs. ---------------------------------------------------------------------- */ static void rfftf1(int n, Treal c[], Treal ch[], const Treal wa[], const int ifac[MAXFAC+2]) { int i; int k1, l1, l2, na, kh, nf, ip, iw, ix2, ix3, ix4, ido, idl1; Treal *cinput, *coutput; nf = ifac[1]; na = 1; l2 = n; iw = n-1; for (k1 = 1; k1 <= nf; ++k1) { kh = nf - k1; ip = ifac[kh + 2]; l1 = l2 / ip; ido = n / l2; idl1 = ido*l1; iw -= (ip - 1)*ido; na = !na; if (na) { cinput = ch; coutput = c; } else { cinput = c; coutput = ch; } switch (ip) { case 4: ix2 = iw + ido; ix3 = ix2 + ido; radf4(ido, l1, cinput, coutput, &wa[iw], &wa[ix2], &wa[ix3]); break; case 2: radf2(ido, l1, cinput, coutput, &wa[iw]); break; case 3: ix2 = iw + ido; radf3(ido, l1, cinput, coutput, &wa[iw], &wa[ix2]); break; case 5: ix2 = iw + ido; ix3 = ix2 + ido; ix4 = ix3 + ido; radf5(ido, l1, cinput, coutput, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4]); break; default: if (ido == 1) na = !na; if (na == 0) { radfg(ido, ip, l1, idl1, c, ch, &wa[iw]); na = 1; } else { radfg(ido, ip, l1, idl1, ch, c, &wa[iw]); na = 0; } } l2 = l1; } if (na == 1) return; for (i = 0; i < n; i++) c[i] = ch[i]; } /* rfftf1 */ void rfftb1(int n, Treal c[], Treal ch[], const Treal wa[], const int ifac[MAXFAC+2]) { int i; int k1, l1, l2, na, nf, ip, iw, ix2, ix3, ix4, ido, idl1; Treal *cinput, *coutput; nf = ifac[1]; na = 0; l1 = 1; iw = 0; for (k1=1; k1<=nf; k1++) { ip = ifac[k1 + 1]; l2 = ip*l1; ido = n / l2; idl1 = ido*l1; if (na) { cinput = ch; coutput = c; } else { cinput = c; coutput = ch; } switch (ip) { case 4: ix2 = iw + ido; ix3 = ix2 + ido; radb4(ido, l1, cinput, coutput, &wa[iw], &wa[ix2], &wa[ix3]); na = !na; break; case 2: radb2(ido, l1, cinput, coutput, &wa[iw]); na = !na; break; case 3: ix2 = iw + ido; radb3(ido, l1, cinput, coutput, &wa[iw], &wa[ix2]); na = !na; break; case 5: ix2 = iw + ido; ix3 = ix2 + ido; ix4 = ix3 + ido; radb5(ido, l1, cinput, coutput, &wa[iw], &wa[ix2], &wa[ix3], &wa[ix4]); na = !na; break; default: radbg(ido, ip, l1, idl1, cinput, coutput, &wa[iw]); if (ido == 1) na = !na; } l1 = l2; iw += (ip - 1)*ido; } if (na == 0) return; for (i=0; i