]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/STEERBase/AliCheb3DCalc.cxx
Update timestamp for new data points simulation
[u/mrichter/AliRoot.git] / STEER / STEERBase / AliCheb3DCalc.cxx
CommitLineData
99adacae 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
b09247a2 16#include <cstdlib>
5406439e 17#include <TSystem.h>
ff66b122 18#include "AliCheb3DCalc.h"
fa638b6a 19#include "AliLog.h"
99adacae 20
21ClassImp(AliCheb3DCalc)
22
40389866 23//__________________________________________________________________________________________
24AliCheb3DCalc::AliCheb3DCalc() :
25 fNCoefs(0),
26 fNRows(0),
27 fNCols(0),
28 fNElemBound2D(0),
29 fNColsAtRow(0),
30 fColAtRowBg(0),
31 fCoefBound2D0(0),
32 fCoefBound2D1(0),
33 fCoefs(0),
34 fTmpCf1(0),
f69ec3f4 35 fTmpCf0(0),
36 fPrec(0)
5406439e 37{
38 // default constructor
39}
99adacae 40
40389866 41//__________________________________________________________________________________________
42AliCheb3DCalc::AliCheb3DCalc(const AliCheb3DCalc& src) :
43 TNamed(src),
44 fNCoefs(src.fNCoefs),
45 fNRows(src.fNRows),
46 fNCols(src.fNCols),
47 fNElemBound2D(src.fNElemBound2D),
48 fNColsAtRow(0),
49 fColAtRowBg(0),
50 fCoefBound2D0(0),
51 fCoefBound2D1(0),
52 fCoefs(0),
53 fTmpCf1(0),
f69ec3f4 54 fTmpCf0(0),
55 fPrec(src.fPrec)
99adacae 56{
5406439e 57 // copy constructor
58 //
40389866 59 if (src.fNColsAtRow) {
1d18ebe0 60 fNColsAtRow = new UShort_t[fNRows];
40389866 61 for (int i=fNRows;i--;) fNColsAtRow[i] = src.fNColsAtRow[i];
62 }
63 if (src.fColAtRowBg) {
1d18ebe0 64 fColAtRowBg = new UShort_t[fNRows];
40389866 65 for (int i=fNRows;i--;) fColAtRowBg[i] = src.fColAtRowBg[i];
66 }
67 if (src.fCoefBound2D0) {
1d18ebe0 68 fCoefBound2D0 = new UShort_t[fNElemBound2D];
40389866 69 for (int i=fNElemBound2D;i--;) fCoefBound2D0[i] = src.fCoefBound2D0[i];
70 }
71 if (src.fCoefBound2D1) {
1d18ebe0 72 fCoefBound2D1 = new UShort_t[fNElemBound2D];
40389866 73 for (int i=fNElemBound2D;i--;) fCoefBound2D1[i] = src.fCoefBound2D1[i];
74 }
75 if (src.fCoefs) {
76 fCoefs = new Float_t[fNCoefs];
77 for (int i=fNCoefs;i--;) fCoefs[i] = src.fCoefs[i];
78 }
79 if (src.fTmpCf1) fTmpCf1 = new Float_t[fNCols];
80 if (src.fTmpCf0) fTmpCf0 = new Float_t[fNRows];
99adacae 81}
82
40389866 83//__________________________________________________________________________________________
84AliCheb3DCalc::AliCheb3DCalc(FILE* stream) :
85 fNCoefs(0),
86 fNRows(0),
87 fNCols(0),
88 fNElemBound2D(0),
89 fNColsAtRow(0),
90 fColAtRowBg(0),
91 fCoefBound2D0(0),
92 fCoefBound2D1(0),
93 fCoefs(0),
94 fTmpCf1(0),
f69ec3f4 95 fTmpCf0(0),
96 fPrec(0)
99adacae 97{
5406439e 98 // constructor from coeffs. streem
40389866 99 LoadData(stream);
99adacae 100}
101
40389866 102//__________________________________________________________________________________________
103AliCheb3DCalc& AliCheb3DCalc::operator=(const AliCheb3DCalc& rhs)
99adacae 104{
5406439e 105 // assignment operator
40389866 106 if (this != &rhs) {
107 Clear();
108 SetName(rhs.GetName());
109 SetTitle(rhs.GetTitle());
110 fNCoefs = rhs.fNCoefs;
111 fNRows = rhs.fNRows;
112 fNCols = rhs.fNCols;
f69ec3f4 113 fPrec = rhs.fPrec;
40389866 114 if (rhs.fNColsAtRow) {
1d18ebe0 115 fNColsAtRow = new UShort_t[fNRows];
40389866 116 for (int i=fNRows;i--;) fNColsAtRow[i] = rhs.fNColsAtRow[i];
99adacae 117 }
40389866 118 if (rhs.fColAtRowBg) {
1d18ebe0 119 fColAtRowBg = new UShort_t[fNRows];
40389866 120 for (int i=fNRows;i--;) fColAtRowBg[i] = rhs.fColAtRowBg[i];
99adacae 121 }
40389866 122 if (rhs.fCoefBound2D0) {
1d18ebe0 123 fCoefBound2D0 = new UShort_t[fNElemBound2D];
40389866 124 for (int i=fNElemBound2D;i--;) fCoefBound2D0[i] = rhs.fCoefBound2D0[i];
99adacae 125 }
40389866 126 if (rhs.fCoefBound2D1) {
1d18ebe0 127 fCoefBound2D1 = new UShort_t[fNElemBound2D];
40389866 128 for (int i=fNElemBound2D;i--;) fCoefBound2D1[i] = rhs.fCoefBound2D1[i];
99adacae 129 }
40389866 130 if (rhs.fCoefs) {
131 fCoefs = new Float_t[fNCoefs];
132 for (int i=fNCoefs;i--;) fCoefs[i] = rhs.fCoefs[i];
99adacae 133 }
40389866 134 if (rhs.fTmpCf1) fTmpCf1 = new Float_t[fNCols];
135 if (rhs.fTmpCf0) fTmpCf0 = new Float_t[fNRows];
136 }
137 return *this;
99adacae 138}
139
140//__________________________________________________________________________________________
5406439e 141void AliCheb3DCalc::Clear(const Option_t*)
99adacae 142{
143 // delete all dynamycally allocated structures
144 if (fTmpCf1) { delete[] fTmpCf1; fTmpCf1 = 0;}
145 if (fTmpCf0) { delete[] fTmpCf0; fTmpCf0 = 0;}
146 if (fCoefs) { delete[] fCoefs; fCoefs = 0;}
147 if (fCoefBound2D0) { delete[] fCoefBound2D0; fCoefBound2D0 = 0; }
148 if (fCoefBound2D1) { delete[] fCoefBound2D1; fCoefBound2D1 = 0; }
149 if (fNColsAtRow) { delete[] fNColsAtRow; fNColsAtRow = 0; }
150 if (fColAtRowBg) { delete[] fColAtRowBg; fColAtRowBg = 0; }
151 //
152}
153
99adacae 154//__________________________________________________________________________________________
5406439e 155void AliCheb3DCalc::Print(const Option_t* ) const
99adacae 156{
5406439e 157 // print info
f69ec3f4 158 printf("Chebyshev parameterization data %s for 3D->1 function. Prec:%e\n",GetName(),fPrec);
99adacae 159 int nmax3d = 0;
160 for (int i=fNElemBound2D;i--;) if (fCoefBound2D0[i]>nmax3d) nmax3d = fCoefBound2D0[i];
161 printf("%d coefficients in %dx%dx%d matrix\n",fNCoefs,fNRows,fNCols,nmax3d);
162 //
163}
164
40389866 165//__________________________________________________________________________________________
5406439e 166Float_t AliCheb3DCalc::EvalDeriv(int dim, const Float_t *par) const
40389866 167{
168 // evaluate Chebyshev parameterization derivative in given dimension for 3D function.
169 // VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
40389866 170 //
171 int ncfRC;
172 for (int id0=fNRows;id0--;) {
173 int nCLoc = fNColsAtRow[id0]; // number of significant coefs on this row
1cf34ee8 174 if (!nCLoc) {fTmpCf0[id0]=0; continue;}
175 //
5406439e 176 int col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
40389866 177 for (int id1=nCLoc;id1--;) {
5406439e 178 int id = id1+col0;
1cf34ee8 179 if (!(ncfRC=fCoefBound2D0[id])) { fTmpCf1[id1]=0; continue;}
ff66b122 180 if (dim==2) fTmpCf1[id1] = ChebEval1Deriv(par[2],fCoefs + fCoefBound2D1[id], ncfRC);
181 else fTmpCf1[id1] = ChebEval1D(par[2],fCoefs + fCoefBound2D1[id], ncfRC);
40389866 182 }
ff66b122 183 if (dim==1) fTmpCf0[id0] = ChebEval1Deriv(par[1],fTmpCf1,nCLoc);
184 else fTmpCf0[id0] = ChebEval1D(par[1],fTmpCf1,nCLoc);
40389866 185 }
ff66b122 186 return (dim==0) ? ChebEval1Deriv(par[0],fTmpCf0,fNRows) : ChebEval1D(par[0],fTmpCf0,fNRows);
40389866 187 //
188}
189
1cf34ee8 190//__________________________________________________________________________________________
5406439e 191Float_t AliCheb3DCalc::EvalDeriv2(int dim1,int dim2, const Float_t *par) const
1cf34ee8 192{
193 // evaluate Chebyshev parameterization 2n derivative in given dimensions for 3D function.
194 // VERY IMPORTANT: par must contain the function arguments ALREADY MAPPED to [-1:1] interval
1cf34ee8 195 //
196 Bool_t same = dim1==dim2;
197 int ncfRC;
198 for (int id0=fNRows;id0--;) {
199 int nCLoc = fNColsAtRow[id0]; // number of significant coefs on this row
200 if (!nCLoc) {fTmpCf0[id0]=0; continue;}
201 //
5406439e 202 int col0 = fColAtRowBg[id0]; // beginning of local column in the 2D boundary matrix
1cf34ee8 203 for (int id1=nCLoc;id1--;) {
5406439e 204 int id = id1+col0;
1cf34ee8 205 if (!(ncfRC=fCoefBound2D0[id])) { fTmpCf1[id1]=0; continue;}
ff66b122 206 if (dim1==2||dim2==2) fTmpCf1[id1] = same ? ChebEval1Deriv2(par[2],fCoefs + fCoefBound2D1[id], ncfRC)
207 : ChebEval1Deriv(par[2],fCoefs + fCoefBound2D1[id], ncfRC);
208 else fTmpCf1[id1] = ChebEval1D(par[2],fCoefs + fCoefBound2D1[id], ncfRC);
1cf34ee8 209 }
ff66b122 210 if (dim1==1||dim2==1) fTmpCf0[id0] = same ? ChebEval1Deriv2(par[1],fTmpCf1,nCLoc):ChebEval1Deriv(par[1],fTmpCf1,nCLoc);
211 else fTmpCf0[id0] = ChebEval1D(par[1],fTmpCf1,nCLoc);
1cf34ee8 212 }
ff66b122 213 return (dim1==0||dim2==0) ? (same ? ChebEval1Deriv2(par[0],fTmpCf0,fNRows):ChebEval1Deriv(par[0],fTmpCf0,fNRows)) :
214 ChebEval1D(par[0],fTmpCf0,fNRows);
1cf34ee8 215 //
216}
217
99adacae 218//_______________________________________________
219#ifdef _INC_CREATION_ALICHEB3D_
220void AliCheb3DCalc::SaveData(const char* outfile,Bool_t append) const
221{
222 // writes coefficients data to output text file, optionallt appending on the end of existing file
223 TString strf = outfile;
224 gSystem->ExpandPathName(strf);
225 FILE* stream = fopen(strf,append ? "a":"w");
226 SaveData(stream);
227 fclose(stream);
228 //
229}
230#endif
231
232//_______________________________________________
233#ifdef _INC_CREATION_ALICHEB3D_
234void AliCheb3DCalc::SaveData(FILE* stream) const
235{
236 // writes coefficients data to existing output stream
237 // Note: fNCols, fNElemBound2D and fColAtRowBg is not stored, will be computed on fly during the loading of this file
238 fprintf(stream,"#\nSTART %s\n",GetName());
239 fprintf(stream,"# Number of rows\n%d\n",fNRows);
240 //
241 fprintf(stream,"# Number of columns per row\n");
242 for (int i=0;i<fNRows;i++) fprintf(stream,"%d\n",fNColsAtRow[i]);
243 //
244 fprintf(stream,"# Number of Coefs in each significant block of third dimension\n");
245 for (int i=0;i<fNElemBound2D;i++) fprintf(stream,"%d\n",fCoefBound2D0[i]);
246 //
247 fprintf(stream,"# Coefficients\n");
248 for (int i=0;i<fNCoefs;i++) fprintf(stream,"%+.8e\n",fCoefs[i]);
f69ec3f4 249 //
250 fprintf(stream,"# Precision\n");
251 fprintf(stream,"%+.8e\n",fPrec);
252 //
99adacae 253 fprintf(stream,"END %s\n",GetName());
254 //
255}
256#endif
257
258//_______________________________________________
259void AliCheb3DCalc::LoadData(FILE* stream)
260{
261 // Load coefs. from the stream
fa638b6a 262 if (!stream) AliFatal("No stream provided");
99adacae 263 TString buffs;
264 Clear();
265 ReadLine(buffs,stream);
fa638b6a 266 if (!buffs.BeginsWith("START")) AliFatalF("Expected: \"START <fit_name>\", found \"%s\"",buffs.Data());
99adacae 267 if (buffs.First(' ')>0) SetName(buffs.Data()+buffs.First(' ')+1);
268 //
269 ReadLine(buffs,stream); // NRows
270 fNRows = buffs.Atoi();
fa638b6a 271 if (fNRows<0 && !buffs.IsDigit()) AliFatalF("Expected: '<number_of_rows>', found \"%s\"",buffs.Data());
99adacae 272 //
273 fNCols = 0;
274 fNElemBound2D = 0;
275 InitRows(fNRows);
276 //
277 for (int id0=0;id0<fNRows;id0++) {
278 ReadLine(buffs,stream); // n.cols at this row
279 fNColsAtRow[id0] = buffs.Atoi();
280 fColAtRowBg[id0] = fNElemBound2D; // begining of this row in 2D boundary surface
281 fNElemBound2D += fNColsAtRow[id0];
282 if (fNCols<fNColsAtRow[id0]) fNCols = fNColsAtRow[id0];
283 }
284 InitCols(fNCols);
285 //
286 fNCoefs = 0;
287 InitElemBound2D(fNElemBound2D);
288 //
289 for (int i=0;i<fNElemBound2D;i++) {
290 ReadLine(buffs,stream); // n.coeffs at 3-d dimension for the given column/row
291 fCoefBound2D0[i] = buffs.Atoi();
292 fCoefBound2D1[i] = fNCoefs;
293 fNCoefs += fCoefBound2D0[i];
294 }
295 //
99adacae 296 InitCoefs(fNCoefs);
297 for (int i=0;i<fNCoefs;i++) {
298 ReadLine(buffs,stream);
299 fCoefs[i] = buffs.Atof();
300 }
f69ec3f4 301 //
302 // read precision
303 ReadLine(buffs,stream);
304 fPrec = buffs.Atof();
305 //
99adacae 306 // check end_of_data record
307 ReadLine(buffs,stream);
fa638b6a 308 if (!buffs.BeginsWith("END") || !buffs.Contains(GetName())) AliFatalF("Expected \"END %s\", found \"%s\"",GetName(),buffs.Data());
99adacae 309 //
310}
311
312//_______________________________________________
313void AliCheb3DCalc::ReadLine(TString& str,FILE* stream)
314{
315 // read single line from the stream, skipping empty and commented lines. EOF is not expected
316 while (str.Gets(stream)) {
317 str = str.Strip(TString::kBoth,' ');
318 if (str.IsNull()||str.BeginsWith("#")) continue;
319 return;
320 }
fa638b6a 321 AliFatalGeneral("ReadLine","Failed to read from stream"); // normally, should not reach here
99adacae 322}
323
324//_______________________________________________
325void AliCheb3DCalc::InitCols(int nc)
326{
327 // Set max.number of significant columns in the coefs matrix
328 fNCols = nc;
b39f9e02 329 if (fTmpCf1) {delete[] fTmpCf1; fTmpCf1 = 0;}
330 if (fNCols>0) fTmpCf1 = new Float_t [fNCols];
99adacae 331}
332
333//_______________________________________________
334void AliCheb3DCalc::InitRows(int nr)
335{
336 // Set max.number of significant rows in the coefs matrix
b39f9e02 337 if (fNColsAtRow) {delete[] fNColsAtRow; fNColsAtRow = 0;}
338 if (fColAtRowBg) {delete[] fColAtRowBg; fColAtRowBg = 0;}
339 if (fTmpCf0) {delete[] fTmpCf0; fTmpCf0 = 0;}
99adacae 340 fNRows = nr;
b39f9e02 341 if (fNRows>0) {
342 fNColsAtRow = new UShort_t[fNRows];
343 fTmpCf0 = new Float_t [fNRows];
344 fColAtRowBg = new UShort_t[fNRows];
345 for (int i=fNRows;i--;) fNColsAtRow[i] = fColAtRowBg[i] = 0;
346 }
99adacae 347}
348
349//_______________________________________________
350void AliCheb3DCalc::InitElemBound2D(int ne)
351{
352 // Set max number of significant coefs for given row/column of coefs 3D matrix
b39f9e02 353 if (fCoefBound2D0) {delete[] fCoefBound2D0; fCoefBound2D0 = 0;}
354 if (fCoefBound2D1) {delete[] fCoefBound2D1; fCoefBound2D1 = 0;}
99adacae 355 fNElemBound2D = ne;
b39f9e02 356 if (fNElemBound2D>0) {
357 fCoefBound2D0 = new UShort_t[fNElemBound2D];
358 fCoefBound2D1 = new UShort_t[fNElemBound2D];
359 for (int i=fNElemBound2D;i--;) fCoefBound2D0[i] = fCoefBound2D1[i] = 0;
360 }
99adacae 361}
362
363//_______________________________________________
364void AliCheb3DCalc::InitCoefs(int nc)
365{
366 // Set total number of significant coefs
b39f9e02 367 if (fCoefs) {delete[] fCoefs; fCoefs = 0;}
99adacae 368 fNCoefs = nc;
b39f9e02 369 if (fNCoefs>0) {
370 fCoefs = new Float_t [fNCoefs];
371 for (int i=fNCoefs;i--;) fCoefs[i] = 0.0;
372 }
99adacae 373}
374
40389866 375//__________________________________________________________________________________________
376Float_t AliCheb3DCalc::ChebEval1Deriv(Float_t x, const Float_t * array, int ncf )
377{
378 // evaluate 1D Chebyshev parameterization's derivative. x is the argument mapped to [-1:1] interval
1cf34ee8 379 if (--ncf<1) return 0;
40389866 380 Float_t b0, b1, b2;
381 Float_t x2 = x+x;
382 b1 = b2 = 0;
383 float dcf0=0,dcf1,dcf2=0;
384 b0 = dcf1 = 2*ncf*array[ncf];
1cf34ee8 385 if (!(--ncf)) return b0/2;
40389866 386 //
387 for (int i=ncf;i--;) {
388 b2 = b1;
389 b1 = b0;
390 dcf0 = dcf2 + 2*(i+1)*array[i+1];
391 b0 = dcf0 + x2*b1 -b2;
392 dcf2 = dcf1;
393 dcf1 = dcf0;
394 }
395 //
396 return b0 - x*b1 - dcf0/2;
397}
1cf34ee8 398
399//__________________________________________________________________________________________
400Float_t AliCheb3DCalc::ChebEval1Deriv2(Float_t x, const Float_t * array, int ncf )
401{
402 // evaluate 1D Chebyshev parameterization's 2nd derivative. x is the argument mapped to [-1:1] interval
403 if (--ncf<2) return 0;
404 Float_t b0, b1, b2;
405 Float_t x2 = x+x;
406 b1 = b2 = 0;
407 float dcf0=0,dcf1=0,dcf2=0;
408 float ddcf0=0,ddcf1,ddcf2=0;
409 //
410 dcf2 = 2*ncf*array[ncf];
411 --ncf;
412
413 dcf1 = 2*ncf*array[ncf];
414 b0 = ddcf1 = 2*ncf*dcf2;
415 //
416 if (!(--ncf)) return b0/2;
417 //
418 for (int i=ncf;i--;) {
419 b2 = b1;
420 b1 = b0;
421 dcf0 = dcf2 + 2*(i+1)*array[i+1];
422 ddcf0 = ddcf2 + 2*(i+1)*dcf1;
423 b0 = ddcf0 + x2*b1 -b2;
424 //
425 ddcf2 = ddcf1;
426 ddcf1 = ddcf0;
427 //
428 dcf2 = dcf1;
429 dcf1 = dcf0;
430 //
431 }
432 //
433 return b0 - x*b1 - ddcf0/2;
434}
2572efdf 435
436//__________________________________________________________________________________________
437Int_t AliCheb3DCalc::GetMaxColsAtRow() const
438{
439 int nmax3d = 0;
440 for (int i=fNElemBound2D;i--;) if (fCoefBound2D0[i]>nmax3d) nmax3d = fCoefBound2D0[i];
441 return nmax3d;
442}