Project
Loading...
Searching...
No Matches
SplineHelper.cxx
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
16
17#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
18
19#include "SplineHelper.h"
20#include "Spline2D.h"
21
22#include "TMath.h"
23#include "TMatrixD.h"
24#include "TVectorD.h"
25#include "TDecompBK.h"
26
27#include <vector>
28#include "TRandom.h"
29#include "TMath.h"
30#include "TCanvas.h"
31#include "TNtuple.h"
32#include "TFile.h"
33#include "GPUCommonMath.h"
34#include <iostream>
35
36using namespace o2::gpu;
37
38template <typename DataT>
39SplineHelper<DataT>::SplineHelper() : mError(), mXdimensions(0), mFdimensions(0), mNumberOfDataPoints(0), mHelpers()
40{
41}
42
43template <typename DataT>
44int32_t SplineHelper<DataT>::storeError(int32_t code, const char* msg)
45{
46 mError = msg;
47 return code;
48}
49
51// pointstoarray
52// HILFSFUNKTION,
53template <typename DataT>
54int32_t SplineHelper<DataT>::pointstoarray(const int32_t indices[], const int32_t numbers[], int32_t dim)
55{
56
57 int32_t result = 0;
58 int32_t factor = 1;
59 for (int32_t i = 0; i < dim; i++) {
60 result += indices[i] * factor;
61 factor *= numbers[i];
62 }
63 return result;
64}
65
67//arraytopoints
68// HILFSFUNKTION
69template <typename DataT>
70int32_t SplineHelper<DataT>::arraytopoints(int32_t point, int32_t result[], const int32_t numbers[], int32_t dim)
71{
72
73 if (point == 0) {
74 for (int32_t i = 0; i < dim; i++) {
75 result[i] = 0;
76 }
77 } else {
78 int32_t divisor = 1;
79 int32_t modoperand = 1;
80 for (int32_t i = 0; i < dim; i++) {
81 modoperand *= numbers[i];
82 result[i] = (int32_t)((point % modoperand) / divisor);
83 divisor *= numbers[i];
84 }
85 }
86 return 0;
87}
88
89template <typename DataT>
91 DataT* Fparameters, const double xMin[/* mXdimensions */], const double xMax[/* mXdimensions */],
92 std::function<void(const double x[/* mXdimensions */], double f[/* mFdimensions */])> F) const
93{
96 // TODO: implement
97 // MY VERSION
98 // LOG(info) << "approximateFunction(Fparameters, xMin[],xMax[],F) :" ;
99 double scaleX[mXdimensions];
100 for (int32_t i = 0; i < mXdimensions; i++) {
101 scaleX[i] = (xMax[i] - xMin[i]) / ((double)(mHelpers[i].getSpline().getUmax()));
102 }
103
104 // calculate F-Values at all datapoints:
105 int32_t nrOfAllPoints = getNumberOfDataPoints();
106 std::vector<double> dataPointF(nrOfAllPoints * mFdimensions);
107
108 int32_t nrOfPoints[mXdimensions];
109 for (int32_t i = 0; i < mXdimensions; i++) {
110 nrOfPoints[i] = mHelpers[i].getNumberOfDataPoints();
111 }
112 double x[mXdimensions];
113 for (int32_t d = 0; d < nrOfAllPoints; d++) { // for all DataPoints
114
115 int32_t indices[mXdimensions];
116 int32_t modoperand = 1;
117 int32_t divisor = 1;
118
119 // get the DataPoint index
120 for (int32_t i = 0; i < mXdimensions; i++) {
121 modoperand *= nrOfPoints[i];
122
123 indices[i] = (int32_t)((d % modoperand) / divisor);
124 divisor *= nrOfPoints[i];
125 // get the respecting u-values:
126 x[i] = xMin[i] + mHelpers[i].getDataPoint(indices[i]).u * scaleX[i];
127 }
128
129 for (int32_t j = 0; j < mXdimensions; j++) {
130 F(x, &dataPointF[d * mFdimensions]);
131 }
132
133 } // end for all DataPoints d
134 // END MY VERSION
135
136 //std::vector<DataT> dataPointF(getNumberOfDataPoints() * mFdimensions);
137 //DUMYY VERSION Commented out
138 /* for (int32_t i = 0; i < getNumberOfDataPoints() * mFdimensions; i++) {
139 dataPointF[i] = 1.;
140 } */
141 /*
142 double scaleX1 = (x1Max - x1Min) / ((double)mHelperU1.getSpline().getUmax());
143 double scaleX2 = (x2Max - x2Min) / ((double)mHelperU2.getSpline().getUmax());
144
145 for (int32_t iv = 0; iv < getNumberOfDataPointsU2(); iv++) {
146 DataT x2 = x2Min + mHelperU2.getDataPoint(iv).u * scaleX2;
147 for (int32_t iu = 0; iu < getNumberOfDataPointsU1(); iu++) {
148 DataT x1 = x1Min + mHelperU1.getDataPoint(iu).u * scaleX1;
149 F(x1, x2, &dataPointF[(iv * getNumberOfDataPointsU1() + iu) * mFdimensions]);
150 }
151 }
152 */
153 approximateFunction(Fparameters, dataPointF.data());
154}
155
156template <typename DataT>
158 DataT* Fparameters, const double xMin[], const double xMax[],
159 std::function<void(const std::vector<double> x[], double f[/*mFdimensions*/])> F,
160 uint32_t batchsize) const
161{
165
166 double scaleX[mXdimensions];
167 for (int32_t i = 0; i < mXdimensions; i++) {
168 scaleX[i] = (xMax[i] - xMin[i]) / ((double)(mHelpers[i].getSpline().getUmax()));
169 }
170
171 const int32_t nrOfAllPoints = getNumberOfDataPoints();
172 std::vector<double> dataPointF(nrOfAllPoints * mFdimensions);
173
174 int32_t nrOfPoints[mXdimensions];
175 for (int32_t i = 0; i < mXdimensions; i++) {
176 nrOfPoints[i] = mHelpers[i].getNumberOfDataPoints();
177 }
178
179 std::vector<double> x[mXdimensions];
180 for (int32_t iDim = 0; iDim < mXdimensions; ++iDim) {
181 x[iDim].reserve(batchsize);
182 }
183
184 uint32_t ibatch = 0;
185 int32_t index = 0;
186 for (int32_t d = 0; d < nrOfAllPoints; d++) { // for all DataPoints
187 int32_t indices[mXdimensions];
188 int32_t modoperand = 1;
189 int32_t divisor = 1;
190
191 // get the DataPoint index
192 for (int32_t i = 0; i < mXdimensions; i++) {
193 modoperand *= nrOfPoints[i];
194 indices[i] = (int32_t)((d % modoperand) / divisor);
195 divisor *= nrOfPoints[i];
196 // get the respecting u-values:
197 x[i].emplace_back(xMin[i] + mHelpers[i].getDataPoint(indices[i]).u * scaleX[i]);
198 }
199 ++ibatch;
200
201 if (ibatch == batchsize || d == nrOfAllPoints - 1) {
202 ibatch = 0;
203
204 F(x, &dataPointF[index]);
205 index = (d + 1) * mFdimensions;
206
207 for (int32_t iDim = 0; iDim < mXdimensions; ++iDim) {
208 x[iDim].clear();
209 }
210 }
211 } // end for all DataPoints d
212
213 approximateFunction(Fparameters, dataPointF.data());
214}
215
216template <typename DataT>
218 DataT* Fparameters, const double DataPointF[/*getNumberOfDataPoints() x nFdim*/]) const
219{
221
222 int32_t numberOfKnots[mXdimensions]; // getting number of Knots for all dimensions into one array
223 for (int32_t i = 0; i < mXdimensions; i++) {
224 numberOfKnots[i] = mHelpers[i].getSpline().getNumberOfKnots();
225 }
226
227 int32_t numberOfDataPoints[mXdimensions]; // getting number of datapoints (incl knots) in all dimensions into one array
228 for (int32_t i = 0; i < mXdimensions; i++) {
229 numberOfDataPoints[i] = mHelpers[i].getNumberOfDataPoints();
230 }
231
232 int32_t numberOfAllKnots = 1; // getting Number of all knots for the entire spline
233 for (int32_t i = 0; i < mXdimensions; i++) {
234 numberOfAllKnots *= numberOfKnots[i];
235 }
236 // TO BE REMOVED (TEST-OUTPUT):
237 LOG(info) << "total number of knots: " << numberOfAllKnots << ", ";
238
239 int32_t numberOfAllDataPoints = 1; // getting Number of all Datapoints for the entire spline
240 for (int32_t i = 0; i < mXdimensions; i++) {
241 numberOfAllDataPoints *= numberOfDataPoints[i];
242 // LOG(info) << mHelpers[0].getNumberOfDataPoints();
243 }
244
245 // TO BE REMOVED TEST:
246 // LOG(info) << "total number of DataPoints (including knots): " << numberOfAllDataPoints << ", ";
247
248 int32_t numberOfParameterTypes = (int32_t)(pow(2.0, mXdimensions)); // number of Parameters per Knot
249
250 // TO BE REMOVED TEST:
251 // LOG(info) << "number of paramtertypes per knot : " << numberOfParameterTypes << ", ";
252
253 std::unique_ptr<double[]> allParameters[numberOfParameterTypes]; //Array for the different parametertypes s, s'u, s'v, s''uv,...
254 for (int32_t i = 0; i < numberOfParameterTypes; i++) {
255 allParameters[i] = std::unique_ptr<double[]>(new double[numberOfAllDataPoints * mFdimensions]); //To-Do:Fdim!!
256 }
257 //filling allParameters[0] and FParameters with s:
258 for (int32_t i = 0; i < numberOfAllDataPoints; i++) {
259 for (int32_t f = 0; f < mFdimensions; f++) { // for all f-dimensions
260 allParameters[0][i * mFdimensions + f] = DataPointF[i * mFdimensions + f]; // TO DO - Just get the pointer adress there PLEASE!
261 }
262 int32_t p0indices[mXdimensions];
263 arraytopoints(i, p0indices, numberOfDataPoints, mXdimensions);
264 bool isKnot = 1;
265 for (int32_t j = 0; j < mXdimensions; j++) { // is the current datapoint a knot?
266 if (!mHelpers[j].getDataPoint(p0indices[j]).isKnot) {
267 isKnot = 0;
268 break;
269 }
270 }
271 if (isKnot) {
272 int32_t knotindices[mXdimensions];
273 for (int32_t j = 0; j < mXdimensions; j++) { // calculate KNotindices for all dimensions
274 // WORKAROUND Getting Knotindices:
275 knotindices[j] = p0indices[j] / ((numberOfDataPoints[j] - 1) / (numberOfKnots[j] - 1));
276 //knotindices[j] = mHelpers[j].getDataPoint(p0indices[j]).iKnot; //in der Annahme der wert ist ein Knotenindex und falls der datapoint ein knoten ist, gibt er seinen eigenen knotenindex zurück
277 }
278 // get the knotindexvalue for FParameters:
279 int32_t knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions);
280
281 for (int32_t f = 0; f < mFdimensions; f++) { // for all f-dimensions get function values into Fparameters
282 Fparameters[knotind * numberOfParameterTypes * mFdimensions + f] = DataPointF[i * mFdimensions + f];
283 }
284 } // end if isKnot
285 } // end i (filling DataPointF Values into allParameters[0] and FParameters)
286 // now: allParameters[0] = dataPointF;
287
288 //Array for input DataPointF-values for Spline1D::approximateFunctionGradually(...);
289 std::unique_ptr<double[]> dataPointF1D[mXdimensions];
290 for (int32_t i = 0; i < mXdimensions; i++) {
291 dataPointF1D[i] = std::unique_ptr<double[]>(new double[numberOfDataPoints[i] * mFdimensions]); // To-Do:Fdim!! For s and derivetives at all knots.
292 }
293 //Array to be filled by Spline1D::approximateFunctionGradually(...);
294 std::unique_ptr<DataT[]> par[mXdimensions];
295 std::unique_ptr<double[]> parD[mXdimensions];
296
297 for (int32_t i = 0; i < mXdimensions; i++) {
298 par[i] = std::unique_ptr<DataT[]>(new DataT[numberOfKnots[i] * mFdimensions * 2]);
299 parD[i] = std::unique_ptr<double[]>(new double[numberOfKnots[i] * mFdimensions * 2]);
300 }
301
302 // LOG(info) << "NumberOfParameters: " << mNumberOfParameters ;
303
304 //STARTING MAIN-LOOP, for all Parametertypes:
305 for (int32_t p = 1; p < numberOfParameterTypes; p++) { // p = 1!! Wir kriegen s (p0) durch approximateFunction()oben
306 int32_t dimension = 0; // find the dimension for approximation
307 for (int32_t i = (int32_t)(log2f((float)p)); i >= 0; i--) {
308 if (p % (int32_t)(pow(2.0, i)) == 0) {
309 dimension = i;
310 break;
311 }
312 }
313
314 int32_t currentDataPointF = p - (int32_t)(pow(2.0, dimension));
315 // LOG(info) << "\n" << "p:" << p << ", dim of approximation: " << dimension << ", based on: " << currentDataPointF ;
316
317 int32_t nrOf1DSplines = (numberOfAllDataPoints / numberOfDataPoints[dimension]); // number of Splines for Parametertyp p in direction dim
318 // LOG(info) << "nr of splines: " << nrOf1DSplines;
319
320 // getting the numbers of Datapoints for all dimension eccept the dimension of interpolation
321 int32_t currentNumbers[mXdimensions - 1];
322 for (int32_t i = 0; i < dimension; i++) {
323 currentNumbers[i] = numberOfDataPoints[i];
324 }
325 for (int32_t i = dimension; i < mXdimensions - 1; i++) {
326 currentNumbers[i] = numberOfDataPoints[i + 1];
327 }
329 for (int32_t i = 0; i < mXdimensions - 1; i++) {
330 // LOG(info) << currentNumbers[i] << ",";
331 }
332 // LOG(info) ;
333
335 for (int32_t s = 0; s < nrOf1DSplines; s++) {
336 int32_t indices[mXdimensions - 1];
337 arraytopoints(s, indices, currentNumbers, mXdimensions - 1);
338 int32_t startpoint[mXdimensions]; // startpoint for the current 1DSpline
339 for (int32_t i = 0; i < dimension; i++) {
340 startpoint[i] = indices[i];
341 }
342 startpoint[dimension] = 0;
343 for (int32_t i = dimension + 1; i < mXdimensions; i++) {
344 startpoint[i] = indices[i - 1];
345 }
346 // NOW WE HAVE THE DATAPOINTINDICES OF THE CURRENT STARTPOINT IN startpoint-Array.
347 int32_t startdatapoint = pointstoarray(startpoint, numberOfDataPoints, mXdimensions);
348 int32_t distance = 1; // distance to the next dataPoint in the array for the current dimension
349 for (int32_t i = 0; i < dimension; i++) {
350 distance *= numberOfDataPoints[i];
351 }
352 distance *= mFdimensions;
353
354 for (int32_t i = 0; i < numberOfDataPoints[dimension]; i++) { // Fill the dataPointF1D-Array
355 for (int32_t f = 0; f < mFdimensions; f++) {
356 dataPointF1D[dimension][i * mFdimensions + f] = allParameters[currentDataPointF][startdatapoint * mFdimensions + (i * distance + f)]; // uiuiui index kuddelmuddel???!!
357 }
358 }
359 mHelpers[dimension].approximateFunction(par[dimension].get(), dataPointF1D[dimension].get());
360 for (int32_t i = 0; i < numberOfKnots[dimension] * mFdimensions * 2; i++) {
361 parD[dimension][i] = par[dimension][i];
362 }
363 // now we have all s and s' values in par[dimension]
364
365 int32_t redistributionindex[mXdimensions];
366 for (int32_t i = 0; i < mXdimensions; i++) {
367 redistributionindex[i] = startpoint[i];
368 }
369 //redistributing the derivatives at dimension-Knots into array p
370 for (int32_t i = 0; i < numberOfKnots[dimension]; i++) { // for all dimension-Knots
371 redistributionindex[dimension] = mHelpers[dimension].getKnotDataPoint(i); //find the indices
372 int32_t finalposition = pointstoarray(redistributionindex, numberOfDataPoints, mXdimensions);
373
374 for (int32_t f = 0; f < mFdimensions; f++) {
375 allParameters[p][finalposition * mFdimensions + f] = par[dimension][2 * i * mFdimensions + mFdimensions + f];
376 }
377
378 bool isKnot = 1;
379 for (int32_t j = 0; j < mXdimensions; j++) { // is dataPoint a knot?
380 if (!mHelpers[j].getDataPoint(redistributionindex[j]).isKnot) {
381 isKnot = 0;
382 break;
383 } //noch mal checken!! Das muss noch anders!!
384 }
385
386 if (isKnot) { // for all knots
387 int32_t knotindices[mXdimensions];
388
389 for (int32_t j = 0; j < mXdimensions; j++) { // calculate Knotindices for all dimensions
390 knotindices[j] = redistributionindex[j] / ((numberOfDataPoints[j] - 1) / (numberOfKnots[j] - 1));
391 //knotindices[j] = mHelpers[j].getDataPoint(redistributionindex[j]).iKnot; //in der Annahme der wert ist ein Knotenindex und falls der datapoint ein knoten ist, gibt er seinen eigenen knotenindex zurück
392 }
393 // get the knotindexvalue for FParameters:
394 int32_t knotind = pointstoarray(knotindices, numberOfKnots, mXdimensions);
395 for (int32_t f = 0; f < mFdimensions; f++) {
396 Fparameters[knotind * numberOfParameterTypes * mFdimensions + p * mFdimensions + f] = par[dimension][2 * i * mFdimensions + mFdimensions + f];
397 }
398 }
399 } // end for all fknots (for redistribution)
400
401 // recalculation:
402 for (int32_t i = 0; i < numberOfDataPoints[dimension]; i++) { // this is somehow still redundant// TO DO: ONLY PART OF approximateFunction WHERE NDIM is considerd!!
403 redistributionindex[dimension] = i; // getting current datapointindices
404 bool isKnot = 1; // check is current datapoint a knot?
405 for (int32_t j = 0; j < mXdimensions; j++) {
406 if (!mHelpers[j].getDataPoint(redistributionindex[j]).isKnot) {
407 isKnot = 0;
408 break;
409 }
410 }
411 double splineF[mFdimensions];
412 double u = mHelpers[dimension].getDataPoint(i).u;
413 mHelpers[dimension].getSpline().interpolateU(mFdimensions, parD[dimension].get(), u, splineF); //recalculate at all datapoints of dimension
414 for (int32_t dim = 0; dim < mFdimensions; dim++) { // writing it in allParameters
415 // LOG(info)<<allParameters [p-(int32_t)(pow(2.0, dimension))] [(int32_t)(startdatapoint*mFdimensions + i*distance + dim)]<<", ";
416 allParameters[p - (int32_t)(pow(2.0, dimension))][(int32_t)(startdatapoint * mFdimensions + i * distance + dim)] = splineF[dim]; // write it in the array.
417 // LOG(info)<<allParameters [p-(int32_t)(pow(2.0, dimension))] [(int32_t)(startdatapoint*mFdimensions + i*distance + dim)]<<", ";
418 }
419
420 if (isKnot) {
421 int32_t knotindices[mXdimensions];
422
423 for (int32_t j = 0; j < mXdimensions; j++) { // calculate KNotindices for all dimensions
424 knotindices[j] = redistributionindex[j] / ((numberOfDataPoints[j] - 1) / (numberOfKnots[j] - 1));
425 //knotindices[j] = mHelpers[j].getDataPoint(redistributionindex[j]).iKnot; //in der Annahme der wert ist ein Knotenindex und falls der datapoint ein knoten ist, gibt er seinen eigenen knotenindex zurück
426 }
427 int32_t currentknotarrayindex = pointstoarray(knotindices, numberOfKnots, mXdimensions);
428 // getting the recalculated value into FParameters:
429 for (int32_t f = 0; f < mFdimensions; f++) {
430 Fparameters[currentknotarrayindex * numberOfParameterTypes * mFdimensions + (p - (int32_t)(pow(2.0, dimension))) * mFdimensions + f] = splineF[f];
431 }
432 } // end if isKnot
433 } // end recalculation
434 } // end of all1DSplines
435 } // end of for parametertypes
436} //end of approxymateFunction MYVERSION!
437
438template <typename DataT>
439int32_t SplineHelper<DataT>::test(const bool draw, const bool drawDataPoints)
440{
441 // Test method
442
443 using namespace std;
444
445 constexpr int32_t nDimX = 2;
446 constexpr int32_t nDimY = 2;
447 constexpr int32_t Fdegree = 4;
448
449 double xMin[nDimX];
450 double xMax[nDimX];
451 int32_t nKnots[nDimX];
452 int32_t* knotsU[nDimX];
453 int32_t nAxiliaryDatapoints[nDimX];
454
455 for (int32_t i = 0; i < nDimX; i++) {
456 xMin[i] = 0.;
457 xMax[i] = 1.;
458 nKnots[i] = 4;
459 knotsU[i] = new int32_t[nKnots[i]];
460 nAxiliaryDatapoints[i] = 4;
461 }
462
463 // Function F
464 const int32_t nTerms1D = 2 * (Fdegree + 1);
465 int32_t nFcoeff = nDimY;
466 for (int32_t i = 0; i < nDimX; i++) {
467 nFcoeff *= nTerms1D;
468 }
469
470 double Fcoeff[nFcoeff];
471
472 auto F = [&](const double x[nDimX], double f[nDimY]) {
473 double a[nFcoeff];
474 a[0] = 1;
475 int32_t na = 1;
476 for (int32_t d = 0; d < nDimX; d++) {
477 double b[nFcoeff];
478 int32_t nb = 0;
479 double t = (x[d] - xMin[d]) * TMath::Pi() / (xMax[d] - xMin[d]);
480 for (int32_t i = 0; i < nTerms1D; i++) {
481 double c = (i % 2) ? cos((i / 2) * t) : cos((i / 2) * t);
482 for (int32_t j = 0; j < na; j++) {
483 b[nb++] = c * a[j];
484 assert(nb <= nFcoeff);
485 }
486 }
487 na = nb;
488 for (int32_t i = 0; i < nb; i++) {
489 a[i] = b[i];
490 }
491 }
492
493 double* c = Fcoeff;
494 for (int32_t dim = 0; dim < nDimY; dim++) {
495 f[dim] = 0;
496 for (int32_t i = 0; i < na; i++) {
497 f[dim] += a[i] * (*c++);
498 }
499 }
500 };
501
502 auto F2D = [&](double x1, double x2, double f[nDimY]) {
503 double x[2] = {x1, x2};
504 F(x, f);
505 };
506
507 for (int32_t seed = 1; seed < 10; seed++) {
508
509 gRandom->SetSeed(seed);
510
511 // getting the coefficents filled randomly
512 for (int32_t i = 0; i < nFcoeff; i++) {
513 Fcoeff[i] = gRandom->Uniform(-1, 1);
514 }
515
516 for (int32_t i = 0; i < nDimX; i++) {
517 knotsU[i][0] = 0;
518 for (int32_t j = 1; j < nKnots[i]; j++) {
519 knotsU[i][j] = j * 4; //+ int32_t(gRandom->Integer(3)) - 1;
520 }
521 }
522
523 Spline<float, nDimX, nDimY> spline(nKnots, knotsU);
524 Spline2D<float, nDimY> spline2D(nKnots[0], knotsU[0], nKnots[1], knotsU[1]);
525
526 spline.approximateFunction(xMin, xMax, F, nAxiliaryDatapoints);
527 spline2D.approximateFunction(xMin[0], xMax[0], xMin[1], xMax[1],
528 F2D, nAxiliaryDatapoints[0], nAxiliaryDatapoints[0]);
529
530 double statDf = 0;
531 double statDf2D = 0;
532
533 double statN = 0;
534
535 double x[nDimX];
536 for (int32_t i = 0; i < nDimX; i++) {
537 x[i] = xMin[i];
538 }
539 do {
540 float xf[nDimX];
541 float s[nDimY];
542 float s2D[nDimY];
543 double f[nDimY];
544 for (int32_t i = 0; i < nDimX; i++) {
545 xf[i] = x[i];
546 }
547 F(x, f);
548 spline.interpolate(xf, s);
549 spline2D.interpolate(xf[0], xf[1], s2D);
550
551 for (int32_t dim = 0; dim < nDimY; dim++) {
552 statDf += (s[dim] - f[dim]) * (s[dim] - f[dim]);
553 statDf2D += (s2D[dim] - f[dim]) * (s2D[dim] - f[dim]);
554 statN++;
555 }
556 int32_t dim = 0;
557 for (; dim < nDimX; dim++) {
558 x[dim] += 0.01;
559 if (x[dim] <= xMax[dim]) {
560 break;
561 }
562 x[dim] = xMin[dim];
563 }
564 if (dim >= nDimX) {
565 break;
566 }
567 } while (1);
568
569 LOG(info) << "\n std dev for SplineND : " << sqrt(statDf / statN);
570 LOG(info) << "\n std dev for Spline2D : " << sqrt(statDf2D / statN);
571
572 } // seed
573
574 for (int32_t i = 0; i < nDimX; i++) {
575 delete[] knotsU[i];
576 }
577
578 return 0;
579}
580
581template class o2::gpu::SplineHelper<float>;
582template class o2::gpu::SplineHelper<double>;
583
584#endif
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
Definition of Spline2D class.
Definition of SplineHelper class.
void approximateFunction(SplineContainer< DataT > &spline, const double xMin[], const double xMax[], std::function< void(const double x[], double f[])> F, const int32_t nAxiliaryDataPoints[]=nullptr)
_______________ Main functionality ________________________
static int32_t pointstoarray(const int32_t indices[], const int32_t numbers[], int32_t dim)
SplineHelper()
_____________ Constructors / destructors __________________________
static int32_t arraytopoints(int32_t point, int32_t result[], const int32_t numbers[], int32_t dim)
void approximateFunctionBatch(DataT *Fparameters, const double xMin[], const double xMax[], std::function< void(const std::vector< double > x[], double f[])> F, uint32_t batchsize) const
approximate std::function, output in Fparameters. F calculates values for a batch of points.
static int32_t test(const bool draw=0, const bool drawDataPoints=1)
Test the Spline class functionality.
GLint GLenum GLint x
Definition glcorearb.h:403
GLuint64EXT * result
Definition glcorearb.h:5662
GLuint divisor
Definition glcorearb.h:1644
GLuint GLfloat GLfloat GLfloat x1
Definition glcorearb.h:5034
GLuint index
Definition glcorearb.h:781
GLdouble f
Definition glcorearb.h:310
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLsizei GLsizei GLfloat distance
Definition glcorearb.h:5506
GLsizei GLenum const void * indices
Definition glcorearb.h:400
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
Defining DataPointCompositeObject explicitly as copiable.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint64_t const void const *restrict const msg
Definition x9.h:153