37template <
typename DataT>
42template <
typename DataT>
49template <
typename DataT>
51 double& cSl,
double& cDl,
double& cSr,
double& cDr)
59 double v = u * double(knotL.Li);
63 cSl =
v2 * (2 *
v - 3.) + 1;
69template <
typename DataT>
71 double& cSl,
double& cDl,
double& cSr,
double& cDr)
74 double dv = double(knotL.Li);
77 cSl = 6 * (
v2 -
v) * dv;
78 cDl = 3 *
v2 - 4 *
v + 1.;
85template <
typename DataT>
87 double& cSl,
double& cDl,
double& cSr,
double& cDr)
90 double dv = double(knotL.Li);
92 cSl = (12 *
v - 6) * dv * dv;
93 cDl = (6 *
v - 4) * dv;
95 cDr = (6 *
v - 2) * dv;
98template <
typename DataT>
100 double& cSl,
double& cDl,
double& cSr,
double& cDr)
102 double dv = double(knotL.Li);
109template <
typename DataT>
111 double& cSl,
double& cDl,
double& cSr,
double& cDr)
113 double dv = double(knotL.Li);
120template <
typename DataT>
122 double& cSl,
double& cDl,
double& cSr,
double& cDr)
124 double dv = double(knotL.Li);
125 cSl = 12 * dv * dv * dv;
131template <
typename DataT>
133 double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
138 int32_t Ndim = spline.getYdimensions();
139 const int32_t nKnots = spline.getNumberOfKnots();
141 TMatrixD
A(nKnots, nKnots);
157 double cZ0 = (-4) * knot0.
Li;
158 double cZ1 = (-2) * knot0.
Li;
166 const Knot<DataT>& knot0 = spline.getKnot(nKnots - 2);
167 double cZ0 = (6 - 4) * knot0.
Li;
168 double cZ1 = (6 - 2) * knot0.
Li;
170 A(nKnots - 1, nKnots - 2) = cZ0;
171 A(nKnots - 1, nKnots - 1) = cZ1;
175 for (int32_t
i = 1;
i < nKnots - 1;
i++) {
177 double cZ0 = (6 - 4) * knot0.
Li;
178 double cZ1_0 = (6 - 2) * knot0.
Li;
182 double cZ1_1 = (-4) * knot1.
Li;
183 double cZ2 = (-2) * knot1.
Li;
186 A(
i,
i) = cZ1_0 - cZ1_1;
192 spline.setXrange(xMin, xMax);
193 DataT* parameters = spline.getParameters();
198 double uToXscale = (((double)xMax) - xMin) / spline.getUmax();
200 for (int32_t
i = 0;
i < nKnots; ++
i) {
204 F(xMin + u * uToXscale,
f);
205 for (int32_t dim = 0; dim < Ndim; dim++) {
206 parameters[(2 *
i) * Ndim + dim] =
f[dim];
210 for (int32_t dim = 0; dim < Ndim; dim++) {
214 double f0 = parameters[(2 * 0) * Ndim + dim];
215 double f1 = parameters[(2 * 1) * Ndim + dim];
217 double cS1 = (6) * knot0.Li * knot0.Li;
219 b(0) = -cS1 * (f1 - f0);
224 double f0 = parameters[2 * (nKnots - 2) * Ndim + dim];
225 double f1 = parameters[2 * (nKnots - 1) * Ndim + dim];
226 const Knot<DataT>& knot0 = spline.getKnot(nKnots - 2);
227 double cS1 = (6 - 12) * knot0.Li * knot0.Li;
229 b(nKnots - 1) = -cS1 * (f1 - f0);
233 for (int32_t
i = 1;
i < nKnots - 1;
i++) {
234 double f0 = parameters[2 * (
i - 1) * Ndim + dim];
235 double f1 = parameters[2 * (
i)*Ndim + dim];
236 double f2 = parameters[2 * (
i + 1) * Ndim + dim];
238 double cS1 = (6 - 12) * knot0.Li * knot0.Li;
242 double cS2 = (6) * knot1.
Li * knot1.
Li;
244 b(
i) = -cS1 * (f1 - f0) + cS2 * (f2 - f1);
248 for (int32_t
i = 0;
i < nKnots;
i++) {
249 parameters[(2 *
i + 1) * Ndim + dim] =
c[
i];
254template <
typename DataT>
257 double xMin,
double xMax,
258 double vx[],
double vf[], int32_t nDataPoints)
262 spline.setXrange(xMin, xMax);
263 setSpline(spline, spline.getYdimensions(), xMin, xMax, vx, nDataPoints);
264 approximateFunction(spline.getParameters(), vf);
267template <
typename DataT>
270 int32_t nAuxiliaryDataPoints)
273 setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints);
274 approximateFunction(spline.getParameters(), xMin, xMax, F);
275 spline.setXrange(xMin, xMax);
278template <
typename DataT>
281 int32_t nAuxiliaryDataPoints)
284 setSpline(spline, spline.getYdimensions(), nAuxiliaryDataPoints);
285 approximateFunctionGradually(spline.getParameters(), xMin, xMax, F);
286 spline.setXrange(xMin, xMax);
289template <
typename DataT>
291 DataT* Sparameters,
double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
const
295 std::vector<double> vF(getNumberOfDataPoints() * mFdimensions);
296 double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax();
297 for (int32_t
i = 0;
i < getNumberOfDataPoints();
i++) {
298 F(xMin + mUtoXscale * mDataPoints[
i].u, &vF[
i * mFdimensions]);
300 approximateFunction(Sparameters, vF.data());
303template <
typename DataT>
305 DataT* Sparameters,
double xMin,
double xMax, std::function<
void(
double x,
double f[])> F)
const
309 std::vector<double> vF(getNumberOfDataPoints() * mFdimensions);
310 double mUtoXscale = (((double)xMax) - xMin) / mSpline.getUmax();
311 for (int32_t
i = 0;
i < getNumberOfDataPoints();
i++) {
312 F(xMin + mUtoXscale * mDataPoints[
i].u, &vF[
i * mFdimensions]);
314 approximateFunctionGradually(Sparameters, vF.data());
317template <
typename DataT>
335 mFdimensions = nFdimensions;
337 if (!spline.isConstructed()) {
338 ret = storeError(-1,
"Spline1DHelperOld<DataT>::setSpline: input spline is not constructed");
339 mSpline.recreate(0, 2);
340 nAuxiliaryDataPoints = 2;
343 std::vector<int32_t> knots;
344 for (int32_t
i = 0;
i < spline.getNumberOfKnots();
i++) {
345 knots.push_back(spline.getKnot(
i).getU());
347 mSpline.recreate(0, spline.getNumberOfKnots(), knots.data());
349 nPoints = 1 + mSpline.getUmax() + mSpline.getUmax() * nAuxiliaryDataPoints;
350 if (nPoints < 2 * mSpline.getNumberOfKnots()) {
351 nAuxiliaryDataPoints = 2;
352 nPoints = 1 + mSpline.getUmax() + mSpline.getUmax() * nAuxiliaryDataPoints;
353 ret = storeError(-3,
"Spline1DHelperOld::setSpline: too few nAuxiliaryDataPoints, increase to 2");
357 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
359 mDataPoints.resize(nPoints);
360 double scalePoints2Knots = ((double)mSpline.getUmax()) / (nPoints - 1.);
362 for (int32_t
i = 0;
i < nPoints; ++
i) {
364 double u =
i * scalePoints2Knots;
365 int32_t iKnot = mSpline.getLeftKnotIndexForU(u);
368 double l = knot1.u - knot0.u;
369 double s = (u - knot0.u) * knot0.Li;
376 p.cS1 = s2 * (3. - 2. * s);
378 p.cZ0 = s * sm1 * sm1 * l;
379 p.cZ1 = s2 * sm1 * l;
382 const int32_t nKnots = mSpline.getNumberOfKnots();
384 mKnotDataPoints.resize(nKnots);
386 for (int32_t
i = 0;
i < nKnots; ++
i) {
388 int32_t iu = (int32_t)(knot.u + 0.1f);
389 mKnotDataPoints[
i] = iu * (1 + nAuxiliaryDataPoints);
390 mDataPoints[mKnotDataPoints[
i]].isKnot = 1;
396 for (int32_t
i = 0;
i < nPoints; ++
i) {
398 int32_t
j = p.iKnot * 2;
399 A(
j + 0,
j + 0) += p.cS0 * p.cS0;
400 A(
j + 1,
j + 0) += p.cS0 * p.cZ0;
401 A(
j + 2,
j + 0) += p.cS0 * p.cS1;
402 A(
j + 3,
j + 0) += p.cS0 * p.cZ1;
404 A(
j + 1,
j + 1) += p.cZ0 * p.cZ0;
405 A(
j + 2,
j + 1) += p.cZ0 * p.cS1;
406 A(
j + 3,
j + 1) += p.cZ0 * p.cZ1;
408 A(
j + 2,
j + 2) += p.cS1 * p.cS1;
409 A(
j + 3,
j + 2) += p.cS1 * p.cZ1;
411 A(
j + 3,
j + 3) += p.cZ1 * p.cZ1;
416 for (int32_t
i = 0;
i < nPar;
i++) {
417 for (int32_t
j =
i + 1;
j < nPar;
j++) {
422 TMatrixDSym Z(nKnots);
423 mLSMmatrixSvalues.resize(nKnots * nKnots);
424 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
425 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
426 mLSMmatrixSvalues[k] =
A(
i * 2 + 1,
j * 2);
427 Z(
i,
j) =
A(
i * 2 + 1,
j * 2 + 1);
433 bool ok = bk.Invert(
A);
436 ret = storeError(-4,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
439 mLSMmatrixFull.resize(nPar * nPar);
440 for (int32_t
i = 0, k = 0;
i < nPar;
i++) {
441 for (int32_t
j = 0;
j < nPar;
j++, k++) {
442 mLSMmatrixFull[k] =
A(
i,
j);
450 ret = storeError(-5,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
453 mLSMmatrixSderivatives.resize(nKnots * nKnots);
454 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
455 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
456 mLSMmatrixSderivatives[k] = Z(
i,
j);
464template <
typename DataT>
482 mFdimensions = nFdimensions;
483 int32_t nPoints = nDataPoints;
484 if (!spline.isConstructed()) {
485 ret = storeError(-1,
"Spline1DHelperOld<DataT>::setSpline: input spline is not constructed");
486 mSpline.recreate(0, 2);
488 std::vector<int32_t> knots;
489 for (int32_t
i = 0;
i < spline.getNumberOfKnots();
i++) {
490 knots.push_back(spline.getKnot(
i).getU());
492 mSpline.recreate(0, spline.getNumberOfKnots(), knots.data());
495 mSpline.setXrange(xMin, xMax);
497 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
499 mDataPoints.resize(nPoints);
501 for (int32_t
i = 0;
i < nPoints; ++
i) {
503 double u = mSpline.convXtoU(vx[
i]);
504 int32_t iKnot = mSpline.getLeftKnotIndexForU(u);
509 getScoefficients(knot0, u, p.cS0, p.cZ0, p.cS1, p.cZ1);
512 const int32_t nKnots = mSpline.getNumberOfKnots();
517 for (int32_t
i = 0;
i < nPoints; ++
i) {
519 int32_t
j = p.iKnot * 2;
520 A(
j + 0,
j + 0) += p.cS0 * p.cS0;
521 A(
j + 1,
j + 0) += p.cS0 * p.cZ0;
522 A(
j + 2,
j + 0) += p.cS0 * p.cS1;
523 A(
j + 3,
j + 0) += p.cS0 * p.cZ1;
525 A(
j + 1,
j + 1) += p.cZ0 * p.cZ0;
526 A(
j + 2,
j + 1) += p.cZ0 * p.cS1;
527 A(
j + 3,
j + 1) += p.cZ0 * p.cZ1;
529 A(
j + 2,
j + 2) += p.cS1 * p.cS1;
530 A(
j + 3,
j + 2) += p.cS1 * p.cZ1;
532 A(
j + 3,
j + 3) += p.cZ1 * p.cZ1;
535 for (int32_t iKnot = 0; iKnot < nKnots - 2; ++iKnot) {
567 double l0 = knot0.Li;
568 double l1 = knot1.Li;
576 double cS0 =
c * -3 * l0 * l0;
577 double cZ0 =
c * -l0;
578 double cS1 =
c * -3 * (l1 * l1 - l0 * l0);
579 double cZ1 =
c * -2 * (l0 + l1);
580 double cS2 =
c * 3 * l1 * l1;
581 double cZ2 =
c * -l1;
583 int32_t
j = iKnot * 2;
585 A(
j + 0,
j + 0) += cS0 * cS0;
586 A(
j + 1,
j + 0) += cS0 * cZ0;
587 A(
j + 2,
j + 0) += cS0 * cS1;
588 A(
j + 3,
j + 0) += cS0 * cZ1;
589 A(
j + 4,
j + 0) += cS0 * cS2;
590 A(
j + 5,
j + 0) += cS0 * cZ2;
592 A(
j + 1,
j + 1) += cZ0 * cZ0;
593 A(
j + 2,
j + 1) += cZ0 * cS1;
594 A(
j + 3,
j + 1) += cZ0 * cZ1;
595 A(
j + 4,
j + 1) += cZ0 * cS2;
596 A(
j + 5,
j + 1) += cZ0 * cZ2;
598 A(
j + 2,
j + 2) += cS1 * cS1;
599 A(
j + 3,
j + 2) += cS1 * cZ1;
600 A(
j + 4,
j + 2) += cS1 * cS2;
601 A(
j + 5,
j + 2) += cS1 * cZ2;
603 A(
j + 3,
j + 3) += cZ1 * cZ1;
604 A(
j + 4,
j + 3) += cZ1 * cS2;
605 A(
j + 5,
j + 3) += cZ1 * cZ2;
607 A(
j + 4,
j + 4) += cS2 * cS2;
608 A(
j + 5,
j + 4) += cS2 * cZ2;
610 A(
j + 5,
j + 5) += cZ2 * cZ2;
613 for (int32_t iKnot = -1; iKnot < nKnots - 2; ++iKnot) {
624 double l1 = knot1.Li;
629 double cS1 =
c * -3 * (l1 * l1);
630 double cZ1 =
c * -2 * (l1);
631 double cS2 =
c * 3 * l1 * l1;
632 double cZ2 =
c * -l1;
634 int32_t
j = iKnot * 2;
636 A(
j + 2,
j + 2) += cS1 * cS1;
637 A(
j + 3,
j + 2) += cS1 * cZ1;
638 A(
j + 4,
j + 2) += cS1 * cS2;
639 A(
j + 5,
j + 2) += cS1 * cZ2;
641 A(
j + 3,
j + 3) += cZ1 * cZ1;
642 A(
j + 4,
j + 3) += cZ1 * cS2;
643 A(
j + 5,
j + 3) += cZ1 * cZ2;
645 A(
j + 4,
j + 4) += cS2 * cS2;
646 A(
j + 5,
j + 4) += cS2 * cZ2;
648 A(
j + 5,
j + 5) += cZ2 * cZ2;
652 int32_t iKnot = nKnots - 2;
662 double l0 = knot0.Li;
667 double cS0 =
c * 3 * l0 * l0;
669 double cS1 =
c * -3 * l0 * l0;
670 double cZ1 =
c * 2 * l0;
672 int32_t
j = iKnot * 2;
674 A(
j + 0,
j + 0) += cS0 * cS0;
675 A(
j + 1,
j + 0) += cS0 * cZ0;
676 A(
j + 2,
j + 0) += cS0 * cS1;
677 A(
j + 3,
j + 0) += cS0 * cZ1;
679 A(
j + 1,
j + 1) += cZ0 * cZ0;
680 A(
j + 2,
j + 1) += cZ0 * cS1;
681 A(
j + 3,
j + 1) += cZ0 * cZ1;
683 A(
j + 2,
j + 2) += cS1 * cS1;
684 A(
j + 3,
j + 2) += cS1 * cZ1;
686 A(
j + 3,
j + 3) += cZ1 * cZ1;
691 for (int32_t
i = 0;
i < nPar;
i++) {
692 for (int32_t
j =
i + 1;
j < nPar;
j++) {
697 TMatrixDSym Z(nKnots);
698 mLSMmatrixSvalues.resize(nKnots * nKnots);
699 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
700 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
701 mLSMmatrixSvalues[k] =
A(
i * 2 + 1,
j * 2);
702 Z(
i,
j) =
A(
i * 2 + 1,
j * 2 + 1);
708 bool ok = bk.Invert(
A);
711 ret = storeError(-4,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
714 mLSMmatrixFull.resize(nPar * nPar);
715 for (int32_t
i = 0, k = 0;
i < nPar;
i++) {
716 for (int32_t
j = 0;
j < nPar;
j++, k++) {
717 mLSMmatrixFull[k] =
A(
i,
j);
725 ret = storeError(-5,
"Spline1DHelperOld::setSpline: internal error - can not invert the matrix");
728 mLSMmatrixSderivatives.resize(nKnots * nKnots);
729 for (int32_t
i = 0, k = 0;
i < nKnots;
i++) {
730 for (int32_t
j = 0;
j < nKnots;
j++, k++) {
731 mLSMmatrixSderivatives[k] = Z(
i,
j);
739template <
typename DataT>
742 const double DataPointF[])
const
746 const int32_t nPar = 2 * mSpline.getNumberOfKnots();
748 for (int32_t idim = 0; idim < mFdimensions; idim++) {
749 for (int32_t
i = 0;
i < nPar;
i++) {
752 for (int32_t
i = 0;
i < getNumberOfDataPoints(); ++
i) {
754 double*
bb = &(
b[p.iKnot * 2]);
755 double f = (double)DataPointF[
i * mFdimensions + idim];
762 const double*
row = mLSMmatrixFull.data();
764 for (int32_t
i = 0;
i < nPar;
i++,
row += nPar) {
766 for (int32_t
j = 0;
j < nPar;
j++) {
769 Sparameters[
i * mFdimensions + idim] = (float)s;
774template <
typename DataT>
776 DataT* Sparameters,
const double DataPointF[])
const
780 copySfromDataPoints(Sparameters, DataPointF);
781 approximateDerivatives(Sparameters, DataPointF);
784template <
typename DataT>
786 DataT* Sparameters,
const double DataPointF[])
const
790 for (int32_t
i = 0;
i < mSpline.getNumberOfKnots(); ++
i) {
791 int32_t ip = mKnotDataPoints[
i];
792 for (int32_t d = 0; d < mFdimensions; d++) {
793 Sparameters[2 *
i * mFdimensions + d] = DataPointF[ip * mFdimensions + d];
798template <
typename DataT>
800 DataT* Sparameters,
const double DataPointF[])
const
806 const int32_t nKnots = mSpline.getNumberOfKnots();
807 const int32_t Ndim = mFdimensions;
808 double b[nKnots * mFdimensions];
809 for (int32_t
i = 0;
i < nKnots * Ndim;
i++) {
813 for (int32_t
i = 0;
i < getNumberOfDataPoints(); ++
i) {
818 for (int32_t d = 0; d < Ndim; d++) {
819 double f = (double)DataPointF[
i * Ndim + d];
820 b[(p.iKnot + 0) * Ndim + d] +=
f * p.cZ0;
821 b[(p.iKnot + 1) * Ndim + d] +=
f * p.cZ1;
825 const double*
row = mLSMmatrixSvalues.data();
826 for (int32_t
i = 0;
i < nKnots; ++
i,
row += nKnots) {
828 for (int32_t d = 0; d < Ndim; d++) {
831 for (int32_t
j = 0;
j < nKnots; ++
j) {
832 for (int32_t d = 0; d < Ndim; d++) {
833 s[d] +=
row[
j] * Sparameters[2 *
j * Ndim + d];
836 for (int32_t d = 0; d < Ndim; d++) {
837 b[
i * Ndim + d] -= s[d];
841 row = mLSMmatrixSderivatives.data();
842 for (int32_t
i = 0;
i < nKnots; ++
i,
row += nKnots) {
844 for (int32_t d = 0; d < Ndim; d++) {
847 for (int32_t
j = 0;
j < nKnots; ++
j) {
848 for (int32_t d = 0; d < Ndim; d++) {
849 s[d] +=
row[
j] *
b[
j * Ndim + d];
852 for (int32_t d = 0; d < Ndim; d++) {
853 Sparameters[(2 *
i + 1) * Ndim + d] = (
float)s[d];
858template <
typename DataT>
865 const int32_t Ndim = 5;
866 const int32_t Fdegree = 4;
867 double Fcoeff[Ndim][2 * (Fdegree + 1)];
869 auto F = [&](
double x,
double f[]) ->
void {
870 double cosx[Fdegree + 1], sinx[Fdegree + 1];
872 for (int32_t
i = 0;
i <= Fdegree;
i++, xi +=
x) {
873 GPUCommonMath::SinCosd(xi, sinx[
i], cosx[
i]);
875 for (int32_t dim = 0; dim < Ndim; dim++) {
877 for (int32_t
i = 1;
i <= Fdegree;
i++) {
878 f[dim] += Fcoeff[dim][2 *
i] * cosx[
i] + Fcoeff[dim][2 *
i + 1] * sinx[
i];
883 TCanvas* canv =
nullptr;
884 TNtuple* nt =
nullptr;
885 TNtuple* knots =
nullptr;
887 auto ask = [&]() ->
bool {
892 LOG(info) <<
"type 'q ' to exit";
894 std::getline(std::cin,
str);
895 return (
str !=
"q" &&
str !=
".q");
898 LOG(info) <<
"Test 1D interpolation with the compact spline";
900 int32_t nTries = 100;
903 canv =
new TCanvas(
"cQA",
"Spline1D QA", 1000, 600);
914 for (int32_t itry = 0; itry < nTries; itry++) {
917 for (int32_t dim = 0; dim < Ndim; dim++) {
918 gRandom->SetSeed(seed++);
919 for (int32_t
i = 0;
i < 2 * (Fdegree + 1);
i++) {
920 Fcoeff[dim][
i] = gRandom->Uniform(-1, 1);
927 const int32_t uMax = nKnots * 3;
930 int32_t knotsU[nKnots];
934 double du = 1. * uMax / (nKnots - 1);
935 for (int32_t
i = 1;
i < nKnots;
i++) {
936 knotsU[
i] = (int32_t)(
i * du);
938 knotsU[nKnots - 1] = uMax;
939 spline1.recreate(nKnots, knotsU);
940 if (nKnots != spline1.getNumberOfKnots()) {
941 LOG(info) <<
"warning: n knots changed during the initialisation " << nKnots
942 <<
" -> " << spline1.getNumberOfKnots();
949 LOG(info) <<
"error at FlatObject functionality: " << err;
955 nKnots = spline1.getNumberOfKnots();
956 int32_t nAuxiliaryPoints = 1;
958 spline1.approximateFunction(0., TMath::Pi(), F, nAuxiliaryPoints);
962 TFile outf(
"testSpline1D.root",
"recreate");
963 if (outf.IsZombie()) {
964 LOG(info) <<
"Failed to open output file testSpline1D.root ";
966 const char*
name =
"Spline1Dtest";
967 spline1.writeToFile(outf,
name);
970 LOG(info) <<
"Failed to read Spline1D from file testSpline1D.root ";
979 helper.
setSpline(spline2, Ndim, nAuxiliaryPoints);
985 for (int32_t dim = 0; dim < Ndim; dim++) {
986 auto F3 = [&](
double u,
double f[]) ->
void {
991 splines3[dim].recreate(nKnots, knotsU);
992 splines3[dim].approximateFunction(0., TMath::Pi(), F3, nAuxiliaryPoints);
996 double stepX = 1.e-2;
997 for (
double x = 0;
x < TMath::Pi();
x += stepX) {
999 DataT
s1[Ndim], s2[Ndim];
1001 spline1.interpolate(
x,
s1);
1002 spline2.interpolate(
x, s2);
1003 for (int32_t dim = 0; dim < Ndim; dim++) {
1004 statDf1 += (
s1[dim] -
f[dim]) * (
s1[dim] -
f[dim]);
1005 statDf2 += (s2[dim] -
f[dim]) * (s2[dim] -
f[dim]);
1006 DataT s1D = splines3[dim].interpolate(
x);
1007 statDf1D += (s1D -
s1[dim]) * (s1D -
s1[dim]);
1016 nt =
new TNtuple(
"nt",
"nt",
"u:f:s");
1017 double drawMax = -1.e20;
1018 double drawMin = 1.e20;
1019 double stepX = 1.e-4;
1020 for (
double x = 0;
x < TMath::Pi();
x += stepX) {
1024 spline1.interpolate(
x, s);
1025 nt->Fill(spline1.convXtoU(
x),
f[0], s[0]);
1026 drawMax = std::max(drawMax, std::max(
f[0], (
double)s[0]));
1027 drawMin = std::min(drawMin, std::min(
f[0], (
double)s[0]));
1030 nt->SetMarkerStyle(8);
1033 TNtuple* ntRange =
new TNtuple(
"ntRange",
"nt",
"u:f");
1034 drawMin -= 0.1 * (drawMax - drawMin);
1036 ntRange->Fill(0, drawMin);
1037 ntRange->Fill(0, drawMax);
1038 ntRange->Fill(uMax, drawMin);
1039 ntRange->Fill(uMax, drawMax);
1040 ntRange->SetMarkerColor(kWhite);
1041 ntRange->SetMarkerSize(0.1);
1042 ntRange->Draw(
"f:u",
"",
"");
1046 nt->SetMarkerColor(kGray);
1047 nt->SetMarkerSize(2.);
1048 nt->Draw(
"f:u",
"",
"P,same");
1050 nt->SetMarkerSize(.5);
1051 nt->SetMarkerColor(kBlue);
1052 nt->Draw(
"s:u",
"",
"P,same");
1054 knots =
new TNtuple(
"knots",
"knots",
"type:u:s");
1055 for (int32_t
i = 0;
i < nKnots;
i++) {
1056 double u = spline1.getKnot(
i).u;
1058 spline1.interpolate(spline1.convUtoX(u), s);
1059 knots->Fill(1, u, s[0]);
1062 knots->SetMarkerStyle(8);
1063 knots->SetMarkerSize(1.5);
1064 knots->SetMarkerColor(kRed);
1065 knots->SetMarkerSize(1.5);
1066 knots->Draw(
"s:u",
"type==1",
"same");
1075 spline1.interpolate(spline1.convUtoX(p.u), s);
1076 knots->Fill(2, p.u, s[0]);
1078 knots->SetMarkerColor(kBlack);
1079 knots->SetMarkerSize(1.);
1080 knots->Draw(
"s:u",
"type==2",
"same");
1092 statDf1 = sqrt(statDf1 / statN);
1093 statDf2 = sqrt(statDf2 / statN);
1094 statDf1D = sqrt(statDf1D / statN);
1096 LOG(info) <<
"\n std dev for Compact Spline : " << statDf1 <<
" / " << statDf2;
1097 LOG(info) <<
" mean difference between 1-D and " << Ndim
1098 <<
"-D splines : " << statDf1D;
1100 if (statDf1 < 0.05 && statDf2 < 0.06 && statDf1D < 1.e-20) {
1101 LOG(info) <<
"Everything is fine";
1103 LOG(info) <<
"Something is wrong!!";
templateClassImp(o2::gpu::Spline1DHelperOld)
Definition of Spline1DHelperOld class.
static std::string stressTest(T &obj)
Test the flat object functionality for a child class T.
static void getDDDScoefficients(const typename Spline1D< double >::KnotType &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
void approximateFunctionClassic(Spline1DContainer< DataT, FlatObject > &spline, double xMin, double xMax, std::function< void(double x, double f[])> F)
Create classic spline parameters for a given input function F.
Spline1DHelperOld()
_____________ Constructors / destructors __________________________
static void getDDScoefficients(const typename Spline1D< double >::KnotType &knotL, double u, double &cSl, double &cDl, double &cSr, double &cDr)
void approximateFunctionGradually(Spline1DContainer< DataT, FlatObject > &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.
static void getDScoefficients(const typename Spline1D< double >::KnotType &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.
void copySfromDataPoints(DataT *Fparameters, const double DataPointF[]) const
a tool for the gradual approximation: set spline values S_i at knots == function values
static void getScoefficients(const typename Spline1D< double >::KnotType &knotL, double u, double &cSl, double &cDl, double &cSr, double &cDr)
void approximateDataPoints(Spline1DContainer< DataT, FlatObject > &spline, double xMin, double xMax, double x[], double f[], int32_t nDataPoints)
Create best-fit spline parameters for a given input function F.
static void getDDScoefficientsRight(const typename Spline1D< double >::KnotType &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
static void getDDScoefficientsLeft(const typename Spline1D< double >::KnotType &knotL, double &cSl, double &cDl, double &cSr, double &cDr)
void approximateDerivatives(DataT *Fparameters, const double DataPointF[]) const
void approximateFunction(Spline1DContainer< DataT, FlatObject > &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.
int32_t getNumberOfDataPoints() const
number of data points
const DataPoint & getDataPoint(int32_t ip) const
int32_t setSpline(const Spline1DContainer< DataT, FlatObject > &spline, int32_t nFdimensions, int32_t nAuxiliaryDataPoints)
_______________ Interface for a step-wise construction of the best-fit spline _______________________...
Forward declaration — specializations below select ClassDefNV based on FlatBase.
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
TCanvas * drawDataPoints(TMultiGraph *mg, double min, double max)
DataT u
u coordinate of the knot i (an integer number in float format)
Helper structure for 1D spline construction.
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
uint64_t const void const *restrict const msg