145void qagi(std::function<
double(
double)> f,
double bound,
const int inf,
146 const double epsabs,
const double epsrel,
147 double& result,
double& abserr,
unsigned int& status) {
154 constexpr double eps = std::numeric_limits<double>::epsilon();
155 if (epsabs <= 0. && epsrel < std::max(50. * eps, 0.5e-28)) {
160 if (inf == 2) bound = 0.;
161 double resabs0 = 0., resasc0 = 0.;
162 qk15i(f, bound, inf, 0., 1., result, abserr, resabs0, resasc0);
165 double tol = std::max(epsabs, epsrel * std::abs(result));
167 if (abserr <= 100. * eps * resabs0 && abserr > tol) {
173 if ((abserr <= tol && abserr != resasc0) || abserr == 0.)
return;
181 std::vector<Interval> intervals(1);
184 intervals[0].r = result;
185 intervals[0].e = abserr;
186 constexpr unsigned int nMaxIntervals = 500;
187 unsigned int nIntervals = 1;
189 auto it = intervals.begin();
193 std::array<double, 52> epstab;
196 unsigned int nEps = 2;
198 std::array<double, 3> lastRes = {0., 0., 0.};
200 unsigned int nRes = 0;
205 unsigned int ktmin = 0;
208 double area = result;
210 double errSum = abserr;
212 double small = 0.375;
215 double errLarge = 0.;
218 double errMax = abserr;
219 abserr = std::numeric_limits<double>::max();
222 std::array<unsigned int, 3> nRoundOff = {0, 0, 0};
223 bool roundOffErrors =
false;
227 const bool pos = (std::abs(result) >= (1. - 50. * eps) * resabs0);
231 for (nIntervals = 2; nIntervals <= nMaxIntervals; ++nIntervals) {
233 const double a1 = (*it).a;
234 const double b2 = (*it).b;
235 const double b1 = 0.5 * (a1 + b2);
236 const double a2 = b1;
238 const double errLast = (*it).e;
239 double area1 = 0., err1 = 0., resabs1 = 0., resasc1 = 0.;
240 qk15i(f, bound, inf, a1, b1, area1, err1, resabs1, resasc1);
241 double area2 = 0., err2 = 0., resabs2 = 0., resasc2 = 0.;
242 qk15i(f, bound, inf, a2, b2, area2, err2, resabs2, resasc2);
245 const double area12 = area1 + area2;
246 const double err12 = err1 + err2;
247 errSum += err12 - errMax;
248 area += area12 - (*it).r;
249 if (resasc1 != err1 && resasc2 != err2) {
250 if (std::abs((*it).r - area12) <= 1.e-5 * std::abs(area12) &&
251 err12 >= 0.99 * errMax) {
258 if (nIntervals > 10 && err12 > errMax) ++nRoundOff[2];
260 tol = std::max(epsabs, epsrel * std::abs(area));
262 if (nRoundOff[0] + nRoundOff[1] >= 10 || nRoundOff[2] >= 20) status = 2;
263 if (nRoundOff[1] >= 5) roundOffErrors =
true;
265 if (nIntervals == nMaxIntervals) status = 1;
268 constexpr double tol1 = 1. + 100. * eps;
269 constexpr double tol2 = 1000. * std::numeric_limits<double>::min();
270 if (std::max(std::abs(a1), std::abs(b2)) <= tol1 * (std::abs(a2) + tol2)) {
283 intervals.push_back(std::move(interval));
293 intervals.push_back(std::move(interval));
296 std::sort(intervals.begin(), intervals.end(),
297 [](
const Interval& lhs,
const Interval& rhs) {
298 return (lhs.e > rhs.e);
301 it = intervals.begin() + nrmax;
307 if (status != 0)
break;
308 if (nIntervals == 2) {
316 if (std::abs(b1 - a1) > small) errLarge += err12;
319 if (std::abs((*it).b - (*it).a) > small)
continue;
326 if (!roundOffErrors && errLarge > errTest) {
327 const size_t k0 = nrmax;
328 size_t k1 = nIntervals;
329 if (nIntervals > (2 + nMaxIntervals / 2)) {
330 k1 = nMaxIntervals + 3 - nIntervals;
333 for (
unsigned int k = k0; k < k1; ++k) {
334 it = intervals.begin() + nrmax;
336 if (std::abs((*it).b - (*it).a) > small) {
347 double resExtr = 0., errExtr = 0.;
348 qelg(nEps, epstab, resExtr, errExtr, lastRes, nRes);
350 if (ktmin > 5 && abserr < 1.e-3 * errSum) status = 5;
351 if (errExtr < abserr) {
356 errTest = std::max(epsabs, epsrel * std::abs(resExtr));
357 if (abserr <= errTest)
break;
360 if (nEps == 1) noext =
true;
361 if (status == 5)
break;
362 it = intervals.begin();
370 if (abserr == std::numeric_limits<double>::max()) dosum =
true;
372 if ((status != 0 || roundOffErrors)) {
373 if (roundOffErrors) {
375 if (status == 0) status = 3;
377 if (result != 0. && area != 0.) {
378 if (abserr / std::abs(result) > errSum / std::abs(area)) dosum =
true;
380 if (abserr > errSum) {
382 }
else if (area == 0.) {
383 if (status > 2) --status;
390 if (!pos && std::max(std::abs(result), std::abs(area)) <= resabs0 * 0.01) {
391 if (status > 2) --status;
394 const double r = result / area;
395 if (r < 0.01 || r > 100. || errSum > std::abs(area)) {
403 for (
const auto& interval : intervals) result += interval.r;
405 if (status > 2) --status;
409void qk15i(std::function<
double(
double)> f,
double bound,
const int inf,
410 const double a,
const double b,
double& result,
double& abserr,
411 double& resabs,
double& resasc) {
418 constexpr double wg[8] = {0., 0.129484966168869693270611432679082,
419 0., 0.279705391489276667901467771423780,
420 0., 0.381830050505118944950369775488975,
421 0., 0.417959183673469387755102040816327};
423 constexpr double xgk[8] = {
424 0.991455371120812639206854697526329,
425 0.949107912342758524526189684047851,
426 0.864864423359769072789712788640926,
427 0.741531185599394439863864773280788,
428 0.586087235467691130294144838258730,
429 0.405845151377397166906606412076961,
430 0.207784955007898467600689403773245,
433 constexpr double wgk[8] = {
434 0.022935322010529224963732008058970,
435 0.063092092629978553290700663189204,
436 0.104790010322250183839876322541518,
437 0.140653259715525918745189590510238,
438 0.169004726639267902826583426598550,
439 0.190350578064785409913256402421014,
440 0.204432940075298892414161999234649,
441 0.209482141084727828012999174891714};
443 const int dinf = std::min(1, inf);
446 const double xc = 0.5 * (a + b);
448 const double h = 0.5 * (b - a);
450 const double tc = bound + dinf * (1. - xc) / xc;
452 if (inf == 2) fc += f(-tc);
455 double resg = wg[7] * fc;
457 double resk = wgk[7] * fc;
458 resabs = std::abs(resk);
459 std::array<double, 7> fv1, fv2;
460 for (
unsigned int j = 0; j < 7; ++j) {
461 const double x = h * xgk[j];
462 const double x1 = xc - x;
463 const double x2 = xc + x;
464 const double t1 = bound + dinf * (1. - x1) / x1;
465 const double t2 = bound + dinf * (1. - x2) / x2;
476 const double fsum = y1 + y2;
477 resg += wg[j] * fsum;
478 resk += wgk[j] * fsum;
479 resabs += wgk[j] * (std::abs(y1) + std::abs(y2));
482 const double reskh = resk * 0.5;
483 resasc = wgk[7] * std::abs(fc - reskh);
484 for (
unsigned int j = 0; j < 7; ++j) {
485 resasc += wgk[j] * (std::abs(fv1[j] - reskh) + std::abs(fv2[j] - reskh));
490 abserr = std::abs((resk - resg) * h);
491 if (resasc != 0. && abserr != 0.) {
492 abserr = resasc * std::min(1., pow(200. * abserr / resasc, 1.5));
494 constexpr double eps = 50. * std::numeric_limits<double>::epsilon();
495 if (resabs > std::numeric_limits<double>::min() / eps) {
496 abserr = std::max(eps * resabs, abserr);
500void qk15(std::function<
double(
double)> f,
const double a,
const double b,
501 double& result,
double& abserr,
double& resabs,
double& resasc) {
508 constexpr double wg[4] = {
509 0.129484966168869693270611432679082,
510 0.279705391489276667901467771423780,
511 0.381830050505118944950369775488975,
512 0.417959183673469387755102040816327};
514 constexpr double xgk[8] = {
515 0.991455371120812639206854697526329,
516 0.949107912342758524526189684047851,
517 0.864864423359769072789712788640926,
518 0.741531185599394439863864773280788,
519 0.586087235467691130294144838258730,
520 0.405845151377397166906606412076961,
521 0.207784955007898467600689403773245,
524 constexpr double wgk[8] = {
525 0.022935322010529224963732008058970,
526 0.063092092629978553290700663189204,
527 0.104790010322250183839876322541518,
528 0.140653259715525918745189590510238,
529 0.169004726639267902826583426598550,
530 0.190350578064785409913256402421014,
531 0.204432940075298892414161999234649,
532 0.209482141084727828012999174891714};
535 const double xc = 0.5 * (a + b);
537 const double h = 0.5 * (b - a);
538 const double dh = std::abs(h);
541 const double fc = f(xc);
543 double resg = fc * wg[3];
545 double resk = fc * wgk[7];
546 resabs = std::abs(resk);
547 std::array<double, 7> fv1, fv2;
548 for (
unsigned int j = 0; j < 3; ++j) {
549 const unsigned int k = j * 2 + 1;
550 const double x = h * xgk[k];
551 double y1 = f(xc - x);
552 double y2 = f(xc + x);
555 const double fsum = y1 + y2;
556 resg += wg[j] * fsum;
557 resk += wgk[k] * fsum;
558 resabs += wgk[k] * (std::abs(y1) + std::abs(y2));
560 for (
unsigned int j = 0; j < 4; ++j) {
561 const unsigned int k = j * 2;
562 const double x = h * xgk[k];
563 const double y1 = f(xc - x);
564 const double y2 = f(xc + x);
567 const double fsum = y1 + y2;
568 resk += wgk[k] * fsum;
569 resabs += wgk[k] * (std::abs(y1) + std::abs(y2));
572 const double reskh = resk * 0.5;
573 resasc = wgk[7] * std::abs(fc - reskh);
574 for (
unsigned int j = 0; j < 7; ++j) {
575 resasc += wgk[j] * (std::abs(fv1[j] - reskh) + std::abs(fv2[j] - reskh));
580 abserr = std::abs((resk - resg) * h);
581 if (resasc != 0. && abserr != 0.) {
582 abserr = resasc * std::min(1., pow(200. * abserr / resasc, 1.5));
584 constexpr double eps = 50. * std::numeric_limits<double>::epsilon();
585 if (resabs > std::numeric_limits<double>::min() / eps) {
586 abserr = std::max(eps * resabs, abserr);
788int dinv(
const int n, std::vector<std::vector<double> >& a) {
796 std::vector<int> ir(n, 0);
797 dfact(n, a, ir, ifail, det, jfail);
798 if (ifail != 0)
return ifail;
802 const double c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
803 const double c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
804 const double c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
805 const double c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
806 const double c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
807 const double c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
808 const double c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
809 const double c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
810 const double c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
811 const double t1 = fabs(a[0][0]);
812 const double t2 = fabs(a[1][0]);
813 const double t3 = fabs(a[2][0]);
816 if (t2 < t1 && t3 < t1) {
818 det = c22 * c33 - c23 * c32;
819 }
else if (t1 < t2 && t3 < t2) {
821 det = c13 * c32 - c12 * c33;
824 det = c23 * c12 - c22 * c13;
827 if (det == 0.)
return -1;
828 double s = pivot / det;
840 const double det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
841 if (det == 0.)
return -1;
842 const double s = 1. / det;
843 const double c11 = s * a[1][1];
844 a[0][1] = -s * a[0][1];
845 a[1][0] = -s * a[1][0];
846 a[1][1] = s * a[0][0];
849 if (a[0][0] == 0.)
return -1;
850 a[0][0] = 1. / a[0][0];
910int deqinv(
const int n, std::vector<std::vector<double> >& a,
911 std::vector<double>& b) {
919 std::vector<int> ir(n, 0);
920 int ifail = 0, jfail = 0;
921 dfact(n, a, ir, ifail, det, jfail);
922 if (ifail != 0)
return ifail;
927 const double c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
928 const double c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
929 const double c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
930 const double c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
931 const double c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
932 const double c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
933 const double c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
934 const double c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
935 const double c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
936 const double t1 = fabs(a[0][0]);
937 const double t2 = fabs(a[1][0]);
938 const double t3 = fabs(a[2][0]);
942 if (t2 < t1 && t3 < t1) {
944 det = c22 * c33 - c23 * c32;
945 }
else if (t1 < t2 && t3 < t2) {
947 det = c13 * c32 - c12 * c33;
950 det = c23 * c12 - c22 * c13;
954 if (det == 0.)
return -1;
955 const double s = temp / det;
967 const double b1 = b[0];
968 const double b2 = b[1];
969 b[0] = a[0][0] * b1 + a[0][1] * b2 + a[0][2] * b[2];
970 b[1] = a[1][0] * b1 + a[1][1] * b2 + a[1][2] * b[2];
971 b[2] = a[2][0] * b1 + a[2][1] * b2 + a[2][2] * b[2];
974 det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
975 if (det == 0.)
return -1;
976 const double s = 1. / det;
977 const double c11 = s * a[1][1];
978 a[0][1] = -s * a[0][1];
979 a[1][0] = -s * a[1][0];
980 a[1][1] = s * a[0][0];
983 const double b1 = b[0];
984 b[0] = c11 * b1 + a[0][1] * b[1];
985 b[1] = a[1][0] * b1 + a[1][1] * b[1];
988 if (a[0][0] == 0.)
return -1;
989 a[0][0] = 1. / a[0][0];
990 b[0] = a[0][0] * b[0];
995void cfact(
const int n, std::vector<std::vector<std::complex<double> > >& a,
996 std::vector<int>& ir,
int& ifail, std::complex<double>& det,
998 constexpr double g1 = 1.e-19;
999 constexpr double g2 = 1.e-19;
1004 det = std::complex<double>(1., 0.);
1006 for (
int j = 1; j <= n; ++j) {
1008 double p = std::max(fabs(real(a[j - 1][j - 1])), fabs(imag(a[j - 1][j - 1])));
1011 det = std::complex<double>(0., 0.);
1016 det *= a[j - 1][j - 1];
1017 a[j - 1][j - 1] = std::complex<double>(1., 0.) / a[j - 1][j - 1];
1018 const double t = std::max(fabs(real(det)), fabs(imag(det)));
1020 det = std::complex<double>(0., 0.);
1021 if (jfail == 0) jfail = -1;
1022 }
else if (t > g2) {
1023 det = std::complex<double>(1., 0.);
1024 if (jfail == 0) jfail = +1;
1028 for (
int i = j + 1; i <= n; ++i) {
1029 double q = std::max(fabs(real(a[i - 1][j - 1])), fabs(imag(a[i - 1][j - 1])));
1030 if (q <= p)
continue;
1035 for (
int l = 1; l <= n; ++l) {
1036 const auto tf = a[j - 1][l - 1];
1037 a[j - 1][l - 1] = a[k - 1][l - 1];
1038 a[k - 1][l - 1] = tf;
1041 ir[nxch - 1] = j * 4096 + k;
1042 }
else if (p <= 0.) {
1043 det = std::complex<double>(0., 0.);
1048 det *= a[j - 1][j - 1];
1049 a[j - 1][j - 1] = 1. / a[j - 1][j - 1];
1050 const double t = std::max(fabs(real(det)), fabs(imag(det)));
1052 det = std::complex<double>(0., 0.);
1053 if (jfail == 0) jfail = -1;
1054 }
else if (t > g2) {
1055 det = std::complex<double>(1., 0.);
1056 if (jfail == 0) jfail = +1;
1058 for (k = j + 1; k <= n; ++k) {
1059 auto s11 = -a[j - 1][k - 1];
1060 auto s12 = -a[k - 1][j];
1062 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
1063 a[k - 1][j] = -(s12 + a[j - 1][j] * a[k - 1][j - 1]);
1066 for (
int i = 1; i <= j - 1; ++i) {
1067 s11 += a[i - 1][k - 1] * a[j - 1][i - 1];
1068 s12 += a[i - 1][j] * a[k - 1][i - 1];
1070 a[j - 1][k - 1] = -s11 * a[j - 1][j - 1];
1071 a[k - 1][j] = -a[j - 1][j] * a[k - 1][j - 1] - s12;
1075 if (nxch % 2 != 0) det = -det;
1076 if (jfail != 0) det = std::complex<double>(0., 0.);
1080void cfinv(
const int n, std::vector<std::vector<std::complex<double> > >& a,
1081 std::vector<int>& ir) {
1084 a[1][0] = -a[1][1] * a[0][0] * a[1][0];
1087 for (
int i = 3; i <= n; ++i) {
1088 for (
int j = 1; j <= i - 2; ++j) {
1089 auto s31 = std::complex<double>(0., 0.);
1090 auto s32 = a[j - 1][i - 1];
1091 for (
int k = j; k <= i - 2; ++k) {
1092 s31 += a[k - 1][j - 1] * a[i - 1][k - 1];
1093 s32 += a[j - 1][k] * a[k][i - 1];
1096 -a[i - 1][i - 1] * (s31 + a[i - 2][j - 1] * a[i - 1][i - 2]);
1097 a[j - 1][i - 1] = -s32;
1099 a[i - 1][i - 2] = -a[i - 1][i - 1] * a[i - 2][i - 2] * a[i - 1][i - 2];
1100 a[i - 2][i - 1] = -a[i - 2][i - 1];
1104 for (
int i = 1; i <= n - 1; ++i) {
1105 for (
int j = 1; j <= i; ++j) {
1106 auto s33 = a[i - 1][j - 1];
1107 for (
int k = 1; k <= n - i; ++k) {
1108 s33 += a[i + k - 1][j - 1] * a[i - 1][i + k - 1];
1110 a[i - 1][j - 1] = s33;
1112 for (
int j = 1; j <= n - i; ++j) {
1113 std::complex<double> s34(0., 0.);
1114 for (
int k = j; k <= n - i; ++k) {
1115 s34 += a[i + k - 1][i + j - 1] * a[i - 1][i + k - 1];
1117 a[i - 1][i + j - 1] = s34;
1121 int nxch = ir[n - 1];
1122 if (nxch == 0)
return;
1124 for (
int m = 1; m <= nxch; ++m) {
1125 int k = nxch - m + 1;
1126 const int ij = ir[k - 1];
1127 const int i = ij / 4096;
1128 const int j = ij % 4096;
1129 for (k = 1; k <= n; ++k) {
1130 std::swap(a[k - 1][i - 1], a[k - 1][j - 1]);
1135int cinv(
const int n, std::vector<std::vector<std::complex<double> > >& a) {
1138 if (n < 1)
return 1;
1140 std::complex<double> det(0., 0.);
1143 std::vector<int> ir(n, 0);
1144 int ifail = 0, jfail = 0;
1145 cfact(n, a, ir, ifail, det, jfail);
1146 if (ifail != 0)
return ifail;
1148 }
else if (n == 3) {
1150 const auto c11 = a[1][1] * a[2][2] - a[1][2] * a[2][1];
1151 const auto c12 = a[1][2] * a[2][0] - a[1][0] * a[2][2];
1152 const auto c13 = a[1][0] * a[2][1] - a[1][1] * a[2][0];
1153 const auto c21 = a[2][1] * a[0][2] - a[2][2] * a[0][1];
1154 const auto c22 = a[2][2] * a[0][0] - a[2][0] * a[0][2];
1155 const auto c23 = a[2][0] * a[0][1] - a[2][1] * a[0][0];
1156 const auto c31 = a[0][1] * a[1][2] - a[0][2] * a[1][1];
1157 const auto c32 = a[0][2] * a[1][0] - a[0][0] * a[1][2];
1158 const auto c33 = a[0][0] * a[1][1] - a[0][1] * a[1][0];
1159 const double t1 = fabs(real(a[0][0])) + fabs(imag(a[0][0]));
1160 const double t2 = fabs(real(a[1][0])) + fabs(imag(a[1][0]));
1161 const double t3 = fabs(real(a[2][0])) + fabs(imag(a[2][0]));
1164 std::complex<double> temp(0., 0.);
1165 if (t2 < t1 && t3 < t1) {
1167 det = c22 * c33 - c23 * c32;
1168 }
else if (t1 < t2 && t3 < t2) {
1170 det = c13 * c32 - c12 * c33;
1173 det = c23 * c12 - c22 * c13;
1176 if (real(det) == 0. && imag(det) == 0.)
return -1;
1177 const auto s = temp / det;
1187 }
else if (n == 2) {
1189 det = a[0][0] * a[1][1] - a[0][1] * a[1][0];
1190 if (real(det) == 0. && imag(det) == 0.)
return -1;
1191 const auto s = std::complex<double>(1., 0.) / det;
1192 const auto c11 = s * a[1][1];
1193 a[0][1] = -s * a[0][1];
1194 a[1][0] = -s * a[1][0];
1195 a[1][1] = s * a[0][0];
1199 if (real(a[0][0]) == 0. && imag(a[0][0]) == 0.)
return -1;
1200 a[0][0] = std::complex<double>(1., 0.) / a[0][0];
1354bool Boxin2(
const std::vector<std::vector<double> >& value,
1355 const std::vector<double>& xAxis,
const std::vector<double>& yAxis,
1356 const int nx,
const int ny,
const double x,
const double y,
1357 double& f,
const int iOrder) {
1362 int iX0 = 0, iX1 = 0;
1363 int iY0 = 0, iY1 = 0;
1364 std::array<double, 3> fX;
1365 std::array<double, 3> fY;
1368 if ((xAxis[nx - 1] - x) * (x - xAxis[0]) < 0 ||
1369 (yAxis[ny - 1] - y) * (y - yAxis[0]) < 0) {
1370 std::cerr <<
"Boxin2: Point not in the grid; no interpolation.\n";
1374 if (iOrder < 0 || iOrder > 2) {
1375 std::cerr <<
"Boxin2: Incorrect order; no interpolation.\n";
1377 }
else if (nx < 1 || ny < 1) {
1378 std::cerr <<
"Boxin2: Incorrect number of points; no interpolation.\n";
1381 if (iOrder == 0 || nx <= 1) {
1384 double dist = fabs(x - xAxis[0]);
1386 for (
int i = 1; i < nx; i++) {
1387 if (fabs(x - xAxis[i]) < dist) {
1388 dist = fabs(x - xAxis[i]);
1397 }
else if (iOrder == 1 || nx <= 2) {
1401 for (
int i = 1; i < nx; i++) {
1402 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1406 const double x0 = xAxis[iGrid - 1];
1407 const double x1 = xAxis[iGrid];
1410 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1414 const double xL = (x - x0) / (x1 - x0);
1419 fX = {1. - xL, xL, 0.};
1420 }
else if (iOrder == 2) {
1423 double dist = fabs(x - xAxis[0]);
1425 for (
int i = 1; i < nx; ++i) {
1426 if (fabs(x - xAxis[i]) < dist) {
1427 dist = fabs(x - xAxis[i]);
1432 int iGrid = std::max(1, std::min(nx - 2, iNode));
1433 const double x0 = xAxis[iGrid - 1];
1434 const double x1 = xAxis[iGrid];
1435 const double x2 = xAxis[iGrid + 1];
1438 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1442 const double xAlpha = (x1 - x0) / (x2 - x0);
1443 const double xL = (x - x0) / (x2 - x0);
1445 if (xAlpha <= 0 || xAlpha >= 1) {
1446 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1453 const double xL2 = xL * xL;
1454 fX[0] = xL2 / xAlpha - xL * (1. + xAlpha) / xAlpha + 1.;
1455 fX[1] = (xL2 - xL) / (xAlpha * xAlpha - xAlpha);
1456 fX[2] = (xL2 - xL * xAlpha) / (1. - xAlpha);
1458 if (iOrder == 0 || ny <= 1) {
1461 double dist = fabs(y - yAxis[0]);
1463 for (
int i = 1; i < ny; i++) {
1464 if (fabs(y - yAxis[i]) < dist) {
1465 dist = fabs(y - yAxis[i]);
1474 }
else if (iOrder == 1 || ny <= 2) {
1478 for (
int i = 1; i < ny; ++i) {
1479 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0) {
1483 const double y0 = yAxis[iGrid - 1];
1484 const double y1 = yAxis[iGrid];
1487 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1491 const double yL = (y - y0) / (y1 - y0);
1496 fY = {1. - yL, yL, 0.};
1497 }
else if (iOrder == 2) {
1500 double dist = fabs(y - yAxis[0]);
1502 for (
int i = 1; i < ny; ++i) {
1503 if (fabs(y - yAxis[i]) < dist) {
1504 dist = fabs(y - yAxis[i]);
1509 int iGrid = std::max(1, std::min(ny - 2, iNode));
1510 const double y0 = yAxis[iGrid - 1];
1511 const double y1 = yAxis[iGrid];
1512 const double y2 = yAxis[iGrid + 1];
1515 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1519 const double yAlpha = (y1 - y0) / (y2 - y0);
1520 const double yL = (y - y0) / (y2 - y0);
1522 if (yAlpha <= 0 || yAlpha >= 1) {
1523 std::cerr <<
"Boxin2: Incorrect grid; no interpolation.\n";
1530 const double yL2 = yL * yL;
1531 fY[0] = yL2 / yAlpha - yL * (1. + yAlpha) / yAlpha + 1.;
1532 fY[1] = (yL2 - yL) / (yAlpha * yAlpha - yAlpha);
1533 fY[2] = (yL2 - yL * yAlpha) / (1. - yAlpha);
1537 for (
int i = iX0; i <= iX1; ++i) {
1538 for (
int j = iY0; j <= iY1; ++j) {
1539 f += value[i][j] * fX[i - iX0] * fY[j - iY0];
1545bool Boxin3(
const std::vector<std::vector<std::vector<double> > >& value,
1546 const std::vector<double>& xAxis,
const std::vector<double>& yAxis,
1547 const std::vector<double>& zAxis,
const int nx,
const int ny,
1548 const int nz,
const double xx,
const double yy,
const double zz,
1549 double& f,
const int iOrder) {
1554 int iX0 = 0, iX1 = 0;
1555 int iY0 = 0, iY1 = 0;
1556 int iZ0 = 0, iZ1 = 0;
1557 std::array<double, 4> fX;
1558 std::array<double, 4> fY;
1559 std::array<double, 4> fZ;
1563 const double x = std::min(std::max(xx, std::min(xAxis[0], xAxis[nx - 1])),
1564 std::max(xAxis[0], xAxis[nx - 1]));
1565 const double y = std::min(std::max(yy, std::min(yAxis[0], yAxis[ny - 1])),
1566 std::max(yAxis[0], yAxis[ny - 1]));
1567 const double z = std::min(std::max(zz, std::min(zAxis[0], zAxis[nz - 1])),
1568 std::max(zAxis[0], zAxis[nz - 1]));
1571 if (iOrder < 0 || iOrder > 2) {
1572 std::cerr <<
"Boxin3: Incorrect order; no interpolation.\n";
1574 }
else if (nx < 1 || ny < 1 || nz < 1) {
1575 std::cerr <<
"Boxin3: Incorrect number of points; no interpolation.\n";
1578 if (iOrder == 0 || nx == 1) {
1581 double dist = fabs(x - xAxis[0]);
1583 for (
int i = 1; i < nx; i++) {
1584 if (fabs(x - xAxis[i]) < dist) {
1585 dist = fabs(x - xAxis[i]);
1593 fX = {1., 0., 0., 0.};
1594 }
else if (iOrder == 1 || nx == 2) {
1598 for (
int i = 1; i < nx; i++) {
1599 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1603 const double x0 = xAxis[iGrid - 1];
1604 const double x1 = xAxis[iGrid];
1607 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1611 const double xL = (x - x0) / (x1 - x0);
1616 fX = {1. - xL, xL, 0., 0.};
1617 }
else if (iOrder == 2) {
1621 for (
int i = 1; i < nx; i++) {
1622 if ((xAxis[i - 1] - x) * (x - xAxis[i]) >= 0.) {
1629 const double x0 = xAxis[iX0];
1630 const double x1 = xAxis[iX0 + 1];
1631 const double x2 = xAxis[iX0 + 2];
1632 if (x0 == x1 || x0 == x2 || x1 == x2) {
1633 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1634 <<
" No interpolation.\n";
1637 fX[0] = (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2));
1638 fX[1] = (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2));
1639 fX[2] = (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
1640 }
else if (iGrid == nx - 1) {
1643 const double x0 = xAxis[iX0];
1644 const double x1 = xAxis[iX0 + 1];
1645 const double x2 = xAxis[iX0 + 2];
1646 if (x0 == x1 || x0 == x2 || x1 == x2) {
1647 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1648 <<
" No interpolation.\n";
1651 fX[0] = (x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2));
1652 fX[1] = (x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2));
1653 fX[2] = (x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1));
1657 const double x0 = xAxis[iX0];
1658 const double x1 = xAxis[iX0 + 1];
1659 const double x2 = xAxis[iX0 + 2];
1660 const double x3 = xAxis[iX0 + 3];
1661 if (x0 == x1 || x0 == x2 || x0 == x3 ||
1662 x1 == x2 || x1 == x3 || x2 == x3) {
1663 std::cerr <<
"Boxin3: One or more grid points in x coincide.\n"
1664 <<
" No interpolation.\n";
1668 const double xL = (x - x1) / (x2 - x1);
1669 fX[0] = ((x - x1) * (x - x2) / ((x0 - x1) * (x0 - x2))) * (1. - xL);
1670 fX[1] = ((x - x0) * (x - x2) / ((x1 - x0) * (x1 - x2))) * (1. - xL) +
1671 ((x - x2) * (x - x3) / ((x1 - x2) * (x1 - x3))) * xL;
1672 fX[2] = ((x - x0) * (x - x1) / ((x2 - x0) * (x2 - x1))) * (1. - xL) +
1673 ((x - x1) * (x - x3) / ((x2 - x1) * (x2 - x3))) * xL;
1674 fX[3] = ((x - x1) * (x - x2) / ((x3 - x1) * (x3 - x2))) * xL;
1678 if (iOrder == 0 || ny == 1) {
1681 double dist = fabs(y - yAxis[0]);
1683 for (
int i = 1; i < ny; i++) {
1684 if (fabs(y - yAxis[i]) < dist) {
1685 dist = fabs(y - yAxis[i]);
1693 fY = {1., 0., 0., 0.};
1694 }
else if (iOrder == 1 || ny == 2) {
1698 for (
int i = 1; i < ny; i++) {
1699 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
1704 const double y0 = yAxis[iGrid - 1];
1705 const double y1 = yAxis[iGrid];
1707 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1711 const double yL = (y - y0) / (y1 - y0);
1716 fY = {1. - yL, yL, 0., 0.};
1717 }
else if (iOrder == 2) {
1721 for (
int i = 1; i < ny; i++) {
1722 if ((yAxis[i - 1] - y) * (y - yAxis[i]) >= 0.) {
1729 const double y0 = yAxis[iY0];
1730 const double y1 = yAxis[iY0 + 1];
1731 const double y2 = yAxis[iY0 + 2];
1732 if (y0 == y1 || y0 == y2 || y1 == y2) {
1733 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1734 <<
" No interpolation.\n";
1737 fY[0] = (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2));
1738 fY[1] = (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2));
1739 fY[2] = (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
1740 }
else if (iGrid == ny - 1) {
1743 const double y0 = yAxis[iY0];
1744 const double y1 = yAxis[iY0 + 1];
1745 const double y2 = yAxis[iY0 + 2];
1746 if (y0 == y1 || y0 == y2 || y1 == y2) {
1747 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1748 <<
" No interpolation.\n";
1751 fY[0] = (y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2));
1752 fY[1] = (y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2));
1753 fY[2] = (y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1));
1757 const double y0 = yAxis[iY0];
1758 const double y1 = yAxis[iY0 + 1];
1759 const double y2 = yAxis[iY0 + 2];
1760 const double y3 = yAxis[iY0 + 3];
1761 if (y0 == y1 || y0 == y2 || y0 == y3 ||
1762 y1 == y2 || y1 == y3 || y2 == y3) {
1763 std::cerr <<
"Boxin3: One or more grid points in y coincide.\n"
1764 <<
" No interpolation.\n";
1768 const double yL = (y - y1) / (y2 - y1);
1769 fY[0] = ((y - y1) * (y - y2) / ((y0 - y1) * (y0 - y2))) * (1. - yL);
1770 fY[1] = ((y - y0) * (y - y2) / ((y1 - y0) * (y1 - y2))) * (1. - yL) +
1771 ((y - y2) * (y - y3) / ((y1 - y2) * (y1 - y3))) * yL;
1772 fY[2] = ((y - y0) * (y - y1) / ((y2 - y0) * (y2 - y1))) * (1. - yL) +
1773 ((y - y1) * (y - y3) / ((y2 - y1) * (y2 - y3))) * yL;
1774 fY[3] = ((y - y1) * (y - y2) / ((y3 - y1) * (y3 - y2))) * yL;
1778 if (iOrder == 0 || nz == 1) {
1781 double dist = fabs(z - zAxis[0]);
1783 for (
int i = 1; i < nz; i++) {
1784 if (fabs(z - zAxis[i]) < dist) {
1785 dist = fabs(z - zAxis[i]);
1793 fZ = {1., 0., 0., 0.};
1794 }
else if (iOrder == 1 || nz == 2) {
1798 for (
int i = 1; i < nz; i++) {
1799 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1803 const double z0 = zAxis[iGrid - 1];
1804 const double z1 = zAxis[iGrid];
1807 std::cerr <<
"Boxin3: Incorrect grid; no interpolation.\n";
1811 const double zL = (z - z0) / (z1 - z0);
1816 fZ = {1. - zL, zL, 0., 0.};
1817 }
else if (iOrder == 2) {
1821 for (
int i = 1; i < nz; i++) {
1822 if ((zAxis[i - 1] - z) * (z - zAxis[i]) >= 0.) {
1829 const double z0 = zAxis[iZ0];
1830 const double z1 = zAxis[iZ0 + 1];
1831 const double z2 = zAxis[iZ0 + 2];
1832 if (z0 == z1 || z0 == z2 || z1 == z2) {
1833 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1834 <<
" No interpolation.\n";
1837 fZ[0] = (z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2));
1838 fZ[1] = (z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2));
1839 fZ[2] = (z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1));
1840 }
else if (iGrid == nz - 1) {
1843 const double z0 = zAxis[iZ0];
1844 const double z1 = zAxis[iZ0 + 1];
1845 const double z2 = zAxis[iZ0 + 2];
1846 if (z0 == z1 || z0 == z2 || z1 == z2) {
1847 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1848 <<
" No interpolation.\n";
1851 fZ[0] = (z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2));
1852 fZ[1] = (z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2));
1853 fZ[2] = (z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1));
1857 const double z0 = zAxis[iZ0];
1858 const double z1 = zAxis[iZ0 + 1];
1859 const double z2 = zAxis[iZ0 + 2];
1860 const double z3 = zAxis[iZ0 + 3];
1861 if (z0 == z1 || z0 == z2 || z0 == z3 ||
1862 z1 == z2 || z1 == z3 || z2 == z3) {
1863 std::cerr <<
"Boxin3: One or more grid points in z coincide.\n"
1864 <<
" No interpolation.\n";
1868 const double zL = (z - z1) / (z2 - z1);
1869 fZ[0] = ((z - z1) * (z - z2) / ((z0 - z1) * (z0 - z2))) * (1. - zL);
1870 fZ[1] = ((z - z0) * (z - z2) / ((z1 - z0) * (z1 - z2))) * (1. - zL) +
1871 ((z - z2) * (z - z3) / ((z1 - z2) * (z1 - z3))) * zL;
1872 fZ[2] = ((z - z0) * (z - z1) / ((z2 - z0) * (z2 - z1))) * (1. - zL) +
1873 ((z - z1) * (z - z3) / ((z2 - z1) * (z2 - z3))) * zL;
1874 fZ[3] = ((z - z1) * (z - z2) / ((z3 - z1) * (z3 - z2))) * zL;
1878 for (
int i = iX0; i <= iX1; ++i) {
1879 for (
int j = iY0; j <= iY1; ++j) {
1880 for (
int k = iZ0; k <= iZ1; ++k) {
1881 f += value[i][j][k] * fX[i - iX0] * fY[j - iY0] * fZ[k - iZ0];
1889 std::function<
double(
double,
const std::vector<double>&)> f,
1890 std::vector<double>& par, std::vector<double>& epar,
1891 const std::vector<double>& x,
const std::vector<double>& y,
1892 const std::vector<double>& ey,
const unsigned int nMaxIter,
1893 const double diff,
double& chi2,
const double eps,
1894 const bool debug,
const bool verbose) {
1911 const unsigned int n = par.size();
1912 const unsigned int m = x.size();
1915 std::cerr <<
"LeastSquaresFit: Number of parameters to be varied\n"
1916 <<
" exceeds the number of data points.\n";
1921 if (*std::min_element(ey.cbegin(), ey.cend()) <= 0.) {
1922 std::cerr <<
"LeastSquaresFit: Not all errors are > 0; no fit done.\n";
1929 std::vector<double> r(m, 0.);
1930 for (
unsigned int i = 0; i < m; ++i) {
1932 r[i] = (y[i] - f(x[i], par)) / ey[i];
1934 diffc = std::max(std::abs(r[i]), diffc);
1936 chi2 += r[i] * r[i];
1939 std::cout <<
" Input data points:\n"
1940 <<
" X Y Y - F(X)\n";
1941 for (
unsigned int i = 0; i < m; ++i) {
1942 std::printf(
" %9u %15.8e %15.8e %15.8e\n", i, x[i], y[i], r[i]);
1944 std::cout <<
" Initial values of the fit parameters:\n"
1945 <<
" Parameter Value\n";
1946 for (
unsigned int i = 0; i < n; ++i) {
1947 std::printf(
" %9u %15.8e\n", i, par[i]);
1951 std::cout <<
" MINIMISATION SUMMARY\n"
1952 <<
" Initial situation:\n";
1953 std::printf(
" Largest difference between fit and target: %15.8e\n",
1955 std::printf(
" Sum of squares of these differences: %15.8e\n",
1959 bool converged =
false;
1961 for (
unsigned int iter = 1; iter <= nMaxIter; ++iter) {
1963 if ((diffc < diff) || (iter > 1 && std::abs(chi2L - chi2) < eps * chi2)) {
1964 if (debug || verbose) {
1966 std::cout <<
" The maximum difference stopping criterion "
1967 <<
"is satisfied.\n";
1969 std::cout <<
" The relative change in chi-squared has dropped "
1970 <<
"below the threshold.\n";
1977 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
1978 for (
unsigned int i = 0; i < n; ++i) {
1979 const double epsdif = eps * (1. + std::abs(par[i]));
1980 par[i] += 0.5 * epsdif;
1981 for (
unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
1983 for (
unsigned int j = 0; j < m; ++j) {
1984 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
1986 par[i] += 0.5 * epsdif;
1989 std::vector<double> colsum(n, 0.);
1990 std::vector<int> pivot(n, 0);
1991 for (
unsigned int i = 0; i < n; ++i) {
1992 colsum[i] = std::inner_product(d[i].cbegin(), d[i].cend(),
1997 std::vector<double> alpha(n, 0.);
1998 bool singular =
false;
1999 for (
unsigned int k = 0; k < n; ++k) {
2000 double sigma = colsum[k];
2001 unsigned int jbar = k;
2002 for (
unsigned int j = k + 1; j < n; ++j) {
2003 if (sigma < colsum[j]) {
2010 std::swap(pivot[k], pivot[jbar]);
2011 std::swap(colsum[k], colsum[jbar]);
2012 std::swap(d[k], d[jbar]);
2015 for (
unsigned int i = k; i < m; ++i) sigma += d[k][i] * d[k][i];
2016 if (sigma == 0. || sqrt(sigma) < 1.e-8 * std::abs(d[k][k])) {
2020 alpha[k] = d[k][k] < 0. ? sqrt(sigma) : -sqrt(sigma);
2021 const double beta = 1. / (sigma - d[k][k] * alpha[k]);
2022 d[k][k] -= alpha[k];
2023 std::vector<double> b(n, 0.);
2024 for (
unsigned int j = k + 1; j < n; ++j) {
2025 for (
unsigned int i = k; i < n; ++i) b[j] += d[k][i] * d[j][i];
2028 for (
unsigned int j = k + 1; j < n; ++j) {
2029 for (
unsigned int i = k; i < m; ++i) {
2030 d[j][i] -= d[k][i] * b[j];
2031 colsum[j] -= d[j][k] * d[j][k];
2036 std::cerr <<
"LeastSquaresFit: Householder matrix (nearly) singular;\n"
2037 <<
" no further optimisation.\n"
2038 <<
" Ensure the function depends on the parameters\n"
2039 <<
" and try to supply reasonable starting values.\n";
2043 for (
unsigned int j = 0; j < n; ++j) {
2045 for (
unsigned int i = j; i < m; ++i) gamma += d[j][i] * r[i];
2046 gamma *= 1. / (alpha[j] * d[j][j]);
2047 for (
unsigned int i = j; i < m; ++i) r[i] += gamma * d[j][i];
2049 std::vector<double> z(n, 0.);
2050 z[n - 1] = r[n - 1] / alpha[n - 1];
2051 for (
int i = n - 1; i >= 1; --i) {
2053 for (
unsigned int j = i + 1; j <= n; ++j) {
2054 sum += d[j - 1][i - 1] * z[j - 1];
2056 z[i - 1] = (r[i - 1] - sum) / alpha[i - 1];
2059 std::vector<double> s(n, 0.);
2060 for (
unsigned int i = 0; i < n; ++i) s[pivot[i]] = z[i];
2063 std::cout <<
" Correction vector in iteration " << iter <<
":\n";
2064 for (
unsigned int i = 0; i < n; ++i) {
2065 std::printf(
" %5u %15.8e\n", i, s[i]);
2071 for (
unsigned int i = 0; i < n; ++i) par[i] += s[i] * 2;
2072 for (
unsigned int i = 0; i <= 10; ++i) {
2073 if (chi2 <= chi2L)
break;
2074 if (std::abs(chi2L - chi2) < eps * chi2) {
2076 std::cout <<
" Too little improvement; reduction loop halted.\n";
2081 const double scale = 1. / pow(2, i);
2082 for (
unsigned int j = 0; j < n; ++j) par[j] -= s[j] * scale;
2083 for (
unsigned int j = 0; j < m; ++j) {
2084 r[j] = (y[j] - f(x[j], par)) / ey[j];
2085 chi2 += r[j] * r[j];
2088 std::printf(
" Reduction loop %3i: chi2 = %15.8e\n", i, chi2);
2092 diffc = std::abs(r[0]);
2093 for (
unsigned int i = 1; i < m; ++i) {
2094 diffc = std::max(std::abs(r[i]), diffc);
2098 std::cout <<
" Values of the fit parameters after iteration "
2099 << iter <<
"\n Parameter Value\n";
2100 for (
unsigned int i = 0; i < n; ++i) {
2101 std::printf(
" %9u %15.8e\n", i, par[i]);
2103 std::printf(
" for which chi2 = %15.8e and diff = %15.8e\n",
2105 }
else if (verbose) {
2106 std::printf(
" Step %3u: largest deviation = %15.8e, chi2 = %15.8e\n",
2112 std::cerr <<
"LeastSquaresFit: Maximum number of iterations reached.\n";
2115 std::vector<std::vector<double> > d(n, std::vector<double>(m, 0.));
2116 for (
unsigned int i = 0; i < n; ++i) {
2117 const double epsdif = eps * (1. + std::abs(par[i]));
2118 par[i] += 0.5 * epsdif;
2119 for (
unsigned int j = 0; j < m; ++j) d[i][j] = f(x[j], par);
2121 for (
unsigned int j = 0; j < m; ++j) {
2122 d[i][j] = (d[i][j] - f(x[j], par)) / (epsdif * ey[j]);
2124 par[i] += 0.5 * epsdif;
2127 std::vector<std::vector<double> > cov(n, std::vector<double>(n, 0.));
2128 for (
unsigned int i = 0; i < n; ++i) {
2129 for (
unsigned int j = 0; j < n; ++j) {
2130 cov[i][j] = std::inner_product(d[i].cbegin(), d[i].cend(),
2135 double scale = m > n ? chi2 / (m - n) : 1.;
2139 std::cerr <<
"LeastSquaresFit: Singular covariance matrix; "
2140 <<
"no error calculation.\n";
2142 for (
unsigned int i = 0; i < n; ++i) {
2143 for (
unsigned int j = 0; j < n; ++j) cov[i][j] *= scale;
2144 epar[i] = sqrt(std::max(0., cov[i][i]));
2149 std::cout <<
" Comparison between input and fit:\n"
2151 for (
unsigned int i = 0; i < m; ++i) {
2152 const double fit = f(x[i], par);
2153 std::printf(
" %5u %15.8e %15.8e %15.8e\n", i, x[i], y[i], fit);
2157 std::cout <<
" Final values of the fit parameters:\n"
2158 <<
" Parameter Value Error\n";
2159 for (
unsigned int i = 0; i < n; ++i) {
2160 std::printf(
" %9u %15.8e %15.8e\n", i, par[i], epar[i]);
2162 std::cout <<
" The errors have been scaled by a factor of "
2163 << sqrt(scale) <<
".\n";
2164 std::cout <<
" Covariance matrix:\n";
2165 for (
unsigned int i = 0; i < n; ++i) {
2166 for (
unsigned int j = 0; j < n; ++j) {
2167 std::printf(
" %15.8e", cov[i][j]);
2171 std::cout <<
" Correlation matrix:\n";
2172 for (
unsigned int i = 0; i < n; ++i) {
2173 for (
unsigned int j = 0; j < n; ++j) {
2175 if (cov[i][i] > 0. && cov[j][j] > 0.) {
2176 cor = cov[i][j] / sqrt(cov[i][i] * cov[j][j]);
2178 std::printf(
" %15.8e", cor);
2182 std::cout <<
" Minimisation finished.\n";