bpp-core  2.2.0
AbstractOptimizer.cpp
Go to the documentation of this file.
1 //
2 // File: AbstractOptimizer.cpp
3 // Created by: Julien Dutheil
4 // Created on: Mon Dec 22 12:18:09 2003
5 //
6 
7 /*
8  Copyright or © or Copr. Bio++ Development Team, (November 17, 2004)
9 
10  This software is a computer program whose purpose is to provide classes
11  for numerical calculus.
12 
13  This software is governed by the CeCILL license under French law and
14  abiding by the rules of distribution of free software. You can use,
15  modify and/ or redistribute the software under the terms of the CeCILL
16  license as circulated by CEA, CNRS and INRIA at the following URL
17  "http://www.cecill.info".
18 
19  As a counterpart to the access to the source code and rights to copy,
20  modify and redistribute granted by the license, users are provided only
21  with a limited warranty and the software's author, the holder of the
22  economic rights, and the successive licensors have only limited
23  liability.
24 
25  In this respect, the user's attention is drawn to the risks associated
26  with loading, using, modifying and/or developing or reproducing the
27  software by the user in light of its specific status of free software,
28  that may mean that it is complicated to manipulate, and that also
29  therefore means that it is reserved for developers and experienced
30  professionals having in-depth computer knowledge. Users are therefore
31  encouraged to load and test the software's suitability as regards their
32  requirements in conditions enabling the security of their systems and/or
33  data to be ensured and, more generally, to use and operate it in the
34  same conditions as regards security.
35 
36  The fact that you are presently reading this means that you have had
37  knowledge of the CeCILL license and that you accept its terms.
38 */
39 
40 #include "AbstractOptimizer.h"
41 #include "../AutoParameter.h"
42 #include "../../Text/TextTools.h"
43 #include "../../App/ApplicationTools.h"
44 
45 // From the STL:
46 #include <iomanip>
47 #include <time.h>
48 
49 using namespace std;
50 using namespace bpp;
51 
52 /******************************************************************************/
53 
54 AbstractOptimizer::AbstractOptimizer(Function* function):
55  function_(function),
56  parameters_(),
57  messageHandler_(ApplicationTools::message),
58  profiler_(ApplicationTools::message),
59  constraintPolicy_(AutoParameter::CONSTRAINTS_KEEP),
60  stopCondition_(0), defaultStopCondition_(0),
61  verbose_(true), isInitialized_(false), startTime_(), listeners_(),
62  updateParameters_(false), stepChar_("*"),
63  nbEvalMax_(1000000), nbEval_(0),
64  currentValue_(0), tolIsReached_(false)
65 {
66 }
67 
68 /******************************************************************************/
69 
71  function_(opt.function_),
72  parameters_(opt.parameters_),
73  messageHandler_(opt.messageHandler_),
74  profiler_(opt.profiler_),
75  constraintPolicy_(opt.constraintPolicy_),
76  stopCondition_(0), defaultStopCondition_(0),
77  verbose_(opt.verbose_),
78  isInitialized_(opt.isInitialized_),
79  startTime_(opt.startTime_),
80  listeners_(), //We do not copy listeners!
81  updateParameters_(opt.updateParameters_),
82  stepChar_(opt.stepChar_),
83  nbEvalMax_(opt.nbEvalMax_),
84  nbEval_(opt.nbEval_),
85  currentValue_(opt.currentValue_),
86  tolIsReached_(opt.tolIsReached_)
87 {
88  if (opt.stopCondition_)
89  {
92  }
93  else
94  stopCondition_ = 0;
95  if (opt.defaultStopCondition_)
96  {
99  }
100  else
102  //In case of AutoParameter instances, we must actualize the pointers toward _messageHandler:
103  if (isInitialized_)
104  {
107  }
108 }
109 
110 /******************************************************************************/
111 
113 {
114  function_ = opt.function_;
115  parameters_ = opt.parameters_;
117  profiler_ = opt.profiler_;
120  if (opt.stopCondition_)
121  {
124  }
125  else
126  stopCondition_ = 0;
127  if (opt.defaultStopCondition_)
128  {
131  }
132  else
134  nbEvalMax_ = opt.nbEvalMax_;
135  nbEval_ = opt.nbEval_;
136  verbose_ = opt.verbose_;
138  //In case of AutoParameter instances, we must actualize the pointers toward messageHandler_:
139  if (isInitialized_)
140  {
143  }
144  startTime_ = opt.startTime_;
145  listeners_.resize(0); //Reset listener list, do not copy it!
147  stepChar_ = opt.stepChar_;
148  return *this;
149 }
150 
151 /******************************************************************************/
152 
154 {
155  if (!function_) throw Exception("AbstractOptimizer::init. Optimizer currently has no function.");
156  //We do this in order to keep original constraints:
157  parameters_ = params;
158  //More secure, but too slow:
159  //parameters_ = function_->getParameters().subList(params.getParameterNames());
160  //parameters_.matchParametersValues(params);
161  if (constraintPolicy_ == AutoParameter::CONSTRAINTS_AUTO) autoParameter();
162  else if (constraintPolicy_ == AutoParameter::CONSTRAINTS_IGNORE) ignoreConstraints();
163  doInit(params);
164  nbEval_ = 0;
165  tolIsReached_ = false;
166  isInitialized_ = true;
167  time(&startTime_);
168  currentValue_ = function_->getValue();
169 
170  profile("Step\t");
171  for (unsigned int i = 0; i < parameters_.size(); i++)
172  {
173  profile(parameters_[i].getName() + "\t");
174  }
175  profileln("Function\tTime");
176 
177  //Parameters must be assigned by doInit:
178 
179  printPoint(parameters_, currentValue_);
180 
181  // Initialize the StopCondition:
182  stopCondition_->init();
183  fireOptimizationInitializationPerformed(OptimizationEvent(this));
184 }
185 
186 /******************************************************************************/
187 
189 {
190  currentValue_ = doStep();
194  {
195  if (!updateParameters_)
197  //else already done!
198  //_currentValue = function_->getValue();
199  //Often useless, but avoid some bizare behaviour in particular cases:
201  }
203  return currentValue_;
204 }
205 
206 /**************************************************************************/
207 
209 {
210  if (!isInitialized_)
211  throw Exception("AbstractOptimizer::optimize. Optimizer not initialized: call the 'init' method first!");
212  tolIsReached_ = false;
213  for (nbEval_ = 1; nbEval_ < nbEvalMax_ && ! tolIsReached_; nbEval_++)
214  {
215  if (verbose_)
217  step();
218  }
219  return currentValue_;
220 }
221 
222 /******************************************************************************/
223 
225 {
226  if (profiler_) *profiler_ << v;
227 }
228 
229 /******************************************************************************/
230 
232 {
233  if (profiler_) (*profiler_ << v).endLine();
234 }
235 
236 /******************************************************************************/
237 
238 void AbstractOptimizer::profile(unsigned int v)
239 {
240  if (profiler_) *profiler_ << v;
241 }
242 /******************************************************************************/
243 
244 void AbstractOptimizer::profileln(unsigned int v)
245 {
246  if (profiler_) (*profiler_ << v).endLine();
247 }
248 
249 /******************************************************************************/
250 
251 void AbstractOptimizer::profile(const std::string& s)
252 {
253  if (profiler_) *profiler_ << s;
254 }
255 
256 /******************************************************************************/
257 
258 void AbstractOptimizer::profileln(const std::string& s)
259 {
260  if (profiler_) (*profiler_ << s).endLine();
261 }
262 
263 /******************************************************************************/
264 
265 void AbstractOptimizer::printPoint(const ParameterList& params, double value)
266 {
267  size_t ndim = params.size();
268  profile(nbEval_);
269  profile("\t");
270  for (size_t j = 0; j < ndim; j++)
271  {
272  profile(TextTools::toString(params[j].getValue()));
273  profile("\t");
274  }
275  profile(value);
276  profile("\t");
277  time_t seconds;
278  time(&seconds);
279  profileln(difftime(seconds, startTime_));
280 }
281 
282 /******************************************************************************/
283 
284 void AbstractOptimizer::printMessage(const std::string& message)
285 {
286  if (messageHandler_) (*messageHandler_ << message).endLine();
287 }
288 
289 /******************************************************************************/
290 
292 {
293  for (unsigned int i = 0; i < parameters_.size(); i++)
294  {
295  AutoParameter ap(parameters_[i]);
297  parameters_.setParameter(i, ap);
298  }
299 }
300 
301 /******************************************************************************/
302 
304 {
305  for (unsigned int i = 0; i < parameters_.size(); i++)
306  {
307  parameters_[i].removeConstraint();
308  }
309 }
310 
311 /******************************************************************************/
312 
314 {
315  for (unsigned int i = 0; i < listeners_.size(); i++)
316  {
317  listeners_[i]->optimizationInitializationPerformed(event);
318  }
319 }
320 
321 /******************************************************************************/
322 
324 {
325  for (unsigned int i = 0; i < listeners_.size(); i++)
326  {
327  listeners_[i]->optimizationStepPerformed(event);
328  }
329 }
330 
331 /******************************************************************************/
332 
334 {
335  for (unsigned int i = 0; i < listeners_.size(); i++)
336  {
338  return true;
339  }
340  return false;
341 }
342 
343 /******************************************************************************/
344 
bool isInitialized_
Check if the optimizer have been feeded with initial parameters values.
static std::string CONSTRAINTS_IGNORE
OptimizationStopCondition * clone() const =0
Create a copy of this object and send a pointer to it.
AbstractOptimizer & operator=(const AbstractOptimizer &opt)
OptimizationStopCondition * defaultStopCondition_
The default stoping condition to use while optimizing.
std::vector< OptimizationListener * > listeners_
virtual double f(const ParameterList &parameters)
Get the value of the function according to a given set of parameters.
Definition: Functions.h:117
This class allows to perform a correspondence analysis.
double optimize()
Basic implementation.
virtual bool matchParametersValues(const ParameterList &params, std::vector< size_t > *updatedParameters=0)
Update the parameters from params.
Function * function_
The function to optimize.
This is the function abstract class.
Definition: Functions.h:86
Interface for otimization stop condition objet.
void profileln(double v)
Print to the profile if there is one and end line.
virtual const ParameterList & getParameters() const =0
Get all parameters available.
size_t size() const
Definition: ParameterList.h:90
STL namespace.
virtual bool isToleranceReached() const =0
Tell if the we reached the desired tolerance with a given new set of estimates.
void ignoreConstraints()
Remove the constraints of all the arguments.
static std::string toString(T t)
General template method to convert to a string.
Definition: TextTools.h:189
The parameter list object.
Definition: ParameterList.h:61
This class provides some common tools for developping applications.
bool tolIsReached_
Tell if the tolerance level has been reached.
OutputStream * profiler_
The profiler.
virtual void setMessageHandler(OutputStream *mh)
Set the message handler for this AutoParameter.
virtual void setOptimizer(const Optimizer *optimizer)=0
Set the optimizer attached to this instance.
double step()
Basic implementation.
bool listenerModifiesParameters() const
unsigned int verbose_
State of the verbose mode: > 0 = enabled.
The AutoParameter class.
Definition: AutoParameter.h:58
virtual void setParameter(size_t index, const Parameter &param)
Change given parameter.
void printPoint(const ParameterList &params, double value)
Print parameters and corresponding function evaluation to profiler.
An event object which indicates that an optimization event occured.
Definition: Optimizer.h:55
OptimizationStopCondition * stopCondition_
The stoping condition to use while optimizing.
Exception base class.
Definition: Exceptions.h:57
static std::string CONSTRAINTS_AUTO
unsigned int nbEvalMax_
The maximum number of function evaluations allowed.
unsigned int nbEval_
The current number of function evaluations achieved.
Partial implementation of the Optimizer interface.
void fireOptimizationInitializationPerformed(const OptimizationEvent &event)
Notify all listeners that optimizer initialization was performed.
double currentValue_
The current value of the function.
static void displayUnlimitedGauge(size_t iter, const std::string &mes="")
Display a gauge for unefined amount of iterations.
std::string constraintPolicy_
The constraint policy.
AbstractOptimizer(Function *function=0)
virtual double doStep()=0
This function is called by the step() method and contains all calculations.
OutputStream * messageHandler_
The message handler.
void profile(double v)
Print to the profile if there is one.
void fireOptimizationStepPerformed(const OptimizationEvent &event)
Notify all listeners that an optimization step was performed.
void printMessage(const std::string &message)
Give a message to print to the message handler.
ParameterList parameters_
The parameters that will be optimized.
void autoParameter()
Build a list of AutoParameter instead of Parameter.
void init(const ParameterList &params)
Basic implementation.