diff --git a/optimization/optimizers/line_search/golden_section.h b/optimization/optimizers/line_search/golden_section.h index 87ad21e38d65c2ac33b8fe2940c00bdcb128285c..44b2679d93e9203084917fab78ab728656ef858c 100644 --- a/optimization/optimizers/line_search/golden_section.h +++ b/optimization/optimizers/line_search/golden_section.h @@ -10,8 +10,12 @@ namespace optimization { //-------------------------------------------------------------------------------------------------- class GoldenSection { public: - // Note: This tolerance default is suitable for double precision floats. - GoldenSection(Scalar tolerance = 3e-8): tolerance_(tolerance), n_evaluations_(0) {} + // Note: + // - the default absolute tolerance is equivalent to no absolute termination condition + // - the default relative tolerance is suitable for double precision floats + GoldenSection(Scalar abs_tol = -1, Scalar rel_tol = 3e-8) + : abs_tol_(abs_tol), rel_tol_(rel_tol), n_evaluations_(0) + {} uint32_t n_evaluations() const { return n_evaluations_; } @@ -19,7 +23,10 @@ public: Sample<Scalar> optimize(Objective const& objective, Bracket const& bracket); private: - Scalar tolerance_; + // Goal for absolute width of the bracket. Put a negative number if you want to abs tol. + Scalar abs_tol_; + // Goal for width of bracket relative to central value. Should always have this. + Scalar rel_tol_; uint32_t n_evaluations_; static constexpr Scalar golden_ratio_big_ = 0.618034; @@ -65,7 +72,7 @@ Sample<Scalar> GoldenSection::optimize(Objective const& objective, Bracket const // Keep interpolating until our bracket is sufficiently tight. // See Numerical Recipes for the thought behind this particular test. - while (x_3 - x_0 > tolerance_ * (std::abs(x_1) + std::abs(x_2))) { + while (x_3 - x_0 > abs_tol_ && x_3 - x_0 > rel_tol_ * (std::abs(x_1) + std::abs(x_2))) { if (y_2 < y_1) { // x_1 is our new left edge; interpolate between x_2 and x_3 shift(x_0, x_1, x_2, golden_ratio_big_ * x_2 + golden_ratio_small_ * x_3);