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

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

Modifs interface FFTServer , Reza 9/2/2001

File size: 5.1 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 , ckR4(true, true) , ckR8(true, true)
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(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
59{
60 ckR8.CheckResize(in, out);
61 out = in;
62 fftf(out.Size(), out.Data());
63 if (getNormalize()) out *= (1./(r_8)(in.Size()));
64}
65
66void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< complex<r_8> > & out)
67{
68 ckR8.CheckResize(in, out);
69 out = in;
70 fftb(out.Size(), out.Data());
71}
72
73
74
75void FFTPackServer::FFTForward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
76{
77 ckR4.CheckResize(in, out);
78 out = in;
79 fftf(out.Size(), out.Data());
80 if (getNormalize()) out *= (1./(r_4)(in.Size()));
81}
82
83void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< complex<r_4> > & out)
84{
85 ckR4.CheckResize(in, out);
86 out = in;
87 fftb(out.Size(), out.Data());
88}
89
90void FFTPackServer::FFTForward(TArray< r_4 > const & in, TArray< complex<r_4> > & out)
91{
92 ckR4.CheckResize(in, out);
93 TArray< r_4 > inout(in, false);
94 fftf(inout.Size(), inout.Data());
95 ckR4.ReShapetoCompl(inout, out);
96 if (getNormalize()) out *= complex<r_4>((1./(r_4)(in.Size())), 0.);
97}
98
99void FFTPackServer::FFTBackward(TArray< complex<r_4> > const & in, TArray< r_4 > & out)
100{
101 ckR4.CheckResize(in, out);
102 ckR4.ReShapetoReal(in, out);
103 fftb(out.Size(), out.Data());
104}
105
106
107void FFTPackServer::FFTForward(TArray< r_8 > const & in, TArray< complex<r_8> > & out)
108{
109 ckR8.CheckResize(in, out);
110 TArray< r_8 > inout(in, false);
111 fftf(inout.Size(), inout.Data());
112 ckR8.ReShapetoCompl(inout, out);
113 if (getNormalize()) out *= complex<r_8>((1./(r_8)(in.Size())), 0.);
114}
115
116void FFTPackServer::FFTBackward(TArray< complex<r_8> > const & in, TArray< r_8 > & out)
117{
118 ckR8.CheckResize(in, out);
119 ckR8.ReShapetoReal(in, out);
120 fftb(out.Size(), out.Data());
121}
122
123
124
125void FFTPackServer::checkint_rfft(int_4 l)
126{
127 if (sz_rfft == l) return; //checkint functions check and reallocate
128 //memory for the work arrays when performing
129 if (ws_rfft) delete[] ws_rfft; //a transform
130 sz_rfft = l;
131 ws_rfft = new r_4[2*l+15];
132 rffti_(&l, ws_rfft);
133}
134
135void FFTPackServer::checkint_cfft(int_4 l)
136{
137 if (sz_cfft == l) return;
138
139 if (ws_cfft) delete[] ws_cfft;
140 sz_cfft = l;
141 ws_cfft = new r_4[4*l+15];
142 cffti_(&l, ws_cfft);
143}
144
145void FFTPackServer::checkint_dfft(int_4 l)
146{
147 if (sz_dfft == l) return;
148
149 if (ws_dfft) delete[] ws_dfft;
150 sz_dfft = l;
151 ws_dfft = new r_8[2*l+15];
152 dffti_(&l, ws_dfft);
153}
154
155void FFTPackServer::checkint_cdfft(int_4 l)
156{
157 if (sz_cdfft == l) return;
158
159 if (ws_cdfft) delete[] ws_cdfft;
160 sz_cdfft = l;
161 ws_cdfft = new r_8[4*l+15];
162 cdffti_(&l, ws_cdfft);
163}
164
165/* In general forward transformations are resorted since fftpack functions
166 return inverse transformations */
167
168void FFTPackServer::fftf(int_4 l, r_4* inout)
169{
170 checkint_rfft(l);
171 rfftf_(&l, inout, ws_rfft);
172 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
173}
174
175void FFTPackServer::fftf(int_4 l, r_8* inout)
176{
177 checkint_dfft(l);
178 dfftf_(&l, inout, ws_dfft);
179 // for (int k= 2;k<=(l+1)/2;k++) inout[2*k-2]=-inout[2*k-2];
180}
181
182void FFTPackServer::fftf(int_4 l, complex<r_4>* inout)
183{
184 checkint_cfft(l);
185 cfftf_(&l, (r_4 *)(inout), ws_cfft);
186}
187
188void FFTPackServer::fftf(int_4 l, complex<r_8>* inout)
189{
190 checkint_cdfft(l);
191 cdfftf_(&l, (r_8*)(inout), ws_cdfft);
192}
193
194void FFTPackServer::fftb(int_4 l, r_4* inout)
195{
196 checkint_rfft(l);
197 rfftb_(&l, inout, ws_rfft);
198}
199
200void FFTPackServer::fftb(int_4 l, r_8* inout)
201{
202 checkint_dfft(l);
203 dfftb_(&l, inout, ws_dfft);
204}
205
206void FFTPackServer::fftb(int_4 l, complex<r_4>* inout)
207{
208 checkint_cfft(l);
209 cfftb_(&l, (r_4 *)(inout), ws_cfft);
210}
211
212void FFTPackServer::fftb(int_4 l, complex<r_8>* inout)
213{
214 checkint_cdfft(l);
215 cdfftb_(&l, (r_8 *)(inout), ws_cdfft);
216}
217
218
Note: See TracBrowser for help on using the repository browser.