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

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

Changement interface FFTServer - Reza 12/2/2001

File size: 7.0 KB
RevLine 
[710]1#include "fftpserver.h"
2#include "fftpackc.h"
3
4#include <iostream.h>
5
6
[896]7/*!
[1371]8 \class SOPHYA::FFTPackServer
9 \ingroup NTools
10 An implementation of FFTServerInterface based on fftpack, for
11 one dimensional arrays.
[710]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()
[717]29 : FFTServerInterface("FFTPackServer using extended FFTPack (C-version) package")
[1394]30 , ckR4("FFTPackServer: ", true, true) , ckR8("FFTPackServer: ", true, true)
[710]31{
[1313]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;
[710]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;
[1313]47if (ws_dfft) delete[] ws_dfft;
[710]48if (ws_cfft) delete[] ws_cfft;
49if (ws_cdfft) delete[] ws_cdfft;
50}
51
52FFTServerInterface * FFTPackServer::Clone()
53{
54 return (new FFTPackServer);
55}
56
[717]57
[1390]58void FFTPackServer::FFTForward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
[710]59{
[1390]60 ckR8.CheckResize(in, out);
[710]61 out = in;
[1390]62 fftf(out.Size(), out.Data());
63 if (getNormalize()) out *= (1./(r_8)(in.Size()));
[710]64}
65
[1390]66void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
[710]67{
[1390]68 ckR8.CheckResize(in, out);
[710]69 out = in;
[1390]70 fftb(out.Size(), out.Data());
[710]71}
72
[717]73
[1390]74void FFTPackServer::FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
[710]75{
[1390]76 ckR4.CheckResize(in, out);
[710]77 out = in;
[1394]78 cout << out << endl;
[1390]79 fftf(out.Size(), out.Data());
80 if (getNormalize()) out *= (1./(r_4)(in.Size()));
[710]81}
82
[1390]83void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
[710]84{
[1390]85 ckR4.CheckResize(in, out);
[710]86 out = in;
[1390]87 fftb(out.Size(), out.Data());
[710]88}
89
[1390]90void FFTPackServer::FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out)
[710]91{
[1390]92 ckR4.CheckResize(in, out);
93 TArray< r_4 > inout(in, false);
94 fftf(inout.Size(), inout.Data());
[1394]95 ReShapetoCompl(inout, out);
[1390]96 if (getNormalize()) out *= complex<r_4>((1./(r_4)(in.Size())), 0.);
[710]97}
98
[1390]99void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out)
[710]100{
[1390]101 ckR4.CheckResize(in, out);
[1394]102 ReShapetoReal(in, out);
[1390]103 fftb(out.Size(), out.Data());
[710]104}
105
[717]106
[1390]107void FFTPackServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
[710]108{
[1390]109 ckR8.CheckResize(in, out);
110 TArray< r_8 > inout(in, false);
111 fftf(inout.Size(), inout.Data());
[1394]112 ReShapetoCompl(inout, out);
[1390]113 if (getNormalize()) out *= complex<r_8>((1./(r_8)(in.Size())), 0.);
[710]114}
115
[1390]116void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out)
[710]117{
[1390]118 ckR8.CheckResize(in, out);
[1394]119 ReShapetoReal(in, out);
[1390]120 fftb(out.Size(), out.Data());
[710]121}
122
123
[1394]124template <class T>
125void FFTPack_ReShapetoReal(TArray< complex<T> > const & ina, TArray< T > & outa)
126{
127 TVector< complex<T> > in(ina);
128 TVector< T > out(outa);
129 sa_size_t n = in.NElts();
130 T thr = FFTArrayChecker<T>::ZeroThreshold();
131 sa_size_t ncs = ( (in(n-1).imag() < -thr) || (in(n-1).imag() > thr) ) ?
132 ncs = 2*n-1 : ncs = 2*n-2;
133
134 if (out.NElts() != ncs)
135 throw SzMismatchError("FFTPack_ReShapetoReal() - Wrong output array size !");
136 // cerr << "DEBUG-FFTPack_ReShapetoReal() ncs = " << ncs
137 // << " out.NElts()= " << out.NElts() << endl;
138
139 sa_size_t k;
140
141 out(0) = in(0).real();
142 for(k=1;k<n-1;k++) {
143 out(2*k-1) = in(k).real();
144 out(2*k) = in(k).imag();
145 }
146 if (ncs == n*2-2) out(ncs-1) = in(n-1).real();
147 else { out(ncs-2) = in(n-1).real(); out(ncs-1) = in(n-1).imag(); }
148
149 return;
150}
151
152template <class T>
153void FFTPack_ReShapetoCompl(TArray< T > const & ina, TArray< complex<T> > & outa)
154{
155 TVector< T > in(ina);
156 TVector< complex<T> > out(outa);
157 sa_size_t n = in.NElts();
158 sa_size_t ncs = n/2+1;
159 sa_size_t nc = (n%2 != 0) ? n/2+1 : n/2;
160 if (out.NElts() != ncs)
161 throw SzMismatchError("FFTPack_ReShapetoCompl() - Wrong output array size !");
162
163 out(0) = complex<T> (in(0),0.);
164 for(int k=1;k<nc;k++)
165 out(k) = complex<r_4> (in(2*k-1), in(2*k));
166 if (n%2 == 0) out(ncs-1) = complex<T>(in(n-1), 0.);
167
168 return;
169}
170
171void FFTPackServer::ReShapetoReal(TArray< complex<r_8> > const & in, TArray< r_8 > & out)
172{
173 FFTPack_ReShapetoReal<r_8>(in, out);
174}
175
176void FFTPackServer::ReShapetoCompl(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
177{
178 FFTPack_ReShapetoCompl<r_8>(in, out);
179}
180
181void FFTPackServer::ReShapetoReal(TArray< complex<r_4> > const & in, TArray< r_4 > & out)
182{
183 FFTPack_ReShapetoReal<r_4>(in, out);
184}
185
186void FFTPackServer::ReShapetoCompl(TArray< r_4 > const & in, TArray< complex<r_4> > & out)
187{
188 FFTPack_ReShapetoCompl<r_4>(in, out);
189}
190
[791]191void FFTPackServer::checkint_rfft(int_4 l)
[710]192{
193 if (sz_rfft == l) return; //checkint functions check and reallocate
194 //memory for the work arrays when performing
195 if (ws_rfft) delete[] ws_rfft; //a transform
196 sz_rfft = l;
[717]197 ws_rfft = new r_4[2*l+15];
[710]198 rffti_(&l, ws_rfft);
199}
200
[791]201void FFTPackServer::checkint_cfft(int_4 l)
[710]202{
203 if (sz_cfft == l) return;
204
205 if (ws_cfft) delete[] ws_cfft;
206 sz_cfft = l;
[717]207 ws_cfft = new r_4[4*l+15];
[710]208 cffti_(&l, ws_cfft);
209}
210
[791]211void FFTPackServer::checkint_dfft(int_4 l)
[710]212{
213 if (sz_dfft == l) return;
214
215 if (ws_dfft) delete[] ws_dfft;
216 sz_dfft = l;
[717]217 ws_dfft = new r_8[2*l+15];
[710]218 dffti_(&l, ws_dfft);
219}
220
[791]221void FFTPackServer::checkint_cdfft(int_4 l)
[710]222{
223 if (sz_cdfft == l) return;
224
225 if (ws_cdfft) delete[] ws_cdfft;
226 sz_cdfft = l;
[717]227 ws_cdfft = new r_8[4*l+15];
[710]228 cdffti_(&l, ws_cdfft);
229}
230
231/* In general forward transformations are resorted since fftpack functions
232 return inverse transformations */
233
[791]234void FFTPackServer::fftf(int_4 l, r_4* inout)
[710]235{
236 checkint_rfft(l);
237 rfftf_(&l, inout, ws_rfft);
[717]238 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
[710]239}
240
[791]241void FFTPackServer::fftf(int_4 l, r_8* inout)
[710]242{
243 checkint_dfft(l);
244 dfftf_(&l, inout, ws_dfft);
[717]245 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
[710]246}
247
[791]248void FFTPackServer::fftf(int_4 l, complex<r_4>* inout)
[710]249{
250 checkint_cfft(l);
[717]251 cfftf_(&l, (r_4 *)(inout), ws_cfft);
[710]252}
253
[791]254void FFTPackServer::fftf(int_4 l, complex<r_8>* inout)
[710]255{
256 checkint_cdfft(l);
[717]257 cdfftf_(&l, (r_8*)(inout), ws_cdfft);
[710]258}
259
[791]260void FFTPackServer::fftb(int_4 l, r_4* inout)
[710]261{
262 checkint_rfft(l);
[717]263 rfftb_(&l, inout, ws_rfft);
[710]264}
265
[791]266void FFTPackServer::fftb(int_4 l, r_8* inout)
[710]267{
268 checkint_dfft(l);
[717]269 dfftb_(&l, inout, ws_dfft);
[710]270}
271
[791]272void FFTPackServer::fftb(int_4 l, complex<r_4>* inout)
[710]273{
274 checkint_cfft(l);
[717]275 cfftb_(&l, (r_4 *)(inout), ws_cfft);
[710]276}
277
[791]278void FFTPackServer::fftb(int_4 l, complex<r_8>* inout)
[710]279{
280 checkint_cdfft(l);
[717]281 cdfftb_(&l, (r_8 *)(inout), ws_cdfft);
282}
283
284
Note: See TracBrowser for help on using the repository browser.