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

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

Correction de bug init pointeur ds FFTPackServer - Reza 9/11/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//the working array and its size for the different
72//possible numerical types
73 sz_rfft = 0;
74 ws_rfft = NULL;
75 sz_dfft = 0;
76 ws_dfft = NULL;
77 sz_cfft = 0;
78 ws_cfft = NULL;
79 sz_cdfft = 0;
80 ws_cdfft = NULL;
81}
82
83FFTPackServer::~FFTPackServer()
84{
85if (ws_rfft) delete[] ws_rfft;
86if (ws_dfft) delete[] ws_dfft;
87if (ws_cfft) delete[] ws_cfft;
88if (ws_cdfft) delete[] ws_cdfft;
89}
90
91FFTServerInterface * FFTPackServer::Clone()
92{
93 return (new FFTPackServer);
94}
95
96
97void FFTPackServer::FFTForward(TVector< complex<r_8> > const & in, TVector< complex<r_8> > & out)
98{
99 out = in;
100 fftf(out.NElts(), out.Data());
101 if (getNormalize()) out *= (1./(r_8)(in.NElts()));
102}
103
104void FFTPackServer::FFTBackward(TVector< complex<r_8> > const & in, TVector< complex<r_8> > & out)
105{
106 out = in;
107 fftb(out.NElts(), out.Data());
108}
109
110
111
112void FFTPackServer::FFTForward(TVector< complex<r_4> > const & in, TVector< complex<r_4> > & out)
113{
114 out = in;
115 fftf(out.NElts(), out.Data());
116 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
117}
118
119void FFTPackServer::FFTBackward(TVector< complex<r_4> > const & in, TVector< complex<r_4> > & out)
120{
121 out = in;
122 fftb(out.NElts(), out.Data());
123}
124
125void FFTPackServer::FFTForward(TVector< r_4 > const & in, TVector< complex<r_4> > & out)
126{
127 TVector< r_4 > inout(in);
128 fftf(inout.NElts(), inout.Data());
129 ReShapetoCompl(inout, out);
130 if (getNormalize()) out *= (1./(r_4)(in.NElts()));
131}
132
133void FFTPackServer::FFTBackward(TVector< complex<r_4> > const & in, TVector< r_4 > & out)
134{
135 ReShapetoReal(in, out);
136 fftb(out.NElts(), out.Data());
137}
138
139
140void FFTPackServer::FFTForward(TVector< r_8 > const & in, TVector< complex<r_8> > & out)
141{
142 TVector< r_8 > inout(in);
143 fftf(inout.NElts(), inout.Data());
144 ReShapetoCompl(inout, out);
145 if (getNormalize()) out *= (1./(r_8)(in.NElts()));
146}
147
148void FFTPackServer::FFTBackward(TVector< complex<r_8> > const & in, TVector< r_8 > & out)
149{
150 ReShapetoReal(in, out);
151 fftb(out.NElts(), out.Data());
152}
153
154
155
156void FFTPackServer::checkint_rfft(int_4 l)
157{
158 if (sz_rfft == l) return; //checkint functions check and reallocate
159 //memory for the work arrays when performing
160 if (ws_rfft) delete[] ws_rfft; //a transform
161 sz_rfft = l;
162 ws_rfft = new r_4[2*l+15];
163 rffti_(&l, ws_rfft);
164}
165
166void FFTPackServer::checkint_cfft(int_4 l)
167{
168 if (sz_cfft == l) return;
169
170 if (ws_cfft) delete[] ws_cfft;
171 sz_cfft = l;
172 ws_cfft = new r_4[4*l+15];
173 cffti_(&l, ws_cfft);
174}
175
176void FFTPackServer::checkint_dfft(int_4 l)
177{
178 if (sz_dfft == l) return;
179
180 if (ws_dfft) delete[] ws_dfft;
181 sz_dfft = l;
182 ws_dfft = new r_8[2*l+15];
183 dffti_(&l, ws_dfft);
184}
185
186void FFTPackServer::checkint_cdfft(int_4 l)
187{
188 if (sz_cdfft == l) return;
189
190 if (ws_cdfft) delete[] ws_cdfft;
191 sz_cdfft = l;
192 ws_cdfft = new r_8[4*l+15];
193 cdffti_(&l, ws_cdfft);
194}
195
196/* In general forward transformations are resorted since fftpack functions
197 return inverse transformations */
198
199void FFTPackServer::fftf(int_4 l, r_4* inout)
200{
201 checkint_rfft(l);
202 rfftf_(&l, inout, ws_rfft);
203 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
204}
205
206void FFTPackServer::fftf(int_4 l, r_8* inout)
207{
208 checkint_dfft(l);
209 dfftf_(&l, inout, ws_dfft);
210 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
211}
212
213void FFTPackServer::fftf(int_4 l, complex<r_4>* inout)
214{
215 checkint_cfft(l);
216 cfftf_(&l, (r_4 *)(inout), ws_cfft);
217}
218
219void FFTPackServer::fftf(int_4 l, complex<r_8>* inout)
220{
221 checkint_cdfft(l);
222 cdfftf_(&l, (r_8*)(inout), ws_cdfft);
223}
224
225void FFTPackServer::fftb(int_4 l, r_4* inout)
226{
227 checkint_rfft(l);
228 rfftb_(&l, inout, ws_rfft);
229}
230
231void FFTPackServer::fftb(int_4 l, r_8* inout)
232{
233 checkint_dfft(l);
234 dfftb_(&l, inout, ws_dfft);
235}
236
237void FFTPackServer::fftb(int_4 l, complex<r_4>* inout)
238{
239 checkint_cfft(l);
240 cfftb_(&l, (r_4 *)(inout), ws_cfft);
241}
242
243void FFTPackServer::fftb(int_4 l, complex<r_8>* inout)
244{
245 checkint_cdfft(l);
246 cdfftb_(&l, (r_8 *)(inout), ws_cdfft);
247}
248
249// Methodes pour reordonner les donnees
250
251/* --Methode-- */
252void FFTPackServer::ReShapetoReal( TVector< complex<r_8> > const & in, TVector< r_8 > & out)
253{
254 int n = in.NElts();
255 int ncs = (fabs(in(n-1).imag()) > 1.e-12) ? ncs = 2*n-1 : ncs = n*2-2;
256 out.ReSize(ncs);
257 int k;
258 out(0) = in(0).real();
259 for(k=1;k<n-1;k++) {
260 out(2*k-1) = in(k).real();
261 out(2*k) = in(k).imag();
262 }
263 if (ncs == n*2-2) out(ncs-1) = in(n-1).real();
264 else { out(ncs-2) = in(n-1).real(); out(ncs-1) = in(n-1).imag(); }
265}
266
267/* --Methode-- */
268void FFTPackServer::ReShapetoReal( TVector< complex<r_4> > const & in, TVector< r_4 > & out)
269{
270 int n = in.NElts();
271 int ncs = (fabs(in(n-1).imag()) > 1.e-12) ? ncs = 2*n-1 : ncs = n*2-2;
272 out.ReSize(ncs);
273 int k;
274 out(0) = in(0).real();
275 for(k=1;k<n-1;k++) {
276 out(2*k-1) = in(k).real();
277 out(2*k) = in(k).imag();
278 }
279 if (ncs == n*2-2) out(ncs-1) = in(n-1).real();
280 else { out(ncs-2) = in(n-1).real(); out(ncs-1) = in(n-1).imag(); }
281}
282
283
284/* --Methode-- */
285void FFTPackServer::ReShapetoCompl(TVector< r_8 > const & in, TVector< complex<r_8> > & out)
286{
287 uint_4 n = in.NElts();
288 uint_4 ncs = n/2+1;
289 uint_4 nc = (n%2 != 0) ? n/2+1 : n/2;
290 out.ReSize(ncs);
291 out(0) = complex<r_8> (in(0),0.);
292 for(int k=1;k<nc;k++)
293 out(k) = complex<r_4> (in(2*k-1), in(2*k));
294 if (n%2 == 0) out(ncs-1) = complex<r_8>(in(n-1), 0.);
295
296}
297
298/* --Methode-- */
299void FFTPackServer::ReShapetoCompl(TVector< r_4 > const & in, TVector< complex<r_4> > & out)
300{
301 uint_4 n = in.NElts();
302 uint_4 ncs = n/2+1;
303 uint_4 nc = (n%2 != 0) ? n/2+1 : n/2;
304 out.ReSize(ncs);
305 out(0) = complex<r_4> (in(0),0.);
306 for(int k=1;k<nc;k++)
307 out(k) = complex<r_4> (in(2*k-1), in(2*k));
308 if (n%2 == 0) out(ncs-1) = complex<r_4>(in(n-1), 0.);
309}
Note: See TracBrowser for help on using the repository browser.