// @(#)root/base:$Id$
// Author: Anna Kreshuk  10/04/2006

#ifndef ROOT_TVirtualFFT
#define ROOT_TVirtualFFT

//////////////////////////////////////////////////////////////////////////
//
// TVirtualFFT
//
// TVirtualFFT is an interface class for Fast Fourier Transforms.
//
//
//
// The default FFT library is FFTW. To use it, FFTW3 library should already
// be installed, and ROOT should be have fftw3 module enabled, with the directories
// of fftw3 include file and library specified (see installation instructions).
// Function SetDefaultFFT() allows to change the default library.
//
// Available transform types:
// FFT:
// - "C2CFORWARD" - a complex input/output discrete Fourier transform (DFT)
//                  in one or more dimensions, -1 in the exponent
// - "C2CBACKWARD"- a complex input/output discrete Fourier transform (DFT)
//                  in one or more dimensions, +1 in the exponent
// - "R2C"        - a real-input/complex-output discrete Fourier transform (DFT)
//                  in one or more dimensions,
// - "C2R"        - inverse transforms to "R2C", taking complex input
//                  (storing the non-redundant half of a logically Hermitian array)
//                  to real output
// - "R2HC"       - a real-input DFT with output in "halfcomplex" format,
//                  i.e. real and imaginary parts for a transform of size n stored as
//                  r0, r1, r2, ..., rn/2, i(n+1)/2-1, ..., i2, i1
// - "HC2R"       - computes the reverse of FFTW_R2HC, above
// - "DHT"        - computes a discrete Hartley transform
//
// Sine/cosine transforms:
// Different types of transforms are specified by parameter kind of the SineCosine() static
// function. 4 different kinds of sine and cosine transforms are available
//  DCT-I  (REDFT00 in FFTW3 notation)- kind=0
//  DCT-II (REDFT10 in FFTW3 notation)- kind=1
//  DCT-III(REDFT01 in FFTW3 notation)- kind=2
//  DCT-IV (REDFT11 in FFTW3 notation)- kind=3
//  DST-I  (RODFT00 in FFTW3 notation)- kind=4
//  DST-II (RODFT10 in FFTW3 notation)- kind=5
//  DST-III(RODFT01 in FFTW3 notation)- kind=6
//  DST-IV (RODFT11 in FFTW3 notation)- kind=7
// Formulas and detailed descriptions can be found in the chapter
// "What FFTW really computes" of the FFTW manual
//
// NOTE: FFTW computes unnormalized transforms, so doing a transform, followed by its
//       inverse will give the original array, multiplied by normalization constant
//       (transform size(N) for FFT, 2*(N-1) for DCT-I, 2*(N+1) for DST-I, 2*N for
//       other sine/cosine transforms)
//
// How to use it:
// Call to the static function FFT returns a pointer to a fast fourier transform
// with requested parameters. Call to the static function SineCosine returns a
// pointer to a sine or cosine transform with requested parameters. Example:
// {
//    Int_t N = 10; Double_t *in = new Double_t[N];
//    TVirtualFFT *fftr2c = TVirtualFFT::FFT(1, &N, "R2C");
//    fftr2c->SetPoints(in);
//    fftr2c->Transform();
//    Double_t re, im;
//    for (Int_t i=0; i<N; i++)
//       fftr2c->GetPointComplex(i, re, im);
//    ...
//    fftr2c->SetPoints(in2);
//    ...
//    fftr2c->SetPoints(in3);
//    ...
// }
// Different options are explained in the function comments
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif

#ifndef ROOT_TString
#include "TString.h"
#endif

class TComplex;

class TVirtualFFT: public TObject {

 protected:
   static TVirtualFFT *fgFFT;      //current transformer
   static TString      fgDefault;  //default transformer

 public:

   TVirtualFFT(){};
   virtual ~TVirtualFFT();

   virtual Int_t     *GetN()    const = 0;

   virtual Int_t      GetNdim() const = 0;
   virtual Option_t  *GetType() const = 0;
   virtual Int_t      GetSign() const = 0;
   virtual Option_t  *GetTransformFlag() const = 0;
   virtual void       Init(Option_t *flag,Int_t sign, const Int_t *kind) = 0;
   virtual Bool_t     IsInplace() const = 0;

