50 ClassImp(TFFTRealComplex);
55 TFFTRealComplex::TFFTRealComplex()
69 TFFTRealComplex::TFFTRealComplex(Int_t n, Bool_t inPlace)
73 fIn = fftw_malloc(
sizeof(Double_t)*n);
74 fOut = fftw_malloc(
sizeof(fftw_complex)*(n/2+1));
76 fIn = fftw_malloc(
sizeof(Double_t)*(2*(n/2+1)));
90 TFFTRealComplex::TFFTRealComplex(Int_t ndim, Int_t *n, Bool_t inPlace)
92 if (ndim>1 && inPlace==kTRUE){
93 Error(
"TFFTRealComplex",
"multidimensional in-place r2c transforms are not implemented yet");
98 fN =
new Int_t[fNdim];
99 for (Int_t i=0; i<fNdim; i++){
103 Int_t sizeout = Int_t(Double_t(fTotalSize)*(n[ndim-1]/2+1)/n[ndim-1]);
105 fIn = fftw_malloc(
sizeof(Double_t)*fTotalSize);
106 fOut = fftw_malloc(
sizeof(fftw_complex)*sizeout);
108 fIn = fftw_malloc(
sizeof(Double_t)*(2*sizeout));
119 TFFTRealComplex::~TFFTRealComplex()
121 fftw_destroy_plan((fftw_plan)fPlan);
126 fftw_free((fftw_complex*)fOut);
152 void TFFTRealComplex::Init(Option_t *flags,Int_t ,
const Int_t* )
157 fftw_destroy_plan((fftw_plan)fPlan);
161 fPlan = (
void*)fftw_plan_dft_r2c(fNdim, fN, (Double_t*)fIn, (fftw_complex*)fOut,MapFlag(flags));
163 fPlan = (
void*)fftw_plan_dft_r2c(fNdim, fN, (Double_t*)fIn, (fftw_complex*)fIn, MapFlag(flags));
169 void TFFTRealComplex::Transform()
173 fftw_execute((fftw_plan)fPlan);
176 Error(
"Transform",
"transform hasn't been initialised");
186 void TFFTRealComplex::GetPoints(Double_t *data, Bool_t fromInput)
const
189 for (Int_t i=0; i<fTotalSize; i++)
190 data[i] = ((Double_t*)fIn)[i];
192 Int_t realN = 2*Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
194 for (Int_t i=0; i<realN; i+=2){
195 data[i] = ((fftw_complex*)fOut)[i/2][0];
196 data[i+1] = ((fftw_complex*)fOut)[i/2][1];
200 for (Int_t i=0; i<realN; i++)
201 data[i] = ((Double_t*)fIn)[i];
210 Double_t TFFTRealComplex::GetPointReal(Int_t ipoint, Bool_t fromInput)
const
212 if (fOut && !fromInput){
213 Warning(
"GetPointReal",
"Output is complex. Only real part returned");
214 return ((fftw_complex*)fOut)[ipoint][0];
217 return ((Double_t*)fIn)[ipoint];
224 Double_t TFFTRealComplex::GetPointReal(
const Int_t *ipoint, Bool_t fromInput)
const
226 Int_t ireal = ipoint[0];
227 for (Int_t i=0; i<fNdim-1; i++)
228 ireal=fN[i+1]*ireal + ipoint[i+1];
230 if (fOut && !fromInput){
231 Warning(
"GetPointReal",
"Output is complex. Only real part returned");
232 return ((fftw_complex*)fOut)[ireal][0];
235 return ((Double_t*)fIn)[ireal];
245 void TFFTRealComplex::GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput)
const
248 re = ((Double_t*)fIn)[ipoint];
252 if (ipoint<fN[0]/2+1){
253 re = ((fftw_complex*)fOut)[ipoint][0];
254 im = ((fftw_complex*)fOut)[ipoint][1];
256 re = ((fftw_complex*)fOut)[fN[0]-ipoint][0];
257 im = -((fftw_complex*)fOut)[fN[0]-ipoint][1];
260 if (ipoint<fN[0]/2+1){
261 re = ((Double_t*)fIn)[2*ipoint];
262 im = ((Double_t*)fIn)[2*ipoint+1];
264 re = ((Double_t*)fIn)[2*(fN[0]-ipoint)];
265 im = ((Double_t*)fIn)[2*(fN[0]-ipoint)+1];
270 Int_t realN = 2*Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
272 Error(
"GetPointComplex",
"Illegal index value");
276 re = ((fftw_complex*)fOut)[ipoint][0];
277 im = ((fftw_complex*)fOut)[ipoint][1];
279 re = ((Double_t*)fIn)[2*ipoint];
280 im = ((Double_t*)fIn)[2*ipoint+1];
290 void TFFTRealComplex::GetPointComplex(
const Int_t *ipoint, Double_t &re, Double_t &im, Bool_t fromInput)
const
293 Int_t ireal = ipoint[0];
294 for (Int_t i=0; i<fNdim-2; i++)
295 ireal=fN[i+1]*ireal + ipoint[i+1];
297 ireal = (fN[fNdim-1]/2+1)*ireal + ipoint[fNdim-1];
300 re = ((Double_t*)fIn)[ireal];
305 if (ipoint[0] <fN[0]/2+1){
306 re = ((fftw_complex*)fOut)[ipoint[0]][0];
307 im = ((fftw_complex*)fOut)[ipoint[0]][1];
309 re = ((fftw_complex*)fOut)[fN[0]-ipoint[0]][0];
310 im = -((fftw_complex*)fOut)[fN[0]-ipoint[0]][1];
313 if (ireal <fN[0]/2+1){
314 re = ((Double_t*)fIn)[2*ipoint[0]];
315 im = ((Double_t*)fIn)[2*ipoint[0]+1];
317 re = ((Double_t*)fIn)[2*(fN[0]-ipoint[0])];
318 im = ((Double_t*)fIn)[2*(fN[0]-ipoint[0])+1];
324 if (ipoint[1]<fN[1]/2+1){
325 re = ((fftw_complex*)fOut)[ipoint[1]+(fN[1]/2+1)*ipoint[0]][0];
326 im = ((fftw_complex*)fOut)[ipoint[1]+(fN[1]/2+1)*ipoint[0]][1];
329 re = ((fftw_complex*)fOut)[fN[1]-ipoint[1]][0];
330 im = -((fftw_complex*)fOut)[fN[1]-ipoint[1]][1];
332 re = ((fftw_complex*)fOut)[(fN[1]-ipoint[1])+(fN[1]/2+1)*(fN[0]-ipoint[0])][0];
333 im = -((fftw_complex*)fOut)[(fN[1]-ipoint[1])+(fN[1]/2+1)*(fN[0]-ipoint[0])][1];
337 if (ipoint[1]<fN[1]/2+1){
338 re = ((Double_t*)fIn)[2*(ipoint[1]+(fN[1]/2+1)*ipoint[0])];
339 im = ((Double_t*)fIn)[2*(ipoint[1]+(fN[1]/2+1)*ipoint[0])+1];
342 re = ((Double_t*)fIn)[2*(fN[1]-ipoint[1])];
343 im = -((Double_t*)fIn)[2*(fN[1]-ipoint[1])+1];
345 re = ((Double_t*)fIn)[2*((fN[1]-ipoint[1])+(fN[1]/2+1)*(fN[0]-ipoint[0]))];
346 im = -((Double_t*)fIn)[2*((fN[1]-ipoint[1])+(fN[1]/2+1)*(fN[0]-ipoint[0]))+1];
354 re = ((fftw_complex*)fOut)[ireal][0];
355 im = ((fftw_complex*)fOut)[ireal][1];
357 re = ((Double_t*)fIn)[2*ireal];
358 im = ((Double_t*)fIn)[2*ireal+1];
368 Double_t* TFFTRealComplex::GetPointsReal(Bool_t fromInput)
const
371 Error(
"GetPointsReal",
"Output array is complex");
374 return (Double_t*)fIn;
382 void TFFTRealComplex::GetPointsComplex(Double_t *re, Double_t *im, Bool_t fromInput)
const
385 if (fOut && !fromInput){
386 nreal = Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
387 for (Int_t i=0; i<nreal; i++){
388 re[i] = ((fftw_complex*)fOut)[i][0];
389 im[i] = ((fftw_complex*)fOut)[i][1];
391 }
else if (fromInput) {
392 for (Int_t i=0; i<fTotalSize; i++){
393 re[i] = ((Double_t *)fIn)[i];
398 nreal = 2*Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
399 for (Int_t i=0; i<nreal; i+=2){
400 re[i/2] = ((Double_t*)fIn)[i];
401 im[i/2] = ((Double_t*)fIn)[i+1];
411 void TFFTRealComplex::GetPointsComplex(Double_t *data, Bool_t fromInput)
const
415 if (fOut && !fromInput){
416 nreal = Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
418 for (Int_t i=0; i<nreal; i+=2){
419 data[i] = ((fftw_complex*)fOut)[i/2][0];
420 data[i+1] = ((fftw_complex*)fOut)[i/2][1];
422 }
else if (fromInput){
423 for (Int_t i=0; i<fTotalSize; i+=2){
424 data[i] = ((Double_t*)fIn)[i/2];
430 nreal = 2*Int_t(Double_t(fTotalSize)*(fN[fNdim-1]/2+1)/fN[fNdim-1]);
431 for (Int_t i=0; i<nreal; i++)
432 data[i] = ((Double_t*)fIn)[i];
439 void TFFTRealComplex::SetPoint(Int_t ipoint, Double_t re, Double_t )
441 ((Double_t *)fIn)[ipoint] = re;
447 void TFFTRealComplex::SetPoint(
const Int_t *ipoint, Double_t re, Double_t )
449 Int_t ireal = ipoint[0];
450 for (Int_t i=0; i<fNdim-1; i++)
451 ireal=fN[i+1]*ireal + ipoint[i+1];
452 ((Double_t*)fIn)[ireal]=re;
458 void TFFTRealComplex::SetPoints(
const Double_t *data)
460 for (Int_t i=0; i<fTotalSize; i++){
461 ((Double_t*)fIn)[i]=data[i];
468 void TFFTRealComplex::SetPointComplex(Int_t ipoint, TComplex &c)
470 ((Double_t *)fIn)[ipoint]=c.Re();
476 void TFFTRealComplex::SetPointsComplex(
const Double_t *re,
const Double_t* )
478 for (Int_t i=0; i<fTotalSize; i++)
479 ((Double_t *)fIn)[i] = re[i];
489 UInt_t TFFTRealComplex::MapFlag(Option_t *flag)
494 if (opt.Contains(
"ES"))
495 return FFTW_ESTIMATE;
496 if (opt.Contains(
"M"))
498 if (opt.Contains(
"P"))
500 if (opt.Contains(
"EX"))
501 return FFTW_EXHAUSTIVE;
502 return FFTW_ESTIMATE;