18 assert(
m_x.size() == 0);
27 assert(
m_x.size() ==
m_y.size());
28 assert(
m_x.size() ==
m_b.size());
29 assert(
m_x.size() > 2);
30 size_t n =
m_b.size();
36 for (
size_t i = 0; i < n - 1; i++) {
37 const double h =
m_x[i + 1] -
m_x[i];
39 m_c[i] = (3.0 * (
m_y[i + 1] -
m_y[i]) / h - (2.0 *
m_b[i] +
m_b[i + 1])) / h;
41 m_d[i] = ((
m_b[i + 1] -
m_b[i]) / (3.0 * h) - 2.0 / 3.0 *
m_c[i]) / h;
50 int n = (int)
m_x.size();
55 for (
int i = 0; i < n - 1; i++) {
68 int n = (int)
m_x.size();
77 std::vector<double> rhs(n);
78 for (
int i = 1; i < n - 1; i++) {
79 A(i, i - 1) = 1.0 / 3.0 * (
m_x[i] -
m_x[i - 1]);
80 A(i, i) = 2.0 / 3.0 * (
m_x[i + 1] -
m_x[i - 1]);
81 A(i, i + 1) = 1.0 / 3.0 * (
m_x[i + 1] -
m_x[i]);
93 A(0, 0) = 2.0 * (
m_x[1] -
m_x[0]);
94 A(0, 1) = 1.0 * (
m_x[1] -
m_x[0]);
99 A(0, 0) = -(
m_x[2] -
m_x[1]);
100 A(0, 1) =
m_x[2] -
m_x[0];
101 A(0, 2) = -(
m_x[1] -
m_x[0]);
108 A(n - 1, n - 1) = 2.0;
109 A(n - 1, n - 2) = 0.0;
115 A(n - 1, n - 1) = 2.0 * (
m_x[n - 1] -
m_x[n - 2]);
116 A(n - 1, n - 2) = 1.0 * (
m_x[n - 1] -
m_x[n - 2]);
121 A(n - 1, n - 3) = -(
m_x[n - 1] -
m_x[n - 2]);
122 A(n - 1, n - 2) =
m_x[n - 1] -
m_x[n - 3];
123 A(n - 1, n - 1) = -(
m_x[n - 2] -
m_x[n - 3]);
136 for (
int i = 0; i < n - 1; i++) {
139 1.0 / 3.0 * (2.0 *
m_c[i] +
m_c[i + 1]) * (
m_x[i + 1] -
m_x[i]);
144 double h =
m_x[n - 1] -
m_x[n - 2];
147 m_b[n - 1] = 3.0 *
m_d[n - 2] * h * h + 2.0 *
m_c[n - 2] * h +
m_b[n - 2];
154 int n = (int)
m_x.size();
162 for (
int i = 1; i < n - 1; i++) {
163 const double h =
m_x[i + 1] -
m_x[i];
164 const double hl =
m_x[i] -
m_x[i - 1];
165 m_b[i] = -h / (hl * (hl + h)) *
m_y[i - 1] + (h - hl) / (hl * h) *
m_y[i] + hl / (h * (hl + h)) *
m_y[i + 1];
171 const double h =
m_x[1] -
m_x[0];
175 const double h0 =
m_x[1] -
m_x[0];
176 const double h1 =
m_x[2] -
m_x[1];
178 h0 * h0 / (h1 * h1) * (
m_b[1] +
m_b[2] - 2.0 * (
m_y[2] -
m_y[1]) / h1);
186 const double h =
m_x[n - 1] -
m_x[n - 2];
191 const double h0 =
m_x[n - 2] -
m_x[n - 3];
192 const double h1 =
m_x[n - 1] -
m_x[n - 2];
193 m_b[n - 1] = -
m_b[n - 2] + 2.0 * (
m_y[n - 1] -
m_y[n - 2]) / h1 +
194 h1 * h1 / (h0 * h0) * (
m_b[n - 3] +
m_b[n - 2] - 2.0 * (
m_y[n - 2] -
m_y[n - 3]) / h0);
196 m_c[n - 1] = (
m_b[n - 2] + 2.0 *
m_b[n - 1]) / h1 - 3.0 * (
m_y[n - 1] -
m_y[n - 2]) / (h1 * h1);
208 int n = (int)
m_x.size();
213 for (
int i = 1; i < n - 1; ++i) {
214 double h = (
m_x[i] -
m_x[i - 1]) / 2.;
222 assert(x.size() ==
y.size());
223 assert(x.size() >= 3);
226 assert(x.size() >= 4);
231 int n = (int)x.size();
233 for (
int i = 0; i < n - 1; i++) {
234 assert(
m_x[i] <
m_x[i + 1]);
253 assert(
m_x.size() ==
m_y.size());
254 assert(
m_x.size() ==
m_b.size());
255 assert(
m_x.size() > 2);
256 bool modified =
false;
257 const int n = (int)
m_x.size();
260 for (
int i = 0; i < n; i++) {
261 int im1 = std::max(i - 1, 0);
262 int ip1 = std::min(i + 1, n - 1);
272 for (
int i = 0; i < n - 1; i++) {
273 double h =
m_x[i + 1] -
m_x[i];
274 double avg = (
m_y[i + 1] -
m_y[i]) / h;
275 if (avg == 0.0 && (
m_b[i] != 0.0 ||
m_b[i + 1] != 0.0)) {
279 }
else if ((
m_b[i] >= 0.0 &&
m_b[i + 1] >= 0.0 && avg > 0.0) ||
280 (
m_b[i] <= 0.0 &&
m_b[i + 1] <= 0.0 && avg < 0.0)) {
282 double r = sqrt(
m_b[i] *
m_b[i] +
m_b[i + 1] *
m_b[i + 1]) / std::fabs(avg);
288 m_b[i + 1] *= (3.0 / r);
293 if (modified ==
true) {
305 std::vector<double>::const_iterator it;
306 it = std::upper_bound(
m_x.begin(),
m_x.end(), x);
307 size_t idx = std::max(
int(it -
m_x.begin()) - 1, 0);
318 size_t n =
m_x.size();
321 double h = x -
m_x[idx];
326 }
else if (x >
m_x[n - 1]) {
328 interpol = (
m_c[n - 1] * h +
m_b[n - 1]) * h +
m_y[n - 1];
331 interpol = ((
m_d[idx] * h +
m_c[idx]) * h +
m_b[idx]) * h +
m_y[idx];
339 size_t n =
m_x.size();
342 double h = x -
m_x[idx];
347 case 1: interpol = 2.0 *
m_c0 * h +
m_b[0];
break;
348 case 2: interpol = 2.0 *
m_c0;
break;
349 default: interpol = 0.0;
break;
351 }
else if (x >
m_x[n - 1]) {
354 case 1: interpol = 2.0 *
m_c[n - 1] * h +
m_b[n - 1];
break;
355 case 2: interpol = 2.0 *
m_c[n - 1];
break;
356 default: interpol = 0.0;
break;
361 case 1: interpol = (3.0 *
m_d[idx] * h + 2.0 *
m_c[idx]) * h +
m_b[idx];
break;
362 case 2: interpol = 6.0 *
m_d[idx] * h + 2.0 *
m_c[idx];
break;
363 case 3: interpol = 6.0 *
m_d[idx];
break;
364 default: interpol = 0.0;
break;
385 double h = (x0 -
m_x[idx_0]) / 2;
386 integral -= h / 3. * (
m_y[idx_0] + 4 * (*this)(
m_x[idx_0] + h) + (*
this)(x0));
389 h = (x1 -
m_x[idx_1]) / 2;
390 integral += h / 3. * (
m_y[idx_1] + 4 * (*this)(
m_x[idx_1] + h) + (*
this)(x1));
397 std::vector<double> x;
398 std::vector<double> root;
399 const size_t n =
m_x.size();
402 if (ignore_extrapolation ==
false) {
404 for (
double j : root) {
406 x.push_back(
m_x[0] + j);
413 for (
size_t i = 0; i < n - 1; i++) {
415 for (
size_t j = 0; j < root.size(); j++) {
416 double h = (i > 0) ? (
m_x[i] -
m_x[i - 1]) : 0.0;
418 if ((-eps <= root[j]) && (root[j] <
m_x[i + 1] -
m_x[i])) {
419 double new_root =
m_x[i] + root[j];
420 if (x.size() > 0 && x.back() + eps > new_root) {
423 x.push_back(new_root);
430 if (ignore_extrapolation ==
false) {
432 for (
size_t j = 0; j < root.size(); j++) {
433 if (0.0 <= root[j]) {
434 x.push_back(
m_x[n - 1] + root[j]);
443 std::string spline::info()
const
445 std::stringstream ss;
446 ss <<
"type " <<
m_type <<
", left boundary deriv " <<
m_left <<
" = ";
450 ss <<
"(spline has been adjusted for piece-wise monotonicity)";
454 #endif // HAVE_SSTREAM
470 m_upper.resize(n_u + 1);
471 m_lower.resize(n_l + 1);
472 for (
size_t i = 0; i < m_upper.size(); i++) {
473 m_upper[i].resize(
dim);
475 for (
size_t i = 0; i < m_lower.size(); i++) {
476 m_lower[i].resize(
dim);
481 if (m_upper.size() > 0) {
482 return m_upper[0].size();
493 assert((i >= 0) && (i <
dim()) && (j >= 0) && (j <
dim()));
497 return m_upper[k][i];
499 return m_lower[-k][i];
504 assert((i >= 0) && (i <
dim()) && (j >= 0) && (j <
dim()));
508 return m_upper[k][i];
510 return m_lower[-k][i];
515 assert((i >= 0) && (i <
dim()));
516 return m_lower[0][i];
520 assert((i >= 0) && (i <
dim()));
521 return m_lower[0][i];
533 for (
int i = 0; i < this->
dim(); i++) {
534 assert(this->
operator()(i, i) != 0.0);
536 j_min = std::max(0, i - this->
num_lower());
537 j_max = std::min(this->
dim() - 1, i + this->
num_upper());
538 for (
int j = j_min; j <= j_max; j++) {
545 for (
int k = 0; k < this->
dim(); k++) {
546 i_max = std::min(this->
dim() - 1, k + this->
num_lower());
547 for (
int i = k + 1; i <= i_max; i++) {
548 assert(this->
operator()(k, k) != 0.0);
551 j_max = std::min(this->
dim() - 1, k + this->
num_upper());
552 for (
int j = k + 1; j <= j_max; j++) {
562 assert(this->
dim() == (
int)b.size());
563 std::vector<double> x(this->
dim());
566 for (
int i = 0; i < this->
dim(); i++) {
568 j_start = std::max(0, i - this->
num_lower());
569 for (
int j = j_start; j < i; j++)
570 sum += this->
operator()(i, j) * x[j];
578 assert(this->
dim() == (
int)b.size());
579 std::vector<double> x(this->
dim());
582 for (
int i = this->
dim() - 1; i >= 0; i--) {
584 j_stop = std::min(this->
dim() - 1, i + this->
num_upper());
585 for (
int j = i + 1; j <= j_stop; j++)
586 sum += this->
operator()(i, j) * x[j];
587 x[i] = (b[i] - sum) / this->
operator()(i, i);
594 assert(this->
dim() == (
int)b.size());
595 std::vector<double> x,
y;
596 if (is_lu_decomposed ==
false) {
608 return 2.2204460492503131e-16;
614 std::vector<double> x;
639 double p = 0.5 * b /
c;
641 double discr = p * p - q;
643 double discr_err = (6.0 * (p * p) + 3.0 * fabs(q) + fabs(discr)) * eps;
645 std::vector<double> x;
646 if (fabs(discr) <= discr_err) {
650 }
else if (discr < 0) {
655 x[0] = -p - sqrt(discr);
656 x[1] = -p + sqrt(discr);
660 for (
size_t i = 0; i < x.size(); i++) {
661 for (
int k = 0; k < newton_iter; k++) {
662 double f = (
c * x[i] + b) * x[i] + a;
663 double f1 = 2.0 *
c * x[i] + b;
665 if (fabs(f1) > 1e-8) {
681 std::vector<double>
solve_cubic(
double a,
double b,
double c,
double d,
int newton_iter)
696 std::vector<double> z;
697 double p = -(1.0 / 3.0) * b + (1.0 / 9.0) * (
c *
c);
698 double r = 2.0 * (
c *
c) - 9.0 * b;
699 double q = -0.5 * a - (1.0 / 54.0) * (
c * r);
700 double discr = p * p * p - q * q;
709 double p_err = eps * ((3.0 / 3.0) * fabs(b) + (4.0 / 9.0) * (
c *
c) + fabs(p));
710 double r_err = eps * (6.0 * (
c *
c) + 18.0 * fabs(b) + fabs(r));
711 double q_err = 0.5 * fabs(a) * eps + (1.0 / 54.0) * fabs(
c) * (r_err + fabs(r) * 3.0 * eps) + fabs(q) * eps;
713 (p * p) * (3.0 * p_err + fabs(p) * 2.0 * eps) + fabs(q) * (2.0 * q_err + fabs(q) * eps) + fabs(discr) * eps;
716 if (fabs(discr) <= discr_err) {
718 if (fabs(p) <= p_err) {
727 }
else if (discr > 0) {
730 double ac = (1.0 / 3.0) * acos(q / (p * sqrt(p)));
731 double sq = 2.0 * sqrt(p);
733 z[1] = sq * cos(ac - 2.0 * M_PI / 3.0);
734 z[2] = sq * cos(ac - 4.0 * M_PI / 3.0);
735 }
else if (discr < 0.0) {
738 double sgnq = (q >= 0 ? 1 : -1);
739 double basis = fabs(q) + sqrt(-discr);
740 double C = sgnq * pow(basis, 1.0 / 3.0);
743 for (
size_t i = 0; i < z.size(); i++) {
745 z[i] -= (1.0 / 3.0) *
c;
747 for (
int k = 0; k < newton_iter; k++) {
748 double f = ((z[i] +
c) * z[i] + b) * z[i] + a;
749 double f1 = (3.0 * z[i] + 2.0 *
c) * z[i] + b;
751 if (fabs(f1) > 1e-8) {
759 assert(z.size() > 0);
760 double xmin = fabs(z[0]);
762 for (
size_t i = 1; i < z.size(); i++) {
763 if (xmin > fabs(z[i])) {
770 std::sort(z.begin(), z.end());