1 #ifndef SOPT_BISECTION_METHOD_H
2 #define SOPT_BISECTION_METHOD_H
3 #include "sopt/config.h"
13 typename std::enable_if<std::is_same<t_real, K>::value, K>::type
bisection_method(
14 const K &function_value,
const std::function<K(K)> &func,
const K &
a,
const K &
b,
15 const t_real &rel_convergence = 1e-4);
19 const K &function_value,
const std::function<K(K)> &func,
const K &
a,
const K &
b,
20 const t_real &rel_convergence) {
23 t_real relative_difference = 1;
25 SOPT_LOW_LOG(
"Starting bisection method over x ∈ [{}, {}], to estimate f(x) = {}",
a,
b,
27 const auto estimate = [&](
const K &x) {
return func(x) - function_value; };
30 if (eb == 0)
return b;
31 if (ea == 0)
return a;
32 if ((ea > 0 and eb > 0) or (ea < 0 and eb < 0))
33 SOPT_THROW(
"f(a) = " << ea <<
" and f(b) = " << eb
34 <<
" have the wrong sign."
36 <<
a <<
" and b = " <<
b
37 <<
" Bisection Method not applicable for "
39 const auto sign = [&](
const K &x) {
return (x > 0) ? 1 : ((x < 0) ? -1 : 0); };
42 while (rel_convergence < relative_difference or
43 std::abs(upper_eta - lower_eta) > rel_convergence) {
44 if (upper_eta == lower_eta)
SOPT_THROW(
"a == b, something is wrong.");
45 eta = (lower_eta + upper_eta) * 0.5;
46 auto const function_est = estimate(eta);
47 if (sign(estimate(lower_eta)) == sign(estimate(eta)))
51 relative_difference = std::abs(function_est);
52 assert(!(estimate(lower_eta) > 0 and estimate(upper_eta) > 0) and
53 !(estimate(lower_eta) < 0 and estimate(upper_eta) < 0));
#define SOPT_LOW_LOG(...)
Low priority message.
double t_real
Root of the type hierarchy for real numbers.
std::enable_if< std::is_same< t_real, K >::value, K >::type bisection_method(const K &function_value, const std::function< K(K)> &func, const K &a, const K &b, const t_real &rel_convergence=1e-4)
Find root to a function within an interval.