#ifndef ALICHEB3D_H
#define ALICHEB3D_H
#include <TNamed.h>
#include <TObjArray.h>
#include "AliCheb3DCalc.h"
class TString;
class TSystem;
class TRandom;
class TH1;
class TMethodCall;
class TRandom;
class TROOT;
class stdio;
class AliCheb3D: public TNamed
{
public:
AliCheb3D();
AliCheb3D(const AliCheb3D& src);
AliCheb3D(const char* inpFile);
AliCheb3D(FILE* stream);
#ifdef _INC_CREATION_ALICHEB3D_
AliCheb3D(const char* funName, Int_t DimOut, const Float_t *bmin, const Float_t *bmax, Int_t *npoints, Float_t prec=1E-6, const Float_t* precD=0);
AliCheb3D(void (*ptr)(float*,float*), Int_t DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec=1E-6, const Float_t* precD=0);
AliCheb3D(void (*ptr)(float*,float*), int DimOut, Float_t *bmin,Float_t *bmax, Int_t *npX,Int_t *npY,Int_t *npZ, Float_t prec=1E-6, const Float_t* precD=0);
AliCheb3D(void (*ptr)(float*,float*), int DimOut, Float_t *bmin,Float_t *bmax, Float_t prec=1E-6, Bool_t run=kTRUE, const Float_t* precD=0);
#endif
~AliCheb3D() {Clear();}
AliCheb3D& operator=(const AliCheb3D& rhs);
void Eval(const Float_t *par, Float_t *res);
Float_t Eval(const Float_t *par,int idim);
void Eval(const Double_t *par, Double_t *res);
Double_t Eval(const Double_t *par,int idim);
void EvalDeriv(int dimd, const Float_t *par, Float_t *res);
void EvalDeriv2(int dimd1, int dimd2, const Float_t *par,Float_t *res);
Float_t EvalDeriv(int dimd, const Float_t *par, int idim);
Float_t EvalDeriv2(int dimd1,int dimd2, const Float_t *par, int idim);
void EvalDeriv3D(const Float_t *par, Float_t dbdr[3][3]);
void EvalDeriv3D2(const Float_t *par, Float_t dbdrdr[3][3][3]);
void Print(const Option_t* opt="") const;
Bool_t IsInside(const Float_t *par) const;
Bool_t IsInside(const Double_t *par) const;
AliCheb3DCalc* GetChebCalc(int i) const {return (AliCheb3DCalc*)fChebCalc.UncheckedAt(i);}
Float_t GetBoundMin(int i) const {return fBMin[i];}
Float_t GetBoundMax(int i) const {return fBMax[i];}
Float_t* GetBoundMin() const {return (float*)fBMin;}
Float_t* GetBoundMax() const {return (float*)fBMax;}
Float_t GetPrecision() const {return fPrec;}
void ShiftBound(int id,float dif);
void LoadData(const char* inpFile);
void LoadData(FILE* stream);
#ifdef _INC_CREATION_ALICHEB3D_
void InvertSign();
int* GetNCNeeded(float xyz[3],int DimVar, float mn,float mx, float prec, Int_t npCheck=30);
void EstimateNPoints(float prec, int gridBC[3][3],Int_t npd1=30,Int_t npd2=30,Int_t npd3=30);
void SaveData(const char* outfile,Bool_t append=kFALSE) const;
void SaveData(FILE* stream=stdout) const;
void SetUsrFunction(const char* name);
void SetUsrFunction(void (*ptr)(float*,float*));
void EvalUsrFunction(const Float_t *x, Float_t *res);
TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0);
static Int_t CalcChebCoefs(const Float_t *funval,int np, Float_t *outCoefs, Float_t prec=-1);
#endif
protected:
void Clear(const Option_t* option = "");
void SetDimOut(const int d, const float* prec=0);
void PrepareBoundaries(const Float_t *bmin,const Float_t *bmax);
#ifdef _INC_CREATION_ALICHEB3D_
void EvalUsrFunction();
void DefineGrid(Int_t* npoints);
Int_t ChebFit();
Int_t ChebFit(int dmOut);
void SetPrecision(float prec) {fPrec = prec;}
#endif
Float_t MapToInternal(Float_t x,Int_t d) const;
Float_t MapToExternal(Float_t x,Int_t d) const {return x/fBScale[d]+fBOffset[d];}
Double_t MapToInternal(Double_t x,Int_t d) const;
Double_t MapToExternal(Double_t x,Int_t d) const {return x/fBScale[d]+fBOffset[d];}
protected:
Int_t fDimOut;
Float_t fPrec;
Float_t fBMin[3];
Float_t fBMax[3];
Float_t fBScale[3];
Float_t fBOffset[3];
TObjArray fChebCalc;
Int_t fMaxCoefs;
Int_t fNPoints[3];
Float_t fArgsTmp[3];
Float_t * fResTmp;
Float_t * fGrid;
Int_t fGridOffs[3];
TString fUsrFunName;
TMethodCall* fUsrMacro;
static const Float_t fgkMinPrec;
ClassDef(AliCheb3D,2)
};
inline Bool_t AliCheb3D::IsInside(const Float_t *par) const
{
for (int i=3;i--;) if (fBMin[i]>par[i] || par[i]>fBMax[i]) return kFALSE;
return kTRUE;
}
inline Bool_t AliCheb3D::IsInside(const Double_t *par) const
{
for (int i=3;i--;) if (fBMin[i]>par[i] || par[i]>fBMax[i]) return kFALSE;
return kTRUE;
}
inline void AliCheb3D::Eval(const Float_t *par, Float_t *res)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int i=fDimOut;i--;) res[i] = GetChebCalc(i)->Eval(fArgsTmp);
}
inline void AliCheb3D::Eval(const Double_t *par, Double_t *res)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int i=fDimOut;i--;) res[i] = GetChebCalc(i)->Eval(fArgsTmp);
}
inline Double_t AliCheb3D::Eval(const Double_t *par, int idim)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
return GetChebCalc(idim)->Eval(fArgsTmp);
}
inline Float_t AliCheb3D::Eval(const Float_t *par, int idim)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
return GetChebCalc(idim)->Eval(fArgsTmp);
}
inline void AliCheb3D::EvalDeriv3D(const Float_t *par, Float_t dbdr[3][3])
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int ib=3;ib--;) for (int id=3;id--;) dbdr[ib][id] = GetChebCalc(ib)->EvalDeriv(id,fArgsTmp)*fBScale[id];
}
inline void AliCheb3D::EvalDeriv3D2(const Float_t *par, Float_t dbdrdr[3][3][3])
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int ib=3;ib--;) for (int id=3;id--;)for (int id1=3;id1--;)
dbdrdr[ib][id][id1] = GetChebCalc(ib)->EvalDeriv2(id,id1,fArgsTmp)*fBScale[id]*fBScale[id1];
}
inline void AliCheb3D::EvalDeriv(int dimd, const Float_t *par, Float_t *res)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int i=fDimOut;i--;) res[i] = GetChebCalc(i)->EvalDeriv(dimd,fArgsTmp)*fBScale[dimd];;
}
inline void AliCheb3D::EvalDeriv2(int dimd1,int dimd2, const Float_t *par, Float_t *res)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
for (int i=fDimOut;i--;) res[i] = GetChebCalc(i)->EvalDeriv2(dimd1,dimd2,fArgsTmp)*fBScale[dimd1]*fBScale[dimd2];
}
inline Float_t AliCheb3D::EvalDeriv(int dimd, const Float_t *par, int idim)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
return GetChebCalc(idim)->EvalDeriv(dimd,fArgsTmp)*fBScale[dimd];
}
inline Float_t AliCheb3D::EvalDeriv2(int dimd1,int dimd2, const Float_t *par, int idim)
{
for (int i=3;i--;) fArgsTmp[i] = MapToInternal(par[i],i);
return GetChebCalc(idim)->EvalDeriv2(dimd1,dimd2,fArgsTmp)*fBScale[dimd1]*fBScale[dimd2];
}
inline Float_t AliCheb3D::MapToInternal(Float_t x,Int_t d) const
{
#ifdef _BRING_TO_BOUNDARY_
T res = (x-fBOffset[d])*fBScale[d];
if (res<-1) return -1;
if (res> 1) return 1;
return res;
#else
return (x-fBOffset[d])*fBScale[d];
#endif
}
inline Double_t AliCheb3D::MapToInternal(Double_t x,Int_t d) const
{
#ifdef _BRING_TO_BOUNDARY_
T res = (x-fBOffset[d])*fBScale[d];
if (res<-1) return -1;
if (res> 1) return 1;
return res;
#else
return (x-fBOffset[d])*fBScale[d];
#endif
}
#endif