65 #ifndef __MO_MATH_FFT_H__
66 #define __MO_MATH_FFT_H__
68 #define __FFTWPP_H_VERSION__ 1.02
89 static array1<Complex> NULL1;
90 static array2<Complex> NULL2;
91 static array3<Complex> NULL3;
96 static const size_t offset =
sizeof(size_t)/
sizeof(
Complex)+
97 (
sizeof(size_t) %
sizeof(
Complex) > 0);
98 void *alloc=fftw_malloc((size+offset)*
sizeof(
Complex));
99 if(size && !alloc) cerr << endl <<
"Memory limits exceeded" << endl;
100 *(
size_t *) alloc=size;
102 for(
size_t i=0; i < size; i++)
new(p+i)
Complex;
108 static const size_t offset =
sizeof(size_t)/
sizeof(
Complex)+
109 (
sizeof(size_t) %
sizeof(
Complex) > 0);
110 void *alloc=fftw_malloc(size*
sizeof(
double)+offset*
sizeof(
Complex));
111 if(size && !alloc) cerr << endl <<
"Memory limits exceeded" << endl;
112 *(
size_t *) alloc=size;
113 double*p=(
double*)((
Complex *)alloc+offset);
114 for(
size_t i=0; i < size; i++)
new(p+i) double;
121 static const size_t offset =
sizeof(size_t)/
sizeof(
Complex)+
122 (
sizeof(size_t) %
sizeof(
Complex) > 0);
123 void *alloc=(
Complex *)p-offset;
124 size_t size=*(
size_t *) alloc;
125 for(
size_t i=size-1; i > 0; i--) ((T *) p)[i].~T();
162 unsigned int Dist(
unsigned int n,
unsigned int stride,
unsigned int dist) {
163 return dist ? dist : ((stride == 1) ? n : 1);
167 return n/2+(!out || in == out);
176 const unsigned int nyp=ny/2+1;
179 for(
Complex *p=data+nyp; p < pstop; p += pinc) {
181 for(
unsigned int j=0; j < nyp; j++) p[j]=-p[j];
188 const unsigned int nzp=nz/2+1;
189 const unsigned int nyzp=ny*nzp;
190 const unsigned int pinc=2*nzp;
193 for(
unsigned i=0; i < nx; i++) {
197 for(; p < pstop; p += pinc) {
199 for(
unsigned int k=0; k < nzp; k++) p[k]=-p[k];
205 fftw(
unsigned int size,
int sign,
unsigned int n=0) :
206 size(size), sign(sign), norm(1.0/(n ? n : size)), shift(false) {}
213 if((
size_t) p %
sizeof(
Complex) == 0)
return;
214 cerr <<
"WARNING: " << s <<
" array is not " <<
sizeof(
Complex)
215 <<
"-byte aligned: address " << p << endl;
222 #ifndef NO_CHECK_ALIGN
232 cerr <<
"Unable to construct FFTW plan" << endl;
244 ifWisdom.open(WisdomName);
251 ofWisdom.open(WisdomName);
257 fftw_execute_dft(plan,(fftw_complex *) in,(fftw_complex *) out);
261 #ifndef NO_CHECK_ALIGN
268 if(inplace ^ (out == in)) {
269 cerr <<
"ERROR: fft constructor and call must be either both in place or out of place" << endl;
303 for(
unsigned int i=0; i <
size; i++) out[i] *= norm;
337 unsigned int nx,
unsigned int m,
338 unsigned int stride,
unsigned int dist) {
344 for(
unsigned int k=0; k < m; k++) {
345 for(
unsigned int j=0; j < nx; j++) {
346 out[j*stride+k*dist] *=
norm;
384 fft1d(
int sign,
const array1<Complex>& in,
const array1<Complex>& out=NULL1)
385 :
fftw(in.Nx(),sign), nx(in.Nx()) {
Setup(in,out);}
389 return fftw_plan_dft_1d(nx,(fftw_complex *) in,(fftw_complex *) out,
420 mfft1d(
unsigned int nx,
int sign,
unsigned int m=1,
unsigned int stride=1,
422 :
fftw((nx-1)*stride+(m-1)*
Dist(nx,stride,dist)+1,sign,nx),
423 nx(nx), m(m), stride(stride), dist(
Dist(nx,stride,dist))
428 return fftw_plan_many_dft(1,n,m,
429 (fftw_complex *) in,NULL,stride,dist,
430 (fftw_complex *) out,NULL,stride,dist,
462 :
fftw(nx/2+1,-1,nx), nx(nx) {
Setup(out);}
465 :
fftw(nx/2+1,-1,nx), nx(nx) {
Setup(in,out);}
468 rcfft1d(
const array1<Complex>& in)
469 :
fftw(in.Size(),-1,2*(in.Nx()-1)), nx(2*(in.Nx()-1)) {
Setup(in);}
471 rcfft1d(
const array1<double>& in,
const array1<Complex>& out)
472 :
fftw(out.Size(),-1,in.Size()), nx(in.Nx()) {
Setup(in,out);}
476 return fftw_plan_dft_r2c_1d(nx,(
double *) in,(fftw_complex *) out,
effort);
480 fftw_execute_dft_r2c(
plan,(
double *) in,(fftw_complex *) out);
515 crfft1d(
const array1<Complex>& in)
516 :
fftw(in.Size(),1,2*(in.Nx()-1)), nx(2*(in.Nx()-1)) {
Setup(in);}
518 crfft1d(
const array1<Complex>& in,
const array1<double>& out)
519 :
fftw(out.Size()/2,1,out.Size()), nx(out.Nx()) {
Setup(in,out);}
523 return fftw_plan_dft_c2r_1d(nx,(fftw_complex *) in,(
double *) out,
effort);
527 fftw_execute_dft_c2r(
plan,(fftw_complex *) in,(
double *) out);
559 mrcfft1d(
unsigned int nx,
unsigned int m=1,
unsigned int stride=1,
560 unsigned int dist=0,
Complex *out=NULL)
561 :
fftw(nx/2*stride+(m-1)*
Dist(nx,stride,dist)+1,-1,nx), nx(nx), m(m),
562 stride(stride), dist(
Dist(nx,stride,dist)) {
Setup(out);}
564 mrcfft1d(
unsigned int nx,
unsigned int m=1,
unsigned int stride=1,
565 unsigned int dist=0,
double *in=NULL,
Complex *out=NULL)
566 :
fftw(nx/2*stride+(m-1)*
Dist(nx,stride,dist)+1,-1,nx), nx(nx), m(m),
567 stride(stride), dist(
Dist(nx,stride,dist)) {
Setup(in,out);}
571 return fftw_plan_many_dft_r2c(1,n,m,
572 (
double *) in,NULL,stride,2*dist,
573 (fftw_complex *) out,NULL,stride,dist,
578 fftw_execute_dft_r2c(
plan,(
double *) in,(fftw_complex *) out);
615 mcrfft1d(
unsigned int nx,
unsigned int m=1,
unsigned int stride=1,
616 unsigned int dist=0,
Complex *in=NULL)
617 :
fftw(nx/2*stride+(m-1)*
Dist(nx,stride,dist)+1,1,nx),
618 nx(nx), m(m), stride(stride), dist(
Dist(nx,stride,dist)) {
Setup(in);}
620 mcrfft1d(
unsigned int nx,
unsigned int m=1,
unsigned int stride=1,
621 unsigned int dist=0,
Complex *in=NULL,
double *out=NULL)
623 nx(nx), m(m), stride(stride), dist(
Dist(nx,stride,dist)) {
Setup(in,out);}
627 return fftw_plan_many_dft_c2r(1,n,m,
628 (fftw_complex *) in,NULL,stride,dist,
629 (
double *) out,NULL,stride,2*dist,
634 fftw_execute_dft_c2r(
plan,(fftw_complex *) in,(
double *) out);
674 :
fftw(nx*ny,sign), nx(nx), ny(ny) {
Setup(in,out);}
677 fft2d(
int sign,
const array2<Complex>& in,
const array2<Complex>& out=NULL2)
678 :
fftw(in.Size(),sign), nx(in.Nx()), ny(in.Ny()) {
Setup(in,out);}
682 return fftw_plan_dft_2d(nx,ny,(fftw_complex *) in,(fftw_complex *) out,
716 fftw(nx*(ny/2+1),-1,nx*ny), nx(nx), ny(ny) {
Setup(out);}
719 fftw(nx*(ny/2+1),-1,nx*ny), nx(nx), ny(ny) {
Setup(in,out);}
722 rcfft2d(
const array2<Complex>& in) :
723 fftw(in.Size(),-1,in.Nx()*2*(in.Ny()-1)), nx(in.Nx()), ny(2*(in.Ny()-1))
726 rcfft2d(
const array2<double>& in,
const array2<Complex>& out) :
727 fftw(out.Size(),-1,in.Size()), nx(in.Nx()), ny(in.Ny()) {
Setup(in,out);}
731 return fftw_plan_dft_r2c_2d(nx,ny,(
double *) in,(fftw_complex *) out,
737 fftw_execute_dft_r2c(
plan,(
double *) in,(fftw_complex *) out);
771 :
fftw(nx*(ny/2+1),1,nx*ny), nx(nx), ny(ny) {
Setup(in);}
777 crfft2d(
const array2<Complex>& in) :
778 fftw(in.Size(),1,in.Nx()*2*(in.Ny()-1)), nx(in.Nx()), ny(2*(in.Ny()-1))
781 crfft2d(
const array2<Complex>& in,
const array2<double>& out) :
782 fftw(out.Size()/2,1,out.Size()), nx(out.Nx()), ny(out.Ny())
787 return fftw_plan_dft_c2r_2d(nx,ny,(fftw_complex *) in,(
double *) out,
792 fftw_execute_dft_c2r(
plan,(fftw_complex *) in,(
double *) out);
829 fft3d(
unsigned int nx,
unsigned int ny,
unsigned int nz,
831 :
fftw(nx*ny*nz,sign), nx(nx), ny(ny), nz(nz) {
Setup(in,out);}
834 fft3d(
int sign,
const array3<Complex>& in,
const array3<Complex>& out=NULL3)
835 :
fftw(in.Size(),sign), nx(in.Nx()), ny(in.Ny()), nz(in.Nz())
840 return fftw_plan_dft_3d(nx,ny,nz,(fftw_complex *) in,
875 :
fftw(nx*ny*(nz/2+1),-1,nx*ny*nz), nx(nx), ny(ny), nz(nz) {
Setup(out);}
877 rcfft3d(
unsigned int nx,
unsigned int ny,
unsigned int nz,
double *in,
878 Complex *out=NULL) :
fftw(nx*ny*(nz/2+1),-1,nx*ny*nz),
879 nx(nx), ny(ny), nz(nz) {
Setup(in,out);}
882 rcfft3d(
const array3<Complex>& in) :
883 fftw(in.Size(),-1,in.Nx()*in.Ny()*2*(in.Nz()-1)),
884 nx(in.Nx()), ny(in.Ny()), nz(2*(in.Nz()-1)) {
Setup(in);}
886 rcfft3d(
const array3<double>& in,
const array3<Complex>& out) :
887 fftw(out.Size(),-1,in.Size()),
888 nx(in.Nx()), ny(in.Ny()), nz(in.Nz()) {
Setup(in,out);}
892 return fftw_plan_dft_r2c_3d(nx,ny,nz,(
double *) in,(fftw_complex *) out,
898 fftw_execute_dft_r2c(
plan,(
double *) in,(fftw_complex *) out);
932 :
fftw(nx*ny*(nz/2+1),1,nx*ny*nz), nx(nx), ny(ny), nz(nz)
935 double *out) :
fftw(nx*ny*(
realsize(nz,in,out)),1,nx*ny*nz),
936 nx(nx), ny(ny), nz(nz) {
Setup(in,out);}
938 crfft3d(
const array3<Complex>& in) :
939 fftw(in.Size(),1,in.Nx()*in.Ny()*2*(in.Nz()-1)),
940 nx(in.Nx()), ny(in.Ny()), nz(2*(in.Nz()-1)) {
Setup(in);}
942 crfft3d(
const array3<Complex>& in,
const array3<double>& out) :
943 fftw(out.Size()/2,1,out.Size()),
944 nx(out.Nx()), ny(out.Ny()), nz(out.Nz()) {
Setup(in,out);}
948 return fftw_plan_dft_c2r_3d(nx,ny,nz,(fftw_complex *) in,(
double *) out,
953 fftw_execute_dft_c2r(
plan,(fftw_complex *) in,(
double *) out);
void Shift(Complex *data, unsigned int nx, unsigned int ny, unsigned int nz)
fftw_plan Plan(Complex *in, Complex *out)
void Setout(Complex *in, Complex *&out)
int GetWisdom(ifstream &s)
crfft1d(unsigned int nx, Complex *in, double *out)
void Execute(Complex *in, Complex *out)
void Execute(Complex *in, Complex *out)
mrcfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1, unsigned int dist=0, Complex *out=NULL)
crfft2d(unsigned int nx, unsigned int ny, Complex *in=NULL)
void Execute(Complex *in, Complex *out)
void fftNormalized(double *in, Complex *out)
void fftNormalized(Complex *in, Complex *out=NULL)
fft3d(unsigned int nx, unsigned int ny, unsigned int nz, int sign, Complex *in=NULL, Complex *out=NULL)
crfft1d(unsigned int nx, Complex *in=NULL)
fft1d(unsigned int nx, int sign, Complex *in=NULL, Complex *out=NULL)
unsigned int realsize(unsigned int n, Complex *in, double *out)
void Setup(Complex *in, Complex *out=NULL)
std::complex< double > Complex
void fftNormalized(Complex *in, double *out)
void Execute(Complex *in, Complex *out)
mcrfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1, unsigned int dist=0, Complex *in=NULL)
void Execute(Complex *in, Complex *out)
void fft(double *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
crfft2d(unsigned int nx, unsigned int ny, Complex *in, double *out)
fftw_plan Plan(Complex *in, Complex *out)
unsigned int Dist(unsigned int n, unsigned int stride, unsigned int dist)
virtual fftw_plan Plan(Complex *in, Complex *out)=0
static unsigned int effort
void fft(Complex *in, Complex *out=NULL)
static const char * WisdomName
void fft0Normalized(Complex *in, Complex *out=NULL)
void Execute(Complex *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
void Execute(Complex *in, Complex *out)
rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *out=NULL)
mrcfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1, unsigned int dist=0, double *in=NULL, Complex *out=NULL)
fftw_plan Plan(Complex *in, Complex *out)
virtual void Execute(Complex *in, Complex *out)
void fft0Normalized(double *in, Complex *out)
void fftNormalized(Complex *in, Complex *out, unsigned int nx, unsigned int m, unsigned int stride, unsigned int dist)
fftw_plan Plan(Complex *in, Complex *out)
void Execute(Complex *in, Complex *out)
void fftw_export_wisdom(void(*emitter)(char c, ofstream &s), ofstream &s)
void PutWisdom(char c, ofstream &s)
rcfft2d(unsigned int nx, unsigned int ny, double *in, Complex *out=NULL)
void fft0(double *in, Complex *out)
crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *in=NULL)
unsigned int realsize(unsigned int n, Complex *in, Complex *out)
fftw_plan Plan(Complex *in, Complex *out)
rcfft3d(unsigned int nx, unsigned int ny, unsigned int nz, double *in, Complex *out=NULL)
int fftw_import_wisdom(int(*g)(ifstream &s), ifstream &s)
void Setup(Complex *in, double *out)
Complex * FFTWComplex(size_t size)
mfft1d(unsigned int nx, int sign, unsigned int m=1, unsigned int stride=1, unsigned int dist=0, Complex *in=NULL, Complex *out=NULL)
rcfft1d(unsigned int nx, double *in, Complex *out=NULL)
void Setup(double *in, Complex *out)
void fft0(Complex *in, double *out)
fftw_plan Plan(Complex *in, Complex *out)
rcfft1d(unsigned int nx, Complex *out=NULL)
fftw(unsigned int size, int sign, unsigned int n=0)
rcfft2d(unsigned int nx, unsigned int ny, Complex *out=NULL)
void Normalize(Complex *out)
void CheckAlign(Complex *p, const char *s)
virtual void fftNormalized(Complex *in, Complex *out=NULL)
void fftNormalized(Complex *in, Complex *out=NULL)
void Shift(Complex *data, unsigned int nx, unsigned int ny)
fft2d(unsigned int nx, unsigned int ny, int sign, Complex *in=NULL, Complex *out=NULL)
crfft3d(unsigned int nx, unsigned int ny, unsigned int nz, Complex *in, double *out)
double * FFTWdouble(size_t size)
mcrfft1d(unsigned int nx, unsigned int m=1, unsigned int stride=1, unsigned int dist=0, Complex *in=NULL, double *out=NULL)
void fft0(Complex *in, Complex *out=NULL)
void fftNormalized(Complex *in, Complex *out=NULL)
fftw_plan Plan(Complex *in, Complex *out)
void fft0Normalized(Complex *in, double *out)
void fft(Complex *in, double *out)