11int deqnGen(
const int n, std::vector<std::vector<double > >& a,
12 std::vector<double>& b) {
14 std::vector<int> ir(n, 0);
16 int ifail = 0, jfail = 0;
18 if (ifail != 0)
return ifail;
38void qelg(
unsigned int& n, std::array<double, 52>& epstab,
39 double& result,
double& abserr,
40 std::array<double, 3>& lastRes,
unsigned int& nres) {
42 constexpr double eps = std::numeric_limits<double>::epsilon();
45 abserr = std::numeric_limits<double>::max();
46 result = epstab[n - 1];
48 abserr = std::max(abserr, 50. * eps * std::abs(result));
51 epstab[n + 1] = epstab[n - 1];
52 epstab[n - 1] = std::numeric_limits<double>::max();
54 const unsigned int nnew = (n - 1) / 2;
55 const unsigned int nold = n;
57 for (
unsigned int i = 1; i <= nnew; ++i) {
58 double res = epstab[k + 1];
64 const double e0 = epstab[k - 3];
65 const double e1 = epstab[k - 2];
66 const double e2 = res;
67 const double delta2 = e2 - e1;
68 const double err2 = std::abs(delta2);
69 const double tol2 = std::max(std::abs(e2), std::abs(e1)) * eps;
70 const double delta3 = e1 - e0;
71 const double err3 = std::abs(delta3);
72 const double tol3 = std::max(std::abs(e1), std::abs(e0)) * eps;
73 if (err2 <= tol2 && err3 <= tol3) {
77 abserr = std::max(err2 + err3, 50. * eps * std::abs(result));
80 const double e3 = epstab[k - 1];
82 const double delta1 = e1 - e3;
83 const double err1 = std::abs(delta1);
84 const double tol1 = std::max(std::abs(e1), std::abs(e3)) * eps;
87 if (err1 <= tol1 || err2 <= tol2 || err3 <= tol3) {
91 const double ss = 1. / delta1 + 1. / delta2 - 1./ delta3;
94 if (std::abs(ss * e1) <= 1.e-4) {
102 const double error = err2 + std::abs(res - e2) + err3;
103 if (error <= abserr) {
109 constexpr unsigned int limexp = 50;
110 if (n == limexp) n = 2 * (limexp / 2) - 1;
111 unsigned int ib = (nold % 2 == 0) ? 1 : 0;
112 for (
unsigned int i = 0; i <= nnew; ++i) {
113 epstab[ib] = epstab[ib + 2];
117 for (
unsigned int i = 0; i < n; ++i) {
118 epstab[i] = epstab[nold - n + i];
123 abserr = std::abs(result - lastRes[2]) +
124 std::abs(result - lastRes[1]) +
125 std::abs(result - lastRes[0]);
126 lastRes[0] = lastRes[1];
127 lastRes[1] = lastRes[2];
130 lastRes[nres - 1] = result;
131 abserr = std::numeric_limits<double>::max();
133 abserr = std::max(abserr, 50. * eps * std::abs(result));
144void qagi(std::function<
double(
double)> f,
double bound,
const int inf,
145 const double epsabs,
const double epsrel,
146 double& result,
double& abserr,
unsigned int& status) {
153 constexpr double eps = std::numeric_limits<double>::epsilon();
154 if (epsabs <= 0. && epsrel < std::max(50. * eps, 0.5e-28)) {
159 if (inf == 2) bound = 0.;
160 double resabs0 = 0., resasc0 = 0.;
161 qk15i(f, bound, inf, 0., 1., result, abserr, resabs0, resasc0);
164 double tol = std::max(epsabs, epsrel * std::abs(result));
166 if (abserr <= 100. * eps * resabs0 && abserr > tol) {
172 if ((abserr <= tol && abserr != resasc0) || abserr == 0.)
return;
180 std::vector<Interval> intervals(1);
183 intervals[0].r = result;
184 intervals[0].e = abserr;
185 constexpr unsigned int nMaxIntervals = 500;
186 unsigned int nIntervals = 1;
188 auto it = intervals.begin();
192 std::array<double, 52> epstab;
195 unsigned int nEps = 2;
197 std::array<double, 3> lastRes = {0., 0., 0.};
199 unsigned int nRes = 0;
204 unsigned int ktmin = 0;
207 double area = result;
209 double errSum = abserr;
211 double small = 0.375;
214 double errLarge = 0.;
217 double errMax = abserr;
218 abserr = std::numeric_limits<double>::max();
221 std::array<unsigned int, 3> nRoundOff = {0, 0, 0};
222 bool roundOffErrors =
false;
226 const bool pos = (std::abs(result) >= (1. - 50. * eps) * resabs0);
230 for (nIntervals = 2; nIntervals <= nMaxIntervals; ++nIntervals) {
232 const double a1 = (*it).a;
233 const double b2 = (*it).b;
234 const double b1 = 0.5 * (a1 + b2);
235 const double a2 = b1;
237 const double errLast = (*it).e;
238 double area1 = 0., err1 = 0., resabs1 = 0., resasc1 = 0.;
239 qk15i(f, bound, inf, a1, b1, area1, err1, resabs1, resasc1);
240 double area2 = 0., err2 = 0., resabs2 = 0., resasc2 = 0.;
241 qk15i(f, bound, inf, a2, b2, area2, err2, resabs2, resasc2);
244 const double area12 = area1 + area2;
245 const double err12 = err1 + err2;
246 errSum += err12 - errMax;
247 area += area12 - (*it).r;
248 if (resasc1 != err1 && resasc2 != err2) {
249 if (std::abs((*it).r - area12) <= 1.e-5 * std::abs(area12) &&
250 err12 >= 0.99 * errMax) {
257 if (nIntervals > 10 && err12 > errMax) ++nRoundOff[2];
259 tol = std::max(epsabs, epsrel * std::abs(area));
261 if (nRoundOff[0] + nRoundOff[1] >= 10 || nRoundOff[2] >= 20) status = 2;
262 if (nRoundOff[1] >= 5) roundOffErrors =
true;
264 if (nIntervals == nMaxIntervals) status = 1;
267 constexpr double tol1 = 1. + 100. * eps;
268 constexpr double tol2 = 1000. * std::numeric_limits<double>::min();
269 if (std::max(std::abs(a1), std::abs(b2)) <= tol1 * (std::abs(a2) + tol2)) {
282 intervals.push_back(std::move(interval));
292 intervals.push_back(std::move(interval));
295 std::sort(intervals.begin(), intervals.end(),
296 [](
const Interval& lhs,
const Interval& rhs) {
297 return (lhs.e > rhs.e);
300 it = intervals.begin() + nrmax;
306 if (status != 0)
break;
307 if (nIntervals == 2) {
315 if (std::abs(b1 - a1) > small) errLarge += err12;
318 if (std::abs((*it).b - (*it).a) > small)
continue;
325 if (!roundOffErrors && errLarge > errTest) {
326 const size_t k0 = nrmax;
327 size_t k1 = nIntervals;
328 if (nIntervals > (2 + nMaxIntervals / 2)) {
329 k1 = nMaxIntervals + 3 - nIntervals;
332 for (
unsigned int k = k0; k < k1; ++k) {
333 it = intervals.begin() + nrmax;
335 if (std::abs((*it).b - (*it).a) > small) {
346 double resExtr = 0., errExtr = 0.;
347 qelg(nEps, epstab, resExtr, errExtr, lastRes, nRes);
349 if (ktmin > 5 && abserr < 1.e-3 * errSum) status = 5;
350 if (errExtr < abserr) {
355 errTest = std::max(epsabs, epsrel * std::abs(resExtr));
356 if (abserr <= errTest)
break;
359 if (nEps == 1) noext =
true;
360 if (status == 5)
break;
361 it = intervals.begin();
369 if (abserr == std::numeric_limits<double>::max()) dosum =
true;
371 if ((status != 0 || roundOffErrors)) {
372 if (roundOffErrors) {
374 if (status == 0) status = 3;
376 if (result != 0. && area != 0.) {
377 if (abserr / std::abs(result) > errSum / std::abs(area)) dosum =
true;
379 if (abserr > errSum) {
381 }
else if (area == 0.) {
382 if (status > 2) --status;
389 if (!pos && std::max(std::abs(result), std::abs(area)) <= resabs0 * 0.01) {
390 if (status > 2) --status;
393 const double r = result / area;
394 if (r < 0.01 || r > 100. || errSum > std::abs(area)) {
402 for (
const auto& interval : intervals) result += interval.r;
404 if (status > 2) --status;
408void qk15i(std::function<
double(
double)> f,
double bound,
const int inf,
409 const double a,
const double b,
double& result,
double& abserr,
410 double& resabs,
double& resasc) {
417 constexpr double wg[8] = {0., 0.129484966168869693270611432679082,
418 0., 0.279705391489276667901467771423780,
419 0., 0.381830050505118944950369775488975,
420 0., 0.417959183673469387755102040816327};
422 constexpr double xgk[8] = {
423 0.991455371120812639206854697526329,
424 0.949107912342758524526189684047851,
425 0.864864423359769072789712788640926,
426 0.741531185599394439863864773280788,
427 0.586087235467691130294144838258730,
428 0.405845151377397166906606412076961,
429 0.207784955007898467600689403773245,
432 constexpr double wgk[8] = {
433 0.022935322010529224963732008058970,
434 0.063092092629978553290700663189204,
435 0.104790010322250183839876322541518,
436 0.140653259715525918745189590510238,
437 0.169004726639267902826583426598550,
438 0.190350578064785409913256402421014,
439 0.204432940075298892414161999234649,
440 0.209482141084727828012999174891714};
442 const int dinf = std::min(1, inf);
445 const double xc = 0.5 * (a + b);
447 const double h = 0.5 * (b - a);
449 const double tc = bound + dinf * (1. - xc) / xc;
451 if (inf == 2) fc += f(-tc);
454 double resg = wg[7] * fc;
456 double resk = wgk[7] * fc;
457 resabs = std::abs(resk);
458 std::array<double, 7> fv1, fv2;
459 for (
unsigned int j = 0; j < 7; ++j) {
460 const double x = h * xgk[j];
461 const double x1 = xc - x;
462 const double x2 = xc + x;
463 const double t1 = bound + dinf * (1. - x1) / x1;
464 const double t2 = bound + dinf * (1. - x2) / x2;
475 const double fsum = y1 + y2;
476 resg += wg[j] * fsum;
477 resk += wgk[j] * fsum;
478 resabs += wgk[j] * (std::abs(y1) + std::abs(y2));
481 const double reskh = resk * 0.5;
482 resasc = wgk[7] * std::abs(fc - reskh);
483 for (
unsigned int j = 0; j < 7; ++j) {
484 resasc += wgk[j] * (std::abs(fv1[j] - reskh) + std::abs(fv2[j] - reskh));
489 abserr = std::abs((resk - resg) * h);
490 if (resasc != 0. && abserr != 0.) {
491 abserr = resasc * std::min(1., pow(200. * abserr / resasc, 1.5));
493 constexpr double eps = 50. * std::numeric_limits<double>::epsilon();
494 if (resabs > std::numeric_limits<double>::min() / eps) {
495 abserr = std::max(eps * resabs, abserr);
499void qk15(std::function<
double(
double)> f,
const double a,
const double b,
500 double& result,
double& abserr,
double& resabs,
double& resasc) {
507 constexpr double wg[4] = {
508 0.129484966168869693270611432679082,
509 0.279705391489276667901467771423780,
510 0.381830050505118944950369775488975,
511 0.417959183673469387755102040816327};
513 constexpr double xgk[8] = {
514 0.991455371120812639206854697526329,
515 0.949107912342758524526189684047851,
516 0.864864423359769072789712788640926,
517 0.741531185599394439863864773280788,
518 0.586087235467691130294144838258730,
519 0.405845151377397166906606412076961,
520 0.207784955007898467600689403773245,
523 constexpr double wgk[8] = {
524 0.022935322010529224963732008058970,
525 0.063092092629978553290700663189204,
526 0.104790010322250183839876322541518,
527 0.140653259715525918745189590510238,
528 0.169004726639267902826583426598550,
529 0.190350578064785409913256402421014,
530 0.204432940075298892414161999234649,
531 0.209482141084727828012999174891714};
534 const double xc = 0.5 * (a + b);
536 const double h = 0.5 * (b - a);
537 const double dh = std::abs(h);
540 const double fc = f(xc);
542 double resg = fc * wg[3];
544 double resk = fc * wgk[7];
545 resabs = std::abs(resk);
546 std::array<double, 7> fv1, fv2;
547 for (
unsigned int j = 0; j < 3; ++j) {
548 const unsigned int k = j * 2 + 1;
549 const double x = h * xgk[k];
550 double y1 = f(xc - x);
551 double y2 = f(xc + x);
554 const double fsum = y1 + y2;
555 resg += wg[j] * fsum;
556 resk += wgk[k] * fsum;
557 resabs += wgk[k] * (std::abs(y1) + std::abs(y2));
559 for (
unsigned int j = 0; j < 4; ++j) {
560 const unsigned int k = j * 2;
561 const double x = h * xgk[k];
562 const double y1 = f(xc - x);
563 const double y2 = f(xc + x);
566 const double fsum = y1 + y2;
567 resk += wgk[k] * fsum;
568 resabs += wgk[k] * (std::abs(y1) + std::abs(y2));
571 const double reskh = resk * 0.5;
572 resasc = wgk[7] * std::abs(fc - reskh);
573 for (
unsigned int j = 0; j < 7; ++j) {
574 resasc += wgk[j] * (std::abs(fv1[j] - reskh) + std::abs(fv2[j] - reskh));
579 abserr = std::abs((resk - resg) * h);
580 if (resasc != 0. && abserr != 0.) {
581 abserr = resasc * std::min(1., pow(200. * abserr / resasc, 1.5));
583 constexpr double eps = 50. * std::numeric_limits<double>::epsilon();
584 if (resabs > std::numeric_limits<double>::min() / eps) {
585 abserr = std::max(eps * resabs, abserr);
593int deqn(
const int n, std::vector<std::vector<double> >& a,
594 std::vector<double>& b) {
600 if (a[0][0] == 0.)
return -1;
601 const double s = 1. / a[0][0];
605 const double det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
606 if (det == 0.)
return -1;
607 const double s = 1. / det;
608 const double b1 = b[0];
609 b[0] = s * ( a[1][1] * b1 - a[0][1] * b[1]);
610 b[1] = s * (-a[1][0] * b1 + a[0][0] * b[1]);
614 const double t1 = std::abs(a[0][0]);
615 const double t2 = std::abs(a[1][0]);
616 const double t3 = std::abs(a[2][0]);
617 unsigned int m1 = 0, m2 = 0, m3 = 0;
618 if (t1 < t2 && t3 < t2) {
623 }
else if (t2 < t1 && t3 < t1) {
634 double temp = a[m1][0];
635 if (temp == 0.)
return deqnGen(n, a, b);
636 const double l11 = 1. / temp;
637 const double u12 = l11 * a[m1][1];
638 const double u13 = l11 * a[m1][2];
639 double l22 = a[m2][1] - a[m2][0] * u12;
640 double l32 = a[m3][1] - a[m3][0] * u12;
642 if (std::abs(l22) < std::abs(l32)) {
646 double l21 = a[m2][0];
647 double l31 = a[m3][0];
648 if (l22 == 0.)
return deqnGen(n, a, b);
650 const double u23 = l22 * (a[m2][2] - l21 * u13);
651 temp = a[m3][2] - l31 * u13 - l32 * u23;
652 if (temp == 0.)
return deqnGen(n, a, b);
653 const double l33 = 1. / temp;
656 const double y1 = l11 * b[m1];
657 const double y2 = l22 * (b[m2] - l21 * y1);
658 b[2] = l33 * (b[m3] - l31 * y1 - l32 * y2);
659 b[1] = y2 - u23 * b[2];
660 b[0] = y1 - u12 * b[1] - u13 * b[2];
663 return deqnGen(n, a, b);
668void dfact(
const int n, std::vector<std::vector<double> >& a,
669 std::vector<int>& ir,
int& ifail,
double& det,
int& jfail) {
670 constexpr double g1 = 1.e-19;
671 constexpr double g2 = 1.e-19;
681 for (
int j = 1; j <= n; ++j) {
683 double p = fabs(a[j - 1][j - 1]);
691 det *= a[j - 1][j - 1];
692 a[j - 1][j - 1] = 1. / a[j - 1][j - 1];
696 if (jfail == 0) jfail = -1;
699 if (jfail == 0) jfail = +1;
703 for (
int i = j + 1; i <= n; ++i) {
704 double q = std::abs(a[i - 1][j - 1]);
705 if (q <= p)
continue;
710 for (
int l = 1; l <= n; ++l) {
711 std::swap(a[j - 1][l - 1], a[k - 1][l - 1]);
714 ir[nxch - 1] = j * 4096 + k;
715 }
else if (p <= 0.) {
721 det *= a[j - 1][j - 1];
722 a[j - 1][j - 1] = 1. / a[j - 1][j - 1];
726 if (jfail == 0) jfail = -1;
729 if (jfail == 0) jfail = +1;
731 for (k = j + 1; k <= n; ++k) {
732 double s11 = -a[j - 1][k - 1];
733 double s12 = -a[k - 1][j];
735 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
736 a[k - 1][j] = -(s12 + a[j - 1][j] * a[k - 1][j - 1]);
739 for (
int i = 1; i <= j - 1; ++i) {
740 s11 += a[i - 1][k - 1] * a[j - 1][i - 1];
741 s12 += a[i - 1][j] * a[k - 1][i - 1];
743 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
744 a[k - 1][j] = -a[j - 1][j] * a[k - 1][j - 1] - s12;
748 if (nxch % 2 != 0) det = -det;
749 if (jfail != 0) det = 0.;
753void dfeqn(
const int n, std::vector<std::vector<double> >& a,
754 std::vector<int>& ir, std::vector<double>& b) {
757 int nxch = ir[n - 1];
759 for (
int m = 1; m <= nxch; ++m) {
760 const int ij = ir[m - 1];
761 const int i = ij / 4096;
762 const int j = ij % 4096;
763 std::swap(b[i - 1], b[j - 1]);
770 for (
int i = 2; i <= n; ++i) {
771 double s21 = -b[i - 1];
772 for (
int j = 1; j <= i - 1; ++j) {
773 s21 += a[i - 1][j - 1] * b[j - 1];
775 b[i - 1] = -a[i - 1][i - 1] * s21;
778 for (
int i = 1; i <= n - 1; ++i) {
779 double s22 = -b[n - i - 1];
780 for (
int j = 1; j <= i; ++j) {
781 s22 += a[n - i - 1][n - j] * b[n - j];
787int dinv(
const int n, std::vector<std::vector<double> >& a) {
795 std::vector<int> ir(n, 0);
796 dfact(n, a, ir, ifail, det, jfail);
797 if (ifail != 0)
return ifail;
801 const double c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
802 const double c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
803 const double c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
804 const double c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
805 const double c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
806 const double c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
807 const double c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
808 const double c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
809 const double c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
810 const double t1 = fabs(a[0][0]);
811 const double t2 = fabs(a[1][0]);
812 const double t3 = fabs(a[2][0]);
815 if (t2 < t1 && t3 < t1) {
817 det = c22 * c33 - c23 * c32;
818 }
else if (t1 < t2 && t3 < t2) {
820 det = c13 * c32 - c12 * c33;
823 det = c23 * c12 - c22 * c13;
826 if (det == 0.)
return -1;
827 double s = pivot / det;
839 const double det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
840 if (det == 0.)
return -1;
841 const double s = 1. / det;
842 const double c11 = s * a[1][1];
843 a[0][1] = -s * a[0][1];
844 a[1][0] = -s * a[1][0];
845 a[1][1] = s * a[0][0];
848 if (a[0][0] == 0.)
return -1;
849 a[0][0] = 1. / a[0][0];
854void dfinv(
const int n, std::vector<std::vector<double> >& a,
855 std::vector<int>& ir) {
858 a[1][0] = -a[1][1] * a[0][0] * a[1][0];
861 for (
int i = 3; i <= n; ++i) {
862 for (
int j = 1; j <= i - 2; ++j) {
864 double s32 = a[j - 1][i - 1];
865 for (
int k = j; k <= i - 2; ++k) {
866 s31 += a[k - 1][j - 1] * a[i - 1][k - 1];
867 s32 += a[j - 1][k] * a[k][i - 1];
870 -a[i - 1][i - 1] * (s31 + a[i - 2][j - 1] * a[i - 1][i - 2]);
871 a[j - 1][i - 1] = -s32;
873 a[i - 1][i - 2] = -a[i - 1][i - 1] * a[i - 2][i - 2] * a[i - 1][i - 2];
874 a[i - 2][i - 1] = -a[i - 2][i - 1];
878 for (
int i = 1; i <= n - 1; ++i) {
879 for (
int j = 1; j <= i; ++j) {
880 double s33 = a[i - 1][j - 1];
881 for (
int k = 1; k <= n - i; ++k) {
882 s33 += a[i + k - 1][j - 1] * a[i - 1][i + k - 1];
884 a[i - 1][j - 1] = s33;
886 for (
int j = 1; j <= n - i; ++j) {
888 for (
int k = j; k <= n - i; ++k) {
889 s34 += a[i + k - 1][i + j - 1] * a[i - 1][i + k - 1];
891 a[i - 1][i + j - 1] = s34;
895 int nxch = ir[n - 1];
896 if (nxch == 0)
return;
898 for (
int m = 1; m <= nxch; ++m) {
899 int k = nxch - m + 1;
903 for (k = 1; k <= n; ++k) {
904 std::swap(a[k - 1][i - 1], a[k - 1][j - 1]);
909int deqinv(
const int n, std::vector<std::vector<double> >& a,
910 std::vector<double>& b) {
918 std::vector<int> ir(n, 0);
919 int ifail = 0, jfail = 0;
920 dfact(n, a, ir, ifail, det, jfail);
921 if (ifail != 0)
return ifail;
926 const double c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
927 const double c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
928 const double c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
929 const double c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
930 const double c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
931 const double c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
932 const double c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
933 const double c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
934 const double c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
935 const double t1 = fabs(a[0][0]);
936 const double t2 = fabs(a[1][0]);
937 const double t3 = fabs(a[2][0]);
941 if (t2 < t1 && t3 < t1) {
943 det = c22 * c33 - c23 * c32;
944 }
else if (t1 < t2 && t3 < t2) {
946 det = c13 * c32 - c12 * c33;
949 det = c23 * c12 - c22 * c13;
953 if (det == 0.)
return -1;
954 const double s = temp / det;
966 const double b1 = b[0];
967 const double b2 = b[1];
968 b[0] = a[0][0] * b1 + a[0][1] * b2 + a[0][2] * b[2];
969 b[1] = a[1][0] * b1 + a[1][1] * b2 + a[1][2] * b[2];
970 b[2] = a[2][0] * b1 + a[2][1] * b2 + a[2][2] * b[2];
973 det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
974 if (det == 0.)
return -1;
975 const double s = 1. / det;
976 const double c11 = s * a[1][1];
977 a[0][1] = -s * a[0][1];
978 a[1][0] = -s * a[1][0];
979 a[1][1] = s * a[0][0];
982 const double b1 = b[0];
983 b[0] = c11 * b1 + a[0][1] * b[1];
984 b[1] = a[1][0] * b1 + a[1][1] * b[1];
987 if (a[0][0] == 0.)
return -1;
988 a[0][0] = 1. / a[0][0];
989 b[0] = a[0][0] * b[0];
994void cfact(
const int n, std::vector<std::vector<std::complex<double> > >& a,
995 std::vector<int>& ir,
int& ifail, std::complex<double>& det,
997 constexpr double g1 = 1.e-19;
998 constexpr double g2 = 1.e-19;
1003 det = std::complex<double>(1., 0.);
1005 for (
int j = 1; j <= n; ++j) {
1007 double p = std::max(fabs(real(a[j - 1][j - 1])), fabs(imag(a[j - 1][j - 1])));
1010 det = std::complex<double>(0., 0.);
1015 det *= a[j - 1][j - 1];
1016 a[j - 1][j - 1] = std::complex<double>(1., 0.) / a[j - 1][j - 1];
1017 const double t = std::max(fabs(real(det)), fabs(imag(det)));
1019 det = std::complex<double>(0., 0.);
1020 if (jfail == 0) jfail = -1;
1021 }
else if (t > g2) {
1022 det = std::complex<double>(1., 0.);
1023 if (jfail == 0) jfail = +1;
1027 for (
int i = j + 1; i <= n; ++i) {
1028 double q = std::max(fabs(real(a[i - 1][j - 1])), fabs(imag(a[i - 1][j - 1])));
1029 if (q <= p)
continue;
1034 for (
int l = 1; l <= n; ++l) {
1035 const auto tf = a[j - 1][l - 1];
1036 a[j - 1][l - 1] = a[k - 1][l - 1];
1037 a[k - 1][l - 1] = tf;
1040 ir[nxch - 1] = j * 4096 + k;
1041 }
else if (p <= 0.) {
1042 det = std::complex<double>(0., 0.);
1047 det *= a[j - 1][j - 1];
1048 a[j - 1][j - 1] = 1. / a[j - 1][j - 1];
1049 const double t = std::max(fabs(real(det)), fabs(imag(det)));
1051 det = std::complex<double>(0., 0.);
1052 if (jfail == 0) jfail = -1;
1053 }
else if (t > g2) {
1054 det = std::complex<double>(1., 0.);
1055 if (jfail == 0) jfail = +1;
1057 for (k = j + 1; k <= n; ++k) {
1058 auto s11 = -a[j - 1][k - 1];
1059 auto s12 = -a[k - 1][j];
1061 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
1062 a[k - 1][j] = -(s12 + a[j - 1][j] * a[k - 1][j - 1]);
1065 for (
int i = 1; i <= j - 1; ++i) {
1066 s11 += a[i - 1][k - 1] * a[j - 1][i - 1];
1067 s12 += a[i - 1][j] * a[k - 1][i - 1];
1069 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
1070 a[k - 1][j] = -a[j - 1][j] * a[k - 1][j - 1] - s12;
1074 if (nxch % 2 != 0) det = -det;
1075 if (jfail != 0) det = std::complex<double>(0., 0.);
1079void cfinv(
const int n, std::vector<std::vector<std::complex<double> > >& a,
1080 std::vector<int>& ir) {
1083 a[1][0] = -a[1][1] * a[0][0] * a[1][0];
1086 for (
int i = 3; i <= n; ++i) {
1087 for (
int j = 1; j <= i - 2; ++j) {
1088 auto s31 = std::complex<double>(0., 0.);
1089 auto s32 = a[j - 1][i - 1];
1090 for (
int k = j; k <= i - 2; ++k) {
1091 s31 += a[k - 1][j - 1] * a[i - 1][k - 1];
1092 s32 += a[j - 1][k] * a[k][i - 1];
1095 -a[i - 1][i - 1] * (s31 + a[i - 2][j - 1] * a[i - 1][i - 2]);
1096 a[j - 1][i - 1] = -s32;
1098 a[i - 1][i - 2] = -a[i - 1][i - 1] * a[i - 2][i - 2] * a[i - 1][i - 2];
1099 a[i - 2][i - 1] = -a[i - 2][i - 1];
1103 for (
int i = 1; i <= n - 1; ++i) {
1104 for (
int j = 1; j <= i; ++j) {
1105 auto s33 = a[i - 1][j - 1];
1106 for (
int k = 1; k <= n - i; ++k) {
1107 s33 += a[i + k - 1][j - 1] * a[i - 1][i + k - 1];
1109 a[i - 1][j - 1] = s33;
1111 for (
int j = 1; j <= n - i; ++j) {
1112 std::complex<double> s34(0., 0.);
1113 for (
int k = j; k <= n - i; ++k) {
1114 s34 += a[i + k - 1][i + j - 1] * a[i - 1][i + k - 1];
1116 a[i - 1][i + j - 1] = s34;
1120 int nxch = ir[n - 1];
1121 if (nxch == 0)
return;
1123 for (
int m = 1; m <= nxch; ++m) {
1124 int k = nxch - m + 1;
1125 const int ij = ir[k - 1];
1126 const int i = ij / 4096;
1127 const int j = ij % 4096;
1128 for (k = 1; k <= n; ++k) {
1129 std::swap(a[k - 1][i - 1], a[k - 1][j - 1]);
1134int cinv(
const int n, std::vector<std::vector<std::complex<double> > >& a) {
1137 if (n < 1)
return 1;
1139 std::complex<double> det(0., 0.);
1142 std::vector<int> ir(n, 0);
1143 int ifail = 0, jfail = 0;
1144 cfact(n, a, ir, ifail, det, jfail);
1145 if (ifail != 0)
return ifail;
1147 }
else if (n == 3) {
1149 const auto c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
1150 const auto c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
1151 const auto c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
1152 const auto c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
1153 const auto c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
1154 const auto c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
1155 const auto c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
1156 const auto c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
1157 const auto c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
1158 const double t1 = fabs(real(a[0][0])) + fabs(imag(a[0][0]));
1159 const double t2 = fabs(real(a[1][0])) + fabs(imag(a[1][0]));
1160 const double t3 = fabs(real(a[2][0])) + fabs(imag(a[2][0]));
1163 std::complex<double> temp(0., 0.);
1164 if (t2 < t1 && t3 < t1) {
1166 det = c22 * c33 - c23 * c32;
1167 }
else if (t1 < t2 && t3 < t2) {
1169 det = c13 * c32 - c12 * c33;
1172 det = c23 * c12 - c22 * c13;
1175 if (real(det) == 0. && imag(det) == 0.)
return -1;
1176 const auto s = temp / det;
1186 }
else if (n == 2) {
1188 det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
1189 if (real(det) == 0. && imag(det) == 0.)
return -1;
1190 const auto s = std::complex<double>(1., 0.) / det;
1191 const auto c11 = s * a[1][1];
1192 a[0][1] = -s * a[0][1];
1193 a[1][0] = -s * a[1][0];
1194 a[1][1] = s * a[0][0];
1198 if (real(a[0][0]) == 0. && imag(a[0][0]) == 0.)
return -1;
1199 a[0][0] = std::complex<double>(1., 0.) / a[0][0];
1206double Divdif(
const std::vector<double>& f,
const std::vector<double>& a,
1207 const int nn,
const double x,
const int mm) {
1209 double t[20], d[20];
1213 std::cerr <<
"Divdif: Array length < 2.\n";
1217 std::cerr <<
"Divdif: Interpolation order < 1.\n";
1222 const double tol1 = 1.e-6 * fabs(fabs(a[1]) - fabs(a[0]));
1223 const double tol2 = 1.e-6 * fabs(fabs(a[nn-1]) - fabs(a[nn-2]));
1224 if (fabs(x - a[0]) < tol1)
return f[0];
1225 if (fabs(x - a[nn - 1]) < tol2)
return f[nn - 1];
1228 constexpr int mmax = 10;
1229 const int m = std::min({mm, mmax, nn - 1});
1230 const int mplus = m + 1;
1233 if (a[0] > a[nn - 1]) {
1236 const int mid = (ix + iy) / 2;
1237 if (x > a[mid - 1]) {
1242 }
while (iy - ix > 1);
1246 const int mid = (ix + iy) / 2;
1247 if (x < a[mid - 1]) {
1252 }
while (iy - ix > 1);
1256 int npts = m + 2 - (m % 2);
1260 const int isub = ix + l;
1261 if ((1 > isub) || (isub > nn)) {
1267 t[ip - 1] = a[isub - 1];
1268 d[ip - 1] = f[isub - 1];
1274 }
while (ip < npts);
1276 const bool extra = npts != mplus;
1279 for (l = 1; l <= m; l++) {
1281 const int isub = mplus - l;
1282 d[m + 1] = (d[m + 1] - d[m - 1]) / (t[m + 1] - t[isub - 1]);
1285 for (
int j = l; j <= m; j++) {
1286 const int isub = i - l;
1287 d[i - 1] = (d[i - 1] - d[i - 2]) / (t[i - 1] - t[isub - 1]);
1293 double sum = d[mplus - 1];
1295 sum = 0.5 * (sum + d[m + 1]);
1298 for (l = 1; l <= m; l++) {
1299 sum = d[j - 1] + (x - t[j - 1]) * sum;
1305bool Boxin2(
const std::vector<std::vector<double> >& value,
1306 const std::vector<double>& xAxis,
const std::vector<double>& yAxis,
1307 const int nx,
const int ny,
const double x,
const double y,
1308 double& f,
const int iOrder) {
1313 int iX0 = 0, iX1 = 0;
1314 int iY0 = 0, iY1 = 0;
1315 std::array<double, 3> fX;
1316 std::array<double, 3> fY;
1319 if ((xAxis[nx - 1] - x) * (x - xAxis[0]) < 0 ||
1320 (yAxis[ny - 1] - y) * (y - yAxis[0]) < 0) {
1321 std::cerr <<
"Boxin2: Point not in the grid; no interpolation.\n";
1325 if (iOrder < 0 || iOrder > 2) {
1326 std::cerr <<
"Boxin2: Incorrect order; no interpolation.\n";
1328 }
else if (nx < 1 || ny < 1) {
1329 std::cerr <<
"Boxin2: Incorrect number of points; no interpolation.\n";
1332 if (iOrder == 0 || nx <= 1) {
1335 double dist = fabs(x - xAxis[0]);
1337 for (
int i = 1; i < nx; i++) {
1338 if (fabs(x - xAxis[i]) < dist) {
1339 dist = fabs(x - xAxis[i]);
1348 }
else if (iOrder == 1 || nx <= 2) {
1352 for (
int i = 1; i < nx; i++) {
1353 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1357 const double x0 = xAxis[iGrid - 1];
1358 const double x1 = xAxis[iGrid];
1361 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1365 const double xL = (x - x0) / (x1 - x0);
1370 fX = {1. - xL, xL, 0.};
1371 }
else if (iOrder == 2) {
1374 double dist = fabs(x - xAxis[0]);
1376 for (
int i = 1; i < nx; ++i) {
1377 if (fabs(x - xAxis[i]) < dist) {
1378 dist = fabs(x - xAxis[i]);
1383 int iGrid = std::max(1, std::min(nx - 2, iNode));
1384 const double x0 = xAxis[iGrid - 1];
1385 const double x1 = xAxis[iGrid];
1386 const double x2 = xAxis[iGrid + 1];
1389 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1393 const double xAlpha = (x1 - x0) / (x2 - x0);
1394 const double xL = (x - x0) / (x2 - x0);
1396 if (xAlpha <= 0 || xAlpha >= 1) {
1397 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1404 const double xL2 = xL * xL;
1405 fX[0] = xL2 / xAlpha - xL * (1. + xAlpha) / xAlpha + 1.;
1406 fX[1] = (xL2 - xL) / (xAlpha * xAlpha - xAlpha);
1407 fX[2] = (xL2 - xL * xAlpha) / (1. - xAlpha);
1409 if (iOrder == 0 || ny <= 1) {
1412 double dist = fabs(y - yAxis[0]);
1414 for (
int i = 1; i < ny; i++) {
1415 if (fabs(y - yAxis[i]) < dist) {
1416 dist = fabs(y - yAxis[i]);
1425 }
else if (iOrder == 1 || ny <= 2) {
1429 for (
int i = 1; i < ny; ++i) {
1430 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0) {
1434 const double y0 = yAxis[iGrid - 1];
1435 const double y1 = yAxis[iGrid];
1438 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1442 const double yL = (y - y0) / (y1 - y0);
1447 fY = {1. - yL, yL, 0.};
1448 }
else if (iOrder == 2) {
1451 double dist = fabs(y - yAxis[0]);
1453 for (
int i = 1; i < ny; ++i) {
1454 if (fabs(y - yAxis[i]) < dist) {
1455 dist = fabs(y - yAxis[i]);
1460 int iGrid = std::max(1, std::min(ny - 2, iNode));
1461 const double y0 = yAxis[iGrid - 1];
1462 const double y1 = yAxis[iGrid];
1463 const double y2 = yAxis[iGrid + 1];
1466 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1470 const double yAlpha = (y1 - y0) / (y2 - y0);
1471 const double yL = (y - y0) / (y2 - y0);
1473 if (yAlpha <= 0 || yAlpha >= 1) {
1474 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1481 const double yL2 = yL * yL;
1482 fY[0] = yL2 / yAlpha - yL * (1. + yAlpha) / yAlpha + 1.;
1483 fY[1] = (yL2 - yL) / (yAlpha * yAlpha - yAlpha);
1484 fY[2] = (yL2 - yL * yAlpha) / (1. - yAlpha);
1488 for (
int i = iX0; i <= iX1; ++i) {
1489 for (
int j = iY0; j <= iY1; ++j) {
1490 f += value[i][j] * fX[i - iX0] * fY[j - iY0];
1496bool Boxin3(
const std::vector<std::vector<std::vector<double> > >& value,
1497 const std::vector<double>& xAxis,
const std::vector<double>& yAxis,
1498 const std::vector<double>& zAxis,
const int nx,
const int ny,
1499 const int nz,
const double xx,
const double yy,
const double zz,
1500 double& f,
const int iOrder) {
1505 int iX0 = 0, iX1 = 0;
1506 int iY0 = 0, iY1 = 0;
1507 int iZ0 = 0, iZ1 = 0;
1508 std::array<double, 4> fX;
1509 std::array<double, 4> fY;
1510 std::array<double, 4> fZ;
1514 const double x = std::min(std::max(xx, std::min(xAxis[0], xAxis[nx - 1])),
1515 std::max(xAxis[0], xAxis[nx - 1]));
1516 const double y = std::min(std::max(yy, std::min(yAxis[0], yAxis[ny - 1])),
1517 std::max(yAxis[0], yAxis[ny - 1]));
1518 const double z = std::min(std::max(zz, std::min(zAxis[0], zAxis[nz - 1])),
1519 std::max(zAxis[0], zAxis[nz - 1]));
1522 if (iOrder < 0 || iOrder > 2) {
1523 std::cerr <<
"Boxin3: Incorrect order; no interpolation.\n";
1525 }
else if (nx < 1 || ny < 1 || nz < 1) {
1526 std::cerr <<
"Boxin3: Incorrect number of points; no interpolation.\n";
1529 if (iOrder == 0 || nx == 1) {
1532 double dist = fabs(x - xAxis[0]);
1534 for (
int i = 1; i < nx; i++) {
1535 if (fabs(x - xAxis[i]) < dist) {
1536 dist = fabs(x - xAxis[i]);
1544 fX = {1., 0., 0., 0.};
1545 }
else if (iOrder == 1 || nx == 2) {
1549 for (
int i = 1; i < nx; i++) {
1550 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1554 const double x0 = xAxis[iGrid - 1];
1555 const double x1 = xAxis[iGrid];
1558 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1562 const double xL = (x - x0) / (x1 - x0);
1567 fX = {1. - xL, xL, 0., 0.};
1568 }
else if (iOrder == 2) {
1572 for (
int i = 1; i < nx; i++) {
1573 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1580 const double x0 = xAxis[iX0];
1581 const double x1 = xAxis[iX0 + 1];
1582 const double x2 = xAxis[iX0 + 2];
1583 if (x0 == x1 || x0 == x2 || x1 == x2) {
1584 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1585 <<
" No interpolation.\n";
1588 fX[0] = (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2));
1589 fX[1] = (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2));
1590 fX[2] = (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
1591 }
else if (iGrid == nx - 1) {
1594 const double x0 = xAxis[iX0];
1595 const double x1 = xAxis[iX0 + 1];
1596 const double x2 = xAxis[iX0 + 2];
1597 if (x0 == x1 || x0 == x2 || x1 == x2) {
1598 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1599 <<
" No interpolation.\n";
1602 fX[0] = (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2));
1603 fX[1] = (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2));
1604 fX[2] = (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
1608 const double x0 = xAxis[iX0];
1609 const double x1 = xAxis[iX0 + 1];
1610 const double x2 = xAxis[iX0 + 2];
1611 const double x3 = xAxis[iX0 + 3];
1612 if (x0 == x1 || x0 == x2 || x0 == x3 ||
1613 x1 == x2 || x1 == x3 || x2 == x3) {
1614 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1615 <<
" No interpolation.\n";
1619 const double xL = (x - x1) / (x2 - x1);
1620 fX[0] = ((x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2))) * (1. - xL);
1621 fX[1] = ((x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2))) * (1. - xL) +
1622 ((x - x2) * (x - x3) / ((x1 - x2) * (x1 - x3))) * xL;
1623 fX[2] = ((x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1))) * (1. - xL) +
1624 ((x - x1) * (x - x3) / ((x2 - x1) * (x2 - x3))) * xL;
1625 fX[3] = ((x - x1) * (x - x2) / ((x3 - x1) * (x3 - x2))) * xL;
1629 if (iOrder == 0 || ny == 1) {
1632 double dist = fabs(y - yAxis[0]);
1634 for (
int i = 1; i < ny; i++) {
1635 if (fabs(y - yAxis[i]) < dist) {
1636 dist = fabs(y - yAxis[i]);
1644 fY = {1., 0., 0., 0.};
1645 }
else if (iOrder == 1 || ny == 2) {
1649 for (
int i = 1; i < ny; i++) {
1650 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
1655 const double y0 = yAxis[iGrid - 1];
1656 const double y1 = yAxis[iGrid];
1658 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1662 const double yL = (y - y0) / (y1 - y0);
1667 fY = {1. - yL, yL, 0., 0.};
1668 }
else if (iOrder == 2) {
1672 for (
int i = 1; i < ny; i++) {
1673 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
1680 const double y0 = yAxis[iY0];
1681 const double y1 = yAxis[iY0 + 1];
1682 const double y2 = yAxis[iY0 + 2];
1683 if (y0 == y1 || y0 == y2 || y1 == y2) {
1684 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1685 <<
" No interpolation.\n";
1688 fY[0] = (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2));
1689 fY[1] = (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2));
1690 fY[2] = (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
1691 }
else if (iGrid == ny - 1) {
1694 const double y0 = yAxis[iY0];
1695 const double y1 = yAxis[iY0 + 1];
1696 const double y2 = yAxis[iY0 + 2];
1697 if (y0 == y1 || y0 == y2 || y1 == y2) {
1698 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1699 <<
" No interpolation.\n";
1702 fY[0] = (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2));
1703 fY[1] = (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2));
1704 fY[2] = (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
1708 const double y0 = yAxis[iY0];
1709 const double y1 = yAxis[iY0 + 1];
1710 const double y2 = yAxis[iY0 + 2];
1711 const double y3 = yAxis[iY0 + 3];
1712 if (y0 == y1 || y0 == y2 || y0 == y3 ||
1713 y1 == y2 || y1 == y3 || y2 == y3) {
1714 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1715 <<
" No interpolation.\n";
1719 const double yL = (y - y1) / (y2 - y1);
1720 fY[0] = ((y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2))) * (1. - yL);
1721 fY[1] = ((y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2))) * (1. - yL) +
1722 ((y - y2) * (y - y3) / ((y1 - y2) * (y1 - y3))) * yL;
1723 fY[2] = ((y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1))) * (1. - yL) +
1724 ((y - y1) * (y - y3) / ((y2 - y1) * (y2 - y3))) * yL;
1725 fY[3] = ((y - y1) * (y - y2) / ((y3 - y1) * (y3 - y2))) * yL;
1729 if (iOrder == 0 || nz == 1) {
1732 double dist = fabs(z - zAxis[0]);
1734 for (
int i = 1; i < nz; i++) {
1735 if (fabs(z - zAxis[i]) < dist) {
1736 dist = fabs(z - zAxis[i]);
1744 fZ = {1., 0., 0., 0.};
1745 }
else if (iOrder == 1 || nz == 2) {
1749 for (
int i = 1; i < nz; i++) {
1750 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1754 const double z0 = zAxis[iGrid - 1];
1755 const double z1 = zAxis[iGrid];
1758 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1762 const double zL = (z - z0) / (z1 - z0);
1767 fZ = {1. - zL, zL, 0., 0.};
1768 }
else if (iOrder == 2) {
1772 for (
int i = 1; i < nz; i++) {
1773 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1780 const double z0 = zAxis[iZ0];
1781 const double z1 = zAxis[iZ0 + 1];
1782 const double z2 = zAxis[iZ0 + 2];
1783 if (z0 == z1 || z0 == z2 || z1 == z2) {
1784 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1785 <<
" No interpolation.\n";
1788 fZ[0] = (z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2));
1789 fZ[1] = (z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2));
1790 fZ[2] = (z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1));
1791 }
else if (iGrid == nz - 1) {
1794 const double z0 = zAxis[iZ0];
1795 const double z1 = zAxis[iZ0 + 1];
1796 const double z2 = zAxis[iZ0 + 2];
1797 if (z0 == z1 || z0 == z2 || z1 == z2) {
1798 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1799 <<
" No interpolation.\n";
1802 fZ[0] = (z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2));
1803 fZ[1] = (z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2));
1804 fZ[2] = (z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1));
1808 const double z0 = zAxis[iZ0];
1809 const double z1 = zAxis[iZ0 + 1];
1810 const double z2 = zAxis[iZ0 + 2];
1811 const double z3 = zAxis[iZ0 + 3];
1812 if (z0 == z1 || z0 == z2 || z0 == z3 ||
1813 z1 == z2 || z1 == z3 || z2 == z3) {
1814 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1815 <<
" No interpolation.\n";
1819 const double zL = (z - z1) / (z2 - z1);
1820 fZ[0] = ((z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2))) * (1. - zL);
1821 fZ[1] = ((z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2))) * (1. - zL) +
1822 ((z - z2) * (z - z3) / ((z1 - z2) * (z1 - z3))) * zL;
1823 fZ[2] = ((z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1))) * (1. - zL) +
1824 ((z - z1) * (z - z3) / ((z2 - z1) * (z2 - z3))) * zL;
1825 fZ[3] = ((z - z1) * (z - z2) / ((z3 - z1) * (z3 - z2))) * zL;
1829 for (
int i = iX0; i <= iX1; ++i) {
1830 for (
int j = iY0; j <= iY1; ++j) {
1831 for (
int k = iZ0; k <= iZ1; ++k) {
1832 f += value[i][j][k] * fX[i - iX0] * fY[j - iY0] * fZ[k - iZ0];
1840 std::function<
double(
double,
const std::vector<double>&)> f,
1841 std::vector<double>& par, std::vector<double>& epar,
1842 const std::vector<double>& x,
const std::vector<double>& y,
1843 const std::vector<double>& ey,
const unsigned int nMaxIter,
1844 const double diff,
double& chi2,
const double eps,
1845 const bool debug,
const bool verbose) {
1862 const unsigned int n = par.size();
1863 const unsigned int m = x.size();
1866 std::cerr <<
"LeastSquaresFit: Number of parameters to be varied\n"
1867 <<
" exceeds the number of data points.\n";
1872 if (*std::min_element(ey.cbegin(), ey.cend()) <= 0.) {
1873 std::cerr <<
"LeastSquaresFit: Not all errors are > 0; no fit done.\n";
1880 std::vector<double> r(m, 0.);
1881 for (
unsigned int i = 0; i < m; ++i) {
1883 r[i] = (y[i] - f(x[i], par)) / ey[i];
1885 diffc = std::max(std::abs(r[i]), diffc);
1887 chi2 += r[i] * r[i];
1890 std::cout <<
" Input data points:\n"
1891 <<
" X Y Y - F(X)\n";
1892 for (
unsigned int i = 0; i < m; ++i) {
1893 std::printf(
" %9u %15.8e %15.8e %15.8e\n", i, x[i], y[i], r[i]);
1895 std::cout <<
" Initial values of the fit parameters:\n"
1896 <<
" Parameter Value\n";
1897 for (
unsigned int i = 0; i < n; ++i) {
1898 std::printf(
" %9u %15.8e\n", i, par[i]);
1902 std::cout <<
" MINIMISATION SUMMARY\n"
1903 <<
" Initial situation:\n";
1904 std::printf(
" Largest difference between fit and target: %15.8e\n",
1906 std::printf(
" Sum of squares of these differences: %15.8e\n",
1910 bool converged =
false;
1912 for (
unsigned int iter = 1; iter <= nMaxIter; ++iter) {
1914 if ((diffc < diff) || (iter > 1 && std::abs(chi2L - chi2) < eps * chi2)) {
1915 if (debug || verbose) {
1917 std::cout <<
" The maximum difference stopping criterion "
1918 <<
"is satisfied.\n";
1920 std::cout <<
" The relative change in chi-squared has dropped "
1921 <<
"below the threshold.\n";
1928 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
1929 for (
unsigned int i = 0; i < n; ++i) {
1930 const double epsdif = eps * (1. + std::abs(par[i]));
1931 par[i] += 0.5 * epsdif;
1932 for (
unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
1934 for (
unsigned int j = 0; j < m; ++j) {
1935 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
1937 par[i] += 0.5 * epsdif;
1940 std::vector<double> colsum(n, 0.);
1941 std::vector<int> pivot(n, 0);
1942 for (
unsigned int i = 0; i < n; ++i) {
1943 colsum[i] = std::inner_product(d[i].cbegin(), d[i].cend(),
1948 std::vector<double> alpha(n, 0.);
1949 bool singular =
false;
1950 for (
unsigned int k = 0; k < n; ++k) {
1951 double sigma = colsum[k];
1952 unsigned int jbar = k;
1953 for (
unsigned int j = k + 1; j < n; ++j) {
1954 if (sigma < colsum[j]) {
1961 std::swap(pivot[k], pivot[jbar]);
1962 std::swap(colsum[k], colsum[jbar]);
1963 std::swap(d[k], d[jbar]);
1966 for (
unsigned int i = k; i < m; ++i) sigma += d[k][i] * d[k][i];
1967 if (sigma == 0. || sqrt(sigma) < 1.e-8 * std::abs(d[k][k])) {
1971 alpha[k] = d[k][k] < 0. ? sqrt(sigma) : -sqrt(sigma);
1972 const double beta = 1. / (sigma - d[k][k] * alpha[k]);
1973 d[k][k] -= alpha[k];
1974 std::vector<double> b(n, 0.);
1975 for (
unsigned int j = k + 1; j < n; ++j) {
1976 for (
unsigned int i = k; i < n; ++i) b[j] += d[k][i] * d[j][i];
1979 for (
unsigned int j = k + 1; j < n; ++j) {
1980 for (
unsigned int i = k; i < m; ++i) {
1981 d[j][i] -= d[k][i] * b[j];
1982 colsum[j] -= d[j][k] * d[j][k];
1987 std::cerr <<
"LeastSquaresFit: Householder matrix (nearly) singular;\n"
1988 <<
" no further optimisation.\n"
1989 <<
" Ensure the function depends on the parameters\n"
1990 <<
" and try to supply reasonable starting values.\n";
1994 for (
unsigned int j = 0; j < n; ++j) {
1996 for (
unsigned int i = j; i < m; ++i) gamma += d[j][i] * r[i];
1997 gamma *= 1. / (alpha[j] * d[j][j]);
1998 for (
unsigned int i = j; i < m; ++i) r[i] += gamma * d[j][i];
2000 std::vector<double> z(n, 0.);
2001 z[n - 1] = r[n - 1] / alpha[n - 1];
2002 for (
int i = n - 1; i >= 1; --i) {
2004 for (
unsigned int j = i + 1; j <= n; ++j) {
2005 sum += d[j - 1][i - 1] * z[j - 1];
2007 z[i - 1] = (r[i - 1] - sum) / alpha[i - 1];
2010 std::vector<double> s(n, 0.);
2011 for (
unsigned int i = 0; i < n; ++i) s[pivot[i]] = z[i];
2014 std::cout <<
" Correction vector in iteration " << iter <<
":\n";
2015 for (
unsigned int i = 0; i < n; ++i) {
2016 std::printf(
" %5u %15.8e\n", i, s[i]);
2022 for (
unsigned int i = 0; i < n; ++i) par[i] += s[i] * 2;
2023 for (
unsigned int i = 0; i <= 10; ++i) {
2024 if (chi2 <= chi2L)
break;
2025 if (std::abs(chi2L - chi2) < eps * chi2) {
2027 std::cout <<
" Too little improvement; reduction loop halted.\n";
2032 const double scale = 1. / pow(2, i);
2033 for (
unsigned int j = 0; j < n; ++j) par[j] -= s[j] * scale;
2034 for (
unsigned int j = 0; j < m; ++j) {
2035 r[j] = (y[j] - f(x[j], par)) / ey[j];
2036 chi2 += r[j] * r[j];
2039 std::printf(
" Reduction loop %3i: chi2 = %15.8e\n", i, chi2);
2043 diffc = std::abs(r[0]);
2044 for (
unsigned int i = 1; i < m; ++i) {
2045 diffc = std::max(std::abs(r[i]), diffc);
2049 std::cout <<
" Values of the fit parameters after iteration "
2050 << iter <<
"\n Parameter Value\n";
2051 for (
unsigned int i = 0; i < n; ++i) {
2052 std::printf(
" %9u %15.8e\n", i, par[i]);
2054 std::printf(
" for which chi2 = %15.8e and diff = %15.8e\n",
2056 }
else if (verbose) {
2057 std::printf(
" Step %3u: largest deviation = %15.8e, chi2 = %15.8e\n",
2063 std::cerr <<
"LeastSquaresFit: Maximum number of iterations reached.\n";
2066 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
2067 for (
unsigned int i = 0; i < n; ++i) {
2068 const double epsdif = eps * (1. + std::abs(par[i]));
2069 par[i] += 0.5 * epsdif;
2070 for (
unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
2072 for (
unsigned int j = 0; j < m; ++j) {
2073 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
2075 par[i] += 0.5 * epsdif;
2078 std::vector<std::vector<double> > cov(n, std::vector<double>(n, 0.));
2079 for (
unsigned int i = 0; i < n; ++i) {
2080 for (
unsigned int j = 0; j < n; ++j) {
2081 cov[i][j] = std::inner_product(d[i].cbegin(), d[i].cend(),
2086 double scale = m > n ? chi2 / (m - n) : 1.;
2090 std::cerr <<
"LeastSquaresFit: Singular covariance matrix; "
2091 <<
"no error calculation.\n";
2093 for (
unsigned int i = 0; i < n; ++i) {
2094 for (
unsigned int j = 0; j < n; ++j) cov[i][j] *= scale;
2095 epar[i] = sqrt(std::max(0., cov[i][i]));
2100 std::cout <<
" Comparison between input and fit:\n"
2102 for (
unsigned int i = 0; i < m; ++i) {
2103 std::printf(
" %5u %15.8e %15.8e %15.8e\n", i, x[i], y[i], f(x[i], par));
2107 std::cout <<
" Final values of the fit parameters:\n"
2108 <<
" Parameter Value Error\n";
2109 for (
unsigned int i = 0; i < n; ++i) {
2110 std::printf(
" %9u %15.8e %15.8e\n", i, par[i], epar[i]);
2112 std::cout <<
" The errors have been scaled by a factor of "
2113 << sqrt(scale) <<
".\n";
2114 std::cout <<
" Covariance matrix:\n";
2115 for (
unsigned int i = 0; i < n; ++i) {
2116 for (
unsigned int j = 0; j < n; ++j) {
2117 std::printf(
" %15.8e", cov[i][j]);
2121 std::cout <<
" Correlation matrix:\n";
2122 for (
unsigned int i = 0; i < n; ++i) {
2123 for (
unsigned int j = 0; j < n; ++j) {
2125 if (cov[i][i] > 0. && cov[j][j] > 0.) {
2126 cor = cov[i][j] / sqrt(cov[i][i] * cov[j][j]);
2128 std::printf(
" %15.8e", cor);
2132 std::cout <<
" Minimisation finished.\n";
void dfinv(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir)
void cfact(const int n, std::vector< std::vector< std::complex< double > > > &a, std::vector< int > &ir, int &ifail, std::complex< double > &det, int &jfail)
int deqn(const int n, std::vector< std::vector< double > > &a, std::vector< double > &b)
void dfact(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir, int &ifail, double &det, int &jfail)
void cfinv(const int n, std::vector< std::vector< std::complex< double > > > &a, std::vector< int > &ir)
int dinv(const int n, std::vector< std::vector< double > > &a)
Replace square matrix A by its inverse.
void dfeqn(const int n, std::vector< std::vector< double > > &a, std::vector< int > &ir, std::vector< double > &b)
int cinv(const int n, std::vector< std::vector< std::complex< double > > > &a)
Replace square matrix A by its inverse.
int deqinv(const int n, std::vector< std::vector< double > > &a, std::vector< double > &b)
Replaces b by the solution x of Ax = b, and replace A by its inverse.
void qk15(std::function< double(double)> f, const double a, const double b, double &result, double &abserr, double &resabs, double &resasc)
15-point Gauss-Kronrod integration with finite integration range.
void qagi(std::function< double(double)> f, double bound, const int inf, const double epsabs, const double epsrel, double &result, double &abserr, unsigned int &status)
void qk15i(std::function< double(double)> f, double bound, const int inf, const double a, const double b, double &result, double &abserr, double &resabs, double &resasc)
bool Boxin3(const std::vector< std::vector< std::vector< double > > > &value, const std::vector< double > &xAxis, const std::vector< double > &yAxis, const std::vector< double > &zAxis, const int nx, const int ny, const int nz, const double xx, const double yy, const double zz, double &f, const int iOrder)
bool LeastSquaresFit(std::function< double(double, const std::vector< double > &)> f, std::vector< double > &par, std::vector< double > &epar, const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &ey, const unsigned int nMaxIter, const double diff, double &chi2, const double eps, const bool debug, const bool verbose)
Least-squares minimisation.
bool Boxin2(const std::vector< std::vector< double > > &value, const std::vector< double > &xAxis, const std::vector< double > &yAxis, const int nx, const int ny, const double xx, const double yy, double &f, const int iOrder)
double Divdif(const std::vector< double > &f, const std::vector< double > &a, int nn, double x, int mm)