Logo ROOT   6.10/09
Reference Guide
GeneticMinimizer.cxx
Go to the documentation of this file.
2 
4 #include "TMVA/IFitterTarget.h"
5 
6 #include "Math/IFunction.h"
7 #include "Math/GenAlgoOptions.h"
8 
9 #include "TError.h"
10 
11 #include <cassert>
12 
13 namespace ROOT {
14 namespace Math {
15 
16 
17 // wrapper class for TMVA interface to evaluate objective function
18 class MultiGenFunctionFitness : public TMVA::IFitterTarget {
19 private:
20  unsigned int fNCalls;
21  unsigned int fNFree;
22  const ROOT::Math::IMultiGenFunction& fFunc;
23  std::vector<int> fFixedParFlag;
24  mutable std::vector<double> fValues;
25 
26 public:
27  MultiGenFunctionFitness(const ROOT::Math::IMultiGenFunction& function) : fNCalls(0),
28  fFunc(function)
29  { fNFree = fFunc.NDim(); }
30 
31  unsigned int NCalls() const { return fNCalls; }
32  unsigned int NDims() const { return fNFree; }
33 
34  unsigned int NTotal() const { return fFunc.NDim(); }
35 
36  void FixParameter(unsigned int ipar, double value, bool fix = true) {
37 
38  if (fValues.size() != fFunc.NDim() ) {
39  fValues.resize(fFunc.NDim() );
40  fFixedParFlag.resize(fFunc.NDim());
41  }
42 
43  if (ipar >= fValues.size() ) return;
44 
45  // first find if it has been already fixed
46  fFixedParFlag[ipar] = fix;
47  fValues[ipar] = value;
48  // count number of fixed params
49  for (unsigned int i = 0; i < fFixedParFlag.size(); ++i)
50  if (!fFixedParFlag[i] ) fNFree++;
51 
52  }
53 
54  // transfrom from internal parameters (not fixed to external vector which include the fixed ones)
55  const std::vector<double> & Transform( const std::vector<double> & factors) const {
56  unsigned int n = fValues.size();
57  if (n == 0 || fNFree == n )
58  return factors;
59 
60  // in case of fixed parameters
61  for (unsigned int i = 0, j = 0; i < n ; ++i) {
62  if (!fFixedParFlag[i] ) {
63  assert (j < fNFree);
64  fValues[i] = factors[j];
65  j++;
66  }
67  }
68  return fValues;
69  }
70 
71  Double_t Evaluate(const std::vector<double> & factors ) const {
72  const std::vector<double> & x = Transform( factors);
73  return fFunc(&x[0]);
74  }
75 
76  Double_t EstimatorFunction(std::vector<double> & factors ){
77  fNCalls += 1;
78  return Evaluate( factors);
79  }
80 };
81 
83 {
84  // constructor of parameters with default values (use 100 is max iterations is not defined)
86  fNsteps = (defmaxiter > 0) ? defmaxiter : 100;
87  fPopSize =300;
88  fCycles = 3;
89  fSC_steps =10;
90  fSC_rate =5;
91  fSC_factor=0.95;
92  fConvCrit =10.0 * ROOT::Math::MinimizerOptions::DefaultTolerance(); // default is 0.001
93  if (fConvCrit <=0 ) fConvCrit = 0.001;
94  fSeed=0; // random seed
95 }
96 
97 // genetic minimizer class
98 
100  fFitness(0),
101  fMinValue(0),
102  fParameters(GeneticMinimizerParameters() )
103 {
104 
105  // check with default minimizer options
107  if (geneticOpt) {
108  ROOT::Math::MinimizerOptions opt; // create using default options
109  opt.SetExtraOptions(*geneticOpt);
110  this->SetOptions(opt);
111  }
112 
113  // set the parameters
116  }
117 
119 {
120  if ( fFitness )
121  {
122  delete fFitness;
123  fFitness = 0;
124  }
125 }
126 
128 {
129  fRanges.clear();
130  fResult.clear();
131  if ( fFitness )
132  {
133  delete fFitness;
134  fFitness = 0;
135  }
136 }
137 
139 {
140  Clear();
141 
142  fFitness = new MultiGenFunctionFitness(func);
143  fResult = std::vector<double>(func.NDim() );
144  assert(fResult.size() == NDim() );
145 }
146 
147 bool GeneticMinimizer::SetLimitedVariable(unsigned int , const std::string & , double , double , double lower , double upper )
148 {
149  fRanges.push_back( new TMVA::Interval(lower,upper) );
150 
151  return true;
152 }
153 
154 bool GeneticMinimizer::SetVariable(unsigned int, const std::string& name, double value, double step)
155 {
156  //It does nothing! As there is no variable if it has no limits!
157  double lower = value - (50 * step);
158  double upper = value + (50 * step);
159  Info("GeneticMinimizer::SetVariable", "Variables should be limited - set automatic range to 50 times step size for %s : [%f, %f]",
160  name.c_str(),lower,upper);
161  fRanges.push_back( new TMVA::Interval(lower, upper ) );
162 
163  return true;
164 }
165 
166 bool GeneticMinimizer::SetFixedVariable(unsigned int par, const std::string& name, double value) {
167  // set a fixed variable
168  if (!fFitness) {
169  Error("GeneticMinimizer::SetFixedVariable", "Function has not been set - cannot set fixed variables %s",name.c_str());
170  return false;
171  }
172 
173  static_cast<MultiGenFunctionFitness*>(fFitness)->FixParameter(par, value);
174  return true;
175 }
176 
177 
179 {
180  fParameters = params;
181  // set also the one defined in Minimizer
184 }
185 
188  GetGeneticOptions(opt);
189  return opt;
190 }
191 
193  // get the genetic options of the class and return them in the MinimizerOptions class
194  opt.SetTolerance(fParameters.fConvCrit/10); // use a factor of 10 to have default as Minuit
195  opt.SetPrintLevel(PrintLevel() );
197  // use fixed or dammy value for the other options
198  opt.SetMinimizerType("Genetic");
199  opt.SetMaxFunctionCalls(0);
200  opt.SetStrategy(-1);
201  opt.SetErrorDef(0);
202  opt.SetPrecision(0);
203  opt.SetMinimizerAlgorithm("");
204 
205  ROOT::Math::GenAlgoOptions geneticOpt;
206  geneticOpt.SetValue("PopSize",fParameters.fPopSize);
207  geneticOpt.SetValue("Steps",fParameters.fNsteps);
208  geneticOpt.SetValue("Cycles",fParameters.fCycles);
209  geneticOpt.SetValue("SC_steps",fParameters.fSC_steps);
210  geneticOpt.SetValue("SC_rate",fParameters.fSC_rate);
211  geneticOpt.SetValue("SC_factor",fParameters.fSC_factor);
212  geneticOpt.SetValue("ConvCrit",fParameters.fConvCrit);
213  geneticOpt.SetValue("RandomSeed",fParameters.fSeed);
214 
215  opt.SetExtraOptions(geneticOpt);
216 }
217 
219 {
220  SetTolerance(opt.Tolerance() );
221  SetPrintLevel(opt.PrintLevel() );
222  //SetMaxFunctionCalls(opt.MaxFunctionCalls() );
224 
225  fParameters.fConvCrit = 10.*opt.Tolerance(); // use a factor of 10 to have default as Minuit
226 
227  // set genetic parameter from minimizer options
228  const ROOT::Math::IOptions * geneticOpt = opt.ExtraOptions();
229  if (!geneticOpt) {
230  Warning("GeneticMinimizer::SetOptions", "No specific genetic minimizer options have been set");
231  return;
232  }
233 
234  // if options are not existing values will not be set
235  geneticOpt->GetValue("PopSize",fParameters.fPopSize);
236  geneticOpt->GetValue("Steps",fParameters.fNsteps);
237  geneticOpt->GetValue("Cycles",fParameters.fCycles);
238  geneticOpt->GetValue("SC_steps",fParameters.fSC_steps);
239  geneticOpt->GetValue("SC_rate",fParameters.fSC_rate);
240  geneticOpt->GetValue("SC_factor",fParameters.fSC_factor);
241  geneticOpt->GetValue("ConvCrit",fParameters.fConvCrit);
242  geneticOpt->GetValue("RandomSeed",fParameters.fSeed);
243 
244  // use same of options in base class
245  int maxiter = opt.MaxIterations();
246  if (maxiter > 0 && fParameters.fNsteps > 0 && maxiter != fParameters.fNsteps ) {
247  Warning("GeneticMinimizer::SetOptions", "max iterations value given different than than Steps - set equal to Steps %d",fParameters.fNsteps);
248  }
250 
251 }
252 
254 {
255 
256  if (!fFitness) {
257  Error("GeneticMinimizer::Minimize","Fitness function has not been set");
258  return false;
259  }
260 
261  // sync parameters
263  if (Tolerance() > 0) fParameters.fConvCrit = 10* Tolerance();
264 
266 
267  if (PrintLevel() > 0) {
268  std::cout << "GeneticMinimizer::Minimize - Start iterating - max iterations = " << MaxIterations()
269  << " conv criteria (tolerance) = " << fParameters.fConvCrit << std::endl;
270  }
271 
272  fStatus = 0;
273  unsigned int niter = 0;
274  do {
275  mg.Init();
276 
277  mg.CalculateFitness();
278 
279  // Just for debugging options
280  //mg.GetGeneticPopulation().Print(0);
281 
283 
285 
286  if (PrintLevel() > 2) {
287  std::cout << "New Iteration " << niter << " with parameter values :" << std::endl;
289  if (genes) {
290  std::vector<Double_t> gvec;
291  gvec = genes->GetFactors();
292  for (unsigned int i = 0; i < gvec.size(); ++i) {
293  std::cout << gvec[i] << " ";
294  }
295  std::cout << std::endl;
296  std::cout << "\tFitness function value = " << static_cast<MultiGenFunctionFitness*>(fFitness)->Evaluate(gvec) << std::endl;
297  }
298  }
299  niter++;
300  if ( niter > MaxIterations() && MaxIterations() > 0) {
301  if (PrintLevel() > 0) {
302  Info("GeneticMinimizer::Minimize","Max number of iterations %d reached - stop iterating",MaxIterations());
303  }
304  fStatus = 1;
305  break;
306  }
307 
308  } while (!mg.HasConverged( fParameters.fNsteps, fParameters.fConvCrit )); // converged if: fitness-improvement < CONVCRIT within the last CONVSTEPS loops
309 
311  std::vector<Double_t> gvec;
312  gvec = genes->GetFactors();
313 
314 
315  // transform correctly gvec on fresult in case there are fixed parameters
316  const std::vector<double> & transVec = static_cast<MultiGenFunctionFitness*>(fFitness)->Transform(gvec);
317  std::copy(transVec.begin(), transVec.end(), fResult.begin() );
318  fMinValue = static_cast<MultiGenFunctionFitness*>(fFitness)->Evaluate(gvec);
319 
320 
321  if (PrintLevel() > 0) {
322  if (PrintLevel() > 2) std::cout << std::endl;
323  std::cout << "Finished Iteration (niter = " << niter << " with fitness function value = " << MinValue() << std::endl;
324  for (unsigned int i = 0; i < fResult.size(); ++i) {
325  std::cout << " Parameter-" << i << "\t=\t" << fResult[i] << std::endl;
326  }
327  }
328 
329  return true;
330 }
331 
333 {
334  return (fFitness) ? fMinValue : 0;
335 }
336 
337 const double * GeneticMinimizer::X() const {
338  return (fFitness) ? &fResult[0] : 0;
339 }
340 
341 unsigned int GeneticMinimizer::NCalls() const
342 {
343  if ( fFitness )
344  return static_cast<MultiGenFunctionFitness*>(fFitness)->NCalls();
345  else
346  return 0;
347 }
348 
349 unsigned int GeneticMinimizer::NDim() const
350 {
351  if ( fFitness )
352  return static_cast<MultiGenFunctionFitness*>(fFitness)->NTotal();
353  else
354  return 0;
355 }
356 unsigned int GeneticMinimizer::NFree() const
357 {
358  if ( fFitness )
359  return static_cast<MultiGenFunctionFitness*>(fFitness)->NDims();
360  else
361  return 0;
362 }
363 
364 // Functions we don't need...
365 const double * GeneticMinimizer::MinGradient() const { return 0; }
366 bool GeneticMinimizer::ProvidesError() const { return false; }
367 const double * GeneticMinimizer::Errors() const { return 0; }
368 double GeneticMinimizer::Edm() const { return 0; }
369 double GeneticMinimizer::CovMatrix(unsigned int, unsigned int) const { return 0; }
370 
371 }
372 }
virtual bool SetFixedVariable(unsigned int ivar, const std::string &name, double val)
set a new fixed variable (override if minimizer supports them )
void GetGeneticOptions(ROOT::Math::MinimizerOptions &opt) const
double par[1]
Definition: unuranDistr.cxx:38
void SetMaxIterations(unsigned int maxiter)
set maximum iterations (one iteration can have many function calls)
Definition: Minimizer.h:451
void SetPrintLevel(int level)
set print level
virtual unsigned int NFree() const
number of free variables (real dimension of the problem) this is <= Function().NDim() which is the to...
virtual bool Minimize()
method to perform the minimization
GeneticMinimizerParameters fParameters
void SetTolerance(double tol)
set the tolerance
void SetMaxIterations(unsigned int maxiter)
set maximum iterations (one iteration can have many function calls)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
void SetMinimizerType(const char *type)
set minimizer type
virtual bool SetVariable(unsigned int ivar, const std::string &name, double val, double step)
set a new free variable
virtual void SetOptions(const ROOT::Math::MinimizerOptions &opt)
virtual Double_t CalculateFitness()
starts the evaluation of the fitness of all different individuals of the population.
GeneticPopulation & GetGeneticPopulation()
virtual double MinValue() const
return minimum function value
virtual Double_t SpreadControl(Int_t steps, Int_t ofSteps, Double_t factor)
this function provides the ability to change the stepSize of a mutation according to the success of t...
const IOptions * ExtraOptions() const
return extra options (NULL pointer if they are not present)
virtual bool ProvidesError() const
minimizer provides error and error matrix
virtual double Edm() const
return expected distance reached from the minimum (re-implement if minimizer provides it ...
void SetErrorDef(double err)
set error def
unsigned int MaxIterations() const
max iterations
bool GetValue(const char *name, T &t) const
Definition: IOptions.h:73
int PrintLevel() const
minimizer configuration parameters
Definition: Minimizer.h:411
virtual unsigned int NDim() const
this is <= Function().NDim() which is the total number of variables (free+ constrained ones) ...
virtual void Clear()
reset for consecutive minimizations - implement if needed
Double_t x[n]
Definition: legend1.C:17
void SetPrecision(double prec)
set the precision
int PrintLevel() const
non-static methods for retrieving options
void Info(const char *location, const char *msgfmt,...)
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:146
void SetExtraOptions(const IOptions &opt)
set extra options (in this case pointer is cloned)
unsigned int MaxIterations() const
max iterations
Definition: Minimizer.h:417
Cut optimisation interface class for genetic algorithm.
Definition: GeneticGenes.h:41
std::vector< double > fResult
double Tolerance() const
absolute tolerance
Definition: Minimizer.h:420
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
void TrimPopulation()
trim the population to the predefined size
static ROOT::Math::IOptions * FindDefault(const char *name)
void SetMaxFunctionCalls(unsigned int maxfcn)
set maximum of function calls
virtual double CovMatrix(unsigned int i, unsigned int j) const
return covariance matrices element for variables ivar,jvar if the variable is fixed the return value ...
The TMVA::Interval Class.
Definition: Interval.h:61
TMVA::IFitterTarget * fFitness
Base definition for genetic algorithm.
GeneticGenes * GetGenes(Int_t index)
gives back the "Genes" of the population with the given index.
void SetParameters(const GeneticMinimizerParameters &params)
void Warning(const char *location, const char *msgfmt,...)
void SetValue(const char *name, double val)
generic methods for retrivieng options
Definition: IOptions.h:44
class implementing generic options for a numerical algorithm Just store the options in a map of strin...
std::vector< TMVA::Interval * > fRanges
virtual const double * X() const
return pointer to X values at the minimum
double Tolerance() const
absolute tolerance
double Double_t
Definition: RtypesCore.h:55
void SetTolerance(double tol)
set the tolerance
Definition: Minimizer.h:454
double func(double *x, double *p)
Definition: stressTF1.cxx:213
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)
set the function to minimize
virtual Bool_t HasConverged(Int_t steps=10, Double_t ratio=0.1)
gives back true if the last "steps" steps have lead to an improvement of the "fitness" of the "indivi...
std::vector< Double_t > & GetFactors()
Definition: GeneticGenes.h:49
virtual ROOT::Math::MinimizerOptions Options() const
retrieve the minimizer options (implement derived class if needed)
Namespace for new Math classes and functions.
Generic interface for defining configuration options of a numerical algorithm.
Definition: IOptions.h:30
void SetStrategy(int stra)
set the strategy
virtual const double * Errors() const
return errors at the minimum
virtual const double * MinGradient() const
return pointer to gradient values at the minimum
void SetPrintLevel(int level)
set print level
Definition: Minimizer.h:445
Interface for a fitter &#39;target&#39;.
Definition: IFitterTarget.h:44
void SetMinimizerAlgorithm(const char *type)
set minimizer algorithm
virtual unsigned int NCalls() const
number of function calls to reach the minimum
void Init()
calls evolution, but if it is not the first time.
const Int_t n
Definition: legend1.C:16
virtual bool SetLimitedVariable(unsigned int, const std::string &, double, double, double, double)
set a new upper/lower limited variable (override if minimizer supports them ) otherwise as default se...
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.