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;
53 std::vector<double> f0, v;
54 std::vector<std::vector<double>> JJ;
55 std::vector<double> x0 = x;
56 Eigen::VectorXd r(x0.size());
57 Eigen::MatrixXd J(x0.size(), x0.size());
59 while (iter == 0 || std::abs(error) > tol) {
63 for (std::size_t i = 0; i < x0.size(); ++i) {
65 for (std::size_t j = 0; j < x0.size(); ++j) {
70 Eigen::VectorXd v = J.colPivHouseholderQr().solve(-r);
73 double max_relchange = -1;
74 for (std::size_t i = 0; i < x0.size(); i++) {
76 double relchange = std::abs(v(i) / x0[i]);
77 if (std::abs(x0[i]) > 1e-16 && relchange > max_relchange) {
78 max_relchange = relchange;
83 double max_abschange = v.cwiseAbs().maxCoeff();
87 if (max_relchange < 1e-12) {
92 f->
errstring =
"reached maximum number of iterations";
110 double x, dx, dfdx, fval = 999;
116 while (f->
iter < maxiter || std::abs(fval) > ftol) {
122 f->
errstring =
"Residual function in newton returned invalid number";
123 throw ValueError(
"Residual function in newton returned invalid number");
127 std::cout <<
format(
"i: %d, x: %0.15g, dx: %g, f: %g, dfdx: %g", f->
iter, x, dx, fval, dfdx) << std::endl;
132 if (std::abs(dx / x) < 1e-11) {
136 if (f->
iter > maxiter) {
137 f->
errstring =
"Newton reached maximum number of iterations";
161 double x, dx, fval = 999, dfdx, d2fdx2;
171 while (f->
iter < 2 || std::abs(fval) > ftol) {
173 std::string msg =
format(
"Input [%0.15g] is out of range", x);
183 f->
errstring =
"Residual function in Halley returned invalid number";
184 throw ValueError(
"Residual function in Halley returned invalid number");
187 f->
errstring =
"Derivative function in Halley returned invalid number";
188 throw ValueError(
"Derivative function in Halley returned invalid number");
191 dx = -omega * (2 * fval * dfdx) / (2 *
POW2(dfdx) - fval * d2fdx2);
194 std::cout <<
format(
"i: %d, x: %0.15g, dx: %g, f: %g, dfdx: %g, d2fdx2: %g", f->
iter, x, dx, fval, dfdx, d2fdx2) << std::endl;
199 if (std::abs(dx / x) < xtol_rel) {
203 if (f->
iter > maxiter) {
204 f->
errstring =
"Halley reached maximum number of iterations";
229 double x, dx, fval = 999, dfdx, d2fdx2, d3fdx3;
239 while (f->
iter < 2 || std::abs(fval) > ftol) {
250 throw ValueError(
"Residual function in Householder4 returned invalid number");
253 throw ValueError(
"Derivative function in Householder4 returned invalid number");
256 throw ValueError(
"Second derivative function in Householder4 returned invalid number");
259 throw ValueError(
"Third derivative function in Householder4 returned invalid number");
262 dx = -omega * fval * (
POW2(dfdx) - fval * d2fdx2 / 2.0) / (
POW3(dfdx) - fval * dfdx * d2fdx2 + d3fdx3 *
POW2(fval) / 6.0);
266 if (std::abs(dx / x) < xtol_rel) {
270 if (f->
iter > maxiter) {
271 f->
errstring =
"reached maximum number of iterations";
290#if defined(COOLPROP_DEEP_DEBUG)
291 static std::vector<double> xlog, flog;
297 double x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, x = x0, fval = 999;
304 if (std::abs(dx) == 0) {
308 while (f->
iter <= 2 || std::abs(fval) > tol) {
327#if defined(COOLPROP_DEEP_DEBUG)
329 flog.push_back(fval);
333 throw ValueError(
"Residual function in secant returned invalid number");
339 double deltax = x2 - x1;
340 if (std::abs(deltax) < 1e-14) {
344 double deltay = y2 - y1;
345 if (f->
iter > 2 && std::abs(deltay) < 1e-14) {
348 x3 = x2 - omega * y2 / (y2 - y1) * (x2 - x1);
353 if (f->
iter > maxiter) {
354 f->
errstring = std::string(
"reached maximum number of iterations");
375 double x1 = 0, x2 = 0, x3 = 0, y1 = 0, y2 = 0, x, fval = 999;
378 if (std::abs(dx) == 0) {
382 while (iter <= 3 || std::abs(fval) > tol) {
386 }
else if (iter == 2) {
397 x3 = x2 - y2 / (y2 - y1) * (x2 - x1);
400 x3 = (xmin + x2) / 2;
403 x3 = (xmax + x2) / 2;
409 if (iter > maxiter) {
410 f->
errstring =
"reached maximum number of iterations";
431#if defined(COOLPROP_DEEP_DEBUG)
432 static std::vector<double> xlog, flog;
438 double x1 = 0, x2 = 0, x3 = 0, y0 = 0, y1 = 0, y2 = 0, x = x0, fval = 999;
445 if (std::abs(dx) == 0) {
449 while (f->
iter <= 2 || std::abs(fval) > tol) {
468#if defined(COOLPROP_DEEP_DEBUG)
470 flog.push_back(fval);
477 return x2 - omega * y1 / (y1 - y0) * (x2 - x1);
484 double deltax = x2 - x1;
485 if (std::abs(deltax) < 1e-14) {
489 double deltay = y2 - y1;
490 if (f->
iter > 2 && std::abs(deltay) < 1e-14) {
493 x3 = x2 - omega * y2 / (y2 - y1) * (x2 - x1);
499 if (f->
iter > maxiter) {
500 f->
errstring = std::string(
"reached maximum number of iterations");
526 double fa, fb, c, fc, m, tol, d, e, p, q, s, r;
531 if (std::abs(fb) < t) {
535 throw ValueError(
format(
"Brent's method f(b) is NAN for b = %g, other input was a = %g", b, a).c_str());
537 if (std::abs(fa) < t) {
541 throw ValueError(
format(
"Brent's method f(a) is NAN for a = %g, other input was b = %g", a, b).c_str());
544 throw ValueError(
format(
"Inputs in Brent [%f,%f] do not bracket the root. Function values are [%f,%f]", a, b, fa, fb));
550 if (std::abs(fc) < std::abs(fb)) {
562 tol = 2 * macheps * std::abs(b) + t;
563 while (std::abs(m) > tol && fb != 0) {
565 if (std::abs(e) < tol || std::abs(fa) <= std::abs(fb)) {
579 p = s * (2 * m * q * (q - r) - (b - a) * (r - 1));
580 q = (q - 1) * (r - 1) * (s - 1);
590 if (2 * p < 3 * m * q - std::abs(tol * q) || p < std::abs(0.5 * s * q)) {
599 if (std::abs(d) > tol) {
608 throw ValueError(
format(
"Brent's method f(t) is NAN for t = %g", b).c_str());
610 if (std::abs(fb) < macheps) {
619 if (std::abs(fc) < std::abs(fb)) {
629 tol = 2 * macheps * std::abs(b) + t;
640 if (iter > maxiter) {
641 throw SolutionError(
format(
"Brent's method reached maximum number of steps of %d ", maxiter));
643 if (std::abs(fb) < 2 * macheps * std::abs(b)) {