84 TFFTReal::TFFTReal(Int_t n, Bool_t inPlace)
86 fIn = fftw_malloc(
sizeof(Double_t)*n);
87 if (inPlace) fOut = 0;
88 else fOut = fftw_malloc(
sizeof(Double_t)*n);
103 TFFTReal::TFFTReal(Int_t ndim, Int_t *n, Bool_t inPlace)
107 fN =
new Int_t[ndim];
110 for (Int_t i=0; i<ndim; i++){
114 fIn = fftw_malloc(
sizeof(Double_t)*fTotalSize);
116 fOut = fftw_malloc(
sizeof(Double_t)*fTotalSize);
124 TFFTReal::~TFFTReal()
126 fftw_destroy_plan((fftw_plan)fPlan);
138 fftw_free((fftw_r2r_kind*)fKind);
176 void TFFTReal::Init( Option_t* flags,Int_t ,
const Int_t *kind)
179 fftw_destroy_plan((fftw_plan)fPlan);
183 fKind = (fftw_r2r_kind*)fftw_malloc(
sizeof(fftw_r2r_kind)*fNdim);
185 if (MapOptions(kind)){
187 fPlan = (
void*)fftw_plan_r2r(fNdim, fN, (Double_t*)fIn, (Double_t*)fOut, (fftw_r2r_kind*)fKind, MapFlag(flags));
189 fPlan = (
void*)fftw_plan_r2r(fNdim, fN, (Double_t*)fIn, (Double_t*)fIn, (fftw_r2r_kind*)fKind, MapFlag(flags));
197 void TFFTReal::Transform()
200 fftw_execute((fftw_plan)fPlan);
202 Error(
"Transform",
"transform hasn't been initialised");
210 Option_t *TFFTReal::GetType()
const
213 Error(
"GetType",
"Type not defined yet (kind not set)");
216 if (((fftw_r2r_kind*)fKind)[0]==FFTW_R2HC)
return "R2HC";
217 if (((fftw_r2r_kind*)fKind)[0]==FFTW_HC2R)
return "HC2R";
218 if (((fftw_r2r_kind*)fKind)[0]==FFTW_DHT)
return "DHT";
226 void TFFTReal::GetPoints(Double_t *data, Bool_t fromInput)
const
228 const Double_t * array = GetPointsReal(fromInput);
230 std::copy(array, array+fTotalSize, data);
236 Double_t TFFTReal::GetPointReal(Int_t ipoint, Bool_t fromInput)
const
238 if (ipoint<0 || ipoint>fTotalSize){
239 Error(
"GetPointReal",
"No such point");
242 const Double_t * array = GetPointsReal(fromInput);
243 return ( array ) ? array[ipoint] : 0;
249 Double_t TFFTReal::GetPointReal(
const Int_t *ipoint, Bool_t fromInput)
const
251 Int_t ireal = ipoint[0];
252 for (Int_t i=0; i<fNdim-1; i++)
253 ireal=fN[i+1]*ireal + ipoint[i+1];
255 const Double_t * array = GetPointsReal(fromInput);
256 return ( array ) ? array[ireal] : 0;
262 void TFFTReal::GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput)
const
264 const Double_t * array = GetPointsReal(fromInput);
266 if ( ( ((fftw_r2r_kind*)fKind)[0]==FFTW_R2HC && !fromInput ) ||
267 ( ((fftw_r2r_kind*)fKind)[0]==FFTW_HC2R && fromInput ) )
269 if (ipoint<fN[0]/2+1){
271 im = array[fN[0]-ipoint];
273 re = array[fN[0]-ipoint];
276 if ((fN[0]%2)==0 && ipoint==fN[0]/2) im = 0;
282 void TFFTReal::GetPointComplex(
const Int_t *ipoint, Double_t &re, Double_t &im, Bool_t fromInput)
const
284 GetPointComplex(ipoint[0], re, im, fromInput);
296 Double_t* TFFTReal::GetPointsReal(Bool_t fromInput)
const
299 if (!fromInput && fOut)
300 return (Double_t*)fOut;
301 else if (fromInput && !fOut) {
302 Error(
"GetPointsReal",
"Input array was destroyed");
306 return (Double_t*)fIn;
311 void TFFTReal::SetPoint(Int_t ipoint, Double_t re, Double_t im)
313 if (ipoint<0 || ipoint>fTotalSize){
314 Error(
"SetPoint",
"illegal point index");
317 if (((fftw_r2r_kind*)fKind)[0]==FFTW_HC2R){
318 if ((fN[0]%2)==0 && ipoint==fN[0]/2)
319 ((Double_t*)fIn)[ipoint] = re;
321 ((Double_t*)fIn)[ipoint] = re;
322 ((Double_t*)fIn)[fN[0]-ipoint]=im;
326 ((Double_t*)fIn)[ipoint]=re;
333 void TFFTReal::SetPoint(
const Int_t *ipoint, Double_t re, Double_t )
335 Int_t ireal = ipoint[0];
336 for (Int_t i=0; i<fNdim-1; i++)
337 ireal=fN[i+1]*ireal + ipoint[i+1];
338 if (ireal < 0 || ireal >fTotalSize){
339 Error(
"SetPoint",
"illegal point index");
342 ((Double_t*)fIn)[ireal]=re;
348 void TFFTReal::SetPoints(
const Double_t *data)
350 for (Int_t i=0; i<fTotalSize; i++)
351 ((Double_t*)fIn)[i] = data[i];
357 Int_t TFFTReal::MapOptions(
const Int_t *kind)
361 Error(
"Init",
"Multidimensional R2HC transforms are not supported, use R2C interface instead");
364 ((fftw_r2r_kind*)fKind)[0] = FFTW_R2HC;
366 else if (kind[0] == 11) {
368 Error(
"Init",
"Multidimensional HC2R transforms are not supported, use C2R interface instead");
371 ((fftw_r2r_kind*)fKind)[0] = FFTW_HC2R;
373 else if (kind[0] == 12) {
374 for (Int_t i=0; i<fNdim; i++)
375 ((fftw_r2r_kind*)fKind)[i] = FFTW_DHT;
378 for (Int_t i=0; i<fNdim; i++){
380 case 0: ((fftw_r2r_kind*)fKind)[i] = FFTW_REDFT00;
break;
381 case 1: ((fftw_r2r_kind*)fKind)[i] = FFTW_REDFT01;
break;
382 case 2: ((fftw_r2r_kind*)fKind)[i] = FFTW_REDFT10;
break;
383 case 3: ((fftw_r2r_kind*)fKind)[i] = FFTW_REDFT11;
break;
384 case 4: ((fftw_r2r_kind*)fKind)[i] = FFTW_RODFT00;
break;
385 case 5: ((fftw_r2r_kind*)fKind)[i] = FFTW_RODFT01;
break;
386 case 6: ((fftw_r2r_kind*)fKind)[i] = FFTW_RODFT10;
break;
387 case 7: ((fftw_r2r_kind*)fKind)[i] = FFTW_RODFT11;
break;
389 ((fftw_r2r_kind*)fKind)[i] = FFTW_R2HC;
break;
403 UInt_t TFFTReal::MapFlag(Option_t *flag)
407 if (opt.Contains(
"ES"))
408 return FFTW_ESTIMATE;
409 if (opt.Contains(
"M"))
411 if (opt.Contains(
"P"))
413 if (opt.Contains(
"EX"))
414 return FFTW_EXHAUSTIVE;
415 return FFTW_ESTIMATE;