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

Last change on this file since 710 was 710, checked in by ansari, 26 years ago

Introduction FFTServerInterface et FFTPackServer - Reza 21/01/2000

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