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

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

Adaptation aux modifications de TArray<T>/TVector<T> - linfit.cc integre
a TArray/sopemtx.cc - Reza 03/04/2000

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