Project
Loading...
Searching...
No Matches
Chebyshev3DCalc.h
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
15
16#ifndef ALICEO2_MATHUTILS_CHEBYSHEV3DCALC_H_
17#define ALICEO2_MATHUTILS_CHEBYSHEV3DCALC_H_
18
19#include <TNamed.h> // for TNamed
20#include <cstdio> // for FILE, stdout
21#include <cmath> // for std::fma
22#include "Rtypes.h" // for Float_t, UShort_t, Int_t, Double_t, etc
23
24class TString;
25
26// To decrease the compilable code size comment this define. This will exclude the routines
27// used for the calculation and saving of the coefficients.
28#define _INC_CREATION_Chebyshev3D_
29
30// When _BRING_TO_BOUNDARY_ is defined, the point outside of the fitted folume is assumed to be on the surface
31// #define _BRING_TO_BOUNDARY_
32
33namespace o2
34{
35namespace math_utils
36{
37class Chebyshev3DCalc : public TNamed
38{
39
40 public:
43
46
49
52 {
53 Clear();
54 }
55
58
60 void Print(const Option_t* opt = "") const override;
61
63 void loadData(FILE* stream);
64
67 Float_t evaluateDerivative(int dim, const Float_t* par) const;
68
71 Float_t evaluateDerivative2(int dim1, int dim2, const Float_t* par) const;
72
73#ifdef _INC_CREATION_Chebyshev3D_
74
76 void saveData(const char* outfile, Bool_t append = kFALSE) const;
77
78 // Writes coefficients data to existing output stream
79 // Note: mNumberOfColumns, mNumberOfElementsBound2D and mColumnAtRowBeginning are not stored, will be computed on fly
80 // during the loading of this file
81 void saveData(FILE* stream = stdout) const;
82
83#endif
84
86 void initializeRows(int nr);
87
89 void initializeColumns(int nc);
90
92 {
93 return mNumberOfCoefficients;
94 }
95
96 Int_t getNumberOfColumns() const
97 {
98 return (Int_t)mNumberOfColumns;
99 }
100
101 Int_t getNumberOfRows() const
102 {
103 return (Int_t)mNumberOfRows;
104 }
105
107 {
108 return (Int_t)mNumberOfElementsBound2D;
109 }
110
111 Int_t getMaxColumnsAtRow() const;
112
113 UShort_t* getNumberOfColumnsAtRow() const
114 {
115 return mNumberOfColumnsAtRow;
116 }
117
118 UShort_t* getColAtRowBg() const
119 {
120 return mColumnAtRowBeginning;
121 }
122
124 {
125 return mPrecision;
126 }
127
129 void setPrecision(Float_t prc = 1e-6)
130 {
131 mPrecision = prc;
132 }
133
135 void initializeElementBound2D(int ne);
136
137 UShort_t* getCoefficientBound2D0() const
138 {
139 return mCoefficientBound2D0;
140 }
141
142 UShort_t* getCoefficientBound2D1() const
143 {
144 return mCoefficientBound2D1;
145 }
146
148 void Clear(const Option_t* option = "") override;
149
150 static Float_t chebyshevEvaluation1D(Float_t x, const Float_t* array, int ncf);
151
154
157
159 void initializeCoefficients(int nc);
160
162 {
163 return mCoefficients;
164 }
165
167 static void readLine(TString& str, FILE* stream);
168
169 Float_t Eval(const Float_t* par) const;
170
171 Double_t Eval(const Double_t* par) const;
172
173 private:
174 Int_t mNumberOfCoefficients;
175 Int_t mNumberOfRows;
176 Int_t mNumberOfColumns;
177 Int_t mNumberOfElementsBound2D;
178 Float_t mPrecision;
180 UShort_t*
181 mNumberOfColumnsAtRow; //[mNumberOfRows] number of sighificant columns (2nd dim) at each row of 3D coefs matrix
182 UShort_t* mColumnAtRowBeginning; //[mNumberOfRows] beginning of significant columns (2nd dim) for row in the 2D
183 // boundary matrix
184 UShort_t* mCoefficientBound2D0; //[mNumberOfElementsBound2D] 2D matrix defining the boundary of significance for 3D
185 // coeffs.matrix
186 //(Ncoefs for col/row)
187 UShort_t* mCoefficientBound2D1; //[mNumberOfElementsBound2D] 2D matrix defining the start beginning of significant
188 // coeffs for col/row
189 Float_t* mCoefficients; //[mNumberOfCoefficients] array of Chebyshev coefficients
190
191 Float_t* mTemporaryCoefficients2D; //[mNumberOfColumns] temp. coeffs for 2d summation
192 Float_t* mTemporaryCoefficients1D; //[mNumberOfRows] temp. coeffs for 1d summation
193
194 ClassDefOverride(o2::math_utils::Chebyshev3DCalc,
195 2) // Class for interpolation of 3D->1 function by Chebyshev parametrization
196};
197
200{
201 if (ncf <= 0) {
202 return 0;
203 }
204
205 Float_t b0, b1, b2, x2 = x + x;
206 b0 = array[--ncf];
207 b1 = b2 = 0;
208
209 for (int i = ncf; i--;) {
210 b2 = b1;
211 b1 = b0;
212 // Clenshaw recurrence, grouped as fma(x2, b1, array[i] - b2). Mathematically
213 // identical to `array[i] + x2 * b1 - b2`, but `array[i] - b2` does not depend
214 // on the just-updated b1, so the loop-carried chain collapses to a single FMA
215 // latency instead of a dependent multiply+add+subtract. This kernel dominates
216 // magnetic-field evaluation in (e.g.) muon track extrapolation.
217 b0 = std::fma(x2, b1, array[i] - b2);
218 }
219 return std::fma(-x, b1, b0);
220}
221
224inline Float_t Chebyshev3DCalc::Eval(const Float_t* par) const
225{
226 for (int id0 = mNumberOfRows; id0--;) {
227 int nCLoc = mNumberOfColumnsAtRow[id0]; // number of significant coefs on this row
228 int col0 = mColumnAtRowBeginning[id0]; // beginning of local column in the 2D boundary matrix
229 for (int id1 = nCLoc; id1--;) {
230 int id = id1 + col0;
231 mTemporaryCoefficients2D[id1] = chebyshevEvaluation1D(par[2], mCoefficients + mCoefficientBound2D1[id], mCoefficientBound2D0[id]);
232 }
233 mTemporaryCoefficients1D[id0] = chebyshevEvaluation1D(par[1], mTemporaryCoefficients2D, nCLoc);
234 }
235 return chebyshevEvaluation1D(par[0], mTemporaryCoefficients1D, mNumberOfRows);
236}
237
240inline Double_t Chebyshev3DCalc::Eval(const Double_t* par) const
241{
242 for (int id0 = mNumberOfRows; id0--;) {
243 int nCLoc = mNumberOfColumnsAtRow[id0]; // number of significant coefs on this row
244 int col0 = mColumnAtRowBeginning[id0]; // beginning of local column in the 2D boundary matrix
245 for (int id1 = nCLoc; id1--;) {
246 int id = id1 + col0;
247 mTemporaryCoefficients2D[id1] = chebyshevEvaluation1D(par[2], mCoefficients + mCoefficientBound2D1[id], mCoefficientBound2D0[id]);
248 }
249 mTemporaryCoefficients1D[id0] = chebyshevEvaluation1D(par[1], mTemporaryCoefficients2D, nCLoc);
250 }
251 return chebyshevEvaluation1D(par[0], mTemporaryCoefficients1D, mNumberOfRows);
252}
253} // namespace math_utils
254} // namespace o2
255
256#endif
int32_t i
Float_t Eval(const Float_t *par) const
void Print(const Option_t *opt="") const override
Prints info.
static Float_t chebyshevEvaluation1Derivative2(Float_t x, const Float_t *array, int ncf)
Evaluates 1D Chebyshev parameterization's 2nd derivative. x is the argument mapped to [-1:1] interval...
void Clear(const Option_t *option="") override
Deletes all dynamically allocated structures.
UShort_t * getNumberOfColumnsAtRow() const
Chebyshev3DCalc & operator=(const Chebyshev3DCalc &rhs)
Assignment operator.
Float_t evaluateDerivative(int dim, const Float_t *par) const
void saveData(const char *outfile, Bool_t append=kFALSE) const
Writes coefficients data to output text file, optionally appending on the end of existing file.
static Float_t chebyshevEvaluation1D(Float_t x, const Float_t *array, int ncf)
Evaluates 1D Chebyshev parameterization. x is the argument mapped to [-1:1] interval.
void loadData(FILE *stream)
Loads coefficients from the stream.
UShort_t * getCoefficientBound2D0() const
void saveData(FILE *stream=stdout) const
Float_t evaluateDerivative2(int dim1, int dim2, const Float_t *par) const
static Float_t chebyshevEvaluation1Derivative(Float_t x, const Float_t *array, int ncf)
Evaluates 1D Chebyshev parameterization's derivative. x is the argument mapped to [-1:1] interval.
void initializeElementBound2D(int ne)
Sets maximum number of significant coefficients for given row/column of coefficients 3D matrix.
static void readLine(TString &str, FILE *stream)
Reads single line from the stream, skipping empty and commented lines. EOF is not expected.
~Chebyshev3DCalc() override
Default destructor.
void initializeRows(int nr)
Sets maximum number of significant rows in the coefficients matrix.
UShort_t * getCoefficientBound2D1() const
void initializeCoefficients(int nc)
Sets total number of significant coefficients.
Chebyshev3DCalc()
Default constructor.
void setPrecision(Float_t prc=1e-6)
Sets requested precision.
void initializeColumns(int nc)
Sets maximum number of significant columns in the coefficients matrix.
GLint GLenum GLint x
Definition glcorearb.h:403
GLenum src
Definition glcorearb.h:1767
GLenum array
Definition glcorearb.h:4274
GLuint GLuint stream
Definition glcorearb.h:1806
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
const std::string str