source: Sophya/trunk/SophyaLib/NTools/fftmserver.cc@ 1394

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

Changement interface FFTServer - Reza 12/2/2001

File size: 9.7 KB
Line 
1#include "fftmserver.h"
2#include <iostream.h>
3#include "fftmayer.h"
4
5
6/* --Methode-- */
7FFTMayerServer::FFTMayerServer()
8 : FFTServerInterface("FFTMayerServer using extended FFTMayer package")
9 , ckR4("FFTMayerServer: ", true, true) , ckR8("FFTMayerServer: ", true, true)
10
11{
12}
13
14/* --Methode-- */
15FFTMayerServer::~FFTMayerServer()
16{
17}
18
19/* --Methode-- */
20FFTServerInterface * FFTMayerServer::Clone()
21{
22 return (new FFTMayerServer);
23}
24
25
26/* --Methode-- */
27void FFTMayerServer::FFTForward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
28{
29 ckR8.CheckResize(ina, outa);
30 TVector< complex<r_8> > in(ina);
31 TVector< complex<r_8> > out(outa);
32
33 r_8 a,b,c,d;
34 r_8 q,r,s,t;
35 int i,j,k;
36 int n = in.NElts();
37 if (checkLength(n)) {
38 char buff[256];
39 sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
40 n, __FILE__,__LINE__);
41 throw ParmError(string(buff));
42 }
43 TVector< r_8 > inoutre(n);
44 TVector< r_8 > inoutim(n);
45 inoutre(0) = in(0).real();
46 inoutim(0) = in(0).imag();
47 inoutre(n/2) = in(n/2).real();
48 inoutim(n/2) = in(n/2).imag();
49 if (n > 2) {
50 inoutre(n/2+1) = in(n/2).real();
51 inoutim(n/2+1) = in(n/2).imag();
52 }
53 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
54 a = in(i).real(); b = in(j).real(); q=a+b; r=a-b;
55 c = in(i).imag(); d = in(j).imag(); s=c+d; t=c-d;
56 inoutre(i) = (q+t)*.5; inoutre(j) = (q-t)*.5;
57 inoutim(i) = (s-r)*.5; inoutim(j) = (s+r)*.5;
58 }
59 fht_r8(inoutre.Data(),inoutre.NElts());
60 fht_r8(inoutim.Data(),inoutim.NElts());
61
62 // out.ReSize(in.NElts());
63 r_8 fn = 1./n;
64 if (getNormalize())
65 for(k=0; k<out.NElts(); k++)
66 out(k) = complex<r_8>(inoutre(k)*fn, inoutim(k)*fn);
67 else
68 for(k=0; k<out.NElts(); k++)
69 out(k) = complex<r_8>(inoutre(k), inoutim(k));
70}
71
72/* --Methode-- */
73void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
74{
75 ckR8.CheckResize(ina, outa);
76 TVector< complex<r_8> > in(ina);
77 TVector< complex<r_8> > out(outa);
78
79 r_8 a,b,c,d;
80 r_8 q,r,s,t;
81 int i,j,k;
82 int n = in.NElts();
83 if (checkLength(n)) {
84 char buff[256];
85 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
86 n, __FILE__,__LINE__);
87 throw ParmError(string(buff));
88 }
89 TVector< r_8 > inoutre(n);
90 TVector< r_8 > inoutim(n);
91 for(k=0; k<out.NElts(); k++) {
92 inoutre(k) = in(k).real();
93 inoutim(k) = in(k).imag();
94 }
95 fht_r8(inoutre.Data(),inoutre.NElts());
96 fht_r8(inoutim.Data(),inoutim.NElts());
97
98 // out.ReSize(in.NElts());
99 out(0) = complex<r_8>(inoutre(0), inoutim(0));
100 out(n/2) = complex<r_8>(inoutre(n/2), inoutim(n/2));
101 if (n > 2) out(n/2+1) = complex<r_8>(inoutre(n/2+1), inoutim(n/2+1));
102
103 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
104 a = inoutre(i); b = inoutre(j); q=a+b; r=a-b;
105 c = inoutim(i); d = inoutim(j); s=c+d; t=c-d;
106 out(i) = complex<r_8>( (q-t)*0.5 , (s+r)*0.5 );
107 out(j) = complex<r_8>( (q+t)*0.5 , (s-r)*0.5 );
108 }
109
110}
111
112/* --Methode-- */
113void FFTMayerServer::FFTForward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
114{
115 ckR4.CheckResize(ina, outa);
116 TVector< complex<r_4> > in(ina);
117 TVector< complex<r_4> > out(outa);
118
119 r_4 a,b,c,d;
120 r_4 q,r,s,t;
121 int i,j,k;
122 int n = in.NElts();
123 if (checkLength(n)) {
124 char buff[256];
125 sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
126 n, __FILE__,__LINE__);
127 throw ParmError(string(buff));
128 }
129 TVector< r_4 > inoutre(n);
130 TVector< r_4 > inoutim(n);
131 inoutre(0) = in(0).real();
132 inoutim(0) = in(0).imag();
133 inoutre(n/2) = in(n/2).real();
134 inoutim(n/2) = in(n/2).imag();
135 if (n > 2) {
136 inoutre(n/2+1) = in(n/2).real();
137 inoutim(n/2+1) = in(n/2).imag();
138 }
139 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
140 a = in(i).real(); b = in(j).real(); q=a+b; r=a-b;
141 c = in(i).imag(); d = in(j).imag(); s=c+d; t=c-d;
142 inoutre(i) = (q+t)*.5; inoutre(j) = (q-t)*.5;
143 inoutim(i) = (s-r)*.5; inoutim(j) = (s+r)*.5;
144 }
145 fht_r4(inoutre.Data(),inoutre.NElts());
146 fht_r4(inoutim.Data(),inoutim.NElts());
147
148 // out.ReSize(in.NElts());
149 r_4 fn = 1./n;
150 if (getNormalize())
151 for(k=0; k<out.NElts(); k++)
152 out(k) = complex<r_4>(inoutre(k)*fn, inoutim(k)*fn);
153 else
154 for(k=0; k<out.NElts(); k++)
155 out(k) = complex<r_4>(inoutre(k), inoutim(k));
156
157}
158
159/* --Methode-- */
160void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
161{
162 ckR4.CheckResize(ina, outa);
163 TVector< complex<r_4> > in(ina);
164 TVector< complex<r_4> > out(outa);
165
166 r_4 a,b,c,d;
167 r_4 q,r,s,t;
168 int i,j,k;
169 int n = in.NElts();
170 if (checkLength(n)) {
171 char buff[256];
172 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
173 n, __FILE__,__LINE__);
174 throw ParmError(string(buff));
175 }
176
177 TVector< r_4 > inoutre(n);
178 TVector< r_4 > inoutim(n);
179 for(k=0; k<out.NElts(); k++) {
180 inoutre(k) = in(k).real();
181 inoutim(k) = in(k).imag();
182 }
183 fht_r4(inoutre.Data(),inoutre.NElts());
184 fht_r4(inoutim.Data(),inoutim.NElts());
185
186 // out.ReSize(in.NElts());
187 out(0) = complex<r_4>(inoutre(0), inoutim(0));
188 out(n/2) = complex<r_4>(inoutre(n/2), inoutim(n/2));
189 if (n > 2) out(n/2+1) = complex<r_4>(inoutre(n/2+1), inoutim(n/2+1));
190
191 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
192 a = inoutre(i); b = inoutre(j); q=a+b; r=a-b;
193 c = inoutim(i); d = inoutim(j); s=c+d; t=c-d;
194 out(i) = complex<r_4>( (q-t)*0.5 , (s+r)*0.5 );
195 out(j) = complex<r_4>( (q+t)*0.5 , (s-r)*0.5 );
196 }
197
198}
199
200/* --Methode-- */
201void FFTMayerServer::FFTForward(TArray< r_4 > const & ina, TArray< complex<r_4> > & outa)
202{
203 ckR4.CheckResize(ina, outa);
204 TVector< r_4 > in(ina);
205 TVector< complex<r_4> > out(outa);
206
207 r_4 a,b;
208 int i,j,k;
209 int n = in.NElts();
210 if (checkLength(n)) {
211 char buff[256];
212 sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
213 n, __FILE__,__LINE__);
214 throw ParmError(string(buff));
215 }
216
217 TVector< r_4 > inout(in);
218 fht_r4(inout.Data(),inout.NElts());
219 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
220 a = inout(i);
221 b = inout(j);
222 inout(j) = (a-b)*0.5;
223 inout(i) = (a+b)*0.5;
224 out(i) = complex<r_4>( (a+b)*0.5 , (a-b)*0.5 );
225 }
226
227
228 // out.ReSize(n/2+1);
229 out(0) = complex<r_4>(inout(0), 0.);
230
231 if (n%2 == 0) { // n pair
232 for (i=1,j=n/2+1; i<n/2; i++,j++)
233 out(i) = complex<r_4>(inout(i), inout(j));
234
235 out(n/2) = complex<r_4>(inout(n/2), 0.);
236 }
237 else { // n impair
238 for (i=1,j=n/2+2; i<n/2; i++,j++)
239 out(i) = complex<r_4>(inout(i), inout(j));
240
241 out(n/2) = complex<r_4>(inout(n/2), inout(n/2+1));
242 }
243
244 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
245}
246
247/* --Methode-- */
248void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< r_4 > & outa)
249{
250 ckR4.CheckResize(ina, outa);
251 TVector< complex<r_4> > in(ina);
252 TVector< r_4 > out(outa);
253
254 r_4 a,b;
255 int i,j,k;
256 int n = in.NElts();
257 int nc = (fabs(in(n-1).imag()) < 1.e-9) ? nc = n*2-2 : nc = n*2-1;
258 if (checkLength(nc)) {
259 char buff[256];
260 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
261 nc, __FILE__,__LINE__);
262 throw ParmError(string(buff));
263 }
264
265 // out.ReSize(nc);
266 out(0) = in(0).real();
267 if (nc%2 == 0) { // nc pair
268 for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
269 out(i) = in(i).real();
270 out(j) = in(i).imag();
271 }
272 out(nc/2) = in(nc/2).real();
273 }
274 else { // nc impair
275 for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
276 out(i) = in(i).real();
277 out(j) = in(i).imag();
278 }
279 out(nc/2) = in(nc/2).real();
280 out(nc/2+1) = in(nc/2).imag();
281 }
282
283 for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
284 a = out(i);
285 b = out(j);
286 out(j) = (a-b);
287 out(i) = (a+b);
288 }
289 fht_r4(out.Data(),out.NElts());
290}
291
292
293/* --Methode-- */
294void FFTMayerServer::FFTForward(TArray< r_8 > const & ina, TArray< complex<r_8> > & outa)
295{
296 ckR8.CheckResize(ina, outa);
297 TVector< r_8 > in(ina);
298 TVector< complex<r_8> > out(outa);
299
300 r_8 a,b;
301 int i,j,k;
302 int n = in.NElts();
303 if (checkLength(n)) {
304 char buff[256];
305 sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
306 n, __FILE__,__LINE__);
307 throw ParmError(string(buff));
308 }
309
310 TVector< r_8 > inout(in);
311 fht_r8(inout.Data(),inout.NElts());
312 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
313 a = inout(i);
314 b = inout(j);
315 inout(j) = (a-b)*0.5;
316 inout(i) = (a+b)*0.5;
317 out(i) = complex<r_8>( (a+b)*0.5 , (a-b)*0.5 );
318 }
319
320
321 // out.ReSize(n/2+1);
322 out(0) = complex<r_8>(inout(0), 0.);
323
324 if (n%2 == 0) { // n pair
325 for (i=1,j=n/2+1; i<n/2; i++,j++)
326 out(i) = complex<r_8>(inout(i), inout(j));
327
328 out(n/2) = complex<r_8>(inout(n/2), 0.);
329 }
330 else { // n impair
331 for (i=1,j=n/2+2; i<n/2; i++,j++)
332 out(i) = complex<r_8>(inout(i), inout(j));
333
334 out(n/2) = complex<r_8>(inout(n/2), inout(n/2+1));
335 }
336 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
337}
338
339/* --Methode-- */
340void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa)
341{
342 ckR8.CheckResize(ina, outa);
343 TVector< r_8 > out(outa);
344 TVector< complex<r_8> > in(ina);
345
346 r_8 a,b;
347 int i,j,k;
348 int n = in.NElts();
349 int nc = (fabs(in(n-1).imag()) < 1.e-18) ? nc = n*2-2 : nc = n*2-1;
350 if (checkLength(nc)) {
351 char buff[256];
352 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
353 nc, __FILE__,__LINE__);
354 throw ParmError(string(buff));
355 }
356
357 // out.ReSize(nc);
358 out(0) = in(0).real();
359 if (nc%2 == 0) { // nc pair
360 for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
361 out(i) = in(i).real();
362 out(j) = in(i).imag();
363 }
364 out(nc/2) = in(nc/2).real();
365 }
366 else { // nc impair
367 for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
368 out(i) = in(i).real();
369 out(j) = in(i).imag();
370 }
371 out(nc/2) = in(nc/2).real();
372 out(nc/2+1) = in(nc/2).imag();
373 }
374
375 for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
376 a = out(i);
377 b = out(j);
378 out(j) = (a-b);
379 out(i) = (a+b);
380 }
381 fht_r8(out.Data(),out.NElts());
382}
383
384
385
386/* --Methode-- */
387bool FFTMayerServer::checkLength(int n)
388{
389 if (n < 2) return(true);
390 int nc = n;
391 while (nc > 1) {
392 if (nc%2 != 0) return(true);
393 nc /= 2;
394 }
395 return(false);
396}
Note: See TracBrowser for help on using the repository browser.