//////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2008 The Regents of the University of California // // This file is part of Qbox // // Qbox is distributed 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. // See the file COPYING in the root directory of this distribution // or . // //////////////////////////////////////////////////////////////////////////////// // // sinft.C // //////////////////////////////////////////////////////////////////////////////// #include "sinft.h" #include #include #include #include using namespace std; #if USE_FFTW2 #if USE_DFFTW #include "dfftw.h" #else #include "fftw.h" #endif #elif USE_FFTW3 #include "fftw3.h" #elif USE_ESSL_FFT extern "C" { void dcft_(int *initflag, std::complex *x, int *inc2x, int *inc3x, std::complex *y, int *inc2y, int *inc3y, int *length, int *ntrans, int *isign, double *scale, double *aux1, int *naux1, double *aux2, int *naux2); } #else // no FFT library void cfft ( int idir, complex *z1, complex *z2, int n, int *inzee ); void fftstp ( int idir, complex *zin, int after, int now, int before, complex *zout ); #endif void sinft(int n, double *y) { vector > zin(2*n), zout(2*n); #if defined(USE_FFTW2) || defined(USE_FFTW3) fftw_plan fwplan; #endif #if USE_FFTW2 fwplan = fftw_create_plan(2*n,FFTW_FORWARD,FFTW_ESTIMATE); #elif USE_FFTW3 fwplan = fftw_plan_dft_1d(2*n,(fftw_complex*)&zin[0],(fftw_complex*)&zout[0], FFTW_FORWARD, FFTW_ESTIMATE); #elif USE_ESSL_FFT int np = 2 * n; int naux1 = (int) (30000 + 2.28 * np); std::vector aux1(naux1); int ntrans = 1; int naux2 = (int) (20000 + 2.28 * np + (256 + 2*np)*min(64,ntrans)); std::vector aux2(naux2); #else // no FFT library // no initialization needed #endif zin[0] = 0.0; for ( int i = 1; i < n; i++ ) { const double t = y[i]; zin[i] = t; zin[2*n-i] = -t; } #if USE_FFTW2 fftw_one(fwplan,(fftw_complex*)&zin[0],(fftw_complex*)&zout[0]); #elif USE_FFTW3 fftw_execute(fwplan); #elif USE_ESSL_FFT // initialize forward transform int initflag = 1; int inc1 = 1, inc2 = np; int isign = 1; double scale = 1.0; complex *p = 0; dcft_(&initflag,p,&inc1,&inc2,p,&inc1,&inc2,&np,&ntrans, &isign,&scale,&aux1[0],&naux1,&aux2[0],&naux2); // call transform initflag = 0; dcft_(&initflag,&zin[0],&inc1,&inc2,&zout[0],&inc1,&inc2,&np,&ntrans, &isign,&scale,&aux1[0],&naux1,&aux2[0],&naux2); #else // no FFT library int idir = 1, inzee = 1, np = 2*n; cfft ( idir, &zin[0],&zout[0],np, &inzee ); #endif for ( int i = 0; i < n; i++ ) { y[i] = -0.5 * imag(zout[i]); } #if defined(USE_FFTW2) || defined(USE_FFTW3) fftw_destroy_plan(fwplan); #endif } void cosft1(int n, double *y) { /* Note: the array y contains n+1 elements */ vector > zin(2*n), zout(2*n); #if defined(USE_FFTW2) || defined(USE_FFTW3) fftw_plan fwplan; #endif #if USE_FFTW2 fwplan = fftw_create_plan(2*n,FFTW_FORWARD,FFTW_ESTIMATE); #elif USE_FFTW3 fwplan = fftw_plan_dft_1d(2*n,(fftw_complex*)&zin[0],(fftw_complex*)&zout[0], FFTW_FORWARD, FFTW_ESTIMATE); #elif USE_ESSL_FFT int np = 2 * n; int naux1 = (int) (30000 + 2.28 * np); std::vector aux1(naux1); int ntrans = 1; int naux2 = (int) (20000 + 2.28 * np + (256 + 2*np)*min(64,ntrans)); std::vector aux2(naux2); #else // no FFT library // no initialization needed #endif zin[0] = y[0]; for ( int i = 1; i < n+1; i++ ) { const double t = y[i]; zin[i] = t; zin[2*n-i] = t; } #if USE_FFTW2 fftw_one(fwplan,(fftw_complex*)&zin[0],(fftw_complex*)&zout[0]); #elif USE_FFTW3 fftw_execute(fwplan); #elif USE_ESSL_FFT // initialize forward transform int initflag = 1; int inc1 = 1, inc2 = np; int isign = 1; double scale = 1.0; complex *p = 0; dcft_(&initflag,p,&inc1,&inc2,p,&inc1,&inc2,&np,&ntrans, &isign,&scale,&aux1[0],&naux1,&aux2[0],&naux2); // call transform initflag = 0; dcft_(&initflag,&zin[0],&inc1,&inc2,&zout[0],&inc1,&inc2,&np,&ntrans, &isign,&scale,&aux1[0],&naux1,&aux2[0],&naux2); #else // no FFT library int idir = 1, inzee = 1, np = 2*n; cfft ( idir, &zin[0],&zout[0],np, &inzee ); #endif y[0] = 0.5 * real(zout[0]); for ( int i = 1; i < n; i++ ) { y[i] = 0.5 * real(zout[i]); } #if defined(USE_FFTW2) || defined(USE_FFTW3) fftw_destroy_plan(fwplan); #endif }