Skip to content
Snippets Groups Projects
Commit 10658ad2 authored by Erik Strand's avatar Erik Strand
Browse files

Add absolute bracket width termination condition

parent 341b55f4
Branches
No related tags found
No related merge requests found
...@@ -10,8 +10,12 @@ namespace optimization { ...@@ -10,8 +10,12 @@ namespace optimization {
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
class GoldenSection { class GoldenSection {
public: public:
// Note: This tolerance default is suitable for double precision floats. // Note:
GoldenSection(Scalar tolerance = 3e-8): tolerance_(tolerance), n_evaluations_(0) {} // - 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_; } uint32_t n_evaluations() const { return n_evaluations_; }
...@@ -19,7 +23,10 @@ public: ...@@ -19,7 +23,10 @@ public:
Sample<Scalar> optimize(Objective const& objective, Bracket const& bracket); Sample<Scalar> optimize(Objective const& objective, Bracket const& bracket);
private: 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_; uint32_t n_evaluations_;
static constexpr Scalar golden_ratio_big_ = 0.618034; static constexpr Scalar golden_ratio_big_ = 0.618034;
...@@ -65,7 +72,7 @@ Sample<Scalar> GoldenSection::optimize(Objective const& objective, Bracket const ...@@ -65,7 +72,7 @@ Sample<Scalar> GoldenSection::optimize(Objective const& objective, Bracket const
// Keep interpolating until our bracket is sufficiently tight. // Keep interpolating until our bracket is sufficiently tight.
// See Numerical Recipes for the thought behind this particular test. // 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) { if (y_2 < y_1) {
// x_1 is our new left edge; interpolate between x_2 and x_3 // 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); shift(x_0, x_1, x_2, golden_ratio_big_ * x_2 + golden_ratio_small_ * x_3);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment