Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/math/tools/roots.hpp view on Meta::CPAN
if(fmax == 0)
return std::make_pair(max, max);
//
// Error checking:
//
static const char* function = "boost::math::tools::bisect<%1%>";
if(min >= max)
{
policies::raise_evaluation_error(function,
"Arguments in wrong order in boost::math::tools::bisect (first arg=%1%)", min, pol);
}
if(fmin * fmax >= 0)
{
policies::raise_evaluation_error(function,
"No change of sign in boost::math::tools::bisect, either there is no root to find, or there are multiple roots in the interval (f(min) = %1%).", fmin, pol);
}
//
// Three function invocations so far:
//
boost::uintmax_t count = max_iter;
if(count < 3)
count = 0;
else
count -= 3;
while(count && (0 == tol(min, max)))
{
T mid = (min + max) / 2;
T fmid = f(mid);
if((mid == max) || (mid == min))
break;
if(fmid == 0)
{
min = max = mid;
break;
}
else if(sign(fmid) * sign(fmin) < 0)
{
max = mid;
fmax = fmid;
}
else
{
min = mid;
fmin = fmid;
}
--count;
}
max_iter -= count;
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Bisection iteration, final count = " << max_iter << std::endl;
static boost::uintmax_t max_count = 0;
if(max_iter > max_count)
{
max_count = max_iter;
std::cout << "Maximum iterations: " << max_iter << std::endl;
}
#endif
return std::make_pair(min, max);
}
template <class F, class T, class Tol>
inline std::pair<T, T> bisect(F f, T min, T max, Tol tol, boost::uintmax_t& max_iter)
{
return bisect(f, min, max, tol, max_iter, policies::policy<>());
}
template <class F, class T, class Tol>
inline std::pair<T, T> bisect(F f, T min, T max, Tol tol)
{
boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
return bisect(f, min, max, tol, m, policies::policy<>());
}
template <class F, class T>
T newton_raphson_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter)
{
BOOST_MATH_STD_USING
T f0(0), f1, last_f0(0);
T result = guess;
T factor = static_cast<T>(ldexp(1.0, 1 - digits));
T delta = 1;
T delta1 = tools::max_value<T>();
T delta2 = tools::max_value<T>();
boost::uintmax_t count(max_iter);
do{
last_f0 = f0;
delta2 = delta1;
delta1 = delta;
boost::math::tie(f0, f1) = f(result);
if(0 == f0)
break;
if(f1 == 0)
{
// Oops zero derivative!!!
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Newton iteration, zero derivative found" << std::endl;
#endif
detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
}
else
{
delta = f0 / f1;
}
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Newton iteration, delta = " << delta << std::endl;
#endif
if(fabs(delta * 2) > fabs(delta2))
{
// last two steps haven't converged, try bisection:
delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
}
guess = result;
result -= delta;
if(result <= min)
{
delta = 0.5F * (guess - min);
result = guess - delta;
if((result == min) || (result == max))
break;
}
else if(result >= max)
{
delta = 0.5F * (guess - max);
result = guess - delta;
if((result == min) || (result == max))
break;
}
// update brackets:
if(delta > 0)
max = guess;
else
min = guess;
}while(--count && (fabs(result * factor) < fabs(delta)));
max_iter -= count;
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Newton Raphson iteration, final count = " << max_iter << std::endl;
static boost::uintmax_t max_count = 0;
if(max_iter > max_count)
{
max_count = max_iter;
std::cout << "Maximum iterations: " << max_iter << std::endl;
}
#endif
return result;
}
template <class F, class T>
inline T newton_raphson_iterate(F f, T guess, T min, T max, int digits)
{
boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
return newton_raphson_iterate(f, guess, min, max, digits, m);
}
template <class F, class T>
T halley_iterate(F f, T guess, T min, T max, int digits, boost::uintmax_t& max_iter)
{
BOOST_MATH_STD_USING
T f0(0), f1, f2;
T result = guess;
T factor = static_cast<T>(ldexp(1.0, 1 - digits));
T delta = (std::max)(T(10000000 * guess), T(10000000)); // arbitarily large delta
T last_f0 = 0;
T delta1 = delta;
T delta2 = delta;
bool out_of_bounds_sentry = false;
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Halley iteration, limit = " << factor << std::endl;
#endif
boost::uintmax_t count(max_iter);
do{
last_f0 = f0;
delta2 = delta1;
delta1 = delta;
boost::math::tie(f0, f1, f2) = f(result);
BOOST_MATH_INSTRUMENT_VARIABLE(f0);
BOOST_MATH_INSTRUMENT_VARIABLE(f1);
BOOST_MATH_INSTRUMENT_VARIABLE(f2);
if(0 == f0)
break;
if((f1 == 0) && (f2 == 0))
{
// Oops zero derivative!!!
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Halley iteration, zero derivative found" << std::endl;
#endif
detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
}
else
{
if(f2 != 0)
{
T denom = 2 * f0;
src/boost/math/tools/roots.hpp view on Meta::CPAN
{
// Oops zero derivative!!!
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Halley iteration, zero derivative found" << std::endl;
#endif
detail::handle_zero_derivative(f, last_f0, f0, delta, result, guess, min, max);
}
else
{
T ratio = f0 / f1;
if(ratio / result < 0.1)
{
delta = ratio + (f2 / (2 * f1)) * ratio * ratio;
// check second derivative doesn't over compensate:
if(delta * ratio < 0)
delta = ratio;
}
else
delta = ratio; // fall back to Newton iteration.
}
if(fabs(delta * 2) > fabs(delta2))
{
// last two steps haven't converged, try bisection:
delta = (delta > 0) ? (result - min) / 2 : (result - max) / 2;
}
guess = result;
result -= delta;
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Halley iteration, delta = " << delta << std::endl;
#endif
if(result <= min)
{
delta = 0.5F * (guess - min);
result = guess - delta;
if((result == min) || (result == max))
break;
}
else if(result >= max)
{
delta = 0.5F * (guess - max);
result = guess - delta;
if((result == min) || (result == max))
break;
}
// update brackets:
if(delta > 0)
max = guess;
else
min = guess;
}while(--count && (fabs(result * factor) < fabs(delta)));
max_iter -= count;
#ifdef BOOST_MATH_INSTRUMENT
std::cout << "Schroeder iteration, final count = " << max_iter << std::endl;
static boost::uintmax_t max_count = 0;
if(max_iter > max_count)
{
max_count = max_iter;
std::cout << "Maximum iterations: " << max_iter << std::endl;
}
#endif
return result;
}
template <class F, class T>
inline T schroeder_iterate(F f, T guess, T min, T max, int digits)
{
boost::uintmax_t m = (std::numeric_limits<boost::uintmax_t>::max)();
return schroeder_iterate(f, guess, min, max, digits, m);
}
} // namespace tools
} // namespace math
} // namespace boost
#endif // BOOST_MATH_TOOLS_NEWTON_SOLVER_HPP
( run in 0.487 second using v1.01-cache-2.11-cpan-96521ef73a4 )