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

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

MAJ documentation, Makefile, ... - Reza 5/1/2001

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