| [765] | 1 | #include "fftwserver.h"
 | 
|---|
 | 2 | #include "FFTW/fftw.h"
 | 
|---|
 | 3 | #include "FFTW/rfftw.h"
 | 
|---|
 | 4 | 
 | 
|---|
 | 5 | class FFTWServerPlan{
 | 
|---|
 | 6 | public:
 | 
|---|
 | 7 |   FFTWServerPlan(int n, fftw_direction dir, bool fgreal=false);
 | 
|---|
 | 8 |   FFTWServerPlan(int nx, int ny, fftw_direction dir, bool fgreal=false);
 | 
|---|
 | 9 |   ~FFTWServerPlan();
 | 
|---|
 | 10 |   void Recreate(int n);
 | 
|---|
 | 11 |   void Recreate(int nx, int ny);
 | 
|---|
 | 12 | 
 | 
|---|
 | 13 |   int _n;
 | 
|---|
 | 14 |   int _nx, _ny;
 | 
|---|
 | 15 |   fftw_direction _dir;
 | 
|---|
 | 16 | 
 | 
|---|
 | 17 |   fftw_plan p;
 | 
|---|
 | 18 |   rfftw_plan rp;
 | 
|---|
 | 19 |   fftwnd_plan pnd;
 | 
|---|
 | 20 |   rfftwnd_plan rpnd;
 | 
|---|
 | 21 |    
 | 
|---|
 | 22 | };
 | 
|---|
 | 23 | 
 | 
|---|
 | 24 | FFTWServerPlan::FFTWServerPlan(int n, fftw_direction dir, bool fgreal)
 | 
|---|
 | 25 | {
 | 
|---|
 | 26 |   if (n < 1) 
 | 
|---|
 | 27 |     throw ParmError("FFTWServerPlan: Array size <= 0 !");
 | 
|---|
 | 28 |   p = NULL;
 | 
|---|
 | 29 |   rp = NULL;
 | 
|---|
 | 30 |   pnd = NULL;
 | 
|---|
 | 31 |   rpnd = NULL;
 | 
|---|
 | 32 |   _nx = _ny = -10;
 | 
|---|
 | 33 |   _n = n;  
 | 
|---|
 | 34 |   _dir = dir;
 | 
|---|
 | 35 |   if (fgreal) rp = rfftw_create_plan(n, dir, FFTW_ESTIMATE);
 | 
|---|
 | 36 |   else p = fftw_create_plan(n, dir, FFTW_ESTIMATE);
 | 
|---|
 | 37 | }
 | 
|---|
 | 38 | FFTWServerPlan::FFTWServerPlan(int nx, int ny, fftw_direction dir, bool fgreal)
 | 
|---|
 | 39 | {
 | 
|---|
 | 40 |   if ( (nx < 1) || (ny <1) ) 
 | 
|---|
 | 41 |     throw ParmError("FFTWServerPlan: Array size Nx or Ny <= 0 !");
 | 
|---|
 | 42 |   p = NULL;
 | 
|---|
 | 43 |   rp = NULL;
 | 
|---|
 | 44 |   pnd = NULL;
 | 
|---|
 | 45 |   rpnd = NULL;
 | 
|---|
 | 46 |   _n = -10;
 | 
|---|
 | 47 |   _nx = nx; 
 | 
|---|
 | 48 |   _ny = ny;
 | 
|---|
 | 49 |   _dir = dir;
 | 
|---|
 | 50 |   int sz[2];
 | 
|---|
 | 51 |   sz[0]= nx; sz[1] = ny;
 | 
|---|
 | 52 |   if (fgreal) rpnd = rfftwnd_create_plan(2, sz, dir, FFTW_ESTIMATE);
 | 
|---|
 | 53 |   else pnd = fftwnd_create_plan(2, sz, dir, FFTW_ESTIMATE);
 | 
|---|
 | 54 | }
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | FFTWServerPlan::~FFTWServerPlan()
 | 
