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

Last change on this file since 825 was 765, checked in by ansari, 26 years ago

Reorganisation - Creation du module ExtLib/IFFTW (FFTWServer) - Reza 2/3/2000

File size: 8.5 KB
Line 
1#include "fftwserver.h"
2#include "FFTW/fftw.h"
3#include "FFTW/rfftw.h"
4
5class FFTWServerPlan{
6public:
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
24FFTWServerPlan::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}
38FFTWServerPlan::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
56FFTWServerPlan::~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
64void
65FFTWServerPlan::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
83void
84FFTWServerPlan::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-- */
108FFTWServer::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-- */
124FFTWServer::~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-- */
138FFTServerInterface * FFTWServer::Clone()
139{
140 return (new FFTWServer) ;
141}
142
143/* --Methode-- */
144void
145FFTWServer::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-- */
154void 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
165void 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
183void 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-- */
201void 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-- */
213void 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-- */
225void 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);
235 rfftwnd_plan p;
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-- */
243void 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);
253 rfftwnd_plan p;
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-- */
267void FFTWServer::ReShapetoReal( TVector< complex<double> > const & in, TVector< double > & out)
268{
269 int N = in.NElts();
270 if (in(in.NElts()).imag() == 0)
271 {
272 out(0) = in(0).real();
273 for(int i=1; i<in.NElts(); i++)
274 {
275 out(i) = in(i).real();
276 }
277 for(int i=1; i<in.NElts(); i++)
278 {
279 out(i+in.NElts()-1) = in(in.NElts()-i-1).imag();
280 }
281 }
282 else
283 {
284 out(0) = in(0).real();
285 for(int i=1; i<in.NElts(); i++)
286 {
287 out(i) = in(i).real();
288 }
289 for(int i=1; i<in.NElts(); i++)
290 {
291 out(i+in.NElts()-1) = in(in.NElts()-i).imag();
292 }
293 }
294 // for(int k=0; k<out.NElts(); k++) cout << "ReShapetoReal out " << k << " " << out(k) << endl;
295}
296
297
298/* --Methode-- */
299void FFTWServer::ReShapetoCompl(TVector< double > const & in, TVector< complex<double> > & out)
300{
301 int N = in.NElts();
302 // for(int k=0; k<in.NElts(); k++) cout << "ReShapetoCompl in " << k << " " << in(k) << endl;
303 out(0) = complex<double> (in(0),0.);
304 if(in.NElts()%2 !=0)
305 {
306 for(int k=1;k<=N/2+1;k++)
307 {
308 out(k) = complex<double> (in(k),in(N-k));
309 }
310 }
311 else
312 {
313 for(int k=1;k<N/2;k++)
314 {
315 out(k) = complex<double> (in(k),in(N-k));
316 }
317 out(N/2) = complex<double> (in(N/2),0.);
318 }
319 // for(int k=0; k<out.NElts(); k++) cout << "ReShapetoCompl out " << k << " " << out(k) << endl;
320}
321
Note: See TracBrowser for help on using the repository browser.