62 std::function<
double(
double)>
f) noexcept :
76 const uint32 maxNumIterations,
77 std::function<
double(
double)>
f) noexcept :
86 ~Brent()
override =
default;
96 double solve(
double a,
double b)
103 checkAndFixAlgorithmCriteria(a, b, fa, fb);
109 double penultimateB = a;
111 bool bisection =
true;
114 if (useInverseQuadraticInterpolation(fa, fb, lastFb))
116 s = calculateInverseQuadraticInterpolation(a, b, lastB, fa, fb, lastFb);
120 s = calculateSecant(a, b, fa, fb);
123 if (useBisection(bisection, b, lastB, penultimateB, s))
125 s = calculateBisection(a, b);
134 penultimateB = lastB;
148 checkAndFixAlgorithmCriteria(a, b, fa, fb);
153 return fb < fs ? b : s;
158 const std::function<double(
double)> f_;
168 static double calculateBisection(
const double a,
const double b) noexcept
170 return 0.5 * (a + b);
183 static double calculateSecant(
const double a,
const double b,
const double fa,
const double fb) noexcept
186 return b - fb * (b - a) / (fb - fa);
201 static double calculateInverseQuadraticInterpolation(
const double a,
const double b,
const double lastB,
202 const double fa,
const double fb,
const double lastFb) noexcept
204 return a * fb * lastFb / ((fa - fb) * (fa - lastFb)) +
205 b * fa * lastFb / ((fb - fa) * (fb - lastFb)) +
206 lastB * fa * fb / ((lastFb - fa) * (lastFb - fb));
218 static bool useInverseQuadraticInterpolation(
const double fa,
const double fb,
const double lastFb) noexcept
220 return fa != lastFb && fb != lastFb;
232 static void checkAndFixAlgorithmCriteria(
double &a,
double &b,
double &fa,
double &fb) noexcept
235 if (std::fabs(fa) < std::fabs(fb))
253 bool useBisection(
const bool bisection,
const double b,
const double lastB,
254 const double penultimateB,
const double s)
const noexcept
258 return (bisection && std::fabs(s - b) >= 0.5 * std::fabs(b - lastB)) ||
259 (!bisection && std::fabs(s - b) >= 0.5 * std::fabs(lastB - penultimateB)) ||
260 (bisection && std::fabs(b - lastB) < DELTA) ||
261 (!bisection && std::fabs(lastB - penultimateB) < DELTA);