```// @(#)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