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

Last change on this file since 3195 was 2615, checked in by cmv, 21 years ago

using namespace sophya enleve de machdefs.h, nouveau sopnamsp.h cmv 10/09/2004

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