/* * This file is part of libfftpack. * * libfftpack is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * libfftpack is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with libfftpack; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * libfftpack is being developed at the Max-Planck-Institut fuer Astrophysik * and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt * (DLR). */ /* fftpack.c : A set of FFT routines in C. Algorithmically based on Fortran-77 FFTPACK by Paul N. Swarztrauber (Version 4, 1985). C port by Martin Reinecke (2010) */ #include #include #include #include "fftpack.h" #define WA(x,i) wa[(i)+(x)*ido] #define CH(a,b,c) ch[(a)+ido*((b)+l1*(c))] #define CC(a,b,c) cc[(a)+ido*((b)+cdim*(c))] #define PM(a,b,c,d) { a=c+d; b=c-d; } #define PMC(a,b,c,d) { a.r=c.r+d.r; a.i=c.i+d.i; b.r=c.r-d.r; b.i=c.i-d.i; } #define ADDC(a,b,c) { a.r=b.r+c.r; a.i=b.i+c.i; } #define SCALEC(a,b) { a.r*=b; a.i*=b; } #define CONJFLIPC(a) { double tmp_=a.r; a.r=-a.i; a.i=tmp_; } /* (a+ib) = conj(c+id) * (e+if) */ #define MULPM(a,b,c,d,e,f) { a=c*e+d*f; b=c*f-d*e; } typedef struct { double r,i; } cmplx; #define CONCAT(a,b) a ## b #define X(arg) CONCAT(passb,arg) #define BACKWARD #include "fftpack_inc.c" #undef BACKWARD #undef X #define X(arg) CONCAT(passf,arg) #include "fftpack_inc.c" #undef X #undef CC #undef CH #define CC(a,b,c) cc[(a)+ido*((b)+l1*(c))] #define CH(a,b,c) ch[(a)+ido*((b)+cdim*(c))] static void radf2 (size_t ido, size_t l1, const double *cc, double *ch, const double *wa) { const size_t cdim=2; size_t i, k, ic; double ti2, tr2; for (k=0; k=2*ip) aidx-=2*ip; ar2=csarr[aidx]; ai2=csarr[aidx+1]; for(ik=0; ik=2*ip) aidx-=2*ip; ar2=csarr[aidx]; ai2=csarr[aidx+1]; for(ik=0; ik0) ? passb4(ido, l1, p1, p2, wa+iw) : passf4(ido, l1, p1, p2, wa+iw); else if(ip==2) (isign>0) ? passb2(ido, l1, p1, p2, wa+iw) : passf2(ido, l1, p1, p2, wa+iw); else if(ip==3) (isign>0) ? passb3(ido, l1, p1, p2, wa+iw) : passf3(ido, l1, p1, p2, wa+iw); else if(ip==5) (isign>0) ? passb5(ido, l1, p1, p2, wa+iw) : passf5(ido, l1, p1, p2, wa+iw); else if(ip==6) (isign>0) ? passb6(ido, l1, p1, p2, wa+iw) : passf6(ido, l1, p1, p2, wa+iw); else (isign>0) ? passbg(ido, ip, l1, p1, p2, wa+iw) : passfg(ido, ip, l1, p1, p2, wa+iw); SWAP(p1,p2,cmplx *); l1=l2; iw+=(ip-1)*ido; } if (p1!=c) memcpy (c,p1,n*sizeof(cmplx)); } void cfftf(size_t n, double c[], double wsave[]) { if (n!=1) cfft1(n, (cmplx*)c, (cmplx*)wsave, (cmplx*)(wsave+2*n), (size_t*)(wsave+4*n),-1); } void cfftb(size_t n, double c[], double wsave[]) { if (n!=1) cfft1(n, (cmplx*)c, (cmplx*)wsave, (cmplx*)(wsave+2*n), (size_t*)(wsave+4*n),+1); } static void factorize (size_t n, const size_t *pf, size_t npf, size_t *ifac) { size_t nl=n, nf=0, ntry=0, j=0, i; startloop: j++; ntry = (j<=npf) ? pf[j-1] : ntry+2; do { size_t nq=nl / ntry; size_t nr=nl-ntry*nq; if (nr!=0) goto startloop; nf++; ifac[nf+1]=ntry; nl=nq; if ((ntry==2) && (nf!=1)) { for (i=nf+1; i>2; --i) ifac[i]=ifac[i-1]; ifac[2]=2; } } while(nl!=1); ifac[0]=n; ifac[1]=nf; } static void cffti1(size_t n, double wa[], size_t ifac[]) { static const size_t ntryh[5]={4,6,3,2,5}; static const double twopi=6.28318530717958647692; size_t j, k, fi; double argh=twopi/n; size_t i=0, l1=1; factorize (n,ntryh,5,ifac); for(k=1; k<=ifac[1]; k++) { size_t ip=ifac[k+1]; size_t ido=n/(l1*ip); for(j=1; j6) { wa[is ]=wa[i ]; wa[is+1]=wa[i+1]; } } l1*=ip; } } void cffti(size_t n, double wsave[]) { if (n!=1) cffti1(n, wsave+2*n,(size_t*)(wsave+4*n)); } /*---------------------------------------------------------------------- rfftf1, rfftb1, rfftf, rfftb, rffti1, rffti. Real FFTs. ----------------------------------------------------------------------*/ static void rfftf1(size_t n, double c[], double ch[], const double wa[], const size_t ifac[]) { size_t k1, l1=n, nf=ifac[1], iw=n-1; double *p1=ch, *p2=c; for(k1=1; k1<=nf;++k1) { size_t ip=ifac[nf-k1+2]; size_t ido=n / l1; l1 /= ip; iw-=(ip-1)*ido; SWAP (p1,p2,double *); if(ip==4) radf4(ido, l1, p1, p2, wa+iw); else if(ip==2) radf2(ido, l1, p1, p2, wa+iw); else if(ip==3) radf3(ido, l1, p1, p2, wa+iw); else if(ip==5) radf5(ido, l1, p1, p2, wa+iw); else { if (ido==1) SWAP (p1,p2,double *); radfg(ido, ip, l1, ido*l1, p1, p2, wa+iw); SWAP (p1,p2,double *); } } if (p1==c) memcpy (c,ch,n*sizeof(double)); } static void rfftb1(size_t n, double c[], double ch[], const double wa[], const size_t ifac[]) { size_t k1, l1=1, nf=ifac[1], iw=0; double *p1=c, *p2=ch; for(k1=1; k1<=nf; k1++) { size_t ip = ifac[k1+1], ido= n/(ip*l1); if(ip==4) radb4(ido, l1, p1, p2, wa+iw); else if(ip==2) radb2(ido, l1, p1, p2, wa+iw); else if(ip==3) radb3(ido, l1, p1, p2, wa+iw); else if(ip==5) radb5(ido, l1, p1, p2, wa+iw); else { radbg(ido, ip, l1, ido*l1, p1, p2, wa+iw); if (ido!=1) SWAP (p1,p2,double *); } SWAP (p1,p2,double *); l1*=ip; iw+=(ip-1)*ido; } if (p1!=c) memcpy (c,ch,n*sizeof(double)); } void rfftf(size_t n, double r[], double wsave[]) { if(n!=1) rfftf1(n, r, wsave, wsave+n,(size_t*)(wsave+2*n)); } void rfftb(size_t n, double r[], double wsave[]) { if(n!=1) rfftb1(n, r, wsave, wsave+n,(size_t*)(wsave+2*n)); } static void rffti1(size_t n, double wa[], size_t ifac[]) { static const size_t ntryh[4]={4,2,3,5}; static const double twopi=6.28318530717958647692; size_t i, j, k, fi; double argh=twopi/n; size_t is=0, l1=1; factorize (n,ntryh,4,ifac); for (k=1; k