#include "fftwserver.h" #include "FFTW/fftw.h" #include "FFTW/rfftw.h" #define MAXND_FFTW 5 class FFTWServerPlan { public: FFTWServerPlan(int n, fftw_direction dir, bool fgreal=false); FFTWServerPlan(int nd, int * nxyz, fftw_direction dir, bool fgreal=false); ~FFTWServerPlan(); void Recreate(int n); void Recreate(int nd, int * nxyz); int _n; // Array dimension for 1-d arrays int _nd; // Nb of dimensions for n-d arrays int _nxyz[MAXND_FFTW]; // Array dimensions for n-d arrays fftw_direction _dir; fftw_plan p; rfftw_plan rp; fftwnd_plan pnd; rfftwnd_plan rpnd; }; FFTWServerPlan::FFTWServerPlan(int n, fftw_direction dir, bool fgreal) { if (n < 1) throw ParmError("FFTWServerPlan: Array size <= 0 !"); p = NULL; rp = NULL; pnd = NULL; rpnd = NULL; _nd = -1; for(int k=0; k MAXND_FFTW) throw ParmError("FFTWServerPlan: Array rank (nd) > MAXND_FFTW !"); p = NULL; rp = NULL; pnd = NULL; rpnd = NULL; _n = -10; _nd = nd; for(k=0; k 0) throw ParmError("FFTWServerPlan::Recreate(n) Multi-dimensional plan ! > 0 !"); if (n == _n) return; _n = n; if (p) { fftw_destroy_plan(p); p = fftw_create_plan(n, _dir, FFTW_ESTIMATE); } else { rfftw_destroy_plan(rp); rp = rfftw_create_plan(n, _dir, FFTW_ESTIMATE); } } void FFTWServerPlan::Recreate(int nd, int * nxyz) { if (_n > 0) throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) 1-dimensional plan !"); int k; if (nd == _nd) { bool samepl = true; for (int k=0; k MAXND_FFTW) throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) Array rank (nd) > MAXND_FFTW !"); _nd = nd; for(k=0; k > const & in, TArray< complex > & out) { int rank = ckR8.CheckResize(in, out); if (rank == 1) { // One dimensional transform if (_p1df) _p1df->Recreate(in.Size()); else _p1df = new FFTWServerPlan(in.Size(), FFTW_FORWARD, false); fftw_one(_p1df->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) ); } else { // Multi dimensional if (in.NbDimensions() > MAXND_FFTW) throw ParmError("FFTWServer::FFTForward( complex, complex ) rank > MAXND_FFTW !"); int sz[MAXND_FFTW]; int k1 = 0; int k2 = 0; for(k1=in.NbDimensions()-1; k1>=0; k1--) { sz[k2] = in.Size(k1); k2++; } if (_pndf) _pndf->Recreate(in.NbDimensions(), sz); else _pndf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_FORWARD, false); fftwnd_one(_pndf->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) ); } // $CHECK$ Reza 9/2/2001 , Verifier normalisation if(this->getNormalize()) out=out/complex(sqrt((double)in.Size()),0.); return; } /* --Methode-- */ void FFTWServer::FFTBackward(TArray< complex > const & in, TArray< complex > & out) { int rank = ckR8.CheckResize(in, out); if (rank == 1) { // One dimensional transform if (_p1db) _p1db->Recreate(in.Size()); else _p1db = new FFTWServerPlan(in.Size(), FFTW_BACKWARD, false); fftw_one(_p1db->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) ); } else { // Multi dimensional if (in.NbDimensions() > MAXND_FFTW) throw ParmError("FFTWServer::FFTForward( complex, complex ) rank > MAXND_FFTW !"); int sz[MAXND_FFTW]; int k1 = 0; int k2 = 0; for(k1=in.NbDimensions()-1; k1>=0; k1--) { sz[k2] = in.Size(k1); k2++; } if (_pndb) _pndb->Recreate(in.NbDimensions(), sz); else _pndb = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_BACKWARD, false); } // $CHECK$ Reza 9/2/2001 , Verifier normalisation if(this->getNormalize()) out=out/complex(sqrt((double)in.Size()),0.); return; } void FFTWServer::FFTForward(TArray< r_8 > const & in, TArray< complex > & out) { int rank = ckR8.CheckResize(in, out); TArray outtemp(in, false); if (rank == 1) { // One dimensional transform if (_p1drf) _p1drf->Recreate(in.Size()); else _p1drf = new FFTWServerPlan(in.Size(), FFTW_REAL_TO_COMPLEX, true); rfftw_one(_p1drf->rp, (fftw_real *)(in.Data()) , (fftw_real *)(outtemp.Data())); ReShapetoCompl(outtemp, out); } else { // Multi dimensional if (in.NbDimensions() > MAXND_FFTW) throw ParmError("FFTWServer::FFTForward( complex, complex ) rank > MAXND_FFTW !"); int sz[MAXND_FFTW]; int k1 = 0; int k2 = 0; for(k1=in.NbDimensions()-1; k1>=0; k1--) { sz[k2] = in.Size(k1); k2++; } if (_pndrf) _pndrf->Recreate(in.NbDimensions(), sz); else _pndrf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_REAL_TO_COMPLEX, true); rfftwnd_one_real_to_complex(_pndrf->rpnd, (fftw_real *)(in.Data()) , (fftw_complex *)(out.Data()) ); } // $CHECK$ Reza 9/2/2001 , Verifier normalisation if(this->getNormalize()) out=out/complex(sqrt((double)in.Size()),0.); return; } void FFTWServer::FFTBackward(TArray< complex > const & in, TArray< r_8 > & out) { throw ParmError("FFTWServer::FFTBackward(TArray< complex > ... Not implemented ... !"); /* int size; if(in(in.NElts()).imag() == 0) { size = 2*in.NElts()-2;} else { size = 2*in.NElts()-1;} TArray< r_8 > inTemp(size); out.ReSize(size); if (_p1drb) _p1drb->Recreate(size); else _p1drb = new FFTWServerPlan(size, FFTW_COMPLEX_TO_REAL, true); ReShapetoReal(in, inTemp); rfftw_one(_p1drb->rp, (fftw_real *)(inTemp.Data()) , (fftw_real *)(out.Data())); if(this->getNormalize()) out=out/pow(size,0.5); */ } /* void FFTWServer::FFTForward(TArray< complex > const & in, TArray< complex > & out) { out.ReSize(in.NRows(),in.NCols()); if (_pndf) _pndf->Recreate( in.NRows(),in.NCols()); else _pndf = new FFTWServerPlan( in.NCols(),in.NRows(), FFTW_FORWARD, false); fftwnd_one(_pndf->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) ); if(this->getNormalize()) out=out/complex(pow(in.NRows()*in.NCols(),0.5),0.); } void FFTWServer::FFTBackward(TArray< complex > const & in, TArray< complex > & out) { if (_pndb) _pndb->Recreate(in.NCols(), in.NRows()); else _pndb = new FFTWServerPlan(in.NCols(), in.NRows(), FFTW_BACKWARD, false); out.ReSize(in.NRows(), in.NCols()); fftwnd_one(_pndb->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) ); if(this->getNormalize()) out=out/complex(pow(in.NRows()*in.NCols(),0.5),0.); } void FFTWServer::FFTForward(TArray< r_8 > const & in, TArray< complex > & out) { TArray< r_8 > inNew(in.NCols(),in.NRows()); for(int i=0; iRecreate(inNew.NRows(),inNew.NCols()); else _pndrf = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_REAL_TO_COMPLEX, true); // rfftwnd_plan p; TArray< complex > outTemp; outTemp.ReSize(in.NRows(),in.NCols()); rfftwnd_one_real_to_complex(_pndrf->rpnd, (fftw_real *)(in.Data()) , (fftw_complex *)(out.Data()) ); } void FFTWServer::FFTBackward(TArray< complex > const & in, TArray< r_8 > & out) { TArray< complex > inNew(in.NCols(),in.NRows()); for(int i=0; iRecreate(inNew.NRows(),inNew.NCols()); else _pndrb = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_COMPLEX_TO_REAL, true); // rfftwnd_plan p; out.ReSize(in.NRows(),in.NCols()); rfftwnd_one_complex_to_real(_pndrb->rpnd, (fftw_complex *)(in.Data()) , (fftw_real *)(out.Data()) ); cout << " in the function !!!" << endl; if(this->getNormalize()) { r_8 norm = (r_8)(in.NRows()*in.NCols()); out=out/norm; } } */ /* --Methode-- */ void FFTWServer::ReShapetoReal( TArray< complex > const & in, TArray< r_8 > & out) { int N = in.Size(); /* int i; if (in(in.Size()).imag() == 0) { out(0) = in(0).real(); for(i=1; i const & in, TArray< complex > & out) { int N = in.Size(); // for(int k=0; k (in[0],0.); for(int k=1; k(in[k], in[N-k]); if (N%2 == 0) out[N/2] = complex(in[N/2], 0.); // for(int k=0; k