* provided "as is" without express or implied warranty. *
**************************************************************************/
-/* $Id$ */
-
-// Author: ruben.shahoyan@cern.ch 09/09/2006
-//
-////////////////////////////////////////////////////////////////////////////////
-// //
-// AliCheb3D produces the interpolation of the user 3D->NDimOut arbitrary //
-// function supplied in "void (*fcn)(float* inp,float* out)" format //
-// either in a separate macro file or as a function pointer. //
-// Only coefficients needed to guarantee the requested precision are kept. //
-// //
-// The user-callable methods are: //
-// To create the interpolation use: //
-// AliCheb3D(const char* funName, // name of the file with user function //
-// or //
-// AliCheb3D(void (*ptr)(float*,float*),// pointer on the user function //
-// Int_t DimOut, // dimensionality of the function's output //
-// Float_t *bmin, // lower 3D bounds of interpolation domain //
-// Float_t *bmax, // upper 3D bounds of interpolation domain //
-// Int_t *npoints, // number of points in each of 3 input //
-// // dimension, defining the interpolation grid //
-// Float_t prec=1E-6); // requested max.absolute difference between //
-// // the interpolation and any point on grid //
-// //
-// To test obtained parameterization use the method //
-// TH1* TestRMS(int idim,int npoints = 1000,TH1* histo=0); //
-// it will compare the user output of the user function and interpolation //
-// for idim-th output dimension and fill the difference in the supplied //
-// histogram. If no histogram is supplied, it will be created. //
-// //
-// To save the interpolation data: //
-// SaveData(const char* filename, Bool_t append ) //
-// write text file with data. If append is kTRUE and the output file already //
-// exists, data will be added in the end of the file. //
-// Alternatively, SaveData(FILE* stream) will write the data to //
-// already existing stream. //
-// //
-// To read back already stored interpolation use either the constructor //
-// AliCheb3D(const char* inpFile); //
-// or the default constructor AliCheb3D() followed by //
-// AliCheb3D::LoadData(const char* inpFile); //
-// //
-// To compute the interpolation use Eval(float* par,float *res) method, with //
-// par being 3D vector of arguments (inside the validity region) and res is //
-// the array of DimOut elements for the output. //
-// //
-// If only one component (say, idim-th) of the output is needed, use faster //
-// Float_t Eval(Float_t *par,int idim) method. //
-// //
-// void Print(option="") will print the name, the ranges of validity and //
-// the absolute precision of the parameterization. Option "l" will also print //
-// the information about the number of coefficients for each output //
-// dimension. //
-// //
-// NOTE: during the evaluation no check is done for parameter vector being //
-// outside the interpolation region. If there is such a risk, use //
-// Bool_t IsInside(float *par) method. Chebyshev parameterization is not //
-// good for extrapolation! //
-// //
-// For the properties of Chebyshev parameterization see: //
-// H.Wind, CERN EP Internal Report, 81-12/Rev. //
-// //
-////////////////////////////////////////////////////////////////////////////////
-
#include <TString.h>
#include <TSystem.h>
-#include <TRandom.h>
#include <TROOT.h>
+#include <TRandom.h>
+#include <stdio.h>
+#include <TMethodCall.h>
+#include <TMath.h>
+#include <TH1.h>
#include "AliCheb3D.h"
-#include "AliLog.h"
-
-
+#include "AliCheb3DCalc.h"
ClassImp(AliCheb3D)
-AliCheb3D::AliCheb3D():
- TNamed("", ""),
- fDimOut(0),
- fPrec(0.),
- fChebCalc(),
- fMaxCoefs(0),
- fResTmp(0),
- fGrid(0),
- fUsrFunName(),
- fUsrMacro(0)
-{
- // Default constructor
- Init0();
-}
-
-AliCheb3D::AliCheb3D(const char* inputFile):
- TNamed("", ""),
- fDimOut(0),
- fPrec(0.),
- fChebCalc(),
- fMaxCoefs(0),
- fResTmp(0),
- fGrid(0),
- fUsrFunName(),
- fUsrMacro(0)
+//__________________________________________________________________________________________
+AliCheb3D::AliCheb3D() :
+ fDimOut(0),
+ fPrec(0),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
{
- // Default constructor
- Init0();
- LoadData(inputFile);
+ for (int i=3;i--;) fBMin[i] = fBMax[i] = fBScale[i] = fBOffset[i] = 0;
}
-
-
-AliCheb3D::AliCheb3D(FILE* stream):
- TNamed("", ""),
- fDimOut(0),
- fPrec(0.),
- fChebCalc(),
- fMaxCoefs(0),
- fResTmp(0),
- fGrid(0),
- fUsrFunName(),
- fUsrMacro(0)
+//__________________________________________________________________________________________
+AliCheb3D::AliCheb3D(const AliCheb3D& src) :
+ TNamed(src),
+ fDimOut(src.fDimOut),
+ fPrec(src.fPrec),
+ fChebCalc(1),
+ fMaxCoefs(src.fMaxCoefs),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(src.fUsrFunName),
+ fUsrMacro(0)
{
- // Default constructor
- Init0();
- LoadData(stream);
+ // read coefs from text file
+ for (int i=3;i--;) {
+ fBMin[i] = src.fBMin[i];
+ fBMax[i] = src.fBMax[i];
+ fBScale[i] = src.fBScale[i];
+ fBOffset[i] = src.fBOffset[i];
+ fNPoints[i] = src.fNPoints[i];
+ }
+ for (int i=0;i<fDimOut;i++) {
+ AliCheb3DCalc* cbc = src.GetChebCalc(i);
+ if (cbc) fChebCalc.AddAtAndExpand(new AliCheb3DCalc(*cbc),i);
+ }
}
-AliCheb3D::AliCheb3D(const AliCheb3D& src) :
- TNamed(src),
- fDimOut(src.fDimOut),
- fPrec(src.fPrec),
- fChebCalc(1),
- fMaxCoefs(src.fMaxCoefs),
- fResTmp(0),
- fGrid(0),
- fUsrFunName(src.fUsrFunName),
- fUsrMacro(0)
+//__________________________________________________________________________________________
+AliCheb3D::AliCheb3D(const char* inpFile) :
+ fDimOut(0),
+ fPrec(0),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
{
- // Copy constructor
- // read coefs from text file
- for (int i=3;i--;) {
- fBMin[i] = src.fBMin[i];
- fBMax[i] = src.fBMax[i];
- fBScale[i] = src.fBScale[i];
- fBOffset[i] = src.fBOffset[i];
- fNPoints[i] = src.fNPoints[i];
- }
- for (int i=0;i<fDimOut;i++) {
- AliCheb3DCalc* cbc = src.GetChebCalc(i);
- if (cbc) fChebCalc.AddAtAndExpand(new AliCheb3DCalc(*cbc),i);
- }
+ // read coefs from text file
+ for (int i=3;i--;) fBMin[i] = fBMax[i] = fBScale[i] = fBOffset[i] = 0;
+ LoadData(inpFile);
}
-AliCheb3D& AliCheb3D::operator=(const AliCheb3D& rhs)
+//__________________________________________________________________________________________
+AliCheb3D::AliCheb3D(FILE* stream) :
+ fDimOut(0),
+ fPrec(0),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
{
- // Assignment operator
- if (this != &rhs) {
- Clear();
- fDimOut = rhs.fDimOut;
- fPrec = rhs.fPrec;
- fMaxCoefs = rhs.fMaxCoefs;
- fUsrFunName = rhs.fUsrFunName;
- fUsrMacro = 0;
- for (int i=3;i--;) {
- fBMin[i] = rhs.fBMin[i];
- fBMax[i] = rhs.fBMax[i];
- fBScale[i] = rhs.fBScale[i];
- fBOffset[i] = rhs.fBOffset[i];
- fNPoints[i] = rhs.fNPoints[i];
- }
- for (int i=0;i<fDimOut;i++) {
- AliCheb3DCalc* cbc = rhs.GetChebCalc(i);
- if (cbc) fChebCalc.AddAtAndExpand(new AliCheb3DCalc(*cbc),i);
- }
- }
- return *this;
- //
+ // read coefs from stream
+ for (int i=3;i--;) fBMin[i] = fBMax[i] = fBScale[i] = fBOffset[i] = 0;
+ LoadData(stream);
}
-
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-AliCheb3D::AliCheb3D(const char* funName, int DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec) : TNamed(funName,funName)
+AliCheb3D::AliCheb3D(const char* funName, int DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec) :
+ TNamed(funName,funName),
+ fDimOut(0),
+ fPrec(TMath::Max(1.E-12f,prec)),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName("") ,
+ fUsrMacro(0)
{
// Construct the parameterization for the function
// funName : name of the file containing the function: void funName(Float_t * inp,Float_t * out)
// npoints : array of 3 elements with the number of points to compute in each of 3 dimension
// prec : max allowed absolute difference between the user function and computed parameterization on the requested grid
//
- Init0();
- fPrec = TMath::Max(1.E-12f,prec);
if (DimOut<1) {Error("AliCheb3D","Requested output dimension is %d\nStop\n",fDimOut); exit(1);}
SetDimOut(DimOut);
PrepareBoundaries(bmin,bmax);
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-AliCheb3D::AliCheb3D(void (*ptr)(float*,float*), int DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec) : TNamed("AliCheb3D","AliCheb3D")
+AliCheb3D::AliCheb3D(void (*ptr)(float*,float*), int DimOut, Float_t *bmin,Float_t *bmax, Int_t *npoints, Float_t prec) :
+ fDimOut(0),
+ fPrec(TMath::Max(1.E-12f,prec)),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
{
// Construct the parameterization for the function
// ptr : pointer on the function: void fun(Float_t * inp,Float_t * out)
// npoints : array of 3 elements with the number of points to compute in each of 3 dimension
// prec : max allowed absolute difference between the user function and computed parameterization on the requested grid
//
- Init0();
- fPrec = TMath::Max(1.E-12f,prec);
if (DimOut<1) {Error("AliCheb3D","Requested output dimension is %d\nStop\n",fDimOut); exit(1);}
SetDimOut(DimOut);
PrepareBoundaries(bmin,bmax);
}
#endif
+//__________________________________________________________________________________________
+#ifdef _INC_CREATION_ALICHEB3D_
+AliCheb3D::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) :
+ fDimOut(0),
+ fPrec(TMath::Max(1.E-12f,prec)),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
+{
+ // Construct very economic parameterization for the function
+ // ptr : pointer on the function: void fun(Float_t * inp,Float_t * out)
+ // DimOut : dimension of the vector computed by the user function
+ // bmin : array of 3 elements with the lower boundaries of the region where the function is defined
+ // bmax : array of 3 elements with the upper boundaries of the region where the function is defined
+ // npX : array of 3 elements with the number of points to compute in each dimension for 1st component
+ // npY : array of 3 elements with the number of points to compute in each dimension for 2nd component
+ // npZ : array of 3 elements with the number of points to compute in each dimension for 3d component
+ // prec : max allowed absolute difference between the user function and computed parameterization on the requested grid
+ //
+ if (DimOut<1) {Error("AliCheb3D","Requested output dimension is %d\nStop\n",fDimOut); exit(1);}
+ SetDimOut(DimOut);
+ PrepareBoundaries(bmin,bmax);
+ SetUsrFunction(ptr);
+ //
+ DefineGrid(npX);
+ ChebFit(0);
+ DefineGrid(npY);
+ ChebFit(1);
+ DefineGrid(npZ);
+ ChebFit(2);
+ //
+}
+#endif
+
+
+//__________________________________________________________________________________________
+#ifdef _INC_CREATION_ALICHEB3D_
+AliCheb3D::AliCheb3D(void (*ptr)(float*,float*), int DimOut, Float_t *bmin,Float_t *bmax, Float_t prec) :
+ fDimOut(0),
+ fPrec(TMath::Max(1.E-12f,prec)),
+ fChebCalc(1),
+ fMaxCoefs(0),
+ fResTmp(0),
+ fGrid(0),
+ fUsrFunName(""),
+ fUsrMacro(0)
+{
+ // Construct very economic parameterization for the function with automatic calculation of the root's grid
+ // ptr : pointer on the function: void fun(Float_t * inp,Float_t * out)
+ // DimOut : dimension of the vector computed by the user function
+ // bmin : array of 3 elements with the lower boundaries of the region where the function is defined
+ // bmax : array of 3 elements with the upper boundaries of the region where the function is defined
+ // prec : max allowed absolute difference between the user function and computed parameterization on the requested grid
+ //
+ if (DimOut!=3) {Error("AliCheb3D","This constructor works only for 3D fits, %dD fit was requested\n",fDimOut); exit(1);}
+ SetDimOut(DimOut);
+ PrepareBoundaries(bmin,bmax);
+ SetUsrFunction(ptr);
+ //
+ int gridNC[3][3];
+ EstimateNPoints(prec,gridNC);
+ DefineGrid(gridNC[0]);
+ ChebFit(0);
+ DefineGrid(gridNC[1]);
+ ChebFit(1);
+ DefineGrid(gridNC[2]);
+ ChebFit(2);
+ //
+}
+#endif
+
+
+//__________________________________________________________________________________________
+AliCheb3D& AliCheb3D::operator=(const AliCheb3D& rhs)
+{
+ // assignment operator
+ //
+ if (this != &rhs) {
+ Clear();
+ fDimOut = rhs.fDimOut;
+ fPrec = rhs.fPrec;
+ fMaxCoefs = rhs.fMaxCoefs;
+ fUsrFunName = rhs.fUsrFunName;
+ fUsrMacro = 0;
+ for (int i=3;i--;) {
+ fBMin[i] = rhs.fBMin[i];
+ fBMax[i] = rhs.fBMax[i];
+ fBScale[i] = rhs.fBScale[i];
+ fBOffset[i] = rhs.fBOffset[i];
+ fNPoints[i] = rhs.fNPoints[i];
+ }
+ for (int i=0;i<fDimOut;i++) {
+ AliCheb3DCalc* cbc = rhs.GetChebCalc(i);
+ if (cbc) fChebCalc.AddAtAndExpand(new AliCheb3DCalc(*cbc),i);
+ }
+ }
+ return *this;
+ //
+}
//__________________________________________________________________________________________
-void AliCheb3D::Clear(Option_t*)
+void AliCheb3D::Clear(const Option_t*)
{
-// Clean-up
+ // clear all dynamic structures
+ //
if (fResTmp) { delete[] fResTmp; fResTmp = 0; }
if (fGrid) { delete[] fGrid; fGrid = 0; }
if (fUsrMacro) { delete fUsrMacro; fUsrMacro = 0;}
}
//__________________________________________________________________________________________
-void AliCheb3D::Print(Option_t* opt) const
+void AliCheb3D::Print(const Option_t* opt) const
{
- // Print Chebyshev parameterisation data
+ // print info
+ //
printf("%s: Chebyshev parameterization for 3D->%dD function. Precision: %e\n",GetName(),fDimOut,fPrec);
printf("Region of validity: [%+.5e:%+.5e] [%+.5e:%+.5e] [%+.5e:%+.5e]\n",fBMin[0],fBMax[0],fBMin[1],fBMax[1],fBMin[2],fBMax[2]);
TString opts = opt; opts.ToLower();
}
//__________________________________________________________________________________________
-void AliCheb3D::Init0()
-{
- // Initialisation
- for (int i=3;i--;) fBMin[i] = fBMax[i] = fBScale[i] = fBOffset[i] = 0;
- fMaxCoefs = 0;
- fGrid = 0;
- fResTmp = 0;
- fUsrFunName = "";
- fUsrMacro = 0;
-#ifdef _INC_CREATION_ALICHEB3D_
- gUsrFunAliCheb3D = 0;
-#endif
-}
-
-//__________________________________________________________________________________________
-void AliCheb3D::PrepareBoundaries(Float_t *bmin,Float_t *bmax)
+void AliCheb3D::PrepareBoundaries(const Float_t *bmin, const Float_t *bmax)
{
// Set and check boundaries defined by user, prepare coefficients for their conversion to [-1:1] interval
//
//
}
+
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
+
+// Pointer on user function (faster altrnative to TMethodCall)
+void (*gUsrFunAliCheb3D) (float* ,float* );
+
+void AliCheb3D::EvalUsrFunction()
+{
+ // call user supplied function
+ if (gUsrFunAliCheb3D) gUsrFunAliCheb3D(fArgsTmp,fResTmp);
+ else fUsrMacro->Execute();
+}
+
void AliCheb3D::SetUsrFunction(const char* name)
{
// load user macro with function definition and compile it
#ifdef _INC_CREATION_ALICHEB3D_
void AliCheb3D::SetUsrFunction(void (*ptr)(float*,float*))
{
+ // assign user training function
+ //
if (fUsrMacro) delete fUsrMacro;
fUsrMacro = 0;
fUsrFunName = "";
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-void AliCheb3D::EvalUsrFunction(Float_t *x, Float_t *res) {
+void AliCheb3D::EvalUsrFunction(const Float_t *x, Float_t *res)
+{
+ // evaluate user function value
+ //
for (int i=3;i--;) fArgsTmp[i] = x[i];
if (gUsrFunAliCheb3D) gUsrFunAliCheb3D(fArgsTmp,fResTmp);
else fUsrMacro->Execute();
//__________________________________________________________________________________________
#ifdef _INC_CREATION_ALICHEB3D_
-Int_t AliCheb3D::CalcChebCoefs(Float_t *funval,int np, Float_t *outCoefs, Float_t prec)
+Int_t AliCheb3D::CalcChebCoefs(const Float_t *funval,int np, Float_t *outCoefs, Float_t prec)
{
// Calculate Chebyshev coeffs using precomputed function values at np roots.
// If prec>0, estimate the highest coeff number providing the needed precision
for (int id=3;id--;) {
fNPoints[id] = npoints[id];
if (fNPoints[id]<kMinPoints) {
- Error("DefineGrid","at %d-th dimension %d point is requested, at least %d is needed\nStop\n",fNPoints[id],kMinPoints);
+ Error("DefineGrid","at %d-th dimension %d point is requested, at least %d is needed\nStop\n",id,fNPoints[id],kMinPoints);
exit(1);
}
ntot += fNPoints[id];
fMaxCoefs *= fNPoints[id];
}
+ printf("Computing Chebyshev nodes on [%2d/%2d/%2d] grid\n",npoints[0],npoints[1],npoints[2]);
+ if (fGrid) delete[] fGrid;
fGrid = new Float_t [ntot];
//
int curp = 0;
Float_t *tmpCoef2D = new Float_t [ fNPoints[0]*fNPoints[1] ];
Float_t *tmpCoef1D = new Float_t [ maxDim ];
//
- Float_t RTiny = fPrec/Float_t(maxDim); // neglect coefficient below this threshold
+ Float_t rTiny = fPrec/Float_t(maxDim); // neglect coefficient below this threshold
//
// 1D Cheb.fit for 0-th dimension at current steps of remaining dimensions
int ncmax = 0;
//
+ printf("Dim%d : 00.00%% Done",dmOut);fflush(stdout);
AliCheb3DCalc* cheb = GetChebCalc(dmOut);
//
+ float ncals2count = fNPoints[2]*fNPoints[1]*fNPoints[0];
+ float ncals = 0;
+ float frac = 0;
+ float fracStep = 0.001;
+ //
for (int id2=fNPoints[2];id2--;) {
fArgsTmp[2] = fGrid[ fGridOffs[2]+id2 ];
//
fArgsTmp[0] = fGrid[ fGridOffs[0]+id0 ];
EvalUsrFunction(); // compute function values at Chebyshev roots of 0-th dimension
fvals[id0] = fResTmp[dmOut];
+ float fr = (++ncals)/ncals2count;
+ if (fr-frac>=fracStep) {
+ frac = fr;
+ printf("\b\b\b\b\b\b\b\b\b\b\b");
+ printf("%05.2f%% Done",fr*100);
+ fflush(stdout);
+ }
+ //
}
int nc = CalcChebCoefs(fvals,fNPoints[0], tmpCoef1D, fPrec);
for (int id0=fNPoints[0];id0--;) tmpCoef2D[id1 + id0*fNPoints[1]] = tmpCoef1D[id0];
for (int id2=fNPoints[2];id2--;) {
int id = id2 + fNPoints[2]*(id1+id0*fNPoints[1]);
Float_t cfa = TMath::Abs(tmpCoef3D[id]);
- if (cfa < RTiny) {tmpCoef3D[id] = 0; continue;} // neglect coeefs below the threshold
-
+ if (cfa < rTiny) {tmpCoef3D[id] = 0; continue;} // neglect coefs below the threshold
resid += cfa;
if (resid<fPrec) continue; // this coeff is negligible
// otherwise go back 1 step
}
*/
// see if there are rows to reject, find max.significant column at each row
- int NRows = fNPoints[0];
- int *tmpCols = new int[NRows];
+ int nRows = fNPoints[0];
+ int *tmpCols = new int[nRows];
for (int id0=fNPoints[0];id0--;) {
int id1 = fNPoints[1];
while (id1>0 && tmpCoefSurf[(id1-1)+id0*fNPoints[1]]==0) id1--;
tmpCols[id0] = id1;
}
// find max significant row
- for (int id0=NRows;id0--;) {if (tmpCols[id0]>0) break; NRows--;}
+ for (int id0=nRows;id0--;) {if (tmpCols[id0]>0) break; nRows--;}
// find max significant column and fill the permanent storage for the max sigificant column of each row
- cheb->InitRows(NRows); // create needed arrays;
- int *NColsAtRow = cheb->GetNColsAtRow();
- int *ColAtRowBg = cheb->GetColAtRowBg();
- int NCols = 0;
+ cheb->InitRows(nRows); // create needed arrays;
+ int *nColsAtRow = cheb->GetNColsAtRow();
+ int *colAtRowBg = cheb->GetColAtRowBg();
+ int nCols = 0;
int NElemBound2D = 0;
- for (int id0=0;id0<NRows;id0++) {
- NColsAtRow[id0] = tmpCols[id0]; // number of columns to store for this row
- ColAtRowBg[id0] = NElemBound2D; // begining of this row in 2D boundary surface
+ for (int id0=0;id0<nRows;id0++) {
+ nColsAtRow[id0] = tmpCols[id0]; // number of columns to store for this row
+ colAtRowBg[id0] = NElemBound2D; // begining of this row in 2D boundary surface
NElemBound2D += tmpCols[id0];
- if (NCols<NColsAtRow[id0]) NCols = NColsAtRow[id0];
+ if (nCols<nColsAtRow[id0]) nCols = nColsAtRow[id0];
}
- cheb->InitCols(NCols);
+ cheb->InitCols(nCols);
delete[] tmpCols;
//
// create the 2D matrix defining the boundary of significance for 3D coeffs.matrix
// and count the number of siginifacnt coefficients
//
cheb->InitElemBound2D(NElemBound2D);
- int *CoefBound2D0 = cheb->GetCoefBound2D0();
- int *CoefBound2D1 = cheb->GetCoefBound2D1();
+ int *coefBound2D0 = cheb->GetCoefBound2D0();
+ int *coefBound2D1 = cheb->GetCoefBound2D1();
fMaxCoefs = 0; // redefine number of coeffs
- for (int id0=0;id0<NRows;id0++) {
- int nCLoc = NColsAtRow[id0];
- int col0 = ColAtRowBg[id0];
+ for (int id0=0;id0<nRows;id0++) {
+ int nCLoc = nColsAtRow[id0];
+ int col0 = colAtRowBg[id0];
for (int id1=0;id1<nCLoc;id1++) {
- CoefBound2D0[col0 + id1] = tmpCoefSurf[id1+id0*fNPoints[1]]; // number of coefs to store for 3-d dimension
- CoefBound2D1[col0 + id1] = fMaxCoefs;
- fMaxCoefs += CoefBound2D0[col0 + id1];
+ coefBound2D0[col0 + id1] = tmpCoefSurf[id1+id0*fNPoints[1]]; // number of coefs to store for 3-d dimension
+ coefBound2D1[col0 + id1] = fMaxCoefs;
+ fMaxCoefs += coefBound2D0[col0 + id1];
}
}
//
// create final compressed 3D matrix for significant coeffs
cheb->InitCoefs(fMaxCoefs);
- Float_t *Coefs = cheb->GetCoefs();
+ Float_t *coefs = cheb->GetCoefs();
int count = 0;
- for (int id0=0;id0<NRows;id0++) {
- int ncLoc = NColsAtRow[id0];
- int col0 = ColAtRowBg[id0];
+ for (int id0=0;id0<nRows;id0++) {
+ int ncLoc = nColsAtRow[id0];
+ int col0 = colAtRowBg[id0];
for (int id1=0;id1<ncLoc;id1++) {
- int ncf2 = CoefBound2D0[col0 + id1];
+ int ncf2 = coefBound2D0[col0 + id1];
for (int id2=0;id2<ncf2;id2++) {
- Coefs[count++] = tmpCoef3D[id2 + fNPoints[2]*(id1+id0*fNPoints[1])];
+ coefs[count++] = tmpCoef3D[id2 + fNPoints[2]*(id1+id0*fNPoints[1])];
}
}
}
delete[] tmpCoef3D;
delete[] fvals;
//
+ printf("\b\b\b\b\b\b\b\b\b\b\b\b");
+ printf("100.00%% Done\n");
return 1;
}
#endif
for (int i=0;i<3;i++) fprintf(stream,"%+.8e\n",fBMin[i]);
fprintf(stream,"# Upper boundaries of interpolation region\n");
for (int i=0;i<3;i++) fprintf(stream,"%+.8e\n",fBMax[i]);
- fprintf(stream,"# Parameterization for each output dimension follows:\n",GetName());
+ fprintf(stream,"# Parameterization for each output dimension follows:\n");
//
for (int i=0;i<fDimOut;i++) GetChebCalc(i)->SaveData(stream);
fprintf(stream,"#\nEND %s\n#\n",GetName());
//_______________________________________________
void AliCheb3D::LoadData(const char* inpFile)
{
- // Load data from input file
+ // load coefficients data from txt file
+ //
TString strf = inpFile;
gSystem->ExpandPathName(strf);
FILE* stream = fopen(strf.Data(),"r");
//_______________________________________________
void AliCheb3D::LoadData(FILE* stream)
{
- // Load data from input stream stream
+ // load coefficients data from stream
+ //
if (!stream) {Error("LoadData","No stream provided.\nStop"); exit(1);}
TString buffs;
Clear();
}
//_______________________________________________
-void AliCheb3D::SetDimOut(int d)
+void AliCheb3D::SetDimOut(const int d)
{
- // Set the dimension of the output array
+ // init output dimensions
fDimOut = d;
if (fResTmp) delete fResTmp;
- fResTmp = new Float_t[fDimOut]; // RRR
+ fResTmp = new Float_t[fDimOut];
fChebCalc.Delete();
for (int i=0;i<d;i++) fChebCalc.AddAtAndExpand(new AliCheb3DCalc(),i);
}
//_______________________________________________
void AliCheb3D::ShiftBound(int id,float dif)
{
- //Shift the boundary of dimension id
+ // modify the bounds of the grid
+ //
if (id<0||id>2) {printf("Maximum 3 dimensions are supported\n"); return;}
fBMin[id] += dif;
fBMax[id] += dif;
//
}
#endif
+
+//_______________________________________________
+#ifdef _INC_CREATION_ALICHEB3D_
+void AliCheb3D::EstimateNPoints(float Prec, int gridBC[3][3])
+{
+ // Estimate number of points to generate a training data
+ //
+ const float sclA[9] = {0.1, 0.5, 0.9, 0.1, 0.5, 0.9, 0.1, 0.5, 0.9} ;
+ const float sclB[9] = {0.1, 0.1, 0.1, 0.5, 0.5, 0.5, 0.9, 0.9, 0.9} ;
+ const float sclDim[2] = {0.01,0.99};
+ const int compDim[3][2] = { {1,2}, {2,0}, {0,1} };
+ static float xyz[3];
+ //
+ for (int i=3;i--;)for (int j=3;j--;) gridBC[i][j] = -1;
+ //
+ for (int idim=0;idim<3;idim++) {
+ float dimMN = fBMin[idim] + sclDim[0]*(fBMax[idim]-fBMin[idim]);
+ float dimMX = fBMin[idim] + sclDim[1]*(fBMax[idim]-fBMin[idim]);
+ //
+ for (int it=0;it<9;it++) { // test in 9 points
+ int id1 = compDim[idim][0]; // 1st fixed dim
+ int id2 = compDim[idim][1]; // 2nd fixed dim
+ xyz[ id1 ] = fBMin[id1] + sclA[it]*( fBMax[id1]-fBMin[id1] );
+ xyz[ id2 ] = fBMin[id2] + sclB[it]*( fBMax[id2]-fBMin[id2] );
+ //
+ int* npt = GetNCNeeded(xyz,idim, dimMN,dimMX, Prec); // npoints for Bx,By,Bz
+ for (int ib=0;ib<3;ib++) if (npt[ib]>gridBC[ib][idim]) gridBC[ib][idim] = npt[ib]+2;
+ //
+ }
+ }
+}
+
+
+int* AliCheb3D::GetNCNeeded(float xyz[3],int DimVar, float mn,float mx, float prec)
+{
+ // estimate needed number of chebyshev coefs for given function desctiption in DimVar dimension
+ // The values for two other dimensions must be set beforehand
+ //
+ static int curNC[3];
+ static int retNC[3];
+ const int kMaxPoint = 400;
+ float* gridVal = new float[3*kMaxPoint];
+ float* coefs = new float[3*kMaxPoint];
+ //
+ float scale = mx-mn;
+ float offs = mn + scale/2.0;
+ scale = 2./scale;
+ //
+ int curNP;
+ int maxNC=-1;
+ int maxNCPrev=-1;
+ for (int i=0;i<3;i++) retNC[i] = -1;
+ for (int i=0;i<3;i++) fArgsTmp[i] = xyz[i];
+ //
+ for (curNP=5; curNP<kMaxPoint; curNP+=5) {
+ maxNCPrev = maxNC;
+ //
+ for (int i=0;i<curNP;i++) { // get function values on Cheb. nodes
+ float x = TMath::Cos( TMath::Pi()*(i+0.5)/curNP );
+ fArgsTmp[DimVar] = x/scale+offs; // map to requested interval
+ EvalUsrFunction();
+ for (int ib=3;ib--;) gridVal[ib*kMaxPoint + i] = fResTmp[ib];
+ }
+ //
+ for (int ib=0;ib<3;ib++) {
+ curNC[ib] = AliCheb3D::CalcChebCoefs(&gridVal[ib*kMaxPoint], curNP, &coefs[ib*kMaxPoint],prec);
+ if (maxNC < curNC[ib]) maxNC = curNC[ib];
+ if (retNC[ib] < curNC[ib]) retNC[ib] = curNC[ib];
+ }
+ if ( (curNP-maxNC)>3 && (maxNC-maxNCPrev)<1 ) break;
+ maxNCPrev = maxNC;
+ //
+ }
+ delete[] gridVal;
+ delete[] coefs;
+ return retNC;
+ //
+}
+#endif