   virtual void       GetPoints(Double_t *data, Bool_t fromInput = kFALSE) const = 0;
   virtual Double_t   GetPointReal(Int_t ipoint, Bool_t fromInput = kFALSE) const = 0;
   virtual Double_t   GetPointReal(const Int_t *ipoint, Bool_t fromInput = kFALSE) const = 0;
   virtual void       GetPointComplex(Int_t ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const = 0;
   virtual void       GetPointComplex(const Int_t *ipoint, Double_t &re, Double_t &im, Bool_t fromInput=kFALSE) const = 0;
   virtual Double_t*  GetPointsReal(Bool_t fromInput=kFALSE) const = 0;
   virtual void       GetPointsComplex(Double_t *re, Double_t *im, Bool_t fromInput = kFALSE) const = 0;
   virtual void       GetPointsComplex(Double_t *data, Bool_t fromInput = kFALSE) const = 0;

   virtual void       SetPoint(Int_t ipoint, Double_t re, Double_t im = 0) = 0;
   virtual void       SetPoint(const Int_t *ipoint, Double_t re, Double_t im = 0) = 0;
   virtual void       SetPoints(const Double_t *data) = 0;
   virtual void       SetPointComplex(Int_t ipoint, TComplex &c) = 0;
   virtual void       SetPointsComplex(const Double_t *re, const Double_t *im) =0;
   virtual void       Transform() = 0;

   static TVirtualFFT* FFT(Int_t ndim, Int_t *n, Option_t *option);
   static TVirtualFFT* SineCosine(Int_t ndim, Int_t *n, Int_t *r2rkind, Option_t *option);
   static TVirtualFFT* GetCurrentTransform();

   static void         SetTransform(TVirtualFFT *fft);
   static const char*  GetDefaultFFT();
   static void         SetDefaultFFT(const char *name ="");

   ClassDef(TVirtualFFT, 0); //abstract interface for FFT calculations
};

#endif
 TVirtualFFT.h:1
 TVirtualFFT.h:2
 TVirtualFFT.h:3
 TVirtualFFT.h:4
 TVirtualFFT.h:5
 TVirtualFFT.h:6
 TVirtualFFT.h:7
 TVirtualFFT.h:8
 TVirtualFFT.h:9
 TVirtualFFT.h:10
 TVirtualFFT.h:11
 TVirtualFFT.h:12
 TVirtualFFT.h:13
 TVirtualFFT.h:14
 TVirtualFFT.h:15
 TVirtualFFT.h:16
 TVirtualFFT.h:17
 TVirtualFFT.h:18
 TVirtualFFT.h:19
 TVirtualFFT.h:20
 TVirtualFFT.h:21
 TVirtualFFT.h:22
 TVirtualFFT.h:23
 TVirtualFFT.h:24
 TVirtualFFT.h:25
 TVirtualFFT.h:26
 TVirtualFFT.h:27
 TVirtualFFT.h:28
 TVirtualFFT.h:29
 TVirtualFFT.h:30
 TVirtualFFT.h:31
 TVirtualFFT.h:32
 TVirtualFFT.h:33
 TVirtualFFT.h:34
 TVirtualFFT.h:35
 TVirtualFFT.h:36
 TVirtualFFT.h:37
 TVirtualFFT.h:38
 TVirtualFFT.h:39
 TVirtualFFT.h:40
 TVirtualFFT.h:41
 TVirtualFFT.h:42
 TVirtualFFT.h:43
 TVirtualFFT.h:44
 TVirtualFFT.h:45
 TVirtualFFT.h:46
 TVirtualFFT.h:47
 TVirtualFFT.h:48
 TVirtualFFT.h:49
 TVirtualFFT.h:50
 TVirtualFFT.h:51
 TVirtualFFT.h:52
 TVirtualFFT.h:53
 TVirtualFFT.h:54
 TVirtualFFT.h:55
 TVirtualFFT.h:56
 TVirtualFFT.h:57
 TVirtualFFT.h:58
 TVirtualFFT.h:59
 TVirtualFFT.h:60
 TVirtualFFT.h:61
 TVirtualFFT.h:62
 TVirtualFFT.h:63
 TVirtualFFT.h:64
 TVirtualFFT.h:65
 TVirtualFFT.h:66
 TVirtualFFT.h:67
 TVirtualFFT.h:68
 TVirtualFFT.h:69
 TVirtualFFT.h:70
 TVirtualFFT.h:71
 TVirtualFFT.h:72
 TVirtualFFT.h:73
 TVirtualFFT.h:74
 TVirtualFFT.h:75
 TVirtualFFT.h:76
 TVirtualFFT.h:77
 TVirtualFFT.h:78
 TVirtualFFT.h:79
 TVirtualFFT.h:80
 TVirtualFFT.h:81
 TVirtualFFT.h:82
 TVirtualFFT.h:83
 TVirtualFFT.h:84
 TVirtualFFT.h:85
 TVirtualFFT.h:86
 TVirtualFFT.h:87
 TVirtualFFT.h:88
 TVirtualFFT.h:89
 TVirtualFFT.h:90
 TVirtualFFT.h:91
 TVirtualFFT.h:92
 TVirtualFFT.h:93
 TVirtualFFT.h:94
 TVirtualFFT.h:95
 TVirtualFFT.h:96
 TVirtualFFT.h:97
 TVirtualFFT.h:98
 TVirtualFFT.h:99
 TVirtualFFT.h:100
 TVirtualFFT.h:101
 TVirtualFFT.h:102
 TVirtualFFT.h:103
 TVirtualFFT.h:104
 TVirtualFFT.h:105
 TVirtualFFT.h:106
 TVirtualFFT.h:107
 TVirtualFFT.h:108
 TVirtualFFT.h:109
 TVirtualFFT.h:110
 TVirtualFFT.h:111
 TVirtualFFT.h:112
 TVirtualFFT.h:113
 TVirtualFFT.h:114
 TVirtualFFT.h:115
 TVirtualFFT.h:116
 TVirtualFFT.h:117
 TVirtualFFT.h:118
 TVirtualFFT.h:119
 TVirtualFFT.h:120
 TVirtualFFT.h:121
 TVirtualFFT.h:122
 TVirtualFFT.h:123
 TVirtualFFT.h:124
 TVirtualFFT.h:125
 TVirtualFFT.h:126
 TVirtualFFT.h:127
 TVirtualFFT.h:128
 TVirtualFFT.h:129
 TVirtualFFT.h:130
 TVirtualFFT.h:131
 TVirtualFFT.h:132
 TVirtualFFT.h:133
 TVirtualFFT.h:134
 TVirtualFFT.h:135
 TVirtualFFT.h:136
 TVirtualFFT.h:137
 TVirtualFFT.h:138
 TVirtualFFT.h:139