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
RevLine 
[717]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")
[1394]9 , ckR4("FFTMayerServer: ", true, true) , ckR8("FFTMayerServer: ", true, true)
[717]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-- */
[1394]27void FFTMayerServer::FFTForward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
[717]28{
[1394]29 ckR8.CheckResize(ina, outa);
30 TVector< complex<r_8> > in(ina);
31 TVector< complex<r_8> > out(outa);
32
[717]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
[1394]62 // out.ReSize(in.NElts());
[717]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-- */
[1394]73void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< complex<r_8> > & outa)
[717]74{
[1394]75 ckR8.CheckResize(ina, outa);
76 TVector< complex<r_8> > in(ina);
77 TVector< complex<r_8> > out(outa);
78
[717]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
[1394]98 // out.ReSize(in.NElts());
[717]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-- */
[1394]113void FFTMayerServer::FFTForward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
[717]114{
[1394]115 ckR4.CheckResize(ina, outa);
116 TVector< complex<r_4> > in(ina);
117 TVector< complex<r_4> > out(outa);
118
[717]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
[1394]148 // out.ReSize(in.NElts());
[717]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-- */
[1394]160void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< complex<r_4> > & outa)
[717]161{
[1394]162 ckR4.CheckResize(ina, outa);
163 TVector< complex<r_4> > in(ina);
164 TVector< complex<r_4> > out(outa);
165
[717]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
[1394]186 // out.ReSize(in.NElts());
[717]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-- */
[1394]201void FFTMayerServer::FFTForward(TArray< r_4 > const & ina, TArray< complex<r_4> > & outa)
[717]202{
[1394]203 ckR4.CheckResize(ina, outa);
204 TVector< r_4 > in(ina);
205 TVector< complex<r_4> > out(outa);
206
[805]207 r_4 a,b;
[717]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
[1394]228 // out.ReSize(n/2+1);
[717]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-- */
[1394]248void FFTMayerServer::FFTBackward(TArray< complex<r_4> > const & ina, TArray< r_4 > & outa)
[717]249{
[1394]250 ckR4.CheckResize(ina, outa);
251 TVector< complex<r_4> > in(ina);
252 TVector< r_4 > out(outa);
253
[805]254 r_4 a,b;
[717]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
[1394]265 // out.ReSize(nc);
[717]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-- */
[1394]294void FFTMayerServer::FFTForward(TArray< r_8 > const & ina, TArray< complex<r_8> > & outa)
[717]295{
[1394]296 ckR8.CheckResize(ina, outa);
297 TVector< r_8 > in(ina);
298 TVector< complex<r_8> > out(outa);
299
[805]300 r_8 a,b;
[717]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
[1394]321 // out.ReSize(n/2+1);
[717]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-- */
[1394]340void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa)
[717]341{
[1394]342 ckR8.CheckResize(ina, outa);
343 TVector< r_8 > out(outa);
344 TVector< complex<r_8> > in(ina);
345
[805]346 r_8 a,b;
[717]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
[1394]357 // out.ReSize(nc);
[717]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.