source: Sophya/trunk/SophyaLib/NTools/fftpserver.cc@ 1242

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

Documentation- namespace, utils.cc mis ds SysTools - Reza 12/4/2000

File size: 8.0 KB
Line 
1#include "fftpserver.h"
2#include "fftpackc.h"
3
4#include <iostream.h>
5
6
7/*!
8\class SOPHYA::FFTPackServer
9A class that calculates Fourier transforms forwards and backwards.
10
11The class calls the c library ``fftpack'', which is accessible and documented
12at http://www.netlib.org/fftpack/. However, the class functions do not
13necessarily correspond with the equivalent fftpack function. For example,
14fftpack "forward" transformations are in fact inverse fourier transformations.
15Otherwise, the output is in the fftpack format.
16
17
18Due to the way that fftpack manages
19its work arrays, an object can run faster if the length of the input arrays
20does not change. For example, if you need to do a series of FFT's
21of differing length, it may be more efficient to create an fftserver object
22for each length.
23*/
24
25/* \fn virtual void FFTServer::fftf(int l, r_4* inout)
26 \param l length of array
27 \param inout input array /output forward FFT (original array destroyed)
28*/
29/*! \fn virtual void FFTServer::fftb(int l, r_4* inout)
30 \param l length of array
31 \param inout input array /output backward FFT (original array destroyed)
32*/
33/* \fn virtual void FFTServer::fftf(int l, r_8* inout)
34 \param l length of array
35 \param inout input array /output forward FFT (original array destroyed)
36 \param inout input/output array (original array destroyed)
37*/
38/* \fn virtual void FFTServer::fftb(int l, r_8* inout)
39 \param l length of array
40 \param inout input array /output backward FFT(original array destroyed)
41*/
42/*\fn virtual void FFTServer::fftf(int l, complex<r_4>* inout)
43 \param l length of array
44 \param inout input array /output forward FFT (original array destroyed)
45*/
46/* \fn virtual void FFTServer::fftb(int l, complex<r_4>* inout)
47 \param l length of array
48 \param inout input array /output backward FFT (original array destroyed)
49*/
50/* \fn virtual void FFTServer::fftf(int l, complex<r_8>* inout)
51 \param l length of array
52 \param inout input array /output forward FFT (original array destroyed)
53*/
54/* \fn virtual void FFTServer::fftb(int l, complex<r_8>* inout)
55 \param l length of array
56 \param inout input array /output backward FFT(original array destroyed)
57*/
58/*\fn virtual void FFTServer::fftf(Vector& in, Vector& out)
59 \param in input array
60 \param out forward FFT
61*/
62/* \fn virtual void FFTServer::fftb(Vector& in, Vector& out)
63 \param in input array
64 \param out backward FFT
65*/
66
67FFTPackServer::FFTPackServer()
68 : FFTServerInterface("FFTPackServer using extended FFTPack (C-version) package")
69
70{
71 sz_rfft = 0; //the working array and its size for the different
72 ws_rfft = NULL; //possible numerical types
73 sz_cfft = 0;
74 ws_cfft = NULL;
75 sz_cdfft = 0;
76 ws_cdfft = NULL;
77}
78
79FFTPackServer::~FFTPackServer()
80{
81if (ws_rfft) delete[] ws_rfft;
82if (ws_cfft) delete[] ws_cfft;
83if (ws_cdfft) delete[] ws_cdfft;
84}
85
86FFTServerInterface * FFTPackServer::Clone()
87{
88 return (new FFTPackServer);
89}
90
91
92void FFTPackServer::FFTForward(TVector< complex<r_8> > const & in, TVector< complex<r_8> > & out)
93{
94 out = in;
95 fftf(out.NElts(), out.Data());
96 if (getNormalize()) out *= (1./(r_8)(in.NElts()));
97}
98
99void FFTPackServer::FFTBackward(TVector< complex<r_8> > const & in, TVector< complex<r_8> > & out)
100{
101 out = in;
102 fftb(out.NElts(), out.Data());
103}
104
105
106
107void FFTPackServer::FFTForward(TVector< complex<r_4> > const & in, TVector< complex<r_4> > & out)
108{
109 out = in;
110 fftf(out.NElts(), out.Data());
111 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
112}
113
114void FFTPackServer::FFTBackward(TVector< complex<r_4> > const & in, TVector< complex<r_4> > & out)
115{
116 out = in;
117 fftb(out.NElts(), out.Data());
118}
119
120void FFTPackServer::FFTForward(TVector< r_4 > const & in, TVector< complex<r_4> > & out)
121{
122 TVector< r_4 > inout(in);
123 fftf(inout.NElts(), inout.Data());
124 ReShapetoCompl(inout, out);
125 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
126}
127
128void FFTPackServer::FFTBackward(TVector< complex<r_4> > const & in, TVector< r_4 > & out)
129{
130 ReShapetoReal(in, out);
131 fftb(out.NElts(), out.Data());
132}
133
134
135void FFTPackServer::FFTForward(TVector< r_8 > const & in, TVector< complex<r_8> > & out)
136{
137 TVector< r_8 > inout(in);
138 fftf(inout.NElts(), inout.Data());
139 ReShapetoCompl(inout, out);
140 if (getNormalize()) out *= (1./(r_8)(in.NElts()));
141}
142
143void FFTPackServer::FFTBackward(TVector< complex<r_8> > const & in, TVector< r_8 > & out)
144{
145 ReShapetoReal(in, out);
146 fftb(out.NElts(), out.Data());
147}
148
149
150
151void FFTPackServer::checkint_rfft(int_4 l)
152{
153 if (sz_rfft == l) return; //checkint functions check and reallocate
154 //memory for the work arrays when performing
155 if (ws_rfft) delete[] ws_rfft; //a transform
156 sz_rfft = l;
157 ws_rfft = new r_4[2*l+15];
158 rffti_(&l, ws_rfft);
159}
160
161void FFTPackServer::checkint_cfft(int_4 l)
162{
163 if (sz_cfft == l) return;
164
165 if (ws_cfft) delete[] ws_cfft;
166 sz_cfft = l;
167 ws_cfft = new r_4[4*l+15];
168 cffti_(&l, ws_cfft);
169}
170
171void FFTPackServer::checkint_dfft(int_4 l)
172{
173 if (sz_dfft == l) return;
174
175 if (ws_dfft) delete[] ws_dfft;
176 sz_dfft = l;
177 ws_dfft = new r_8[2*l+15];
178 dffti_(&l, ws_dfft);
179}
180
181void FFTPackServer::checkint_cdfft(int_4 l)
182{
183 if (sz_cdfft == l) return;
184
185 if (ws_cdfft) delete[] ws_cdfft;
186 sz_cdfft = l;
187 ws_cdfft = new r_8[4*l+15];
188 cdffti_(&l, ws_cdfft);
189}
190
191/* In general forward transformations are resorted since fftpack functions
192 return inverse transformations */
193
194void FFTPackServer::fftf(int_4 l, r_4* inout)
195{
196 checkint_rfft(l);
197 rfftf_(&l, inout, ws_rfft);
198 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
199}
200
201void FFTPackServer::fftf(int_4 l, r_8* inout)
202{
203 checkint_dfft(l);
204 dfftf_(&l, inout, ws_dfft);
205 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
206}
207
208void FFTPackServer::fftf(int_4 l, complex<r_4>* inout)
209{
210 checkint_cfft(l);
211 cfftf_(&l, (r_4 *)(inout), ws_cfft);
212}
213
214void FFTPackServer::fftf(int_4 l, complex<r_8>* inout)
215{
216 checkint_cdfft(l);
217 cdfftf_(&l, (r_8*)(inout), ws_cdfft);
218}
219
220void FFTPackServer::fftb(int_4 l, r_4* inout)
221{
222 checkint_rfft(l);
223 rfftb_(&l, inout, ws_rfft);
224}
225
226void FFTPackServer::fftb(int_4 l, r_8* inout)
227{
228 checkint_dfft(l);
229 dfftb_(&l, inout, ws_dfft);
230}
231
232void FFTPackServer::fftb(int_4 l, complex<r_4>* inout)
233{
234 checkint_cfft(l);
235 cfftb_(&l, (r_4 *)(inout), ws_cfft);
236}
237
238void FFTPackServer::fftb(int_4 l, complex<r_8>* inout)
239{
240 checkint_cdfft(l);
241 cdfftb_(&l, (r_8 *)(inout), ws_cdfft);
242}
243
244// Methodes pour reordonner les donnees
245
246/* --Methode-- */
247void FFTPackServer::ReShapetoReal( TVector< complex<r_8> > const & in, TVector< r_8 > & out)
248{
249 int n = in.NElts();
250 int ncs = (fabs(in(n-1).imag()) > 1.e-12) ? ncs = 2*n-1 : ncs = n*2-2;
251 out.ReSize(ncs);
252 int k;
253 out(0) = in(0).real();
254 for(k=1;k<n-1;k++) {
255 out(2*k-1) = in(k).real();
256 out(2*k) = in(k).imag();
257 }
258 if (ncs == n*2-2) out(ncs-1) = in(n-1).real();
259 else { out(ncs-2) = in(n-1).real(); out(ncs-1) = in(n-1).imag(); }
260}
261
262/* --Methode-- */
263void FFTPackServer::ReShapetoReal( TVector< complex<r_4> > const & in, TVector< r_4 > & out)
264{
265 int n = in.NElts();
266 int ncs = (fabs(in(n-1).imag()) > 1.e-12) ? ncs = 2*n-1 : ncs = n*2-2;
267 out.ReSize(ncs);
268 int k;
269 out(0) = in(0).real();
270 for(k=1;k<n-1;k++) {
271 out(2*k-1) = in(k).real();
272 out(2*k) = in(k).imag();
273 }
274 if (ncs == n*2-2) out(ncs-1) = in(n-1).real();
275 else { out(ncs-2) = in(n-1).real(); out(ncs-1) = in(n-1).imag(); }
276}
277
278
279/* --Methode-- */
280void FFTPackServer::ReShapetoCompl(TVector< r_8 > const & in, TVector< complex<r_8> > & out)
281{
282 uint_4 n = in.NElts();
283 uint_4 ncs = n/2+1;
284 uint_4 nc = (n%2 != 0) ? n/2+1 : n/2;
285 out.ReSize(ncs);
286 out(0) = complex<r_8> (in(0),0.);
287 for(int k=1;k<nc;k++)
288 out(k) = complex<r_4> (in(2*k-1), in(2*k));
289 if (n%2 == 0) out(ncs-1) = complex<r_8>(in(n-1), 0.);
290
291}
292
293/* --Methode-- */
294void FFTPackServer::ReShapetoCompl(TVector< r_4 > const & in, TVector< complex<r_4> > & out)
295{
296 uint_4 n = in.NElts();
297 uint_4 ncs = n/2+1;
298 uint_4 nc = (n%2 != 0) ? n/2+1 : n/2;
299 out.ReSize(ncs);
300 out(0) = complex<r_4> (in(0),0.);
301 for(int k=1;k<nc;k++)
302 out(k) = complex<r_4> (in(2*k-1), in(2*k));
303 if (n%2 == 0) out(ncs-1) = complex<r_4>(in(n-1), 0.);
304}
Note: See TracBrowser for help on using the repository browser.