|---|
 | 57 | {
 | 
|---|
 | 58 |   if (p) fftw_destroy_plan(p);
 | 
|---|
 | 59 |   if (rp) rfftw_destroy_plan(rp);
 | 
|---|
 | 60 |   if (pnd) fftwnd_destroy_plan(pnd);
 | 
|---|
 | 61 |   if (rpnd) rfftwnd_destroy_plan(rpnd);
 | 
|---|
 | 62 | }
 | 
|---|
 | 63 | 
 | 
|---|
 | 64 | void
 | 
|---|
 | 65 | FFTWServerPlan::Recreate(int n)
 | 
|---|
 | 66 | {
 | 
|---|
 | 67 |   if (n < 1) 
 | 
|---|
 | 68 |    throw ParmError("FFTWServerPlan::Recreate(n) n < 0 !");
 | 
|---|
 | 69 |   if ((_nx > 0) || (_ny > 0))  
 | 
|---|
 | 70 |    throw ParmError("FFTWServerPlan::Recreate(n) Nx or Ny > 0 !");
 | 
|---|
 | 71 |   if (n == _n) return;
 | 
|---|
 | 72 |   _n = n;  
 | 
|---|
 | 73 |   if (p) {
 | 
|---|
 | 74 |     fftw_destroy_plan(p);
 | 
|---|
 | 75 |     p = fftw_create_plan(n, _dir, FFTW_ESTIMATE);
 | 
|---|
 | 76 |   }
 | 
|---|
 | 77 |   else {
 | 
|---|
 | 78 |     rfftw_destroy_plan(rp);
 | 
|---|
 | 79 |     rp = rfftw_create_plan(n, _dir, FFTW_ESTIMATE);
 | 
|---|
 | 80 |   }
 | 
|---|
 | 81 | }
 | 
|---|
 | 82 | 
 | 
|---|
 | 83 | void
 | 
|---|
 | 84 | FFTWServerPlan::Recreate(int nx, int ny)
 | 
|---|
 | 85 | {
 | 
|---|
 | 86 |   if ( (nx < 1) || (ny <1) ) 
 | 
|---|
 | 87 |     throw ParmError("FFTWServerPlan:Recreate(nx, ny) size Nx or Ny <= 0 !");
 | 
|---|
 | 88 |   if (_n > 0)
 | 
|---|
 | 89 |     throw ParmError("FFTWServerPlan::Recreate(nx, ny) N > 0 !");
 | 
|---|
 | 90 |   if ((nx == _nx) && (ny == _ny)) return;
 | 
|---|
 | 91 |   _nx = nx; 
 | 
|---|
 | 92 |   _ny = ny;
 | 
|---|
 | 93 |   int sz[2];
 | 
|---|
 | 94 |   sz[0]= nx; sz[1] = ny;
 | 
|---|
 | 95 |   if (pnd) {
 | 
|---|
 | 96 |     fftwnd_destroy_plan(pnd);
 | 
|---|
 | 97 |     pnd = fftwnd_create_plan(2, sz,_dir, FFTW_ESTIMATE);
 | 
|---|
 | 98 |   }
 | 
|---|
 | 99 |   else {
 | 
|---|
 | 100 |     rfftwnd_destroy_plan(rpnd);
 | 
|---|
 | 101 |     rpnd = rfftwnd_create_plan(2, sz, _dir, FFTW_ESTIMATE);
 | 
|---|
 | 102 |   }
 | 
|---|
 | 103 | 
 | 
|---|
 | 104 | }
 | 
|---|
 | 105 | 
 | 
|---|
 | 106 | 
 | 
|---|
 | 107 | /* --Methode-- */
 | 
|---|
 | 108 | FFTWServer::FFTWServer()
 | 
|---|
 | 109 |   : FFTServerInterface("FFTServer using FFTW package")
 | 
