// @(#)root/fft:$Id$ // Author: Anna Kreshuk 07/4/2006 /************************************************************************* * Copyright (C) 1995-2006, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ //////////////////////////////////////////////////////////////////////////////// /// /// \class TFFTRealComplex /// /// One of the interface classes to the FFTW package, can be used directly /// or via the TVirtualFFT class. Only the basic interface of FFTW is implemented. /// /// Computes a real input/complex output discrete Fourier transform in 1 or more /// dimensions. However, only out-of-place transforms are now supported for transforms /// in more than 1 dimension. For detailed information about the computed transforms, /// please refer to the FFTW manual /// /// How to use it: /// 1. Create an instance of TFFTRealComplex - this will allocate input and output /// arrays (unless an in-place transform is specified) /// 2. Run the Init() function with the desired flags and settings (see function /// comments for possible kind parameters) /// 3. Set the data (via SetPoints()or SetPoint() functions) /// 4. Run the Transform() function /// 5. Get the output (via GetPoints() or GetPoint() functions) /// 6. Repeat steps 3)-5) as needed /// For a transform of the same size, but with different flags, /// rerun the Init() function and continue with steps 3)-5) /// /// NOTE: /// 1. running Init() function will overwrite the input array! Don't set any data /// before running the Init() function /// 2. FFTW computes unnormalized transform, so doing a transform followed by /// its inverse will lead to the original array scaled by the transform size /// /// ///////////////////////////////////////////////////////////////////////////////// #include "TFFTRealComplex.h" #include "fftw3.h" #include "TComplex.h" ClassImp(TFFTRealComplex); //////////////////////////////////////////////////////////////////////////////// ///default TFFTRealComplex::TFFTRealComplex() { fIn = 0; fOut = 0; fPlan = 0; fN = 0; fNdim = 0; fTotalSize = 0; } //////////////////////////////////////////////////////////////////////////////// ///For 1d transforms ///Allocates memory for the input array, and, if inPlace = kFALSE, for the output array TFFTRealComplex::TFFTRealComplex(Int_t n, Bool_t inPlace) { if (!inPlace){ fIn = fftw_malloc(sizeof(Double_t)*n); fOut = fftw_malloc(sizeof(fftw_complex)*(n/2+1)); } else { fIn = fftw_malloc(sizeof(Double_t)*(2*(n/2+1))); fOut = 0; } fN = new Int_t[1]; fN[0] = n; fTotalSize = n; fNdim = 1; fPlan = 0; } //////////////////////////////////////////////////////////////////////////////// ///For ndim-dimensional transforms ///Second argument contains sizes of the transform in each dimension TFFTRealComplex::TFFTRealComplex(Int_t ndim, Int_t *n, Bool_t inPlace) { if (ndim>1 && inPlace==kTRUE){ Error("TFFTRealComplex", "multidimensional in-place r2c transforms are not implemented yet"); return; } fNdim = ndim; fTotalSize = 1; fN = new Int_t[fNdim]; for (Int_t i=0; i fN/2+1 (the point is in the Hermitian symmetric part), it is still ///returned. For >1d, only the first (roughly)half of points can be returned ///For 2d, see function GetPointComplex(Int_t *ipoint,...) void TFFTRealComplex::GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput) const { if (fromInput){ re = ((Double_t*)fIn)[ipoint]; } else { if (fNdim==1){ if (fOut){ if (ipointrealN/2){ Error("GetPointComplex", "Illegal index value"); return; } if (fOut){ re = ((fftw_complex*)fOut)[ipoint][0]; im = ((fftw_complex*)fOut)[ipoint][1]; } else { re = ((Double_t*)fIn)[2*ipoint]; im = ((Double_t*)fIn)[2*ipoint+1]; } } } } //////////////////////////////////////////////////////////////////////////////// ///For multidimensional transforms. Returns the point #ipoint. ///In case of transforms of more than 2 dimensions, ///only points from the first (roughly)half are returned, the rest being Hermitian symmetric void TFFTRealComplex::GetPointComplex(const Int_t *ipoint, Double_t &re, Double_t &im, Bool_t fromInput) const { Int_t ireal = ipoint[0]; for (Int_t i=0; i