From 10658ad278badab9f4b27748f254206955cdac7f Mon Sep 17 00:00:00 2001 From: Erik Strand <erik.strand@cba.mit.edu> Date: Mon, 13 Apr 2020 02:52:27 -0400 Subject: [PATCH] Add absolute bracket width termination condition --- .../optimizers/line_search/golden_section.h | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/optimization/optimizers/line_search/golden_section.h b/optimization/optimizers/line_search/golden_section.h index 87ad21e..44b2679 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); -- GitLab