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

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

Modifs FFTServerInterface + FFTPackServer (Suite - Fin ?) - Reza 13/2/2001

File size: 9.8 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 bool usoutsz)
250{
251 ckR4.CheckResize(ina, outa);
252 TVector< complex<r_4> > in(ina);
253 TVector< r_4 > out(outa);
254
255 r_4 a,b;
256 int i,j,k;
257 int n = in.NElts();
258 int nc = (fabs(in(n-1).imag()) < 1.e-9) ? nc = n*2-2 : nc = n*2-1;
259 if (checkLength(nc)) {
260 char buff[256];
261 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
262 nc, __FILE__,__LINE__);
263 throw ParmError(string(buff));
264 }
265
266 // out.ReSize(nc);
267 out(0) = in(0).real();
268 if (nc%2 == 0) { // nc pair
269 for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
270 out(i) = in(i).real();
271 out(j) = in(i).imag();
272 }
273 out(nc/2) = in(nc/2).real();
274 }
275 else { // nc impair
276 for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
277 out(i) = in(i).real();
278 out(j) = in(i).imag();
279 }
280 out(nc/2) = in(nc/2).real();
281 out(nc/2+1) = in(nc/2).imag();
282 }
283
284 for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
285 a = out(i);
286 b = out(j);
287 out(j) = (a-b);
288 out(i) = (a+b);
289 }
290 fht_r4(out.Data(),out.NElts());
291}
292
293
294/* --Methode-- */
295void FFTMayerServer::FFTForward(TArray< r_8 > const & ina, TArray< complex<r_8> > & outa)
296{
297 ckR8.CheckResize(ina, outa);
298 TVector< r_8 > in(ina);
299 TVector< complex<r_8> > out(outa);
300
301 r_8 a,b;
302 int i,j,k;
303 int n = in.NElts();
304 if (checkLength(n)) {
305 char buff[256];
306 sprintf(buff, "FFTMayerServer::FFTForward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
307 n, __FILE__,__LINE__);
308 throw ParmError(string(buff));
309 }
310
311 TVector< r_8 > inout(in);
312 fht_r8(inout.Data(),inout.NElts());
313 for (i=1,j=n-1,k=n/2;i<k;i++,j--) {
314 a = inout(i);
315 b = inout(j);
316 inout(j) = (a-b)*0.5;
317 inout(i) = (a+b)*0.5;
318 out(i) = complex<r_8>( (a+b)*0.5 , (a-b)*0.5 );
319 }
320
321
322 // out.ReSize(n/2+1);
323 out(0) = complex<r_8>(inout(0), 0.);
324
325 if (n%2 == 0) { // n pair
326 for (i=1,j=n/2+1; i<n/2; i++,j++)
327 out(i) = complex<r_8>(inout(i), inout(j));
328
329 out(n/2) = complex<r_8>(inout(n/2), 0.);
330 }
331 else { // n impair
332 for (i=1,j=n/2+2; i<n/2; i++,j++)
333 out(i) = complex<r_8>(inout(i), inout(j));
334
335 out(n/2) = complex<r_8>(inout(n/2), inout(n/2+1));
336 }
337 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
338}
339
340/* --Methode-- */
341void FFTMayerServer::FFTBackward(TArray< complex<r_8> > const & ina, TArray< r_8 > & outa,
342 bool usoutsz)
343{
344 ckR8.CheckResize(ina, outa);
345 TVector< r_8 > out(outa);
346 TVector< complex<r_8> > in(ina);
347
348 r_8 a,b;
349 int i,j,k;
350 int n = in.NElts();
351 int nc = (fabs(in(n-1).imag()) < 1.e-18) ? nc = n*2-2 : nc = n*2-1;
352 if (checkLength(nc)) {
353 char buff[256];
354 sprintf(buff, "FFTMayerServer::FFTBackward/Error Size(%d) != 2^n ! (File=%s Line=%d)",
355 nc, __FILE__,__LINE__);
356 throw ParmError(string(buff));
357 }
358
359 // out.ReSize(nc);
360 out(0) = in(0).real();
361 if (nc%2 == 0) { // nc pair
362 for (i=1,j=nc/2+1; i<nc/2; i++,j++) {
363 out(i) = in(i).real();
364 out(j) = in(i).imag();
365 }
366 out(nc/2) = in(nc/2).real();
367 }
368 else { // nc impair
369 for (i=1,j=nc/2+2; i<nc/2; i++,j++) {
370 out(i) = in(i).real();
371 out(j) = in(i).imag();
372 }
373 out(nc/2) = in(nc/2).real();
374 out(nc/2+1) = in(nc/2).imag();
375 }
376
377 for (i=1,j=nc-1,k=nc/2;i<k;i++,j--) {
378 a = out(i);
379 b = out(j);
380 out(j) = (a-b);
381 out(i) = (a+b);
382 }
383 fht_r8(out.Data(),out.NElts());
384}
385
386
387
388/* --Methode-- */
389bool FFTMayerServer::checkLength(int n)
390{
391 if (n < 2) return(true);
392 int nc = n;
393 while (nc > 1) {
394 if (nc%2 != 0) return(true);
395 nc /= 2;
396 }
397 return(false);
398}
Note: See TracBrowser for help on using the repository browser.