Logo ROOT  
Reference Guide
BasicMinimizer.cxx
Go to the documentation of this file.
1 // @(#)root/mathmore:$Id$
2 // Author: L. Moneta Oct 2012
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class BasicMinimizer
12 
13 #include "Math/BasicMinimizer.h"
14 
15 #include "Math/IFunction.h"
16 
17 #include "Math/IFunctionfwd.h"
18 
19 #include "Math/IParamFunctionfwd.h"
20 
21 #include "Math/FitMethodFunction.h"
22 
24 
25 #include "Math/Error.h"
26 
27 #include "Fit/ParameterSettings.h"
28 
29 #include <cassert>
30 
31 #include <iostream>
32 #include <cmath>
33 #include <algorithm>
34 #include <functional>
35 #include <cctype> // need to use c version of tolower defined here
36 #include <limits>
37 
38 namespace ROOT {
39 
40  namespace Math {
41 
42 
44  fDim(0),
45  fObjFunc(0),
46  fMinVal(0)
47 {
48  fValues.reserve(10);
49  fNames.reserve(10);
50  fSteps.reserve(10);
51 
53  if (niter <=0 ) niter = 1000;
54  SetMaxIterations(niter);
56 }
57 
58 
60  if (fObjFunc) delete fObjFunc;
61 }
62 
63 bool BasicMinimizer::SetVariable(unsigned int ivar, const std::string & name, double val, double step) {
64  // set variable in minimizer - support only free variables
65  // no transformation implemented - so far
66  if (ivar > fValues.size() ) return false;
67  if (ivar == fValues.size() ) {
68  fValues.push_back(val);
69  fNames.push_back(name);
70  fSteps.push_back(step);
71  fVarTypes.push_back(kDefault);
72  }
73  else {
74  fValues[ivar] = val;
75  fNames[ivar] = name;
76  fSteps[ivar] = step;
77  fVarTypes[ivar] = kDefault;
78 
79  // remove bounds if needed
80  std::map<unsigned int, std::pair<double, double> >::iterator iter = fBounds.find(ivar);
81  if ( iter != fBounds.end() ) fBounds.erase (iter);
82 
83  }
84 
85  return true;
86 }
87 
88 bool BasicMinimizer::SetLowerLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower) {
89  // set lower limited variable
90  bool ret = SetVariable(ivar, name, val, step);
91  if (!ret) return false;
92  const double upper = std::numeric_limits<double>::infinity();
93  fBounds[ivar] = std::make_pair( lower, upper);
94  fVarTypes[ivar] = kLowBound;
95  return true;
96 }
97 bool BasicMinimizer::SetUpperLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double upper ) {
98  // set upper limited variable
99  bool ret = SetVariable(ivar, name, val, step);
100  if (!ret) return false;
101  const double lower = -std::numeric_limits<double>::infinity();
102  fBounds[ivar] = std::make_pair( lower, upper);
103  fVarTypes[ivar] = kUpBound;
104  return true;
105 }
106 
107 bool BasicMinimizer::SetLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower, double upper) {
108  // set double bounded variable
109  bool ret = SetVariable(ivar, name, val, step);
110  if (!ret) return false;
111  fBounds[ivar] = std::make_pair( lower, upper);
112  fVarTypes[ivar] = kBounds;
113  return true;
114 }
115 
116 bool BasicMinimizer::SetFixedVariable(unsigned int ivar , const std::string & name , double val ) {
117  /// set fixed variable
118  bool ret = SetVariable(ivar, name, val, 0.);
119  if (!ret) return false;
120  fVarTypes[ivar] = kFix;
121  return true;
122 }
123 
124 
125 bool BasicMinimizer::SetVariableValue(unsigned int ivar, double val) {
126  // set variable value in minimizer
127  // no change to transformation or variable status
128  if (ivar >= fValues.size() ) return false;
129  fValues[ivar] = val;
130  return true;
131 }
132 
133 bool BasicMinimizer::SetVariableValues( const double * x) {
134  // set all variable values in minimizer
135  if (x == 0) return false;
136  std::copy(x,x+fValues.size(), fValues.begin() );
137  return true;
138 }
139 
140 bool BasicMinimizer::SetVariableStepSize(unsigned int ivar, double step) {
141  // set step size
142  if (ivar > fValues.size() ) return false;
143  fSteps[ivar] = step;
144  return true;
145 }
146 
147 bool BasicMinimizer::SetVariableLowerLimit(unsigned int ivar, double lower) {
148  // set variable lower limit
149  double upper = (fBounds.count(ivar)) ? fBounds[ivar].second : std::numeric_limits<double>::infinity();
150  return SetVariableLimits(ivar, lower, upper);
151 }
152 
153 bool BasicMinimizer::SetVariableUpperLimit(unsigned int ivar, double upper) {
154  // set variable upper limit
155  double lower = (fBounds.count(ivar)) ? fBounds[ivar].first : - std::numeric_limits<double>::infinity();
156  return SetVariableLimits(ivar, lower, upper);
157 }
158 
159 bool BasicMinimizer::SetVariableLimits(unsigned int ivar, double lower, double upper) {
160  // set variable limits (remove limits if lower >= upper)
161  if (ivar > fVarTypes.size() ) return false;
162  // if limits do not exists add them or update
163  fBounds[ivar] = std::make_pair( lower, upper);
164  if (lower > upper || (lower == - std::numeric_limits<double>::infinity() &&
165  upper == std::numeric_limits<double>::infinity() ) ) {
166  fBounds.erase(ivar);
167  fVarTypes[ivar] = kDefault;
168  }
169  else if (lower == upper)
170  FixVariable(ivar);
171  else {
172  if (lower == - std::numeric_limits<double>::infinity() )
173  fVarTypes[ivar] = kLowBound;
174  else if (upper == std::numeric_limits<double>::infinity() )
175  fVarTypes[ivar] = kUpBound;
176  else
177  fVarTypes[ivar] = kBounds;
178  }
179  return true;
180 }
181 
182 bool BasicMinimizer::FixVariable(unsigned int ivar) {
183  // fix variable
184  if (ivar >= fVarTypes.size() ) return false;
185  fVarTypes[ivar] = kFix;
186  return true;
187 }
188 
189 bool BasicMinimizer::ReleaseVariable(unsigned int ivar) {
190  // fix variable
191  if (ivar >= fVarTypes.size() ) return false;
192  if (fBounds.count(ivar) == 0) {
193  fVarTypes[ivar] = kDefault;
194  return true;
195  }
196  if (fBounds[ivar].first == - std::numeric_limits<double>::infinity() )
197  fVarTypes[ivar] = kLowBound;
198  else if (fBounds[ivar].second == std::numeric_limits<double>::infinity() )
200  else
201  fVarTypes[ivar] = kBounds;
202 
203  return true;
204 }
205 
206 bool BasicMinimizer::IsFixedVariable(unsigned int ivar) const {
207  if (ivar >= fVarTypes.size() ) return false;
208  return (fVarTypes[ivar] == kFix ) ;
209 }
210 
211 bool BasicMinimizer::GetVariableSettings(unsigned int ivar, ROOT::Fit::ParameterSettings & varObj) const {
212  if (ivar >= fValues.size() ) return false;
213  assert(fValues.size() == fNames.size() && fValues.size() == fVarTypes.size() );
214  varObj.Set(fNames[ivar],fValues[ivar],fSteps[ivar]);
215  std::map< unsigned int , std::pair< double, double> >::const_iterator itr = fBounds.find(ivar);
216  if (itr != fBounds.end() ) {
217  double lower = (itr->second).first;
218  double upper = (itr->second).second;
219  if (fVarTypes[ivar] == kLowBound) varObj.SetLowerLimit( lower );
220  if (fVarTypes[ivar] == kUpBound) varObj.SetUpperLimit( upper );
221  else varObj.SetLimits( lower,upper);
222  }
223  if (fVarTypes[ivar] == kFix ) varObj.Fix();
224  return true;
225 }
226 
227 std::string BasicMinimizer::VariableName(unsigned int ivar) const {
228  if (ivar >= fNames.size() ) return "";
229  return fNames[ivar];
230 }
231 
232 int BasicMinimizer::VariableIndex(const std::string & name) const {
233  std::vector<std::string>::const_iterator itr = std::find( fNames.begin(), fNames.end(), name);
234  if (itr == fNames.end() ) return -1;
235  return itr - fNames.begin();
236 }
237 
238 
239 
241  // set the function to minimizer
242  fObjFunc = func.Clone();
243  fDim = fObjFunc->NDim();
244 }
245 
247  // set the function to minimize
248  fObjFunc = dynamic_cast<const ROOT::Math::IMultiGradFunction *>( func.Clone());
249  assert(fObjFunc != 0);
251 }
252 
253 
254 bool BasicMinimizer::CheckDimension() const {
255  unsigned int npar = fValues.size();
256  if (npar == 0 || npar < fDim ) {
257  MATH_ERROR_MSGVAL("BasicMinimizer::CheckDimension","Wrong number of parameters",npar);
258  return false;
259  }
260  return true;
261 }
262 
264  if (fObjFunc == 0) {
265  MATH_ERROR_MSG("BasicMinimizer::CheckFunction","Function has not been set");
266  return false;
267  }
268  return true;
269 }
270 
271 
272 MinimTransformFunction * BasicMinimizer::CreateTransformation(std::vector<double> & startValues, const ROOT::Math::IMultiGradFunction * func) {
273 
274  bool doTransform = (fBounds.size() > 0);
275  unsigned int ivar = 0;
276  while (!doTransform && ivar < fVarTypes.size() ) {
277  doTransform = (fVarTypes[ivar++] != kDefault );
278  }
279 
280  startValues = std::vector<double>(fValues.begin(), fValues.end() );
281 
283 
284  // in case of transformation wrap objective function in a new transformation function
285  // and transform from external variables to internals one
286  // Transformations are supported only for gradient function
287  const IMultiGradFunction * gradObjFunc = (func) ? func : dynamic_cast<const IMultiGradFunction *>(fObjFunc);
288  doTransform &= (gradObjFunc != 0);
289 
290  if (doTransform) {
291  // minim transform function manages the passed function pointer (gradObjFunc)
292  trFunc = new MinimTransformFunction ( gradObjFunc, fVarTypes, fValues, fBounds );
293  // transform from external to internal
294  trFunc->InvTransformation(&fValues.front(), &startValues[0]);
295  // size can be different since internal parameter can have smaller size
296  // if there are fixed parameters
297  startValues.resize( trFunc->NDim() );
298  // no need to save fObjFunc since trFunc will manage it
299  fObjFunc = trFunc;
300  }
301  else {
302  if (func) fObjFunc = func; // to manege the passed function object
303  }
304 
305 // std::cout << " f has transform " << doTransform << " " << fBounds.size() << " " << startValues.size() << " ndim " << fObjFunc->NDim() << std::endl; std::cout << "InitialValues external : ";
306 // for (int i = 0; i < fValues.size(); ++i) std::cout << fValues[i] << " ";
307 // std::cout << "\n";
308 // std::cout << "InitialValues internal : ";
309 // for (int i = 0; i < startValues.size(); ++i) std::cout << startValues[i] << " ";
310 // std::cout << "\n";
311 
312 
313  return trFunc;
314 }
315 
317 
318  // do nothing
319  return false;
320 }
321 
322 void BasicMinimizer::SetFinalValues(const double * x) {
323  // check to see if a transformation need to be applied
324  const MinimTransformFunction * trFunc = TransformFunction();
325  if (trFunc) {
326  assert(fValues.size() >= trFunc->NTot() );
327  trFunc->Transformation(x, &fValues[0]);
328  }
329  else {
330  // case of no transformation applied
331  assert( fValues.size() >= NDim() );
332  std::copy(x, x + NDim(), fValues.begin() );
333  }
334 }
335 
336 void BasicMinimizer::PrintResult() const {
337  int pr = std::cout.precision(18);
338  std::cout << "FVAL = " << fMinVal << std::endl;
339  std::cout.precision(pr);
340 // std::cout << "Edm = " << fState.Edm() << std::endl;
341  std::cout << "Niterations = " << NIterations() << std::endl;
342  unsigned int ncalls = NCalls();
343  if (ncalls) std::cout << "NCalls = " << ncalls << std::endl;
344  for (unsigned int i = 0; i < fDim; ++i)
345  std::cout << fNames[i] << "\t = " << fValues[i] << std::endl;
346 }
347 
349  return dynamic_cast<const ROOT::Math::IMultiGradFunction *>(fObjFunc);
350 }
351 
352 const MinimTransformFunction * BasicMinimizer::TransformFunction() const {
353  return dynamic_cast<const MinimTransformFunction *>(fObjFunc);
354 }
355 
356 unsigned int BasicMinimizer::NFree() const {
357  // number of free variables
358  unsigned int nfree = fValues.size();
359  for (unsigned int i = 0; i < fVarTypes.size(); ++i)
360  if (fVarTypes[i] == kFix) nfree--;
361  return nfree;
362 }
363 
364 
365  } // end namespace Math
366 
367 } // end namespace ROOT
368 
ROOT::Math::BasicMinimizer::fValues
std::vector< double > fValues
Definition: BasicMinimizer.h:195
first
Definition: first.py:1
ROOT::Math::BasicMinimizer::VariableName
virtual std::string VariableName(unsigned int ivar) const
get name of variables (override if minimizer support storing of variable names)
Definition: BasicMinimizer.cxx:237
IFunction.h
ROOT::Fit::ParameterSettings::SetLowerLimit
void SetLowerLimit(double low)
set a single lower limit
Definition: ParameterSettings.h:189
ROOT::Math::BasicMinimizer::fBounds
std::map< unsigned int, std::pair< double, double > > fBounds
Definition: BasicMinimizer.h:199
ROOT::Math::Minimizer::NIterations
virtual unsigned int NIterations() const
number of iterations to reach the minimum
Definition: Minimizer.h:265
ROOT::Math::BasicMinimizer::CheckObjFunction
bool CheckObjFunction() const
Definition: BasicMinimizer.cxx:273
ROOT::Math::BasicMinimizer::IsFixedVariable
virtual bool IsFixedVariable(unsigned int ivar) const
query if an existing variable is fixed (i.e.
Definition: BasicMinimizer.cxx:216
ROOT::Math::BasicMinimizer::SetFunction
virtual void SetFunction(const ROOT::Math::IMultiGenFunction &func)
set the function to minimize
Definition: BasicMinimizer.cxx:250
ROOT::Math::BasicMinimizer::FixVariable
virtual bool FixVariable(unsigned int ivar)
fix an existing variable
Definition: BasicMinimizer.cxx:192
ROOT::Math::BasicMinimizer::fSteps
std::vector< double > fSteps
Definition: BasicMinimizer.h:196
ROOT::Math::BasicMinimizer::fMinVal
double fMinVal
Definition: BasicMinimizer.h:194
ROOT::Math::BasicMinimizer::NFree
virtual unsigned int NFree() const
number of free variables (real dimension of the problem)
Definition: BasicMinimizer.cxx:366
IFunctionfwd.h
ROOT::Math::BasicMinimizer::GradObjFunction
const ROOT::Math::IMultiGradFunction * GradObjFunction() const
return pointer to used gradient object function (NULL if gradient is not supported)
Definition: BasicMinimizer.cxx:358
ROOT::Math::BasicMinimizer::fNames
std::vector< std::string > fNames
Definition: BasicMinimizer.h:197
ROOT::Math::MinimTransformFunction
MinimTransformFunction class to perform a transformations on the variables to deal with fixed or limi...
Definition: MinimTransformFunction.h:49
ROOT::Math::kFix
@ kFix
Definition: MinimTransformVariable.h:44
ROOT::Math::IBaseFunctionMultiDimTempl::NDim
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
ROOT::Math::BasicMinimizer::ReleaseVariable
virtual bool ReleaseVariable(unsigned int ivar)
release an existing variable
Definition: BasicMinimizer.cxx:199
ROOT::Math::IBaseFunctionMultiDimTempl::Clone
virtual IBaseFunctionMultiDimTempl< T > * Clone() const =0
Clone a function.
x
Double_t x[n]
Definition: legend1.C:17
ROOT::Math::IGradientFunctionMultiDimTempl
Interface (abstract class) for multi-dimensional functions providing a gradient calculation.
Definition: IFunction.h:326
ROOT::Math::kLowBound
@ kLowBound
Definition: MinimTransformVariable.h:46
FitMethodFunction.h
MATH_ERROR_MSG
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:83
ROOT::Fit::ParameterSettings::Fix
void Fix()
fix the parameter
Definition: ParameterSettings.h:151
ROOT::Math::Minimizer::NCalls
virtual unsigned int NCalls() const
number of function calls to reach the minimum
Definition: Minimizer.h:262
ROOT::Math::kDefault
@ kDefault
Definition: MinimTransformVariable.h:43
ROOT::Math::BasicMinimizer::SetUpperLimitedVariable
virtual bool SetUpperLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double upper)
set upper limit variable (override if minimizer supports them )
Definition: BasicMinimizer.cxx:107
ROOT::Math::BasicMinimizer::SetVariableStepSize
virtual bool SetVariableStepSize(unsigned int ivar, double step)
set the step size of an already existing variable
Definition: BasicMinimizer.cxx:150
ROOT::Math::BasicMinimizer::CheckDimension
bool CheckDimension() const
Definition: BasicMinimizer.cxx:264
ROOT::Math::BasicMinimizer::SetVariable
virtual bool SetVariable(unsigned int ivar, const std::string &name, double val, double step)
set free variable
Definition: BasicMinimizer.cxx:73
MinimTransformFunction.h
ROOT::Math::BasicMinimizer::BasicMinimizer
BasicMinimizer()
Default constructor.
Definition: BasicMinimizer.cxx:53
ROOT::Math::BasicMinimizer::fDim
unsigned int fDim
Definition: BasicMinimizer.h:190
ROOT::Math::BasicMinimizer::GetVariableSettings
virtual bool GetVariableSettings(unsigned int ivar, ROOT::Fit::ParameterSettings &varObj) const
get variable settings in a variable object (like ROOT::Fit::ParamsSettings)
Definition: BasicMinimizer.cxx:221
Error.h
ROOT::Math::BasicMinimizer::SetFinalValues
void SetFinalValues(const double *x)
Definition: BasicMinimizer.cxx:332
ROOT::Math::MinimTransformFunction::InvTransformation
void InvTransformation(const double *xext, double *xint) const
inverse transformation (external -> internal)
Definition: MinimTransformFunction.cxx:97
ROOT::Math::BasicMinimizer::SetVariableUpperLimit
virtual bool SetVariableUpperLimit(unsigned int ivar, double upper)
set the upper-limit of an already existing variable
Definition: BasicMinimizer.cxx:163
ROOT::Fit::ParameterSettings::SetUpperLimit
void SetUpperLimit(double up)
set a single upper limit
Definition: ParameterSettings.h:182
MATH_ERROR_MSGVAL
#define MATH_ERROR_MSGVAL(loc, txt, x)
Definition: Error.h:109
ROOT::Fit::ParameterSettings::SetLimits
void SetLimits(double low, double up)
set a double side limit, if low == up the parameter is fixed if low > up the limits are removed The c...
Definition: ParameterSettings.h:162
ROOT::Fit::ParameterSettings::Set
void Set(const std::string &name, double value, double step)
set value and name (unlimited parameter)
Definition: ParameterSettings.h:93
ROOT::Math::BasicMinimizer::fObjFunc
const ROOT::Math::IMultiGenFunction * fObjFunc
Definition: BasicMinimizer.h:192
IParamFunctionfwd.h
ROOT::Math::BasicMinimizer::SetVariableValues
virtual bool SetVariableValues(const double *x)
set the values of all existing variables (array must be dimensioned to the size of existing parameter...
Definition: BasicMinimizer.cxx:143
ROOT::Fit::ParameterSettings
Class, describing value, limits and step size of the parameters Provides functionality also to set/re...
Definition: ParameterSettings.h:46
ROOT::Math::BasicMinimizer::SetVariableLowerLimit
virtual bool SetVariableLowerLimit(unsigned int ivar, double lower)
set the lower-limit of an already existing variable
Definition: BasicMinimizer.cxx:157
ROOT::Math::BasicMinimizer::SetVariableLimits
virtual bool SetVariableLimits(unsigned int ivar, double lower, double upper)
set the limits of an already existing variable
Definition: BasicMinimizer.cxx:169
ROOT::Math::BasicMinimizer::fVarTypes
std::vector< ROOT::Math::EMinimVariableType > fVarTypes
Definition: BasicMinimizer.h:198
ROOT::Math::BasicMinimizer::SetFixedVariable
virtual bool SetFixedVariable(unsigned int, const std::string &, double)
set fixed variable (override if minimizer supports them )
Definition: BasicMinimizer.cxx:126
ROOT::Math::MinimizerOptions::DefaultMaxIterations
static int DefaultMaxIterations()
Definition: MinimizerOptions.cxx:97
BasicMinimizer.h
ROOT::Math::kBounds
@ kBounds
Definition: MinimTransformVariable.h:45
ROOT::Math::BasicMinimizer::NDim
virtual unsigned int NDim() const
number of dimensions
Definition: BasicMinimizer.h:152
ROOT::Math::MinimTransformFunction::NDim
unsigned int NDim() const
Retrieve the dimension of the function.
Definition: MinimTransformFunction.h:82
ROOT::Math::MinimizerOptions::DefaultPrintLevel
static int DefaultPrintLevel()
Definition: MinimizerOptions.cxx:99
name
char name[80]
Definition: TGX11.cxx:110
ROOT::Math::BasicMinimizer::SetLimitedVariable
virtual bool SetLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double, double)
set upper/lower limited variable (override if minimizer supports them )
Definition: BasicMinimizer.cxx:117
ROOT::Math::BasicMinimizer::CreateTransformation
MinimTransformFunction * CreateTransformation(std::vector< double > &startValues, const ROOT::Math::IMultiGradFunction *func=0)
Definition: BasicMinimizer.cxx:282
ROOT::Math::BasicMinimizer::SetVariableValue
virtual bool SetVariableValue(unsigned int ivar, double val)
set the value of an existing variable
Definition: BasicMinimizer.cxx:135
ParameterSettings.h
ROOT::Math::kUpBound
@ kUpBound
Definition: MinimTransformVariable.h:47
ROOT::Math::IBaseFunctionMultiDimTempl
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
ROOT::Math::BasicMinimizer::PrintResult
void PrintResult() const
print result of minimization
Definition: BasicMinimizer.cxx:346
TGeant4Unit::second
static constexpr double second
Definition: TGeant4SystemOfUnits.h:157
ROOT
VSD Structures.
Definition: StringConv.hxx:21
ROOT::Math::BasicMinimizer::Minimize
virtual bool Minimize()
method to perform the minimization
Definition: BasicMinimizer.cxx:326
ROOT::Math::BasicMinimizer::TransformFunction
const ROOT::Math::MinimTransformFunction * TransformFunction() const
return transformation function (NULL if not having a transformation)
Definition: BasicMinimizer.cxx:362
Math
ROOT::Math::BasicMinimizer::SetLowerLimitedVariable
virtual bool SetLowerLimitedVariable(unsigned int ivar, const std::string &name, double val, double step, double lower)
set lower limit variable (override if minimizer supports them )
Definition: BasicMinimizer.cxx:98
ROOT::Math::BasicMinimizer::~BasicMinimizer
virtual ~BasicMinimizer()
Destructor.
Definition: BasicMinimizer.cxx:69
ROOT::Math::BasicMinimizer::VariableIndex
virtual int VariableIndex(const std::string &name) const
get index of variable given a variable given a name return -1 if variable is not found
Definition: BasicMinimizer.cxx:242