17#ifndef ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
18#define ALICEO2_GPUCOMMON_TPCFASTTRANSFORMATION_SPLINESPEC_H
25#if !defined(__CLING__) && !defined(G__ROOT) && !defined(GPUCA_GPUCODE) && !defined(GPUCA_NO_VC)
27#include <Vc/SimdArray>
44template <
typename DataT>
68#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
71 std::function<
void(
const double x[],
double f[])> F,
72 const int32_t nAuxiliaryDataPoints[] =
nullptr);
77#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
88 GPUd() int32_t getXdimensions()
const {
return mXdim; }
91 GPUd() int32_t getYdimensions()
const {
return mYdim; }
94 GPUd() static constexpr
size_t getParameterAlignmentBytes() {
return 16; }
97 GPUd() int32_t getNumberOfParameters()
const {
return this->calcNumberOfParameters(
mYdim); }
100 GPUd() size_t getSizeOfParameters()
const {
return sizeof(DataT) * this->getNumberOfParameters(); }
106 GPUd() int32_t getNumberOfParametersPerKnot()
const {
return calcNumberOfParametersPerKnot(
mYdim); }
137 GPUd() int32_t calcNumberOfParameters(int32_t nYdim)
const
139 return calcNumberOfParametersPerKnot(nYdim) * getNumberOfKnots();
143 GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim)
const
145 return (1 <<
mXdim) * nYdim;
150#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
152 static int32_t test(const bool draw = 0, const bool drawDataPoints = 1);
160#if !defined(GPUCA_GPUCODE)
172#if !defined(GPUCA_GPUCODE)
174 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[]);
177 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[]);
192template <
typename DataT>
196 for (int32_t dim = 0; dim < mXdim; dim++) {
197 int32_t
n = mGrid[dim].getNumberOfKnots();
198 u[dim] = mGrid[dim].getKnot(iKnot %
n).getU();
203template <
typename DataT>
204GPUdi() int32_t SplineContainer<DataT>::getKnotIndex(const int32_t iKnot[])
const
207 int32_t ind = iKnot[0];
209 for (int32_t dim = 1; dim < mXdim; dim++) {
210 n *= mGrid[dim - 1].getNumberOfKnots();
211 ind +=
n * iKnot[dim];
216template <
typename DataT>
218 setXrange(const DataT xMin[], const DataT xMax[])
221 for (int32_t
i = 0;
i < mXdim;
i++) {
222 mGrid[
i].setXrange(xMin[
i], xMax[
i]);
248template <
typename DataT,
int32_t XdimT,
int32_t YdimT,
int32_t SpecT>
255template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
268 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
269 const auto nXdim = nXdimTmp.get();
270 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
271 DataT u[maxXdimTmp.get()];
272 for (int32_t
i = 0;
i < nXdim;
i++) {
273 u[
i] = mGrid[
i].convXtoU(
x[
i]);
275 interpolateAtU<SafetyLevel::kSafe>(mXdim, mYdim, mParameters, u,
S);
279 template <SafetyLevel SafeT = SafetyLevel::kSafe>
283 const auto nXdimTmp = SplineUtil::getNdim<XdimT>(mXdim);
284 const auto nXdim = nXdimTmp.get();
285 const auto maxXdimTmp = SplineUtil::getMaxNdim<XdimT>(mXdim);
286 const auto maxXdim = maxXdimTmp.get();
287 const auto nYdimTmp = SplineUtil::getNdim<YdimT>(mYdim);
288 const auto nYdim = nYdimTmp.get();
289 const auto maxYdimTmp = SplineUtil::getMaxNdim<XdimT>(mYdim);
290 const auto maxYdim = maxYdimTmp.get();
293 const auto nKnotParametersPerY = 1 << nXdim;
294 const auto nKnotParameters = (1 << nXdim) * nYdim;
296 DataT iParameters[(1 << (2 * maxXdim)) * maxYdim];
301 for (int32_t
i = 0;
i < nXdim;
i++) {
302 indices[
i] = mGrid[
i].getLeftKnotIndexForU(u[
i]);
305 int32_t indicestmp[maxXdim];
306 for (int32_t
i = 0;
i < nKnotParametersPerY;
i++) {
307 for (int32_t k = 0; k < nXdim; k++) {
308 indicestmp[k] =
indices[k] + (
i / (1 << k)) % 2;
310 int32_t
index = TBase::getKnotIndex(indicestmp);
312 for (int32_t
j = 0;
j < nKnotParameters;
j++) {
318 constexpr auto maxInterpolations = (1 << (2 * maxXdim - 2)) * maxYdim;
320 DataT S0[maxInterpolations];
321 DataT D0[maxInterpolations];
322 DataT S1[maxInterpolations];
323 DataT D1[maxInterpolations];
325 int32_t nInterpolations = (1 << (2 * nXdim - 2)) * nYdim;
326 int32_t nKnots = 1 << (nXdim);
328 for (int32_t d = 0; d < nXdim; d++) {
329 DataT*
pointer[4] = {S0, D0, S1, D1};
330 for (int32_t
i = 0;
i < nKnots;
i++) {
331 for (int32_t
j = 0;
j < nKnots;
j++) {
332 int32_t pointernr = 2 * (
i % 2) + (
j % 2);
333 for (int32_t k = 0; k < nYdim; k++) {
334 pointer[pointernr][0] = iParameters[(
i * nKnots +
j) * nYdim + k];
341 DataT coordinate = u[d];
343 const GridXBase& gridX = *((
const GridXBase*)&(mGrid[d]));
344 gridX.interpolateAtU(nInterpolations, knotL, S0, D0, S1, D1, coordinate, iParameters);
345 nInterpolations /= 4;
349 for (int32_t
i = 0;
i < nYdim;
i++) {
350 S[
i] = iParameters[
i];
357 using TBase::mParameters;
367template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
375#if !defined(GPUCA_GPUCODE)
385 SplineSpec(
const int32_t nKnots[],
const int32_t*
const knotU[])
388 recreate(nKnots, knotU);
393 TBase::cloneFromObject(
v,
nullptr);
398 TBase::recreate(XdimT, YdimT, nKnots);
402 void recreate(
const int32_t nKnots[],
const int32_t*
const knotU[])
404 TBase::recreate(XdimT, YdimT, nKnots, knotU);
409 GPUd() constexpr int32_t getXdimensions()
const {
return XdimT; }
412 GPUd() constexpr int32_t getYdimensions()
const {
return YdimT; }
417 template <SafetyLevel SafeT = SafetyLevel::kSafe>
421 TBase::template interpolateAtU<SafeT>(XdimT, YdimT,
Parameters, u,
S);
426#if !defined(GPUCA_GPUCODE)
427 using TBase::recreate;
429 using TBase::interpolateAtU;
436template <
typename DataT,
int32_t XdimT,
int32_t YdimT>
444#if !defined(GPUCA_GPUCODE)
451 this->recreate(nXdim, nYdim, nKnots);
455 SplineSpec(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[])
458 this->recreate(nXdim, nYdim, nKnots, knotU);
464 cloneFromObject(
v,
nullptr);
468 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[])
470 checkDimensions(nXdim, nYdim);
471 TBase::recreate(nXdim, nYdim, nKnots);
475 void recreate(int32_t nXdim, int32_t nYdim,
const int32_t nKnots[],
const int32_t*
const knotU[])
477 checkDimensions(nXdim, nYdim);
478 TBase::recreate(nXdim, nYdim, nKnots, knotU);
485 using TBase::interpolateAtU;
490 if (XdimT > 0 && nXdim != XdimT) {
494 if (XdimT < 0 && nXdim > abs(XdimT)) {
502 if (YdimT > 0 && nYdim != YdimT) {
506 if (YdimT < 0 && nYdim > abs(YdimT)) {
520template <
typename DataT,
int32_t XdimT>
522 :
public SplineSpec<DataT, XdimT, 1, SplineUtil::getSpec(XdimT, 999)>
530 GPUd() DataT interpolate(const DataT
x[])
const
533 TBase::interpolate(
x, &
S);
539 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()
GPUCA_GPUCODE.
Forward declaration — specializations below select ClassDefNV based on FlatBase.
GPUd() void setXrange(const DataT xMin[]
Set X range.
SplineContainer()=default
_____________ C++ constructors / destructors __________________________
GPUd() int32_t getXdimensions() const
_______________ Getters ________________________
int32_t mYdim
dimentionality of Y
GPUd() size_t getGridOffset(int32_t dimX) const
_______________ Technical stuff ________________________
~SplineContainer()=default
Destructor.
GPUd() int32_t getNumberOfKnots() const
Get a number of knots.
int32_t mNknots
number of spline knots
GPUd() size_t getSizeOfParameters() const
Size of the parameter array in bytes.
int32_t writeToFile(TFile &outf, const char *name)
_______________ IO ________________________
void cloneFromObject(const SplineContainer &obj, char *newFlatBufferPtr)
static SplineContainer * readFromFile(TFile &inpf, const char *name)
read a class object from the file
ClassDefNV(SplineContainer, 1)
(transient!!) F-dependent parameters of the spline
void moveBufferTo(char *newBufferPtr)
GPUd() static const expr int32_t getVersion()
_____________ Version control __________________________
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
Spline1D< DataT > * mGrid
void setActualBufferAddress(char *actualFlatBufferPtr)
void setFutureBufferAddress(char *futureFlatBufferPtr)
GPUd() int32_t getNumberOfParametersPerKnot() const
Number of parameters per knot.
int32_t mXdim
_____________ Data members ____________
GPUd() const Spline1D< DataT > &getGrid(int32_t dimX) const
Get 1-D grid for dimX dimension.
DataT * mParameters
(transient!!) mXdim grids
GPUd() int32_t getNumberOfParameters() const
Number of parameters.
void print() const
Print method.
GPUd() int32_t getYdimensions() const
Get number of Y dimensions.
SplineContainer(const SplineContainer &)=delete
Disable all other constructors.
void approximateFunction(const double xMin[], const double xMax[], std::function< void(const double x[], double f[])> F, const int32_t nAuxiliaryDataPoints[]=nullptr)
_______________ Construction interface ________________________
GPUd() const DataT *getParameters() const
Get spline parameters const.
GPUd() int32_t calcNumberOfParametersPerKnot(int32_t nYdim) const
Number of parameters per knot.
GPUd() static const expr size_t getParameterAlignmentBytes()
Get minimal required alignment for the spline parameters.
GPUd() DataT interpolate(const DataT x[]) const
Simplified interface for 1D: return the interpolated value.
GPUd() void interpolate(const DataT x[]
_______________ Interpolation math ________________________
GPUd() void interpolateAtU(int32_t inpXdim
Get interpolated value for S(u):inpXdim->inpYdim using spline parameters Parameters.
GPUd() const expr int32_t getYdimensions() const
Get number of Y dimensions.
void recreate(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec()
Default constructor.
GPUd() void interpolateAtU(GPUgeneric() const DataT Parameters[]
_______ Expert tools: interpolation with given nYdim and external Parameters _______
GPUd() const expr int32_t getXdimensions() const
Get number of X dimensions.
SplineSpec(const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const SplineSpec &v)
Copy constructor.
void recreate(const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
SplineSpec(const SplineSpec &v)
Copy constructor.
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec(int32_t nXdim, int32_t nYdim, const int32_t nKnots[], const int32_t *const knotU[])
Constructor for an irregular spline.
SplineSpec()
Default constructor.
void recreate(int32_t nXdim, int32_t nYdim, const int32_t nKnots[])
Constructor for a regular spline.
void checkDimensions(int32_t &nXdim, int32_t &nYdim)
Check dimensions.
static constexpr int32_t getSpec(int32_t nXdim, int32_t nYdim)
GLuint const GLchar * name
GLsizei GLenum const void * indices
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)