source: Sophya/trunk/SophyaExt/IFFTW/fftwserver.cc@ 1391

Last change on this file since 1391 was 1391, checked in by ansari, 25 years ago

Modifs interface FFTServer, adaptation a FFTW, PAS FINI , Reza 9/2/2001

File size: 10.9 KB
Line 
1#include "fftwserver.h"
2#include "FFTW/fftw.h"
3#include "FFTW/rfftw.h"
4
5
6#define MAXND_FFTW 5
7
8class FFTWServerPlan {
9public:
10 FFTWServerPlan(int n, fftw_direction dir, bool fgreal=false);
11 FFTWServerPlan(int nd, int * nxyz, fftw_direction dir, bool fgreal=false);
12 ~FFTWServerPlan();
13 void Recreate(int n);
14 void Recreate(int nd, int * nxyz);
15
16 int _n; // Array dimension for 1-d arrays
17 int _nd; // Nb of dimensions for n-d arrays
18 int _nxyz[MAXND_FFTW]; // Array dimensions for n-d arrays
19 fftw_direction _dir;
20
21 fftw_plan p;
22 rfftw_plan rp;
23 fftwnd_plan pnd;
24 rfftwnd_plan rpnd;
25
26};
27
28FFTWServerPlan::FFTWServerPlan(int n, fftw_direction dir, bool fgreal)
29{
30 if (n < 1)
31 throw ParmError("FFTWServerPlan: Array size <= 0 !");
32 p = NULL;
33 rp = NULL;
34 pnd = NULL;
35 rpnd = NULL;
36 _nd = -1;
37 for(int k=0; k<MAXND_FFTW; k++) _nxyz[k] = -10;
38 _n = n;
39 _dir = dir;
40 if (fgreal) rp = rfftw_create_plan(n, dir, FFTW_ESTIMATE);
41 else p = fftw_create_plan(n, dir, FFTW_ESTIMATE);
42}
43
44FFTWServerPlan::FFTWServerPlan(int nd, int * nxyz, fftw_direction dir, bool fgreal)
45{
46 int k;
47 if (nd > MAXND_FFTW)
48 throw ParmError("FFTWServerPlan: Array rank (nd) > MAXND_FFTW !");
49 p = NULL;
50 rp = NULL;
51 pnd = NULL;
52 rpnd = NULL;
53 _n = -10;
54 _nd = nd;
55 for(k=0; k<nd; k++) {
56 if (nxyz[k] < 1)
57 throw ParmError("FFTWServerPlan: One of the Array size <= 0 !");
58 _nxyz[k] = nxyz[k];
59 }
60 for(k=nd; k<MAXND_FFTW; k++) _nxyz[k] = -10;
61 _dir = dir;
62 if (fgreal) rpnd = rfftwnd_create_plan(_nd, _nxyz, dir, FFTW_ESTIMATE);
63 else pnd = fftwnd_create_plan(_nd, _nxyz, dir, FFTW_ESTIMATE);
64}
65
66FFTWServerPlan::~FFTWServerPlan()
67{
68 if (p) fftw_destroy_plan(p);
69 if (rp) rfftw_destroy_plan(rp);
70 if (pnd) fftwnd_destroy_plan(pnd);
71 if (rpnd) rfftwnd_destroy_plan(rpnd);
72}
73
74void
75FFTWServerPlan::Recreate(int n)
76{
77 if (n < 1)
78 throw ParmError("FFTWServerPlan::Recreate(n) n < 0 !");
79 if (_nd > 0)
80 throw ParmError("FFTWServerPlan::Recreate(n) Multi-dimensional plan ! > 0 !");
81 if (n == _n) return;
82 _n = n;
83 if (p) {
84 fftw_destroy_plan(p);
85 p = fftw_create_plan(n, _dir, FFTW_ESTIMATE);
86 }
87 else {
88 rfftw_destroy_plan(rp);
89 rp = rfftw_create_plan(n, _dir, FFTW_ESTIMATE);
90 }
91}
92
93void
94FFTWServerPlan::Recreate(int nd, int * nxyz)
95{
96 if (_n > 0)
97 throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) 1-dimensional plan !");
98 int k;
99 if (nd == _nd) {
100 bool samepl = true;
101 for (int k=0; k<nd; k++)
102 if (nxyz[k] != _nxyz[k]) samepl = false;
103 if (samepl) return;
104 }
105 if (nd > MAXND_FFTW)
106 throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) Array rank (nd) > MAXND_FFTW !");
107 _nd = nd;
108 for(k=0; k<nd; k++) {
109 if (nxyz[k] < 1)
110 throw ParmError("FFTWServerPlan::Recreate(nd, nxyz) One of the Array size <= 0 !");
111 _nxyz[k] = nxyz[k];
112 }
113 for(k=nd; k<MAXND_FFTW; k++) _nxyz[k] = -10;
114 if (pnd) {
115 fftwnd_destroy_plan(pnd);
116 pnd = fftwnd_create_plan(_nd, _nxyz, _dir, FFTW_ESTIMATE);
117 }
118 else {
119 rfftwnd_destroy_plan(rpnd);
120 rpnd = rfftwnd_create_plan(_nd, _nxyz, _dir, FFTW_ESTIMATE);
121 }
122
123}
124
125
126/* --Methode-- */
127FFTWServer::FFTWServer()
128 : FFTServerInterface("FFTServer using FFTW package")
129 , ckR4(true, false) , ckR8(true, false)
130
131{
132 _p1df = NULL;
133 _p1db = NULL;
134 _pndf = NULL;
135 _pndb = NULL;
136
137 _p1drf = NULL;
138 _p1drb = NULL;
139 _pndrf = NULL;
140 _pndrb = NULL;
141}
142
143
144/* --Methode-- */
145FFTWServer::~FFTWServer()
146{
147 if (_p1df) delete _p1df ;
148 if (_p1db) delete _p1db ;
149 if (_pndf) delete _pndf ;
150 if (_pndb) delete _pndb ;
151
152 if (_p1drf) delete _p1drf ;
153 if (_p1drb) delete _p1drb ;
154 if (_pndrf) delete _pndrf ;
155 if (_pndrb) delete _pndrb ;
156}
157
158/* --Methode-- */
159FFTServerInterface * FFTWServer::Clone()
160{
161 return (new FFTWServer) ;
162}
163
164/* --Methode-- */
165void
166FFTWServer::FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
167{
168 int rank = ckR8.CheckResize(in, out);
169 if (rank == 1) { // One dimensional transform
170 if (_p1df) _p1df->Recreate(in.Size());
171 else _p1df = new FFTWServerPlan(in.Size(), FFTW_FORWARD, false);
172 fftw_one(_p1df->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
173 }
174 else { // Multi dimensional
175 if (in.NbDimensions() > MAXND_FFTW)
176 throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !");
177 int sz[MAXND_FFTW];
178 int k1 = 0;
179 int k2 = 0;
180 for(k1=in.NbDimensions()-1; k1>=0; k1--) {
181 sz[k2] = in.Size(k1); k2++;
182 }
183 if (_pndf) _pndf->Recreate(in.NbDimensions(), sz);
184 else _pndf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_FORWARD, false);
185 fftwnd_one(_pndf->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
186 }
187 // $CHECK$ Reza 9/2/2001 , Verifier normalisation
188 if(this->getNormalize()) out=out/complex<r_8>(sqrt((double)in.Size()),0.);
189 return;
190}
191
192/* --Methode-- */
193void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
194{
195 int rank = ckR8.CheckResize(in, out);
196 if (rank == 1) { // One dimensional transform
197 if (_p1db) _p1db->Recreate(in.Size());
198 else _p1db = new FFTWServerPlan(in.Size(), FFTW_BACKWARD, false);
199 fftw_one(_p1db->p, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
200 }
201 else { // Multi dimensional
202 if (in.NbDimensions() > MAXND_FFTW)
203 throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !");
204 int sz[MAXND_FFTW];
205 int k1 = 0;
206 int k2 = 0;
207 for(k1=in.NbDimensions()-1; k1>=0; k1--) {
208 sz[k2] = in.Size(k1); k2++;
209 }
210 if (_pndb) _pndb->Recreate(in.NbDimensions(), sz);
211 else _pndb = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_BACKWARD, false);
212 }
213 // $CHECK$ Reza 9/2/2001 , Verifier normalisation
214 if(this->getNormalize()) out=out/complex<r_8>(sqrt((double)in.Size()),0.);
215 return;
216}
217
218
219void FFTWServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
220{
221 int rank = ckR8.CheckResize(in, out);
222 TArray<r_8> outtemp(in, false);
223
224 if (rank == 1) { // One dimensional transform
225 if (_p1drf) _p1drf->Recreate(in.Size());
226 else _p1drf = new FFTWServerPlan(in.Size(), FFTW_REAL_TO_COMPLEX, true);
227 rfftw_one(_p1drf->rp, (fftw_real *)(in.Data()) , (fftw_real *)(outtemp.Data()));
228 ReShapetoCompl(outtemp, out);
229 }
230 else { // Multi dimensional
231 if (in.NbDimensions() > MAXND_FFTW)
232 throw ParmError("FFTWServer::FFTForward( complex<r_8>, complex<r_8> ) rank > MAXND_FFTW !");
233 int sz[MAXND_FFTW];
234 int k1 = 0;
235 int k2 = 0;
236 for(k1=in.NbDimensions()-1; k1>=0; k1--) {
237 sz[k2] = in.Size(k1); k2++;
238 }
239 if (_pndrf) _pndrf->Recreate(in.NbDimensions(), sz);
240 else _pndrf = new FFTWServerPlan(in.NbDimensions(), sz, FFTW_REAL_TO_COMPLEX, true);
241 rfftwnd_one_real_to_complex(_pndrf->rpnd, (fftw_real *)(in.Data()) ,
242 (fftw_complex *)(out.Data()) );
243 }
244 // $CHECK$ Reza 9/2/2001 , Verifier normalisation
245 if(this->getNormalize()) out=out/complex<r_8>(sqrt((double)in.Size()),0.);
246 return;
247
248}
249
250
251
252void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out)
253{
254 throw ParmError("FFTWServer::FFTBackward(TArray< complex<r_8> > ... Not implemented ... !");
255 /*
256 int size;
257 if(in(in.NElts()).imag() == 0) { size = 2*in.NElts()-2;}
258 else { size = 2*in.NElts()-1;}
259
260 TArray< r_8 > inTemp(size);
261 out.ReSize(size);
262
263 if (_p1drb) _p1drb->Recreate(size);
264 else _p1drb = new FFTWServerPlan(size, FFTW_COMPLEX_TO_REAL, true);
265
266 ReShapetoReal(in, inTemp);
267 rfftw_one(_p1drb->rp, (fftw_real *)(inTemp.Data()) , (fftw_real *)(out.Data()));
268 if(this->getNormalize()) out=out/pow(size,0.5);
269 */
270}
271
272/*
273void FFTWServer::FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
274{
275 out.ReSize(in.NRows(),in.NCols());
276
277 if (_pndf) _pndf->Recreate( in.NRows(),in.NCols());
278 else _pndf = new FFTWServerPlan( in.NCols(),in.NRows(), FFTW_FORWARD, false);
279
280 fftwnd_one(_pndf->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
281 if(this->getNormalize()) out=out/complex<r_8>(pow(in.NRows()*in.NCols(),0.5),0.);
282}
283
284void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
285{
286 if (_pndb) _pndb->Recreate(in.NCols(), in.NRows());
287 else _pndb = new FFTWServerPlan(in.NCols(), in.NRows(), FFTW_BACKWARD, false);
288 out.ReSize(in.NRows(), in.NCols());
289 fftwnd_one(_pndb->pnd, (fftw_complex *)(in.Data()) , (fftw_complex *)(out.Data()) );
290 if(this->getNormalize()) out=out/complex<r_8>(pow(in.NRows()*in.NCols(),0.5),0.);
291
292}
293
294
295void FFTWServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
296{
297
298 TArray< r_8 > inNew(in.NCols(),in.NRows());
299 for(int i=0; i<in.NRows(); i++)
300 for(int j=0;j<in.NCols(); j++)
301 inNew(j,i) = in(i,j);
302
303 if (_pndrf) _pndrf->Recreate(inNew.NRows(),inNew.NCols());
304 else _pndrf = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_REAL_TO_COMPLEX, true);
305 // rfftwnd_plan p;
306 TArray< complex<r_8> > outTemp;
307 outTemp.ReSize(in.NRows(),in.NCols());
308
309 rfftwnd_one_real_to_complex(_pndrf->rpnd, (fftw_real *)(in.Data()) , (fftw_complex *)(out.Data()) );
310}
311
312void FFTWServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out)
313{
314
315 TArray< complex<r_8> > inNew(in.NCols(),in.NRows());
316 for(int i=0; i<in.NRows(); i++)
317 for(int j=0;j<in.NCols(); j++)
318 inNew(j,i) = in(i,j);
319
320 if (_pndrb) _pndrb->Recreate(inNew.NRows(),inNew.NCols());
321 else _pndrb = new FFTWServerPlan(inNew.NRows(), inNew.NCols(),FFTW_COMPLEX_TO_REAL, true);
322 // rfftwnd_plan p;
323 out.ReSize(in.NRows(),in.NCols());
324
325 rfftwnd_one_complex_to_real(_pndrb->rpnd, (fftw_complex *)(in.Data()) , (fftw_real *)(out.Data()) );
326 cout << " in the function !!!" << endl;
327 if(this->getNormalize())
328 {
329 r_8 norm = (r_8)(in.NRows()*in.NCols());
330 out=out/norm;
331 }
332}
333
334*/
335
336
337/* --Methode-- */
338void FFTWServer::ReShapetoReal( TArray< complex<r_8> > const & in, TArray< r_8 > & out)
339{
340 int N = in.Size();
341 /*
342 int i;
343 if (in(in.Size()).imag() == 0)
344 {
345 out(0) = in(0).real();
346 for(i=1; i<in.NElts(); i++)
347 {
348 out(i) = in(i).real();
349 }
350 for(i=1; i<in.NElts(); i++)
351 {
352 out(i+in.NElts()-1) = in(in.NElts()-i-1).imag();
353 }
354 }
355 else
356 {
357 out(0) = in(0).real();
358 for(i=1; i<in.NElts(); i++)
359 {
360 out(i) = in(i).real();
361 }
362 for(i=1; i<in.NElts(); i++)
363 {
364 out(i+in.NElts()-1) = in(in.NElts()-i).imag();
365 }
366 }
367 */
368 out[0] = in[0].real();
369 int k=0;
370 for(int i=1; i<N; i++) {
371 out[i] = in[i].real();
372 out[N-i] = in[i].imag();
373 }
374
375 // for(int k=0; k<out.NElts(); k++) cout << "ReShapetoReal out " << k << " " << out(k) << endl;
376}
377
378
379/* --Methode-- */
380void FFTWServer::ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
381{
382 int N = in.Size();
383 // for(int k=0; k<in.NElts(); k++) cout << "ReShapetoCompl in " << k << " " << in(k) << endl;
384 out[0] = complex<r_8> (in[0],0.);
385 for(int k=1; k<N+1/2; k++)
386 out[k] = complex<r_8>(in[k], in[N-k]);
387 if (N%2 == 0) out[N/2] = complex<r_8>(in[N/2], 0.);
388 // for(int k=0; k<out.NElts(); k++) cout << "ReShapetoCompl out " << k << " " << out(k) << endl;
389}
390
Note: See TracBrowser for help on using the repository browser.