15 std::size_t N = x.size();
16 std::vector<double> r, xp;
17 std::vector<std::vector<double>> J(N, std::vector<double>(N, 0));
18 std::vector<double> r0 =
call(x);
20 for (std::size_t i = 0; i < N; ++i) {
22 epsilon = 0.001 * x[i];
26 for (std::size_t j = 0; j < N; ++j) {
27 J[j][i] = (r[j] - r0[j]) / epsilon;
52 std::vector<double> f0, v;
53 std::vector<std::vector<double>> JJ;
54 std::vector<double> x0 = x;
55 Eigen::VectorXd r(x0.size());
56 Eigen::MatrixXd J(x0.size(), x0.size());
58 while (iter == 0 || std::abs(error) > tol) {
62 for (std::size_t i = 0; i < x0.size(); ++i) {
64 for (std::size_t j = 0; j < x0.size(); ++j) {
69 Eigen::VectorXd v = J.colPivHouseholderQr().solve(-r);
72 double max_relchange = -1;
73 for (std::size_t i = 0; i < x0.size(); i++) {
75 double relchange = std::abs(v(i) / x0[i]);
76 if (std::abs(x0[i]) > 1e-16 && relchange > max_relchange) {
77 max_relchange = relchange;
82 double max_abschange = v.cwiseAbs().maxCoeff();
86 if (max_relchange < 1e-12) {
91 f->
errstring =
"reached maximum number of iterations";
109 double x = NAN, dx = NAN, dfdx = NAN, fval = 999;
115 while (f->
iter < maxiter || std::abs(fval) > ftol) {
121 f->
errstring =
"Residual function in newton returned invalid number";
122 throw ValueError(
"Residual function in newton returned invalid number");
126 std::cout <<
format(
"i: %d, x: %0.15g, dx: %g, f: %g, dfdx: %g", f->
iter, x, dx, fval, dfdx) <<
'\n';
131 if (std::abs(dx / x) < 1e-11) {
135 if (f->
iter > maxiter) {
136 f->
errstring =
"Newton reached maximum number of iterations";
160 double x = NAN, dx = NAN, fval = 999, dfdx = NAN, d2fdx2 = NAN;
170 while (f->
iter < 2 || std::abs(fval) > ftol) {
172 std::string msg =
format(
"Input [%0.15g] is out of range", x);
182 f->
errstring =
"Residual function in Halley returned invalid number";
183 throw ValueError(
"Residual function in Halley returned invalid number");
186 f->
errstring =
"Derivative function in Halley returned invalid number";
187 throw ValueError(
"Derivative function in Halley returned invalid number");
190 dx = -omega * (2 * fval * dfdx) / (2 *
POW2(dfdx) - fval * d2fdx2);
193 std::cout <<
format(
"i: %d, x: %0.15g, dx: %g, f: %g, dfdx: %g, d2fdx2: %g", f->
iter, x, dx, fval, dfdx, d2fdx2) <<
'\n';
198 if (std::abs(dx / x) < xtol_rel) {
202 if (f->
iter > maxiter) {
203 f->
errstring =
"Halley reached maximum number of iterations";
228 double x = NAN, dx = NAN, fval = 999, dfdx = NAN, d2fdx2 = NAN, d3fdx3 = NAN;
238 while (f->
iter < 2 || std::abs(fval) > ftol) {
249 throw ValueError(
"Residual function in Householder4 returned invalid number");
252 throw ValueError(
"Derivative function in Householder4 returned invalid number");
255 throw ValueError(
"Second derivative function in Householder4 returned invalid number");
258 throw ValueError(
"Third derivative function in Householder4 returned invalid number");
261 dx = -omega * fval * (
POW2(dfdx) - fval * d2fdx2 / 2.0) / (
POW3(dfdx) - fval * dfdx * d2fdx2 + d3fdx3 *
POW2(fval) / 6.0);
265 if (std::abs(dx / x) < xtol_rel) {
269 if (f->
iter > maxiter) {
270 f->
errstring =
"reached maximum number of iterations";
289#if defined(COOLPROP_DEEP_DEBUG)
290 static std::vector<double> xlog, flog;
296 double x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, x = x0, fval = 999;
303 if (std::abs(dx) == 0) {
307 while (f->
iter <= 2 || std::abs(fval) > tol) {
326#if defined(COOLPROP_DEEP_DEBUG)
328 flog.push_back(fval);
332 throw ValueError(
"Residual function in secant returned invalid number");
338 double deltax = x2 - x1;
339 if (std::abs(deltax) < 1e-14) {
343 double deltay = y2 - y1;
344 if (f->
iter > 2 && std::abs(deltay) < 1e-14) {
347 x3 = x2 - omega * y2 / (y2 - y1) * (x2 - x1);
352 if (f->
iter > maxiter) {
353 f->
errstring = std::string(
"reached maximum number of iterations");
374 double x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, x = NAN, fval = 999;
377 if (std::abs(dx) == 0) {
381 while (iter <= 3 || std::abs(fval) > tol) {
385 }
else if (iter == 2) {
396 x3 = x2 - y2 / (y2 - y1) * (x2 - x1);
399 x3 = (xmin + x2) / 2;
402 x3 = (xmax + x2) / 2;
408 if (iter > maxiter) {
409 f->
errstring =
"reached maximum number of iterations";
430#if defined(COOLPROP_DEEP_DEBUG)
431 static std::vector<double> xlog, flog;
437 double x1 = 0, x2 = 0, x3 = 0, y0 = 0, y1 = 0, y2 = 0, x = x0, fval = 999;
444 if (std::abs(dx) == 0) {
448 while (f->
iter <= 2 || std::abs(fval) > tol) {
467#if defined(COOLPROP_DEEP_DEBUG)
469 flog.push_back(fval);
476 return x2 - omega * y1 / (y1 - y0) * (x2 - x1);
483 double deltax = x2 - x1;
484 if (std::abs(deltax) < 1e-14) {
488 double deltay = y2 - y1;
489 if (f->
iter > 2 && std::abs(deltay) < 1e-14) {
492 x3 = x2 - omega * y2 / (y2 - y1) * (x2 - x1);
498 if (f->
iter > maxiter) {
499 f->
errstring = std::string(
"reached maximum number of iterations");
525 double fa = NAN, fb = NAN, c = NAN, fc = NAN, m = NAN, tol = NAN, d = NAN, e = NAN, p = NAN, q = NAN, s = NAN, r = NAN;
530 if (std::abs(fb) < t) {
534 throw ValueError(
format(
"Brent's method f(b) is NAN for b = %g, other input was a = %g", b, a).c_str());
536 if (std::abs(fa) < t) {
540 throw ValueError(
format(
"Brent's method f(a) is NAN for a = %g, other input was b = %g", a, b).c_str());
543 throw ValueError(
format(
"Inputs in Brent [%f,%f] do not bracket the root. Function values are [%f,%f]", a, b, fa, fb));
549 if (std::abs(fc) < std::abs(fb)) {
561 tol = 2 * macheps * std::abs(b) + t;
562 while (std::abs(m) > tol && fb != 0) {
564 if (std::abs(e) < tol || std::abs(fa) <= std::abs(fb)) {
578 p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
579 q = (q - 1) * (r - 1) * (s - 1);
589 if (2 * p < 3 * m * q - std::abs(tol * q) || p < std::abs(0.5 * s * q)) {
598 if (std::abs(d) > tol) {
607 throw ValueError(
format(
"Brent's method f(t) is NAN for t = %g", b).c_str());
609 if (std::abs(fb) < macheps) {
618 if (std::abs(fc) < std::abs(fb)) {
628 tol = 2 * macheps * std::abs(b) + t;
639 if (iter > maxiter) {
640 throw SolutionError(
format(
"Brent's method reached maximum number of steps of %d ", maxiter));
642 if (std::abs(fb) < 2 * macheps * std::abs(b)) {