17#if !defined(GPUCA_GPUCODE) && !defined(GPUCA_STANDALONE)
39template <
typename DataT>
44template <
typename DataT>
51template <
typename DataT>
53 double& cSl,
double& cDl,
double& cSr,
double& cDr)
61 double v = u * double(knotL.
Li);
65 cSl =
v2 * (2 *
v - 3.) + 1;
71template <
typename DataT>
73 double& cSl,
double& cDl,
double& cSr,
double& cDr)
76 double dv = double(knotL.
Li);
79 cSl = 6 * (
v2 -
v) * dv;
80 cDl = 3 *
v2 - 4 *
v + 1.;
87template <
typename DataT>
89 double& cSl,
double& cDl,
double& cSr,
double& cDr)
92 double dv = double(knotL.
Li);
94 cSl = (12 *
v - 6) * dv * dv;
95 cDl = (6 *
v - 4) * dv;
97 cDr = (6 *
v - 2) * dv;
100template <
typename DataT>
102 double& cSl,
double& cDl,
double& cSr,
double& cDr)
104 double dv = double(knotL.
Li);
111template <
typename DataT>
113 double& cSl,
double& cDl,
double& cSr,
double& cDr)
115 double dv = double(knotL.
Li);
122template <
typename DataT>
124 double& cSl,
double& cDl,
double& cSr,
double& cDr)
126 double dv = double(knotL.
Li);
127 cSl = 12 * dv * dv * dv;
133template <
typename DataT>
135 double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
140 int32_t Ndim = spline.getYdimensions();
141 const int32_t nKnots = spline.getNumberOfKnots();
143 TMatrixD
A(nKnots, nKnots);
159 double cZ0 = (-4) * knot0.
Li;
160 double cZ1 = (-2) * knot0.
Li;
169 double cZ0 = (6 - 4) * knot0.
Li;
170 double cZ1 = (6 - 2) * knot0.
Li;
172 A(nKnots - 1, nKnots - 2) = cZ0;
173 A(nKnots - 1, nKnots - 1) = cZ1;
177 for (int32_t
i = 1;
i < nKnots - 1;
i++) {
179 double cZ0 = (6 - 4) * knot0.
Li;
180 double cZ1_0 = (6 - 2) * knot0.
Li;
184 double cZ1_1 = (-4) * knot1.
Li;
185 double cZ2 = (-2) * knot1.
Li;
188 A(
i,
i) = cZ1_0 - cZ1_1;
194 spline.setXrange(xMin, xMax);
195 DataT* parameters = spline.getParameters();
200 double uToXscale = (((double)xMax) - xMin) / spline.getUmax();
202 for (int32_t
i = 0;
i < nKnots; ++
i) {
206 F(xMin + u * uToXscale,
f);
207 for (int32_t dim = 0; dim < Ndim; dim++) {
208 parameters[(2 *
i) * Ndim + dim] =
f[dim];
212 for (int32_t dim = 0; dim < Ndim; dim++) {
216 double f0 = parameters[(2 * 0) * Ndim + dim];
217 double f1 = parameters[(2 * 1) * Ndim + dim];
219 double cS1 = (6) * knot0.Li * knot0.Li;
221 b(0) = -cS1 * (f1 - f0);
226 double f0 = parameters[2 * (nKnots - 2) * Ndim + dim];
227 double f1 = parameters[2 * (nKnots - 1) * Ndim + dim];
229 double cS1 = (6 - 12) * knot0.Li * knot0.Li;
231 b(nKnots - 1) = -cS1 * (f1 - f0);
235 for (int32_t
i = 1;
i < nKnots - 1;
i++) {
236 double f0 = parameters[2 * (
i - 1) * Ndim + dim];
237 double f1 = parameters[2 * (
i)*Ndim + dim];
238 double f2 = parameters[2 * (
i + 1) * Ndim + dim];
240 double cS1 = (6 - 12) * knot0.Li * knot0.Li;
244 double cS2 = (6) * knot1.
Li * knot1.
Li;
246 b(
i) = -cS1 * (f1 - f0) + cS2 * (f2 - f1);
250 for (int32_t
i = 0;
i < nKnots;
i++) {
251 parameters[(2 *
i + 1) * Ndim + dim] =
c[
i];
256template <
typename DataT>
259 double xMin,
double xMax,
260 double vx[],
double vf[], int32_t nDataPoints)
264 spline.setXrange(xMin, xMax);
265 setSpline(spline, spline.getYdimensions(), xMin, xMax, vx, nDataPoints);
266 approximateFunction(spline.getParameters(), vf);
269template <
typename DataT>
272 int32_t nAuxiliaryDataPoints)
275 setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints);
276 approximateFunction(spline.getParameters(), xMin, xMax, F);
277 spline.setXrange(xMin, xMax);
280template <
typename DataT>
283 int32_t nAuxiliaryDataPoints)
286 setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints);
287 approximateFunctionGradually(spline.getParameters(), xMin, xMax, F);
288 spline.setXrange(xMin, xMax);
291template <
typename DataT>
293 DataT* Sparameters,
double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
const
297 std::vector<double> vF(getNumberOfDataPoints() * mFdimensions);
298 double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax();
299 for (int32_t
i = 0;
i < getNumberOfDataPoints();
i++) {
300 F(xMin + mUtoXscale * mDataPoints[
i].u, &vF[
i * mFdimensions]);
302 approximateFunction(Sparameters, vF.data());
305template <
typename DataT>
307 DataT* Sparameters,
double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
const
311 std::vector<double> vF(getNumberOfDataPoints() * mFdimensions);
312 double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax();
313 for (int32_t
i = 0;
i < getNumberOfDataPoints();
i++) {
314 F(xMin + mUtoXscale * mDataPoints[
i].u, &vF[
i * mFdimensions]);
316 approximateFunctionGradually(Sparameters, vF.data());
319template <
typename DataT>
337 mFdimensions = nFdimensions;
340 ret = storeError(-1,
"Spline1DHelperOld<DataT>::setSpline: input spline is not constructed");
341 mSpline.recreate(0, 2);
342 nAuxiliaryDataPoints = 2;
345 std::vector<int32_t> knots;
346 for (int32_t
i = 0;
i < spline.getNumberOfKnots();
i++) {
347 knots.push_back(spline.getKnot(
i).getU());
349 mSpline.recreate(0, spline.getNumberOfKnots(), knots.data());
351 nPoints = 1 + mSpline.getUmax() + mSpline.getUmax() * nAuxiliaryDataPoints;
352 if (nPoints < 2 * mSpline.getNumberOfKnots()) {
353 nAuxiliaryDataPoints = 2;
354 nPoints = 1 + mSpline.getUmax() + mSpline.getUmax() * nAuxiliaryDataPoints;
355 ret = storeError(-3,
"Spline1DHelperOld::setSpline: too few nAuxiliaryDataPoints, increase to 2");
359 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
361 mDataPoints.resize(nPoints);
362 double scalePoints2Knots = ((double)mSpline.getUmax()) / (nPoints - 1.);
364 for (int32_t
i = 0;
i < nPoints; ++
i) {
366 double u =
i * scalePoints2Knots;
367 int32_t iKnot = mSpline.getLeftKnotIndexForU(u);
370 double l = knot1.
u - knot0.
u;
371 double s = (u - knot0.
u) * knot0.
Li;
378 p.
cS1 = s2 * (3. - 2. * s);
380 p.
cZ0 = s * sm1 * sm1 * l;
381 p.
cZ1 = s2 * sm1 * l;
384 const int32_t nKnots = mSpline.getNumberOfKnots();
386 mKnotDataPoints.resize(nKnots);
388 for (int32_t
i = 0;
i < nKnots; ++
i) {
390 int32_t iu = (int32_t)(knot.
u + 0.1f);
391 mKnotDataPoints[
i] = iu * (1 + nAuxiliaryDataPoints);
392 mDataPoints[mKnotDataPoints[
i]].isKnot = 1;
398 for (int32_t
i = 0;
i < nPoints; ++
i) {
418 for (int32_t
i = 0;
i < nPar;
i++) {
419 for (int32_t
j =
i + 1;
j < nPar;
j++) {
424 TMatrixDSym Z(nKnots);
425 mLSMmatrixSvalues.resize(nKnots * nKnots);
426 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
427 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
428 mLSMmatrixSvalues[k] =
A(
i * 2 + 1,
j * 2);
429 Z(
i,
j) =
A(
i * 2 + 1,
j * 2 + 1);
435 bool ok = bk.Invert(
A);
438 ret = storeError(-4,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
441 mLSMmatrixFull.resize(nPar * nPar);
442 for (int32_t
i = 0, k = 0;
i < nPar;
i++) {
443 for (int32_t
j = 0;
j < nPar;
j++, k++) {
444 mLSMmatrixFull[k] =
A(
i,
j);
452 ret = storeError(-5,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
455 mLSMmatrixSderivatives.resize(nKnots * nKnots);
456 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
457 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
458 mLSMmatrixSderivatives[k] = Z(
i,
j);
466template <
typename DataT>
468 const Spline1DContainer<DataT>& spline, int32_t nFdimensions,
double xMin,
double xMax,
double vx[], int32_t nDataPoints)
484 mFdimensions = nFdimensions;
485 int32_t nPoints = nDataPoints;
487 ret = storeError(-1,
"Spline1DHelperOld<DataT>::setSpline: input spline is not constructed");
488 mSpline.recreate(0, 2);
490 std::vector<int32_t> knots;
491 for (int32_t
i = 0;
i < spline.getNumberOfKnots();
i++) {
492 knots.push_back(spline.getKnot(
i).getU());
494 mSpline.recreate(0, spline.getNumberOfKnots(), knots.data());
497 mSpline.setXrange(xMin, xMax);
499 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
501 mDataPoints.resize(nPoints);
503 for (int32_t
i = 0;
i < nPoints; ++
i) {
505 double u = mSpline.convXtoU(vx[
i]);
506 int32_t iKnot = mSpline.getLeftKnotIndexForU(u);
514 const int32_t nKnots = mSpline.getNumberOfKnots();
519 for (int32_t
i = 0;
i < nPoints; ++
i) {
537 for (int32_t iKnot = 0; iKnot < nKnots - 2; ++iKnot) {
569 double l0 = knot0.
Li;
570 double l1 = knot1.
Li;
578 double cS0 =
c * -3 * l0 * l0;
579 double cZ0 =
c * -l0;
580 double cS1 =
c * -3 * (l1 * l1 - l0 * l0);
581 double cZ1 =
c * -2 * (l0 + l1);
582 double cS2 =
c * 3 * l1 * l1;
583 double cZ2 =
c * -l1;
585 int32_t
j = iKnot * 2;
587 A(
j + 0,
j + 0) += cS0 * cS0;
588 A(
j + 1,
j + 0) += cS0 * cZ0;
589 A(
j + 2,
j + 0) += cS0 * cS1;
590 A(
j + 3,
j + 0) += cS0 * cZ1;
591 A(
j + 4,
j + 0) += cS0 * cS2;
592 A(
j + 5,
j + 0) += cS0 * cZ2;
594 A(
j + 1,
j + 1) += cZ0 * cZ0;
595 A(
j + 2,
j + 1) += cZ0 * cS1;
596 A(
j + 3,
j + 1) += cZ0 * cZ1;
597 A(
j + 4,
j + 1) += cZ0 * cS2;
598 A(
j + 5,
j + 1) += cZ0 * cZ2;
600 A(
j + 2,
j + 2) += cS1 * cS1;
601 A(
j + 3,
j + 2) += cS1 * cZ1;
602 A(
j + 4,
j + 2) += cS1 * cS2;
603 A(
j + 5,
j + 2) += cS1 * cZ2;
605 A(
j + 3,
j + 3) += cZ1 * cZ1;
606 A(
j + 4,
j + 3) += cZ1 * cS2;
607 A(
j + 5,
j + 3) += cZ1 * cZ2;
609 A(
j + 4,
j + 4) += cS2 * cS2;
610 A(
j + 5,
j + 4) += cS2 * cZ2;
612 A(
j + 5,
j + 5) += cZ2 * cZ2;
615 for (int32_t iKnot = -1; iKnot < nKnots - 2; ++iKnot) {
626 double l1 = knot1.
Li;
631 double cS1 =
c * -3 * (l1 * l1);
632 double cZ1 =
c * -2 * (l1);
633 double cS2 =
c * 3 * l1 * l1;
634 double cZ2 =
c * -l1;
636 int32_t
j = iKnot * 2;
638 A(
j + 2,
j + 2) += cS1 * cS1;
639 A(
j + 3,
j + 2) += cS1 * cZ1;
640 A(
j + 4,
j + 2) += cS1 * cS2;
641 A(
j + 5,
j + 2) += cS1 * cZ2;
643 A(
j + 3,
j + 3) += cZ1 * cZ1;
644 A(
j + 4,
j + 3) += cZ1 * cS2;
645 A(
j + 5,
j + 3) += cZ1 * cZ2;
647 A(
j + 4,
j + 4) += cS2 * cS2;
648 A(
j + 5,
j + 4) += cS2 * cZ2;
650 A(
j + 5,
j + 5) += cZ2 * cZ2;
654 int32_t iKnot = nKnots - 2;
664 double l0 = knot0.
Li;
669 double cS0 =
c * 3 * l0 * l0;
671 double cS1 =
c * -3 * l0 * l0;
672 double cZ1 =
c * 2 * l0;
674 int32_t
j = iKnot * 2;
676 A(
j + 0,
j + 0) += cS0 * cS0;
677 A(
j + 1,
j + 0) += cS0 * cZ0;
678 A(
j + 2,
j + 0) += cS0 * cS1;
679 A(
j + 3,
j + 0) += cS0 * cZ1;
681 A(
j + 1,
j + 1) += cZ0 * cZ0;
682 A(
j + 2,
j + 1) += cZ0 * cS1;
683 A(
j + 3,
j + 1) += cZ0 * cZ1;
685 A(
j + 2,
j + 2) += cS1 * cS1;
686 A(
j + 3,
j + 2) += cS1 * cZ1;
688 A(
j + 3,
j + 3) += cZ1 * cZ1;
693 for (int32_t
i = 0;
i < nPar;
i++) {
694 for (int32_t
j =
i + 1;
j < nPar;
j++) {
699 TMatrixDSym Z(nKnots);
700 mLSMmatrixSvalues.resize(nKnots * nKnots);
701 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
702 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
703 mLSMmatrixSvalues[k] =
A(
i * 2 + 1,
j * 2);
704 Z(
i,
j) =
A(
i * 2 + 1,
j * 2 + 1);
710 bool ok = bk.Invert(
A);
713 ret = storeError(-4,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
716 mLSMmatrixFull.resize(nPar * nPar);
717 for (int32_t
i = 0, k = 0;
i < nPar;
i++) {
718 for (int32_t
j = 0;
j < nPar;
j++, k++) {
719 mLSMmatrixFull[k] =
A(
i,
j);
727 ret = storeError(-5,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
730 mLSMmatrixSderivatives.resize(nKnots * nKnots);
731 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
732 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
733 mLSMmatrixSderivatives[k] = Z(
i,
j);
741template <
typename DataT>
744 const double DataPointF[])
const
748 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
750 for (int32_t idim = 0; idim < mFdimensions; idim++) {
751 for (int32_t
i = 0;
i < nPar;
i++) {
754 for (int32_t
i = 0;
i < getNumberOfDataPoints(); ++
i) {
757 double f = (double)DataPointF[
i * mFdimensions + idim];
764 const double*
row = mLSMmatrixFull.data();
766 for (int32_t
i = 0;
i < nPar;
i++,
row += nPar) {
768 for (int32_t
j = 0;
j < nPar;
j++) {
771 Sparameters[
i * mFdimensions + idim] = (float)s;
776template <
typename DataT>
778 DataT* Sparameters,
const double DataPointF[])
const
782 copySfromDataPoints(Sparameters, DataPointF);
783 approximateDerivatives(Sparameters, DataPointF);
786template <
typename DataT>
788 DataT* Sparameters,
const double DataPointF[])
const
792 for (int32_t
i = 0;
i < mSpline.getNumberOfKnots(); ++
i) {
793 int32_t ip = mKnotDataPoints[
i];
794 for (int32_t d = 0; d < mFdimensions; d++) {
795 Sparameters[2 *
i * mFdimensions + d] = DataPointF[ip * mFdimensions + d];
800template <
typename DataT>
802 DataT* Sparameters,
const double DataPointF[])
const
808 const int32_t nKnots = mSpline.getNumberOfKnots();
809 const int32_t Ndim = mFdimensions;
810 double b[nKnots * mFdimensions];
811 for (int32_t
i = 0;
i < nKnots * Ndim;
i++) {
815 for (int32_t
i = 0;
i < getNumberOfDataPoints(); ++
i) {
820 for (int32_t d = 0; d < Ndim; d++) {
821 double f = (double)DataPointF[
i * Ndim + d];
827 const double*
row = mLSMmatrixSvalues.data();
828 for (int32_t
i = 0;
i < nKnots; ++
i,
row += nKnots) {
830 for (int32_t d = 0; d < Ndim; d++) {
833 for (int32_t
j = 0;
j < nKnots; ++
j) {
834 for (int32_t d = 0; d < Ndim; d++) {
835 s[d] +=
row[
j] * Sparameters[2 *
j * Ndim + d];
838 for (int32_t d = 0; d < Ndim; d++) {
839 b[
i * Ndim + d] -= s[d];
843 row = mLSMmatrixSderivatives.data();
844 for (int32_t
i = 0;
i < nKnots; ++
i,
row += nKnots) {
846 for (int32_t d = 0; d < Ndim; d++) {
849 for (int32_t
j = 0;
j < nKnots; ++
j) {
850 for (int32_t d = 0; d < Ndim; d++) {
851 s[d] +=
row[
j] *
b[
j * Ndim + d];
854 for (int32_t d = 0; d < Ndim; d++) {
855 Sparameters[(2 *
i + 1) * Ndim + d] = (
float)s[d];
860template <
typename DataT>
867 const int32_t Ndim = 5;
868 const int32_t Fdegree = 4;
869 double Fcoeff[Ndim][2 * (Fdegree + 1)];
871 auto F = [&](
double x,
double f[]) ->
void {
872 double cosx[Fdegree + 1], sinx[Fdegree + 1];
874 for (int32_t
i = 0;
i <= Fdegree;
i++, xi +=
x) {
875 GPUCommonMath::SinCosd(xi, sinx[
i], cosx[
i]);
877 for (int32_t dim = 0; dim < Ndim; dim++) {
879 for (int32_t
i = 1;
i <= Fdegree;
i++) {
880 f[dim] += Fcoeff[dim][2 *
i] * cosx[
i] + Fcoeff[dim][2 *
i + 1] * sinx[
i];
885 TCanvas* canv =
nullptr;
886 TNtuple* nt =
nullptr;
887 TNtuple* knots =
nullptr;
889 auto ask = [&]() ->
bool {
894 LOG(info) <<
"type 'q ' to exit";
896 std::getline(std::cin,
str);
897 return (
str !=
"q" &&
str !=
".q");
900 LOG(info) <<
"Test 1D interpolation with the compact spline";
902 int32_t nTries = 100;
905 canv =
new TCanvas(
"cQA",
"Spline1D QA", 1000, 600);
916 for (int32_t itry = 0; itry < nTries; itry++) {
919 for (int32_t dim = 0; dim < Ndim; dim++) {
920 gRandom->SetSeed(seed++);
921 for (int32_t
i = 0;
i < 2 * (Fdegree + 1);
i++) {
922 Fcoeff[dim][
i] = gRandom->Uniform(-1, 1);
929 const int32_t uMax = nKnots * 3;
932 int32_t knotsU[nKnots];
936 double du = 1. * uMax / (nKnots - 1);
937 for (int32_t
i = 1;
i < nKnots;
i++) {
938 knotsU[
i] = (int32_t)(
i * du);
940 knotsU[nKnots - 1] = uMax;
941 spline1.recreate(nKnots, knotsU);
942 if (nKnots != spline1.getNumberOfKnots()) {
943 LOG(info) <<
"warning: n knots changed during the initialisation " << nKnots
944 <<
" -> " << spline1.getNumberOfKnots();
951 LOG(info) <<
"error at FlatObject functionality: " << err;
957 nKnots = spline1.getNumberOfKnots();
958 int32_t nAuxiliaryPoints = 1;
960 spline1.approximateFunction(0., TMath::Pi(), F, nAuxiliaryPoints);
964 TFile outf(
"testSpline1D.root",
"recreate");
965 if (outf.IsZombie()) {
966 LOG(info) <<
"Failed to open output file testSpline1D.root ";
968 const char*
name =
"Spline1Dtest";
969 spline1.writeToFile(outf,
name);
972 LOG(info) <<
"Failed to read Spline1D from file testSpline1D.root ";
981 helper.
setSpline(spline2, Ndim, nAuxiliaryPoints);
987 for (int32_t dim = 0; dim < Ndim; dim++) {
988 auto F3 = [&](
double u,
double f[]) ->
void {
993 splines3[dim].recreate(nKnots, knotsU);
994 splines3[dim].approximateFunction(0., TMath::Pi(), F3, nAuxiliaryPoints);
998 double stepX = 1.e-2;
999 for (
double x = 0;
x < TMath::Pi();
x += stepX) {
1001 DataT
s1[Ndim], s2[Ndim];
1003 spline1.interpolate(
x,
s1);
1004 spline2.interpolate(
x, s2);
1005 for (int32_t dim = 0; dim < Ndim; dim++) {
1006 statDf1 += (
s1[dim] -
f[dim]) * (
s1[dim] -
f[dim]);
1007 statDf2 += (s2[dim] -
f[dim]) * (s2[dim] -
f[dim]);
1008 DataT s1D = splines3[dim].interpolate(
x);
1009 statDf1D += (s1D -
s1[dim]) * (s1D -
s1[dim]);
1018 nt =
new TNtuple(
"nt",
"nt",
"u:f:s");
1019 double drawMax = -1.e20;
1020 double drawMin = 1.e20;
1021 double stepX = 1.e-4;
1022 for (
double x = 0;
x < TMath::Pi();
x += stepX) {
1026 spline1.interpolate(
x, s);
1027 nt->Fill(spline1.convXtoU(
x),
f[0], s[0]);
1028 drawMax = std::max(drawMax, std::max(
f[0], (
double)s[0]));
1029 drawMin = std::min(drawMin, std::min(
f[0], (
double)s[0]));
1032 nt->SetMarkerStyle(8);
1035 TNtuple* ntRange =
new TNtuple(
"ntRange",
"nt",
"u:f");
1036 drawMin -= 0.1 * (drawMax - drawMin);
1038 ntRange->Fill(0, drawMin);
1039 ntRange->Fill(0, drawMax);
1040 ntRange->Fill(uMax, drawMin);
1041 ntRange->Fill(uMax, drawMax);
1042 ntRange->SetMarkerColor(kWhite);
1043 ntRange->SetMarkerSize(0.1);
1044 ntRange->Draw(
"f:u",
"",
"");
1048 nt->SetMarkerColor(kGray);
1049 nt->SetMarkerSize(2.);
1050 nt->Draw(
"f:u",
"",
"P,same");
1052 nt->SetMarkerSize(.5);
1053 nt->SetMarkerColor(kBlue);
1054 nt->Draw(
"s:u",
"",
"P,same");
1056 knots =
new TNtuple(
"knots",
"knots",
"type:u:s");
1057 for (int32_t
i = 0;
i < nKnots;
i++) {
1058 double u = spline1.getKnot(
i).u;
1060 spline1.interpolate(spline1.convUtoX(u), s);
1061 knots->Fill(1, u, s[0]);
1064 knots->SetMarkerStyle(8);
1065 knots->SetMarkerSize(1.5);
1066 knots->SetMarkerColor(kRed);
1067 knots->SetMarkerSize(1.5);
1068 knots->Draw(
"s:u",
"type==1",
"same");
1070 if (drawDataPoints) {
1077 spline1.interpolate(spline1.convUtoX(p.
u), s);
1078 knots->Fill(2, p.
u, s[0]);
1080 knots->SetMarkerColor(kBlack);
1081 knots->SetMarkerSize(1.);
1082 knots->Draw(
"s:u",
"type==2",
"same");
1094 statDf1 = sqrt(statDf1 / statN);
1095 statDf2 = sqrt(statDf2 / statN);
1096 statDf1D = sqrt(statDf1D / statN);
1098 LOG(info) <<
"\n std dev for Compact Spline : " << statDf1 <<
" / " << statDf2;
1099 LOG(info) <<
" mean difference between 1-D and " << Ndim
1100 <<
"-D splines : " << statDf1D;
1102 if (statDf1 < 0.05 && statDf2 < 0.06 && statDf1D < 1.e-20) {
1103 LOG(info) <<
"Everything is fine";
1105 LOG(info) <<
"Something is wrong!!";
templateClassImp(o2::gpu::Spline1DHelperOld)
Definition of Spline1DHelperOld class.
bool isConstructed() const
Tells if the object is constructed.
static std::string stressTest(T &obj)
Test the flat object functionality for a child class T.
static void getDDScoefficientsLeft(const typename Spline1D< double >::Knot &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
Spline1DHelperOld()
_____________ Constructors / destructors __________________________
void approximateFunction(Spline1DContainer< DataT > &spline, double xMin, double xMax, std::function< void(double x, double f[])> F, int32_t nAuxiliaryDataPoints=4)
Create best-fit spline parameters for a given input function F.
static void getScoefficients(const typename Spline1D< double >::Knot &knotL, double u, double &cSl, double &cDl, double &cSr, double &cDr)
static void getDScoefficients(const typename Spline1D< double >::Knot &knotL, double u, double &cSl, double &cDl, double &cSr, double &cDr)
static int32_t test(const bool draw=0, const bool drawDataPoints=1)
Test the Spline1D class functionality.
static void getDDScoefficientsRight(const typename Spline1D< double >::Knot &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
void approximateDataPoints(Spline1DContainer< DataT > &spline, double xMin, double xMax, double x[], double f[], int32_t nDataPoints)
Create best-fit spline parameters for a given input function F.
void approximateFunctionGradually(Spline1DContainer< DataT > &spline, double xMin, double xMax, std::function< void(double x, double f[])> F, int32_t nAuxiliaryDataPoints=4)
Create best-fit spline parameters gradually for a given input function F.
void copySfromDataPoints(DataT *Fparameters, const double DataPointF[]) const
a tool for the gradual approximation: set spline values S_i at knots == function values
void approximateFunctionClassic(Spline1DContainer< DataT > &spline, double xMin, double xMax, std::function< void(double x, double f[])> F)
Create classic spline parameters for a given input function F.
static void getDDScoefficients(const typename Spline1D< double >::Knot &knotL, double u, double &cSl, double &cDl, double &cSr, double &cDr)
static void getDDDScoefficients(const typename Spline1D< double >::Knot &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
int32_t setSpline(const Spline1DContainer< DataT > &spline, int32_t nFdimensions, int32_t nAuxiliaryDataPoints)
_______________ Interface for a step-wise construction of the best-fit spline _______________________...
void approximateDerivatives(DataT *Fparameters, const double DataPointF[]) const
int32_t getNumberOfDataPoints() const
number of data points
const DataPoint & getDataPoint(int32_t ip) const
static Spline1D * readFromFile(TFile &inpf, const char *name)
read a class object from the file
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat s1
GLuint const GLchar * name
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
GLfloat GLfloat GLfloat v2
Defining DataPointCompositeObject explicitly as copiable.
DataT u
u coordinate of the knot i (an integer number in float format)
Helper structure for 1D spline construction.
double cZ0
a coefficient for s'0
double cS1
a coefficient for s1
double cS0
a coefficient for s0
bool isKnot
is the point placed at a knot
int32_t iKnot
index of the left knot of the segment
double cZ1
a coefficient for s'1
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint64_t const void const *restrict const msg