|---|
 | 110 | {
 | 
|---|
 | 111 |   _p1df = NULL;
 | 
|---|
 | 112 |   _p1db = NULL;
 | 
|---|
 | 113 |   _p2df = NULL;
 | 
|---|
 | 114 |   _p2db = NULL;
 | 
|---|
 | 115 | 
 | 
|---|
 | 116 |   _p1drf = NULL;
 | 
|---|
 | 117 |   _p1drb = NULL;
 | 
|---|
 | 118 |   _p2drf = NULL;
 | 
|---|
 | 119 |   _p2drb = NULL;
 | 
|---|
 | 120 | }
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 | /* --Methode-- */
 | 
|---|
 | 124 | FFTWServer::~FFTWServer()
 | 
|---|
 | 125 | {
 | 
|---|
 | 126 |   if (_p1df) delete _p1df ;
 | 
|---|
 | 127 |   if (_p1db) delete _p1db ;
 | 
|---|
 | 128 |   if (_p2df) delete _p2df ;
 | 
|---|
 | 129 |   if (_p2db) delete _p2db ;
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 |   if (_p1drf) delete _p1drf ;
 | 
|---|
 | 132 |   if (_p1drb) delete _p1drb ;
 | 
|---|
 | 133 |   if (_p2drf) delete _p2drf ;
 | 
|---|
 | 134 |   if (_p2drb) delete _p2drb ;
 | 
|---|
 | 135 | }
 | 
|---|
 | 136 | 
 | 
|---|
 | 137 | /* --Methode-- */
 | 
|---|
 | 138 | FFTServerInterface * FFTWServer::Clone()
 | 
|---|
 | 139 | {
 | 
|---|
 | 140 |   return (new FFTWServer) ;
 | 
|---|
 | 141 | }
 | 
|---|
 | 142 | 
 | 
|---|
 | 143 | /* --Methode-- */
 | 
|---|
 | 144 | void 
 | 
|---|
 | 145 | FFTWServer::FFTForward(TVector< complex<double> > const & in, TVector< complex<double> > & out)
 | 
