46template<std::
floating_po
int T, std::invocable<T> F> T
brent(F&& func,
const T x1,
const T x2,
const T tol) {
47 static constexpr auto eps = std::numeric_limits<T>::epsilon();
48 auto a = x1, b = x2, c = x2;
49 T fa = func(a), fb = func(b), fc = fb;
62 if(std::fabs(fc) < std::fabs(fb)) {
70 const auto comp_tol = T(2) * eps * std::fabs(b) + T(.5) * tol;
71 const auto xm = T(.5) * (c - b);
72 if(std::fabs(xm) <= comp_tol || std::fabs(fb) < tol) {
73 suanpan_debug(
"Brent's method initial guess {:.5E} with {} iterations.\n", b, counter);
76 if(std::fabs(e) >= comp_tol && std::fabs(fa) > std::fabs(fb)) {
77 const auto s = fb / fa;
84 const auto r = fb / fc;
85 p = s * (T(2) * xm * q * (q - r) - (b - a) * (r - T(1)));
86 q = (q - T(1)) * (r - T(1)) * (s - T(1));
89 else p = std::fabs(p);
90 if(T(2) * p < std::min(T(3) * xm * q - std::fabs(comp_tol * q), std::fabs(e * q))) {
99 const auto dd = xm >= T(0) ? comp_tol : -comp_tol;
100 fb = func(b += std::fabs(d) > comp_tol ? d : dd);
T brent(F &&func, const T x1, const T x2, const T tol)
Implements Brent's method for finding a root of a function within a given interval.
Definition brent.hpp:46