17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE2DSPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINE2DSPEC_H
25#if !defined(__ROOTCLING__) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
27#include <Vc/SimdArray>
46template <
typename DataT>
71#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
74 std::function<
void(
double x1,
double x2,
double f[])> F,
75 int32_t nAuxiliaryDataPointsU1 = 4, int32_t nAuxiliaryDataPointsU2 = 4);
78 std::function<
void(
double x1,
double x2,
double f[])> F,
79 int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2);
84#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
95 GPUd() int32_t getYdimensions()
const {
return mYdim; }
98 GPUd() static constexpr
size_t getParameterAlignmentBytes() {
return 16; }
101 GPUd() int32_t getNumberOfParameters()
const {
return this->calcNumberOfParameters(
mYdim); }
104 GPUd() size_t getSizeOfParameters()
const {
return sizeof(DataT) * this->getNumberOfParameters(); }
107 GPUd() int32_t getNumberOfKnots()
const {
return mGridX1.getNumberOfKnots() *
mGridX2.getNumberOfKnots(); }
126 GPUd() int32_t getKnotIndex(int32_t iKnotX1, int32_t iKnotX2)
const
128 return mGridX1.getNumberOfKnots() * iKnotX2 + iKnotX1;
158 GPUd() int32_t calcNumberOfParameters(int32_t nYdim)
const {
return (4 * nYdim) * getNumberOfKnots(); }
162#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
164 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
172#if !defined(GPUCA_GPUCODE)
184#if !defined(GPUCA_GPUCODE)
186 void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2);
189 void recreate(int32_t nYdim, int32_t nKnotsX1,
const int32_t knotU1[], int32_t nKnotsX2,
const int32_t knotU2[]);
220template <
typename DataT,
int32_t YdimT,
int32_t SpecT>
227template <
typename DataT,
int32_t YdimT>
242 interpolateU<SafetyLevel::kSafe>(mYdim, mParameters, mGridX1.convXtoU(
x1), mGridX2.convXtoU(x2),
S);
246 template <SafetyLevel SafeT = SafetyLevel::kSafe>
251 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
252 const int32_t nYdim = nYdimTmp.get();
254 const auto maxYdim = SplineUtil::getMaxNdim<YdimT>(inpYdim);
255 const int32_t maxYdim4 = 4 * maxYdim.get();
257 const auto nYdim2 = nYdim * 2;
258 const auto nYdim4 = nYdim * 4;
262 int32_t nu = mGridX1.getNumberOfKnots();
263 int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
264 int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(
v);
266 const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
267 const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
269 const DataT* par00 =
Parameters + (nu * iv + iu) * nYdim4;
270 const DataT* par10 = par00 + nYdim4;
271 const DataT* par01 = par00 + nYdim4 * nu;
272 const DataT* par11 = par01 + nYdim4;
279 for (int32_t
i = 0;
i < nYdim2;
i++) {
281 Su0[nYdim2 +
i] = par01[
i];
283 Du0[
i] = par00[nYdim2 +
i];
284 Du0[nYdim2 +
i] = par01[nYdim2 +
i];
287 Su1[nYdim2 +
i] = par11[
i];
289 Du1[
i] = par10[nYdim2 +
i];
290 Du1[nYdim2 +
i] = par11[nYdim2 +
i];
293 DataT parU[maxYdim4];
296 const TGridX1& gridX1 =
reinterpret_cast<const TGridX1&
>(mGridX1);
298 gridX1.interpolateU(nYdim4, knotU, Su0, Du0, Su1, Du1, u, parU);
300 const DataT* Sv0 = parU + 0;
301 const DataT* Dv0 = parU + nYdim;
302 const DataT* Sv1 = parU + nYdim2;
303 const DataT* Dv1 = parU + nYdim2 + nYdim;
306 const TGridX2& gridX2 =
reinterpret_cast<const TGridX2&
>(mGridX2);
307 gridX2.interpolateU(nYdim, knotV, Sv0, Dv0, Sv1, Dv1,
v,
S);
311 template <SafetyLevel SafeT = SafetyLevel::kSafe>
316 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(inpYdim);
317 const int32_t nYdim = nYdimTmp.get();
323 const auto nYdim4 = nYdim * 4;
327 int32_t nu = mGridX1.getNumberOfKnots();
328 int32_t iu = mGridX1.template getLeftKnotIndexForU<SafeT>(u);
329 int32_t iv = mGridX2.template getLeftKnotIndexForU<SafeT>(
v);
331 const typename TBase::Knot& knotU = mGridX1.template getKnot<SafetyLevel::kNotSafe>(iu);
332 const typename TBase::Knot& knotV = mGridX2.template getKnot<SafetyLevel::kNotSafe>(iv);
334 const DataT*
A =
Parameters + (nu * iv + iu) * nYdim4;
335 const DataT*
B =
A + nYdim4 * nu;
337 DataT dSl, dDl, dSr, dDr;
338 mGridX1.getUderivatives(knotU, u, dSl, dDl, dSr, dDr);
339 DataT dSd, dDd, dSu, dDu;
340 mGridX2.getUderivatives(knotV,
v, dSd, dDd, dSu, dDu);
348 DataT
a[8] = {dSl * dSd, dSl * dDd, dDl * dSd, dDl * dDd,
349 dSr * dSd, dSr * dDd, dDr * dSd, dDr * dDd};
350 DataT
b[8] = {dSl * dSu, dSl * dDu, dDl * dSu, dDl * dDu,
351 dSr * dSu, dSr * dDu, dDr * dSu, dDr * dDu};
355 for (int32_t dim = 0; dim < nYdim; dim++) {
357 for (int32_t
i = 0;
i < 8;
i++) {
358 S[dim] +=
a[
i] *
A[nYdim *
i + dim] +
b[
i] *
B[nYdim *
i + dim];
364 using TBase::mGridX1;
365 using TBase::mGridX2;
366 using TBase::mParameters;
375template <
typename DataT,
int32_t YdimT>
385#if !defined(GPUCA_GPUCODE)
392 recreate(nKnotsX1, nKnotsX2);
396 int32_t nKnotsX2,
const int32_t knotU2[])
399 recreate(nKnotsX1, knotU1, nKnotsX2, knotU2);
404 TBase::cloneFromObject(
v,
nullptr);
409 TBase::recreate(YdimT, nKnotsX1, nKnotsX2);
413 void recreate(int32_t nKnotsX1,
const int32_t knotU1[],
414 int32_t nKnotsX2,
const int32_t knotU2[])
416 TBase::recreate(YdimT, nKnotsX1, knotU1, nKnotsX2, knotU2);
421 GPUd() constexpr int32_t getYdimensions()
const {
return YdimT; }
424 GPUd() int32_t getNumberOfParameters()
const {
return (4 * YdimT) * getNumberOfKnots(); }
427 GPUd() size_t getSizeOfParameters()
const {
return (
sizeof(DataT) * 4 * YdimT) * getNumberOfKnots(); }
432 template <SafetyLevel SafeT = SafetyLevel::kSafe>
436 TBase::template interpolateU<SafeT>(YdimT,
Parameters, u1, u2,
S);
440 template <SafetyLevel SafeT = SafetyLevel::kSafe>
444 TBase::template interpolateUold<SafeT>(YdimT,
Parameters, u1, u2,
S);
447 using TBase::getNumberOfKnots;
451#if !defined(GPUCA_GPUCODE)
452 using TBase::recreate;
454 using TBase::interpolateU;
461template <
typename DataT,
int32_t YdimT>
471#if !defined(GPUCA_GPUCODE)
478 TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
483 int32_t nKnotsX2,
const int32_t knotU2[]) :
TBase()
485 TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
491 cloneFromObject(
v,
nullptr);
495 void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
497 TBase::recreate(nYdim, nKnotsX1, nKnotsX2);
501 void recreate(int32_t nYdim, int32_t nKnotsX1,
const int32_t knotU1[],
502 int32_t nKnotsX2,
const int32_t knotU2[])
504 TBase::recreate(nYdim, nKnotsX1, knotU1, nKnotsX2, knotU2);
510 using TBase::interpolateU;
516template <
typename DataT>
518 :
public Spline2DSpec<DataT, 1, SplineUtil::getSpec(999)>
526 GPUd() DataT interpolate(DataT
x1, DataT x2)
const
529 TBase::interpolate(
x1, x2, &
S);
535 using TBase::interpolate;
Definition of FlatObject class.
Definition of Spline1D class.
char * releaseInternalBuffer()
_____________ Methods for making the data buffer external __________________________
static constexpr size_t getBufferAlignmentBytes()
Gives minimal alignment in bytes required for the flat buffer.
static constexpr size_t getClassAlignmentBytes()
_____________ Memory alignment __________________________
SafetyLevel
Named enumeration for the safety level used by some methods.
int32_t int32_t &u2 const
mGridX2 setXrange(x2Min, x2Max)
GPUd() DataT *getParameters()
Get spline parameters.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void cloneFromObject(const Spline2DContainer &obj, char *newFlatBufferPtr)
void approximateFunction(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsU1=4, int32_t nAuxiliaryDataPointsU2=4)
_______________ Construction interface ________________________
Spline1D< DataT >::Knot Knot
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
void setActualBufferAddress(char *actualFlatBufferPtr)
void print() const
Print method.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
GPUd() size_t getGridX2Offset() const
Get offset of GridX2 flat data in the flat buffer.
GPUd() size_t getGridX1Offset() const
_______________ Technical stuff ________________________
Spline2DContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
GPUd() const Spline1D< DataT > &getGrid(int32_t ix) const
Get 1-D grid for X1 or X2 coordinate.
Spline1D< DataT > mGridX2
grid for V axis
Spline1D< DataT >::SafetyLevel SafetyLevel
int32_t mYdim
_____________ Data members ____________
~Spline2DContainer()=default
Destructor.
ClassDefNV(Spline2DContainer, 1)
(transient!!) F-dependent parameters of the spline
GPUd() int32_t calcNumberOfParameters(int32_t nYdim) const
_______________ Expert tools _______________
GPUd() void setXrange(DataT x1Min
Set X range.
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
void moveBufferTo(char *newBufferPtr)
GPUd() const DataT *getParameters() const
Get spline parameters const.
GPUd() int32_t getYdimensions() const
_______________ Getters ________________________
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
GPUd() const Spline1D< DataT > &getGridX1() const
Get 1-D grid for the X1 coordinate.
static Spline2DContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
Spline1D< DataT > mGridX1
grid for U axis
Spline2DContainer(const Spline2DContainer &)=delete
Disable all other constructors.
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void setFutureBufferAddress(char *futureFlatBufferPtr)
void approximateFunctionViaDataPoints(double x1Min, double x1Max, double x2Min, double x2Max, std::function< void(double x1, double x2, double f[])> F, int32_t nAuxiliaryDataPointsX1, int32_t nAuxiliaryDataPointsX2)
GPUd() const Spline1D< DataT > &getGridX2() const
Get 1-D grid for the X2 coordinate.
GPUd() void interpolateU(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
TBase::SafetyLevel SafetyLevel
GPUd() void interpolateUold(int32_t inpYdim
Get interpolated value for an inpYdim-dimensional S(u1,u2) using spline parameters Parameters.
GPUd() void interpolate(DataT x1
_______________ Interpolation math ________________________
Spline2DSpec(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
Spline2DSpec(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
TVeryBase::SafetyLevel SafetyLevel
Spline2DSpec()
Default constructor.
GPUd() void interpolateU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
void recreate(int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void recreate(int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
GPUd() void interpolateUold(GPUgeneric() const DataT Parameters[]
Get interpolated value for an YdimT-dimensional S(u1,u2) using spline parameters Parameters.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
Spline2DSpec(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
Spline2DSpec()
Default constructor.
Spline2DSpec(const Spline2DSpec &v)
Copy constructor.
void recreate(int32_t nYdim, int32_t nKnotsX1, const int32_t knotU1[], int32_t nKnotsX2, const int32_t knotU2[])
Constructor for an irregular spline.
void recreate(int32_t nYdim, int32_t nKnotsX1, int32_t nKnotsX2)
Constructor for a regular spline.
TVeryBase::SafetyLevel SafetyLevel
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
GLuint GLfloat GLfloat GLfloat x1
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
GPUd() const expr uint32_t MultivariatePolynomialHelper< Dim
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...