36double get_minima(
const std::function<
double(
double)> &f,
double lim_a,
41 std::swap(lim_a, lim_b);
42 }
else if (std::abs(lim_a - lim_b) <=
EPSILON) {
43 std::cerr <<
"Search range must be greater than " <<
EPSILON <<
"\n";
48 const double M_GOLDEN_RATIO = (3.f - std::sqrt(5.f)) / 2.f;
50 double v = lim_a + M_GOLDEN_RATIO * (lim_b - lim_a);
51 double u, w = v, x = v;
53 double fw = fv, fx = fv;
55 double mid_point = (lim_a + lim_b) / 2.f;
56 double p = 0, q = 0, r = 0;
59 double tolerance, tolerance2;
62 mid_point = (lim_a + lim_b) / 2.f;
63 tolerance =
EPSILON * std::abs(x);
64 tolerance2 = 2 * tolerance;
66 if (std::abs(e) > tolerance2) {
68 r = (x - w) * (fx - fv);
69 q = (x - v) * (fx - fw);
70 p = (x - v) * q - (x - w) * r;
80 if (std::abs(p) < std::abs(0.5 * q * r) && p < q * (lim_b - x)) {
84 if (u - lim_a < tolerance2 || lim_b - u < tolerance2)
85 d = x < mid_point ? tolerance : -tolerance;
88 e = (x < mid_point ? lim_b : lim_a) - x;
89 d = M_GOLDEN_RATIO * e;
93 if (std::abs(d) >= tolerance)
119 if (fu <= fw || x == w) {
124 }
else if (fu <= fv || v == x || v == w) {
131 }
while (std::abs(x - mid_point) > (tolerance - (lim_b - lim_a) / 2.f));
133 std::cout <<
" (iters: " << iters <<
") ";