bpp-core3  3.0.0
GoldenSectionSearch.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
5 #include "../../Text/TextTools.h"
6 #include "../NumConstants.h"
7 #include "../NumTools.h"
8 #include "GoldenSectionSearch.h"
10 
11 using namespace bpp;
12 
13 /******************************************************************************/
14 
16 {
17  callCount_++;
18  if (callCount_ <= burnin_)
19  return false;
20  return getTolerance() <= tolerance_;
21 }
22 
23 /******************************************************************************/
24 
26 {
27  // NRC Test for done:
28  const GoldenSectionSearch* gss = dynamic_cast<const GoldenSectionSearch*>(optimizer_);
29  return NumTools::abs(gss->x3 - gss->x0) / (NumTools::abs(gss->x1) + NumTools::abs(gss->x2));
30 }
31 
32 /******************************************************************************/
33 
34 GoldenSectionSearch::GoldenSectionSearch(std::shared_ptr<FunctionInterface> function) :
36  f1(0), f2(0), x0(0), x1(0), x2(0), x3(0), xinf_(0), xsup_(0), isInitialIntervalSet_(false)
37 {
38  nbEvalMax_ = 10000;
39  setDefaultStopCondition_(make_shared<GSSStopCondition>(this));
41 }
42 
43 /******************************************************************************/
44 
46 {
47  // Set the initial value (no use here! Use setInitialValues() instead).
48  if (params.size() != 1)
49  throw Exception("GoldenSectionSearch::init(). This optimizer only deals with one parameter.");
50 
51  // Bracket the minimum.
53  if (getVerbose() > 0)
54  {
55  printMessage("Initial bracketing:");
56  printMessage("A: x = " + TextTools::toString(bracket.a.x) + ", f = " + TextTools::toString(bracket.a.f));
57  printMessage("B: x = " + TextTools::toString(bracket.b.x) + ", f = " + TextTools::toString(bracket.b.f));
58  printMessage("C: x = " + TextTools::toString(bracket.c.x) + ", f = " + TextTools::toString(bracket.c.f));
59  }
60 
61  // At any given time we will keep track of four points, x0, x1, x2 and x3.
62  x0 = bracket.a.x;
63  x3 = bracket.c.x;
64  if (NumTools::abs(bracket.c.x - bracket.b.x)
65  > NumTools::abs(bracket.b.x - bracket.a.x))
66  {
67  // Make x0 to x1 the smaller segment,
68  x1 = bracket.b.x;
69  // and fill in the new point to be tried.
70  x2 = bracket.b.x + NumConstants::GOLDEN_RATIO_C() * (bracket.c.x - bracket.b.x);
71  }
72  else
73  {
74  x2 = bracket.b.x;
75  x1 = bracket.b.x - NumConstants::GOLDEN_RATIO_C() * (bracket.b.x - bracket.a.x);
76  }
77  // The initial function evaluations.
78  // Note that we never need to evaluate the function at the original endpoints.
81 }
82 
83 /******************************************************************************/
84 
85 void GoldenSectionSearch::setInitialInterval(double inf, double sup)
86 {
87  if (sup > inf)
88  {
89  xinf_ = inf; xsup_ = sup;
90  }
91  else
92  {
93  xinf_ = sup; xsup_ = inf;
94  }
95  isInitialIntervalSet_ = true;
96 }
97 
98 /******************************************************************************/
99 
101 {
103  throw Exception("GoldenSectionSearch::step. Initial interval not set: call the 'setInitialInterval' method first!");
104 
105  nbEval_++;
106 
107  if (f2 < f1)
108  {
109  // One possible outcome, its housekeeping,
110  NumTools::shift<double>(x0, x1, x2);
112  // and a new function evaluation.
113  getParameter_(0).setValue(x2);
114  tolIsReached_ = nbEval_ > 2 && getStopCondition()->isToleranceReached();
115  NumTools::shift<double>(f1, f2, getFunction()->f(getParameters()));
116  return f2;
117  }
118  else
119  {
120  // The other outcome,
121  NumTools::shift<double>(x3, x2, x1);
123  // and its new function evaluation.
124  getParameter_(0).setValue(x1);
125  tolIsReached_ = nbEval_ > 2 && getStopCondition()->isToleranceReached();
126  NumTools::shift<double>(f2, f1, getFunction()->f(getParameters()));
127  return f1;
128  }
129 }
130 
131 /******************************************************************************/
132 
134 {
135  if (!hasFunction())
136  throw NullPointerException("GoldenSectionSearch::getFunctionValue. No function associated to this optimizer.");
137  // return NumTools::min(f1, f2);
138  return currentValue_;
139 }
140 
141 /******************************************************************************/
void doInit(const ParameterList &params) override
This function is called by the init() method and contains all calculations.
bool isToleranceReached() const
Tell if the we reached the desired tolerance with a given new set of estimates.
double getTolerance() const
Get the tolerance parameter.
std::shared_ptr< OptimizationStopCondition > getStopCondition() override
Get the stop condition of the optimization algorithm.
double doStep() override
This function is called by the step() method and contains all calculations.
size_t size() const
Definition: ParameterList.h:56
void setDefaultStopCondition_(std::shared_ptr< OptimizationStopCondition > osc)
const ParameterList & getParameters() const override
static double GOLDEN_RATIO_C()
Definition: NumConstants.h:32
double getCurrentTolerance() const
Get the current tolerance.
The parameter list object.
Definition: ParameterList.h:27
static Bracket bracketMinimum(double a, double b, FunctionInterface &function, ParameterList parameters)
Bracket a minimum.
bool tolIsReached_
Tell if the tolerance level has been reached.
virtual void setValue(double value)
Set the value of this parameter.
Definition: Parameter.cpp:55
unsigned int getVerbose() const override
Get the verbose level.
GoldenSectionSearch(std::shared_ptr< FunctionInterface > function)
Golden Section Search optimization algorithm for one parameter.
Parameter & getParameter_(size_t i)
double getFunctionValue() const override
Initialize optimizer.
The base class exception for NULL pointer error. This exception may be thrown when an unexpected NULL...
Definition: Exceptions.h:56
Exception base class. Overload exception constructor (to control the exceptions mechanism). Destructor is already virtual (from std::exception)
Definition: Exceptions.h:20
unsigned int nbEvalMax_
The maximum number of function evaluations allowed.
double callCount_
Count the number of times the isToleranceReached() function has been called.
unsigned int nbEval_
The current number of function evaluations achieved.
Partial implementation of the Optimizer interface.
double currentValue_
The current value of the function.
const FunctionInterface & function() const override
Get the current function being optimized.
std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:115
void setInitialInterval(double inf, double sup)
Set intial search interval.
bool hasFunction() const override
Tell if a funciton is associatied to this optimizer.
std::shared_ptr< const FunctionInterface > getFunction() const override
Get the current function being optimized.
std::shared_ptr< OptimizationStopCondition > getDefaultStopCondition() override
Get the default stop condition of the optimization algorithm.
void printMessage(const std::string &message)
Give a message to print to the message handler.
void setStopCondition(std::shared_ptr< OptimizationStopCondition > stopCondition) override
Set the stop condition of the optimization algorithm.
static double GOLDEN_RATIO_R()
Definition: NumConstants.h:31
static T abs(T a)
Get the magnitude of a value.
Definition: NumTools.h:31