ROOT logo
#ifndef ALICHEB3DCALC_H
#define ALICHEB3DCALC_H
/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 * See cxx source for full Copyright notice                               */
#include <TNamed.h>
class TSystem;
//
// Author: Ruben Shahoyan
// ruben.shahoyan@cern.ch   09/09/2006
// See Comments in AliCheb3D.h
//


// to decrease the compilable code size comment this define. This will exclude the routines 
// used for the calculation and saving of the coefficients. 
#define _INC_CREATION_ALICHEB3D_

// when _BRING_TO_BOUNDARY_ is defined, the point outside of the fitted folume is assumed
// to be on the surface 
// #define _BRING_TO_BOUNDARY_
//


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;            // total number of coeeficients
  Int_t      fNRows;             // number of significant rows in the 3D coeffs matrix
  Int_t      fNCols;             // max number of significant cols in the 3D coeffs matrix
  Int_t      fNElemBound2D;      // number of elements (fNRows*fNCols) to store for the 2D boundary of significant coeffs
  UShort_t*  fNColsAtRow;        //[fNRows] number of sighificant columns (2nd dim) at each row of 3D coefs matrix
  UShort_t*  fColAtRowBg;        //[fNRows] beginnig of significant columns (2nd dim) for row in the 2D boundary matrix
  UShort_t*  fCoefBound2D0;      //[fNElemBound2D] 2D matrix defining the boundary of significance for 3D coeffs.matrix (Ncoefs for col/row)
  UShort_t*  fCoefBound2D1;      //[fNElemBound2D] 2D matrix defining the start beginnig of significant coeffs for col/row
  Float_t *  fCoefs;             //[fNCoefs] array of Chebyshev coefficients
  //
  Float_t *  fTmpCf1;            //[fNCols] temp. coeffs for 2d summation
  Float_t *  fTmpCf0;            //[fNRows] temp. coeffs for 1d summation
  //
  Float_t    fPrec;              // Requested precision
  ClassDef(AliCheb3DCalc,4)      // Class for interpolation of 3D->1 function by Chebyshev parametrization 
};

