#ifndef ALICHEB3DCALC_H
#define ALICHEB3DCALC_H
#include <TNamed.h>
class TSystem;
#define _INC_CREATION_ALICHEB3D_
class AliCheb3DCalc: public TNamed
{
public:
AliCheb3DCalc();
AliCheb3DCalc(const AliCheb3DCalc& src);
AliCheb3DCalc(FILE* stream);
~AliCheb3DCalc() {Clear();}
AliCheb3DCalc& operator=(const AliCheb3DCalc& rhs);
void Print(const Option_t* opt="") const;
void LoadData(FILE* stream);
Float_t EvalDeriv(int dim, const Float_t *par) const;
Float_t EvalDeriv2(int dim1,int dim2, const Float_t *par) const;
#ifdef _INC_CREATION_ALICHEB3D_
void SaveData(const char* outfile,Bool_t append=kFALSE) const;
void SaveData(FILE* stream=stdout) const;
#endif
void InitRows(int nr);
void InitCols(int nc);
void SetPrecision(Float_t prc=1e-6) {fPrec = prc;}
Float_t GetPrecision() const {return fPrec;}
Int_t GetNCoefs() const {return fNCoefs;}
Int_t GetNCols() const {return (Int_t)fNCols;}
Int_t GetNRows() const {return (Int_t)fNRows;}
Int_t GetNElemBound2D() const {return (Int_t)fNElemBound2D;}
Int_t GetMaxColsAtRow() const;
UShort_t* GetNColsAtRow() const {return fNColsAtRow;}
UShort_t* GetColAtRowBg() const {return fColAtRowBg;}
void InitElemBound2D(int ne);
UShort_t* GetCoefBound2D0() const {return fCoefBound2D0;}
UShort_t* GetCoefBound2D1() const {return fCoefBound2D1;}
void Clear(const Option_t* option = "");
static Float_t ChebEval1D(Float_t x, const Float_t * array, int ncf);
static Float_t ChebEval1Deriv(Float_t x, const Float_t * array, int ncf);
static Float_t ChebEval1Deriv2(Float_t x, const Float_t * array, int ncf);
void InitCoefs(int nc);
Float_t * GetCoefs() const {return fCoefs;}
static void ReadLine(TString& str,FILE* stream);
Float_t Eval(const Float_t *par) const;
Double_t Eval(const Double_t *par) const;
protected:
Int_t fNCoefs;
Int_t fNRows;
Int_t fNCols;
Int_t fNElemBound2D;
UShort_t* fNColsAtRow;
UShort_t* fColAtRowBg;
UShort_t* fCoefBound2D0;
UShort_t* fCoefBound2D1;
Float_t * fCoefs;
Float_t * fTmpCf1;
Float_t * fTmpCf0;
Float_t fPrec;
ClassDef(AliCheb3DCalc,4)
};
inline Float_t AliCheb3DCalc::ChebEval1D(Float_t x, const Float_t * array, int ncf )
{
if (ncf<=0) return 0;
Float_t b0, b1, b2, x2 = x+x;
b0 = array[--ncf];
b1 = b2 = 0;
for (int i=ncf;i--;) {
b2 = b1;
b1 = b0;
b0 = array[i] + x2*b1 -b2;
}
return b0 - x*b1;
}
inline Float_t AliCheb3DCalc::Eval(const Float_t *par) const
{
if (!fNRows) return 0.;
int ncfRC;
for (int id0=fNRows;id0--;) {
int nCLoc = fNColsAtRow[id0];
int col0 = fColAtRowBg[id0];
for (int id1=nCLoc;id1--;) {
int id = id1+col0;
fTmpCf1[id1] = (ncfRC=fCoefBound2D0[id]) ? ChebEval1D(par[2],fCoefs + fCoefBound2D1[id], ncfRC) : 0.0;
}
fTmpCf0[id0] = nCLoc>0 ? ChebEval1D(par[1],fTmpCf1,nCLoc):0.0;
}
return ChebEval1D(par[0],fTmpCf0,fNRows);
}
inline Double_t AliCheb3DCalc::Eval(const Double_t *par) const
{
if (!fNRows) return 0.;
int ncfRC;
for (int id0=fNRows;id0--;) {
int nCLoc = fNColsAtRow[id0];
int col0 = fColAtRowBg[id0];
for (int id1=nCLoc;id1--;) {
int id = id1+col0;
fTmpCf1[id1] = (ncfRC=fCoefBound2D0[id]) ? ChebEval1D(par[2],fCoefs + fCoefBound2D1[id], ncfRC) : 0.0;
}
fTmpCf0[id0] = nCLoc>0 ? ChebEval1D(par[1],fTmpCf1,nCLoc):0.0;
}
return ChebEval1D(par[0],fTmpCf0,fNRows);
}
#endif