61 std::function<
double(
double)>
f) noexcept :
75 const uint32 maxNumIterations,
76 std::function<
double(
double)>
f) noexcept :
85 ~Brent()
override =
default;
95 double solve(
double a,
double b)
102 checkAndFixAlgorithmCriteria(a, b, fa, fb);
108 double penultimateB = a;
110 bool bisection =
true;
113 if (useInverseQuadraticInterpolation(fa, fb, lastFb))
115 s = calculateInverseQuadraticInterpolation(a, b, lastB, fa, fb, lastFb);
119 s = calculateSecant(a, b, fa, fb);
122 if (useBisection(bisection, b, lastB, penultimateB, s))
124 s = calculateBisection(a, b);
133 penultimateB = lastB;
147 checkAndFixAlgorithmCriteria(a, b, fa, fb);
152 return fb < fs ? b : s;
157 const std::function<double(
double)> f_;
167 static double calculateBisection(
const double a,
const double b) noexcept
169 return 0.5 * (a + b);
182 static double calculateSecant(
const double a,
const double b,
const double fa,
const double fb) noexcept
185 return b - fb * (b - a) / (fb - fa);
200 static double calculateInverseQuadraticInterpolation(
const double a,
const double b,
const double lastB,
201 const double fa,
const double fb,
const double lastFb) noexcept
203 return a * fb * lastFb / ((fa - fb) * (fa - lastFb)) +
204 b * fa * lastFb / ((fb - fa) * (fb - lastFb)) +
205 lastB * fa * fb / ((lastFb - fa) * (lastFb - fb));
217 static bool useInverseQuadraticInterpolation(
const double fa,
const double fb,
const double lastFb) noexcept
219 return fa != lastFb && fb != lastFb;
231 static void checkAndFixAlgorithmCriteria(
double &a,
double &b,
double &fa,
double &fb) noexcept
234 if (std::fabs(fa) < std::fabs(fb))
252 bool useBisection(
const bool bisection,
const double b,
const double lastB,
253 const double penultimateB,
const double s)
const noexcept
257 return (bisection && std::fabs(s - b) >= 0.5 * std::fabs(b - lastB)) ||
258 (!bisection && std::fabs(s - b) >= 0.5 * std::fabs(lastB - penultimateB)) ||
259 (bisection && std::fabs(b - lastB) < DELTA) ||
260 (!bisection && std::fabs(lastB - penultimateB) < DELTA);