|---|
 | 146 | {
 | 
|---|
 | 147 |   if (_p1df) _p1df->Recreate(in.NElts());
 | 
|---|
 | 148 |   else _p1df = new FFTWServerPlan(in.NElts(), FFTW_FORWARD, false);
 | 
|---|
 | 149 |   out.ReSize(in.NElts());
 | 
|---|
 | 150 |   fftw_one(_p1df->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
 | 
|---|
 | 151 |   if(this->getNormalize()) out=out/complex<double>(pow(in.NElts(),0.5),0.);
 | 
|---|
 | 152 | }
 | 
|---|
 | 153 | /* --Methode-- */
 | 
|---|
 | 154 | void FFTWServer::FFTBackward(TVector< complex<double> > const & in, TVector< complex<double> > & out)
 | 
|---|
 | 155 | {
 | 
|---|
 | 156 |   if (_p1db) _p1db->Recreate(in.NElts());
 | 
|---|
 | 157 |   else _p1db = new FFTWServerPlan(in.NElts(), FFTW_BACKWARD, false);
 | 
|---|
 | 158 |   out.ReSize(in.NElts());
 | 
|---|
 | 159 |   fftw_one(_p1db->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
 | 
|---|
 | 160 |   if(this->getNormalize()) out=out/complex<double>(pow(in.NElts(),0.5),0.);
 | 
|---|
 | 161 | 
 | 
|---|
 | 162 | }
 | 
|---|
 | 163 | 
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | void FFTWServer::FFTForward(TVector< double > const & in, TVector< complex<double> > & out)
 | 
|---|
 | 166 | {  
 | 
|---|
 | 167 |   int size = in.NElts()/2;
 | 
|---|
 | 168 |   
 | 
|---|
 | 169 |   if(in.NElts()%2 != 0)  { size = in.NElts()/2 +1;}
 | 
|---|
 | 170 |   else  { size = in.NElts()/2 +1 ;}
 | 
|---|
 | 171 | 
 | 
|---|
 | 172 |   TVector< double > const outTemp(in.NElts());
 | 
|---|
 | 173 |   out.ReSize(size);
 | 
|---|
 | 174 |   if (_p1drf) _p1drf->Recreate(in.NElts());
 | 
|---|
 | 175 |   else _p1drf = new FFTWServerPlan(in.NElts(), FFTW_REAL_TO_COMPLEX, true);
 | 
|---|
 | 176 |   rfftw_one(_p1drf->rp, (fftw_real *)(in.Data()) , (fftw_real *)(outTemp.Data()));
 | 
|---|
 | 177 |   ReShapetoCompl(outTemp, out);
 | 
|---|
 | 178 |   if(this->getNormalize()) out=out/complex<double>(pow(in.NElts(),0.5),0.);
 | 
|---|
 | 179 | }
 | 
|---|
 | 180 | 
 | 
|---|
 | 181 | 
 | 
|---|
 | 182 | 
 | 
|---|
 | 183 | void FFTWServer::FFTBackward(TVector< complex<double> > const & in, TVector< double > & out)
 | 
|---|
 | 184 | {
 | 
|---|
 | 185 |   int size;
 | 
|---|
 | 186 |   if(in(in.NElts()).imag()  == 0) { size = 2*in.NElts()-2;}
 | 
|---|
 | 187 |   else { size = 2*in.NElts()-1;}
 | 
|---|
 | 188 |   
 | 
|---|
 | 189 |   TVector< double > inTemp(size);
 | 
|---|
 | 190 |   out.ReSize(size);
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 |   if (_p1drb) _p1drb->Recreate(size);
 | 
|---|
 | 193 |   else _p1drb = new FFTWServerPlan(size, FFTW_COMPLEX_TO_REAL, true);
 | 
|---|
 | 194 | 
 | 
|---|
 | 195 |   ReShapetoReal(in, inTemp);
 | 
|---|
 | 196 |   rfftw_one(_p1drb->rp, (fftw_real *)(inTemp.Data()) , (fftw_real *)(out.Data()));
 | 
|---|
 | 197 |   if(this->getNormalize()) out=out/pow(size,0.5);
 | 
|---|
 | 198 | }
 | 
|---|
 | 199 | 
 | 
|---|
 | 200 | /* --Methode-- */
 | 
|---|
 | 201 | void FFTWServer::FFTForward(TMatrix< complex<double> > const & in, TMatrix< complex<double> > & out)
 | 
|---|
 | 202 | {
 | 
|---|
 | 203 |   out.ReSize(in.NRows(),in.NCols());
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 |   if (_p2df) _p2df->Recreate( in.NRows(),in.NCols());
 | 
|---|
 | 206 |   else _p2df = new FFTWServerPlan( in.NCols(),in.NRows(), FFTW_FORWARD, false);
 | 
|---|
 | 207 |   
 | 
|---|
 | 208 |   fftwnd_one(_p2df->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
 | 
|---|
 | 209 |   if(this->getNormalize()) out=out/complex<double>(pow(in.NRows()*in.NCols(),0.5),0.);  
 | 
|---|
 | 210 | }
 | 
|---|
 | 211 | 
 | 
|---|
 | 212 | /* --Methode-- */
 | 
|---|
 | 213 | void FFTWServer::FFTBackward(TMatrix< complex<double> > const & in, TMatrix< complex<double> > & out)
 | 
|---|
 | 214 | {
 | 
|---|
 | 215 |   if (_p2db) _p2db->Recreate(in.NCols(), in.NRows());
 | 
|---|
 | 216 |   else _p2db = new FFTWServerPlan(in.NCols(), in.NRows(), FFTW_BACKWARD, false);
 | 
|---|
 | 217 |   out.ReSize(in.NRows(), in.NCols());
 | 
|---|
 | 218 |   fftwnd_one(_p2db->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
 | 
|---|
 | 219 |   if(this->getNormalize()) out=out/complex<double>(pow(in.NRows()*in.NCols(),0.5),0.);
 | 
|---|
 | 220 | 
 | 
|---|
 | 221 | }
 | 
|---|
 | 222 | 
 | 
|---|
 | 223 | 
 | 
|---|
 | 224 | /* --Methode-- */
 | 
|---|
 | 225 | void FFTWServer::FFTForward(TMatrix< double > const & in, TMatrix< complex<double> > & out)
 | 
|---|
 | 226 | {
 | 
|---|
 | 227 | 
 | 
|---|
 | 228 |   TMatrix< double > inNew(in.NCols(),in.NRows());
 | 
|---|
 | 229 |   for(int i=0; i<in.NRows(); i++)
 | 
|---|
 | 230 |     for(int j=0;j<in.NCols(); j++)
 | 
|---|
 | 231 |       inNew(j,i) = in(i,j);
 | 
|---|
 | 232 |   
 | 
|---|
 | 233 |   if (_p2drf) _p2drf->Recreate(inNew.NRows(),inNew.NCols());
 | 
|---|
 | 234 |   else _p2drf = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_REAL_TO_COMPLEX, true);
 | 
|---|
| [834] | 235 |   //  rfftwnd_plan p;
 | 
|---|
| [765] | 236 |   TMatrix< complex<double> > outTemp;
 | 
|---|
 | 237 |   outTemp.ReSize(in.NRows(),in.NCols());
 | 
|---|
 | 238 | 
 | 
|---|
 | 239 |   rfftwnd_one_real_to_complex(_p2drf->rpnd, (fftw_real *)(in.Data()) , (fftw_complex *)(out.Data()) );
 | 
|---|
 | 240 | }
 | 
|---|
 | 241 | 
 | 
|---|
 | 242 | /* --Methode-- */
 | 
|---|
 | 243 | void FFTWServer::FFTBackward(TMatrix< complex<double> > const & in, TMatrix< double > & out)
 | 
|---|
 | 244 | {
 | 
|---|
 | 245 | 
 | 
|---|
 | 246 |   TMatrix< complex<double> > inNew(in.NCols(),in.NRows());
 | 
|---|
 | 247 |   for(int i=0; i<in.NRows(); i++)
 | 
|---|
 | 248 |     for(int j=0;j<in.NCols(); j++)
 | 
|---|
 | 249 |       inNew(j,i) = in(i,j);
 | 
|---|
 | 250 |   
 | 
|---|
 | 251 |   if (_p2drb) _p2drb->Recreate(inNew.NRows(),inNew.NCols());
 | 
|---|
 | 252 |   else _p2drb = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_COMPLEX_TO_REAL, true);
 | 
|---|
| [834] | 253 |   //  rfftwnd_plan p;
 | 
|---|
| [765] | 254 |   out.ReSize(in.NRows(),in.NCols());
 | 
|---|
 | 255 | 
 | 
|---|
 | 256 |   rfftwnd_one_complex_to_real(_p2drb->rpnd, (fftw_complex *)(in.Data()) , (fftw_real *)(out.Data()) );
 | 
|---|
 | 257 |   cout << " in the function !!!" << endl;
 | 
|---|
 | 258 |   if(this->getNormalize()) 
 | 
|---|
 | 259 |     {
 | 
|---|
 | 260 |       double norm = (double)(in.NRows()*in.NCols());
 | 
|---|
 | 261 |       out=out/norm;
 | 
|---|
 | 262 |     }
 | 
|---|
 | 263 | }
 | 
|---|
 | 264 | 
 | 
|---|
 | 265 | 
 | 
|---|
 | 266 | /* --Methode-- */
 | 
|---|
 | 267 | void FFTWServer::ReShapetoReal( TVector< complex<double> > const & in, TVector< double >  & out)
 | 
|---|
 | 268 | {
 | 
|---|
 | 269 |   int N = in.NElts();
 | 
|---|
| [834] | 270 |   int i;
 | 
|---|
| [765] | 271 |   if (in(in.NElts()).imag() == 0) 
 | 
|---|
 | 272 |     {
 | 
|---|
 | 273 |       out(0) = in(0).real();
 | 
|---|
| [834] | 274 |       for(i=1; i<in.NElts(); i++)
 | 
|---|
| [765] | 275 |         {
 | 
|---|
 | 276 |           out(i) = in(i).real();
 | 
|---|
 | 277 |         }
 | 
|---|
| [834] | 278 |       for(i=1; i<in.NElts(); i++)
 | 
|---|
| [765] | 279 |         {
 | 
|---|
 | 280 |           out(i+in.NElts()-1) = in(in.NElts()-i-1).imag();
 | 
|---|
 | 281 |         }
 | 
|---|
 | 282 |     }
 | 
|---|
 | 283 |   else
 | 
|---|
 | 284 |     {
 | 
|---|
 | 285 |       out(0) = in(0).real();
 | 
|---|
| [834] | 286 |       for(i=1; i<in.NElts(); i++)
 | 
|---|
| [765] | 287 |         {
 | 
|---|
 | 288 |           out(i) = in(i).real();
 | 
|---|
 | 289 |         }
 | 
|---|
| [834] | 290 |       for(i=1; i<in.NElts(); i++)
 | 
|---|
| [765] | 291 |         {
 | 
|---|
 | 292 |           out(i+in.NElts()-1) = in(in.NElts()-i).imag();
 | 
|---|
 | 293 |         }
 | 
|---|
 | 294 |     }
 | 
|---|
 | 295 |   //  for(int k=0; k<out.NElts(); k++) cout << "ReShapetoReal out " << k << " " << out(k) << endl;
 | 
|---|
 | 296 | }
 | 
|---|
 | 297 | 
 | 
|---|
 | 298 | 
 | 
|---|
 | 299 | /* --Methode-- */
 | 
|---|
 | 300 | void FFTWServer::ReShapetoCompl(TVector< double > const & in, TVector< complex<double> > & out)
 | 
|---|
 | 301 | {
 | 
|---|
 | 302 |   int N = in.NElts();
 | 
|---|
 | 303 |   //  for(int k=0; k<in.NElts(); k++) cout << "ReShapetoCompl in " << k << " "  << in(k) << endl;
 | 
|---|
 | 304 |   out(0) = complex<double> (in(0),0.);
 | 
|---|
 | 305 |   if(in.NElts()%2 !=0)
 | 
|---|
 | 306 |     {
 | 
|---|
 | 307 |       for(int k=1;k<=N/2+1;k++)
 | 
|---|
 | 308 |         {
 | 
|---|
 | 309 |           out(k) =  complex<double> (in(k),in(N-k));
 | 
|---|
 | 310 |         }
 | 
|---|
 | 311 |     }
 | 
|---|
 | 312 |   else 
 | 
|---|
 | 313 |     {
 | 
|---|
 | 314 |       for(int k=1;k<N/2;k++)
 | 
|---|
 | 315 |         {
 | 
|---|
 | 316 |           out(k) =  complex<double> (in(k),in(N-k));
 | 
|---|
 | 317 |         }
 | 
|---|
 | 318 |       out(N/2) = complex<double> (in(N/2),0.);
 | 
|---|
 | 319 |     }
 | 
|---|
 | 320 |   //  for(int k=0; k<out.NElts(); k++) cout << "ReShapetoCompl out " << k << " "  << out(k) << endl;
 | 
|---|
 | 321 | }
 | 
|---|
 | 322 | 
 | 
|---|