//__________________________________________________________________________________________
inline Float_t AliCheb3DCalc::ChebEval1D(Float_t  x, const Float_t * array, int ncf ) 
{
  // evaluate 1D Chebyshev parameterization. x is the argument mapped to [-1:1] interval
  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 
{
  // evaluate Chebyshev parameterization for 3D function.
  // VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
  if (!fNRows) return 0.;
  int ncfRC;
  for (int id0=fNRows;id0--;) {
    int nCLoc = fNColsAtRow[id0];                   // number of significant coefs on this row
    int col0  = fColAtRowBg[id0];                   // beginning of local column in the 2D boundary matrix
    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 
{
  // evaluate Chebyshev parameterization for 3D function.
  // VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
  if (!fNRows) return 0.;
  int ncfRC;
  for (int id0=fNRows;id0--;) {
    int nCLoc = fNColsAtRow[id0];                   // number of significant coefs on this row
    int col0  = fColAtRowBg[id0];                   // beginning of local column in the 2D boundary matrix
    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
 AliCheb3DCalc.h:1
 AliCheb3DCalc.h:2
 AliCheb3DCalc.h:3
 AliCheb3DCalc.h:4
 AliCheb3DCalc.h:5
 AliCheb3DCalc.h:6
 AliCheb3DCalc.h:7
 AliCheb3DCalc.h:8
 AliCheb3DCalc.h:9
 AliCheb3DCalc.h:10
 AliCheb3DCalc.h:11
 AliCheb3DCalc.h:12
 AliCheb3DCalc.h:13
 AliCheb3DCalc.h:14
 AliCheb3DCalc.h:15
 AliCheb3DCalc.h:16
 AliCheb3DCalc.h:17
 AliCheb3DCalc.h:18
 AliCheb3DCalc.h:19
 AliCheb3DCalc.h:20
 AliCheb3DCalc.h:21
 AliCheb3DCalc.h:22
 AliCheb3DCalc.h:23
 AliCheb3DCalc.h:24
 AliCheb3DCalc.h:25
 AliCheb3DCalc.h:26
 AliCheb3DCalc.h:27
 AliCheb3DCalc.h:28
 AliCheb3DCalc.h:29
 AliCheb3DCalc.h:30
 AliCheb3DCalc.h:31
 AliCheb3DCalc.h:32
 AliCheb3DCalc.h:33
 AliCheb3DCalc.h:34
 AliCheb3DCalc.h:35
 AliCheb3DCalc.h:36
 AliCheb3DCalc.h:37
 AliCheb3DCalc.h:38
 AliCheb3DCalc.h:39
 AliCheb3DCalc.h:40
 AliCheb3DCalc.h:41
 AliCheb3DCalc.h:42
 AliCheb3DCalc.h:43
 AliCheb3DCalc.h:44
 AliCheb3DCalc.h:45
 AliCheb3DCalc.h:46
 AliCheb3DCalc.h:47
 AliCheb3DCalc.h:48
 AliCheb3DCalc.h:49
 AliCheb3DCalc.h:50
 AliCheb3DCalc.h:51
 AliCheb3DCalc.h:52
 AliCheb3DCalc.h:53
 AliCheb3DCalc.h:54
 AliCheb3DCalc.h:55
 AliCheb3DCalc.h:56
 AliCheb3DCalc.h:57
 AliCheb3DCalc.h:58
 AliCheb3DCalc.h:59
 AliCheb3DCalc.h:60
 AliCheb3DCalc.h:61
 AliCheb3DCalc.h:62
 AliCheb3DCalc.h:63
 AliCheb3DCalc.h:64
 AliCheb3DCalc.h:65
 AliCheb3DCalc.h:66
 AliCheb3DCalc.h:67
 AliCheb3DCalc.h:68
 AliCheb3DCalc.h:69
 AliCheb3DCalc.h:70
 AliCheb3DCalc.h:71
 AliCheb3DCalc.h:72
 AliCheb3DCalc.h:73
 AliCheb3DCalc.h:74
 AliCheb3DCalc.h:75
 AliCheb3DCalc.h:76
 AliCheb3DCalc.h:77
 AliCheb3DCalc.h:78
 AliCheb3DCalc.h:79
 AliCheb3DCalc.h:80
 AliCheb3DCalc.h:81
 AliCheb3DCalc.h:82
 AliCheb3DCalc.h:83
 AliCheb3DCalc.h:84
 AliCheb3DCalc.h:85
 AliCheb3DCalc.h:86
 AliCheb3DCalc.h:87
 AliCheb3DCalc.h:88
 AliCheb3DCalc.h:89
 AliCheb3DCalc.h:90
 AliCheb3DCalc.h:91
 AliCheb3DCalc.h:92
 AliCheb3DCalc.h:93
 AliCheb3DCalc.h:94
 AliCheb3DCalc.h:95
 AliCheb3DCalc.h:96
 AliCheb3DCalc.h:97
 AliCheb3DCalc.h:98
 AliCheb3DCalc.h:99
 AliCheb3DCalc.h:100
 AliCheb3DCalc.h:101
 AliCheb3DCalc.h:102
 AliCheb3DCalc.h:103
 AliCheb3DCalc.h:104
 AliCheb3DCalc.h:105
 AliCheb3DCalc.h:106
 AliCheb3DCalc.h:107
 AliCheb3DCalc.h:108
 AliCheb3DCalc.h:109
 AliCheb3DCalc.h:110
 AliCheb3DCalc.h:111
 AliCheb3DCalc.h:112
 AliCheb3DCalc.h:113
 AliCheb3DCalc.h:114
 AliCheb3DCalc.h:115
 AliCheb3DCalc.h:116
 AliCheb3DCalc.h:117
 AliCheb3DCalc.h:118
 AliCheb3DCalc.h:119
 AliCheb3DCalc.h:120
 AliCheb3DCalc.h:121
 AliCheb3DCalc.h:122
 AliCheb3DCalc.h:123
 AliCheb3DCalc.h:124
 AliCheb3DCalc.h:125
 AliCheb3DCalc.h:126
 AliCheb3DCalc.h:127
 AliCheb3DCalc.h:128
 AliCheb3DCalc.h:129
 AliCheb3DCalc.h:130
 AliCheb3DCalc.h:131
 AliCheb3DCalc.h:132
 AliCheb3DCalc.h:133
 AliCheb3DCalc.h:134
 AliCheb3DCalc.h:135
 AliCheb3DCalc.h:136
 AliCheb3DCalc.h:137
 AliCheb3DCalc.h:138
 AliCheb3DCalc.h:139
 AliCheb3DCalc.h:140
 AliCheb3DCalc.h:141
 AliCheb3DCalc.h:142