| 481 | |
| 482 | template <class Stepper, class F, class T> |
| 483 | T second_order_root_finder(F f, T guess, T min, T max, int digits, std::uintmax_t& max_iter) noexcept(policies::is_noexcept_error_policy<policies::policy<> >::value&& BOOST_MATH_IS_FLOAT(T) && noexcept(std::declval<F>()(std::declval<T>()))) |
| 484 | { |
| 485 | BOOST_MATH_STD_USING |
| 486 | |
| 487 | #ifdef BOOST_MATH_INSTRUMENT |
| 488 | std::cout << "Second order root iteration, guess = " << guess << ", min = " << min << ", max = " << max |
| 489 | << ", digits = " << digits << ", max_iter = " << max_iter << "\n"; |
| 490 | #endif |
| 491 | static const char* function = "boost::math::tools::halley_iterate<%1%>"; |
| 492 | if (min >= max) |
| 493 | { |
| 494 | return policies::raise_evaluation_error(function, "Range arguments in wrong order in boost::math::tools::halley_iterate(first arg=%1%)", min, boost::math::policies::policy<>()); |
| 495 | } |
| 496 | |
| 497 | T f0(0), f1, f2; |
| 498 | T result = guess; |
| 499 | |
| 500 | T factor = ldexp(static_cast<T>(1.0), 1 - digits); |
| 501 | T delta = (std::max)(T(10000000 * guess), T(10000000)); // arbitrarily large delta |
| 502 | T last_f0 = 0; |
| 503 | T delta1 = delta; |
| 504 | T delta2 = delta; |
| 505 | bool out_of_bounds_sentry = false; |
| 506 | |
| 507 | #ifdef BOOST_MATH_INSTRUMENT |
| 508 | std::cout << "Second order root iteration, limit = " << factor << "\n"; |
| 509 | #endif |
| 510 | |
| 511 | // |
| 512 | // We use these to sanity check that we do actually bracket a root, |
| 513 | // we update these to the function value when we update the endpoints |
| 514 | // of the range. Then, provided at some point we update both endpoints |
| 515 | // checking that max_range_f * min_range_f <= 0 verifies there is a root |
| 516 | // to be found somewhere. Note that if there is no root, and we approach |
| 517 | // a local minima, then the derivative will go to zero, and hence the next |
| 518 | // step will jump out of bounds (or at least past the minima), so this |
| 519 | // check *should* happen in pathological cases. |
| 520 | // |
| 521 | T max_range_f = 0; |
| 522 | T min_range_f = 0; |
| 523 | |
| 524 | std::uintmax_t count(max_iter); |
| 525 | |
| 526 | do { |
| 527 | last_f0 = f0; |
| 528 | delta2 = delta1; |
| 529 | delta1 = delta; |
| 530 | detail::unpack_tuple(f(result), f0, f1, f2); |
| 531 | --count; |
| 532 | |
| 533 | BOOST_MATH_INSTRUMENT_VARIABLE(f0); |
| 534 | BOOST_MATH_INSTRUMENT_VARIABLE(f1); |
| 535 | BOOST_MATH_INSTRUMENT_VARIABLE(f2); |
| 536 | |
| 537 | if (0 == f0) |
| 538 | break; |
| 539 | if (f1 == 0) |
| 540 | { |
nothing calls this directly
no test coverage detected