25 void SetSamples(
const std::vector<T>& x,
const std::vector<double>& y) {
26 assert(x.size() == y.size());
28 if (x.empty() || y.empty())
return;
32 std::vector<double> xvals(x.begin(), x.end());
33 std::vector<double> yvals = y;
39 if (xvals.size() == 1)
42 slopel = (yvals[1] - y1) / (xvals[1] - x1);
43 sloper = (y2 - yvals[yvals.size() - 2]) / (x2 - xvals[xvals.size() - 2]);
47 bool fallbackToLinear =
false;
51 if (xvals.size() < 4) fallbackToLinear =
true;
57 for (
size_t i = 1; i < xvals.size(); ++i)
58 if (xvals[i] <= xvals[i - 1]) {
59 fallbackToLinear =
true;
64 if (fallbackToLinear) {
65 linearExtrapolation = std::make_unique<SimpleLinearRegression<double, double>>();
66 linearExtrapolation->SetTrueLinearRegression(trueInterpolation);
69 for (
size_t i = 0; i < xvals.size(); ++i) {
70 if (xvals[i] > 1E-12) {
77 xvals.erase(xvals.begin(), xvals.begin() + offset);
78 yvals.erase(yvals.begin(), yvals.begin() + offset);
81 linearExtrapolation->SetSamples(xvals, yvals);
85 spline = std::make_unique<
86 boost::math::interpolators::pchip<std::vector<double>>>(
87 std::move(xvals), std::move(yvals));
93 const bool smallx = x <= x1;
94 const bool largex = x >= x2;
95 if (smallx || largex) {
100 result = y1 + slopel * (x - x1);
105 result = y2 + sloper * (x - x2);
108 result = (*spline)(x);
109 }
else if (linearExtrapolation) {
110 result = linearExtrapolation->Predict(x);
112 const double slope = (y2 - y1) / (x2 - x1);
113 result = y1 + slope * (x - x1);
116 if (trueInterpolation)
return result;
118 const auto m = 1E-12;
119 if (result < m)
return m;