![]() |
|
|||
File indexing completed on 2025-09-17 09:14:02
0001 // @(#)root/mathcore:$Id$ 0002 // Author: L. Moneta Fri Sep 22 15:06:47 2006 0003 0004 /********************************************************************** 0005 * * 0006 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * 0007 * * 0008 * * 0009 **********************************************************************/ 0010 0011 // Header file for class Minimizer 0012 0013 #ifndef ROOT_Math_Minimizer 0014 #define ROOT_Math_Minimizer 0015 0016 #include "Math/IFunction.h" 0017 #include "Math/MinimizerOptions.h" 0018 0019 #include <ROOT/RSpan.hxx> 0020 0021 #include <string> 0022 #include <limits> 0023 #include <cmath> 0024 #include <vector> 0025 #include <functional> 0026 0027 0028 0029 namespace ROOT { 0030 0031 namespace Fit { 0032 class ParameterSettings; 0033 } 0034 0035 0036 namespace Math { 0037 0038 /** 0039 @defgroup MultiMin Multi-dimensional Minimization 0040 @ingroup NumAlgo 0041 0042 Classes implementing algorithms for multi-dimensional minimization 0043 */ 0044 0045 0046 0047 //_______________________________________________________________________________ 0048 /** 0049 Abstract Minimizer class, defining the interface for the various minimizer 0050 (like Minuit2, Minuit, GSL, etc..) in ROOT. 0051 Plug-in's exist in ROOT to be able to instantiate the derived classes without linking the library 0052 using the static function ROOT::Math::Factory::CreateMinimizer. 0053 0054 Here is the list of all possible minimizers and their respective methods (algorithms) that can be instantiated: 0055 The name shown below can be used to create them. More documentation can be found in the respective class 0056 0057 - Minuit (class TMinuitMinimizer) 0058 - Migrad (default) 0059 - MigradImproved (Migrad with adding a method to improve minimization when ends-up in a local minimum, see par. 6.3 of [Minuit tutorial on Function Minimization](https://seal.web.cern.ch/documents/minuit/mntutorial.pdf)) 0060 - Simplex 0061 - Minimize (a combination of Simplex + Migrad) 0062 - Minimize 0063 - Scan 0064 - Seek 0065 0066 - Minuit2 (class ROOT::Minuit2::Minuit2Minimizer) 0067 - Migrad (default) 0068 - Simplex 0069 - Minimize 0070 - Fumili (Fumili2) 0071 - Scan 0072 0073 - Fumili (class TFumiliMinimizer) 0074 0075 - Linear (see TLinearFitter and TLinearMinimizer) minimizer (fitter) working only for linear functions 0076 0077 - GSLMultiMin (class ROOT::Math::GSLMinimizer) available when ROOT is built with `mathmore` support 0078 - BFGS2 (Default) 0079 - BFGS 0080 - ConjugateFR 0081 - ConjugatePR 0082 - SteepestDescent 0083 0084 - GSLMultiFit (class ROOT::Math::GSLNLMinimizer) available when ROOT is built `mathmore` support 0085 0086 - GSLSimAn (class ROOT::Math::GSLSimAnMinimizer) available when ROOT is built with `mathmore` support 0087 0088 - Genetic (class ROOT::Math::GeneticMinimizer) 0089 0090 - RMinimizer (class ROOT::Math::RMinimizer) available when ROOT is built with `r` support 0091 - BFGS (default) 0092 - L-BFGS-S 0093 - Nelder-Mead 0094 - CG 0095 - and more methods, see the Details in the documentation of the function `optimix` of the [optmix R package](https://cran.r-project.org/web/packages/optimx/optimx.pdf) 0096 0097 0098 The Minimizer class provides the interface to perform the minimization including 0099 0100 0101 In addition to provide the API for function minimization (via ROOT::Math::Minimizer::Minimize) the Minimizer class provides: 0102 - the interface for setting the function to be minimized. The objective function passed to the Minimizer must implement the multi-dimensional generic interface 0103 ROOT::Math::IBaseFunctionMultiDim. If the function provides gradient calculation (e.g. implementing the ROOT::Math::IGradientFunctionMultiDim interface) 0104 the gradient will be used by the Minimizer class, when needed. There are convenient classes for the users to wrap their own functions in this required interface for minimization. 0105 These are the `ROOT::Math::Functor` class and the `ROOT::Math::GradFunctor` class for wrapping functions providing both evaluation and gradient. Some methods, like Fumili, Fumili2 and GSLMultiFit are 0106 specialized method for least-square and also likelihood minimizations. They require then that the given function implements in addition 0107 the `ROOT::Math::FitMethodFunction` interface. 0108 - The interface for setting the initial values for the function variables (which are the parameters in 0109 of the model function in case of solving for fitting) and specifying their limits. 0110 - The interface to set and retrieve basic minimization parameters. These parameter are controlled by the class `ROOT::Math::MinimizerOptions`. 0111 When no parameters are specified the default ones are used. Specific Minimizer options can also be passed via the `MinimizerOptions` class. 0112 For the list of the available option parameter one must look at the documentation of the corresponding derived class. 0113 - The interface to retrieve the result of minimization ( minimum X values, function value, gradient, error on the minimum, etc...) 0114 - The interface to perform a Scan, Hesse or a Contour plot (for the minimizers that support this, i.e. Minuit and Minuit2) 0115 0116 An example on how to use this interface is the tutorial NumericalMinimization.C in the tutorials/math directory. 0117 0118 @ingroup MultiMin 0119 */ 0120 0121 class Minimizer { 0122 0123 public: 0124 0125 /// Default constructor. 0126 Minimizer () {} 0127 0128 /// Destructor (no operations). 0129 virtual ~Minimizer () {} 0130 0131 // usually copying is non trivial, so we delete this 0132 Minimizer(Minimizer const&) = delete; 0133 Minimizer &operator=(Minimizer const&) = delete; 0134 Minimizer(Minimizer &&) = delete; 0135 Minimizer &operator=(Minimizer &&) = delete; 0136 0137 /// Reset for consecutive minimization - implement if needed. 0138 virtual void Clear() {} 0139 0140 /// Set the function to minimize. 0141 virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) = 0; 0142 0143 /// Set the function implementing Hessian computation (re-implemented by Minimizer using it). 0144 virtual void SetHessianFunction(std::function<bool(std::span<const double>, double *)> ) {} 0145 0146 /// Add variables. @return number of variables successfully added 0147 template<class VariableIterator> 0148 int SetVariables(const VariableIterator & begin, const VariableIterator & end) { 0149 unsigned int ivar = 0; 0150 for ( VariableIterator vitr = begin; vitr != end; ++vitr) { 0151 bool iret = false; 0152 if (vitr->IsFixed() ) 0153 iret = SetFixedVariable(ivar, vitr->Name(), vitr->Value() ); 0154 else if (vitr->IsDoubleBound() ) 0155 iret = SetLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit(), vitr->UpperLimit() ); 0156 else if (vitr->HasLowerLimit() ) 0157 iret = SetLowerLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit() ); 0158 else if (vitr->HasUpperLimit() ) 0159 iret = SetUpperLimitedVariable(ivar, vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->UpperLimit() ); 0160 else 0161 iret = SetVariable( ivar, vitr->Name(), vitr->Value(), vitr->StepSize() ); 0162 0163 if (iret) ivar++; 0164 0165 // an error message should be eventually be reported in the virtual single SetVariable methods 0166 } 0167 return ivar; 0168 } 0169 /// Set a new free variable. 0170 virtual bool SetVariable(unsigned int ivar, const std::string & name, double val, double step) = 0; 0171 /// Set initial second derivatives. 0172 virtual bool SetCovarianceDiag(std::span<const double> d2, unsigned int n); 0173 /// Set initial covariance matrix. 0174 virtual bool SetCovariance(std::span<const double> cov, unsigned int nrow); 0175 0176 /// Set a new lower limit variable (override if minimizer supports them), leave upper bound unlimited. 0177 /// @see Minimizer::SetLimitedVariable 0178 /// @param ivar the index of this variable in the array 0179 /// @param name the variable name 0180 /// @param val the value 0181 /// @param step the step size 0182 /// @param lower the lower bound 0183 virtual bool SetLowerLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double lower) { 0184 return SetLimitedVariable(ivar, name, val, step, lower, std::numeric_limits<double>::infinity()); 0185 } 0186 /// Set a new upper limit variable (override if minimizer supports them), leave lower bound unlimited. 0187 /// @see Minimizer::SetLimitedVariable 0188 /// @param ivar the index of this variable in the array 0189 /// @param name the variable name 0190 /// @param val the value 0191 /// @param step the step size 0192 /// @param upper the upper bound 0193 virtual bool SetUpperLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, double upper) { 0194 return SetLimitedVariable(ivar, name, val, step, - std::numeric_limits<double>::infinity(), upper); 0195 } 0196 virtual bool SetLimitedVariable(unsigned int ivar, const std::string & name, double val, double step, 0197 double lower, double upper); 0198 virtual bool SetFixedVariable(unsigned int ivar, const std::string & name, double val); 0199 virtual bool SetVariableValue(unsigned int ivar, double value); 0200 /// Set the values of all existing variables (array must be dimensioned to the size of the existing parameters). 0201 virtual bool SetVariableValues(const double * x) { 0202 bool ret = true; 0203 unsigned int i = 0; 0204 while ( i <= NDim() && ret) { 0205 ret &= SetVariableValue(i,x[i] ); i++; 0206 } 0207 return ret; 0208 } 0209 virtual bool SetVariableStepSize(unsigned int ivar, double value); 0210 virtual bool SetVariableLowerLimit(unsigned int ivar, double lower); 0211 virtual bool SetVariableUpperLimit(unsigned int ivar, double upper); 0212 /// Set the limits of an already existing variable. 0213 virtual bool SetVariableLimits(unsigned int ivar, double lower, double upper) { 0214 return SetVariableLowerLimit(ivar,lower) && SetVariableUpperLimit(ivar,upper); 0215 } 0216 virtual bool FixVariable(unsigned int ivar); 0217 virtual bool ReleaseVariable(unsigned int ivar); 0218 virtual bool IsFixedVariable(unsigned int ivar) const; 0219 virtual bool GetVariableSettings(unsigned int ivar, ROOT::Fit::ParameterSettings & pars) const; 0220 0221 /// Set the initial range of an existing variable. 0222 virtual bool SetVariableInitialRange(unsigned int /* ivar */, double /* mininitial */, double /* maxinitial */) { 0223 return false; 0224 } 0225 0226 /// Method to perform the minimization. 0227 virtual bool Minimize() = 0; 0228 0229 /// @return minimum function value 0230 virtual double MinValue() const = 0; 0231 0232 /// @return pointer to X values at the minimum 0233 virtual const double * X() const = 0; 0234 0235 /// @return expected distance reached from the minimum (re-implement if minimizer provides it 0236 virtual double Edm() const { return -1; } 0237 0238 /// @return pointer to gradient values at the minimum 0239 virtual const double * MinGradient() const { return nullptr; } 0240 0241 /// Number of function calls to reach the minimum. 0242 virtual unsigned int NCalls() const { return 0; } 0243 0244 /// Number of iterations to reach the minimum. 0245 virtual unsigned int NIterations() const { return NCalls(); } 0246 0247 /// this is <= Function().NDim() which is the total 0248 /// number of variables (free+ constrained ones) 0249 virtual unsigned int NDim() const = 0; 0250 0251 /// Number of free variables (real dimension of the problem). 0252 /// this is <= Function().NDim() which is the total 0253 /// (re-implement if minimizer supports bounded parameters) 0254 virtual unsigned int NFree() const { return NDim(); } 0255 0256 /// Minimizer provides error and error matrix. 0257 virtual bool ProvidesError() const { return false; } 0258 0259 /// @return errors at the minimum 0260 virtual const double * Errors() const { return nullptr; } 0261 0262 virtual double CovMatrix(unsigned int ivar , unsigned int jvar ) const; 0263 virtual bool GetCovMatrix(double * covMat) const; 0264 virtual bool GetHessianMatrix(double * hMat) const; 0265 0266 0267 /// @return status of covariance matrix 0268 /// using Minuit convention {0 not calculated 1 approximated 2 made pos def , 3 accurate} 0269 /// Minimizer who implements covariance matrix calculation will re-implement the method 0270 virtual int CovMatrixStatus() const { 0271 return 0; 0272 } 0273 0274 /** 0275 * @return correlation coefficient between variable i and j. 0276 * If the variable is fixed or const the return value is zero 0277 */ 0278 virtual double Correlation(unsigned int i, unsigned int j ) const { 0279 double tmp = CovMatrix(i,i) * CovMatrix(j,j); 0280 return ( tmp < 0) ? 0 : CovMatrix(i,j) / std::sqrt( tmp ); 0281 } 0282 0283 virtual double GlobalCC(unsigned int ivar) const; 0284 0285 virtual bool GetMinosError(unsigned int ivar , double & errLow, double & errUp, int option = 0); 0286 virtual bool Hesse(); 0287 virtual bool Scan(unsigned int ivar , unsigned int & nstep , double * x , double * y , 0288 double xmin = 0, double xmax = 0); 0289 virtual bool Contour(unsigned int ivar , unsigned int jvar, unsigned int & npoints, 0290 double * xi , double * xj ); 0291 0292 /// @return reference to the objective function 0293 /// virtual const ROOT::Math::IGenFunction & Function() const = 0; 0294 0295 /// Print the result according to set level (implemented for TMinuit for maintaining Minuit-style printing). 0296 virtual void PrintResults() {} 0297 0298 virtual std::string VariableName(unsigned int ivar) const; 0299 0300 virtual int VariableIndex(const std::string & name) const; 0301 0302 /* minimizer configuration parameters */ 0303 0304 /// Set print level. 0305 int PrintLevel() const { return fOptions.PrintLevel(); } 0306 0307 /// Max number of function calls. 0308 unsigned int MaxFunctionCalls() const { return fOptions.MaxFunctionCalls(); } 0309 0310 /// Max iterations. 0311 unsigned int MaxIterations() const { return fOptions.MaxIterations(); } 0312 0313 /// Absolute tolerance. 0314 double Tolerance() const { return fOptions.Tolerance(); } 0315 0316 /// Precision of minimizer in the evaluation of the objective function. 0317 /// (a value <=0 corresponds to the let the minimizer choose its default one) 0318 double Precision() const { return fOptions.Precision(); } 0319 0320 /// Strategy. 0321 int Strategy() const { return fOptions.Strategy(); } 0322 0323 /// Status code of minimizer. 0324 int Status() const { return fStatus; } 0325 0326 /// Status code of Minos (to be re-implemented by the minimizers supporting Minos). 0327 virtual int MinosStatus() const { return -1; } 0328 0329 /// @return the statistical scale used for calculate the error 0330 /// is typically 1 for Chi2 and 0.5 for likelihood minimization 0331 double ErrorDef() const { return fOptions.ErrorDef(); } 0332 0333 /// @return true if Minimizer has performed a detailed error validation (e.g. run Hesse for Minuit) 0334 bool IsValidError() const { return fValidError; } 0335 0336 /// Retrieve the minimizer options (implement derived class if needed). 0337 virtual MinimizerOptions Options() const { 0338 return fOptions; 0339 } 0340 0341 /// Set print level. 0342 void SetPrintLevel(int level) { fOptions.SetPrintLevel(level); } 0343 0344 /// Set maximum of function calls. 0345 void SetMaxFunctionCalls(unsigned int maxfcn) { if (maxfcn > 0) fOptions.SetMaxFunctionCalls(maxfcn); } 0346 0347 /// Set maximum iterations (one iteration can have many function calls). 0348 void SetMaxIterations(unsigned int maxiter) { if (maxiter > 0) fOptions.SetMaxIterations(maxiter); } 0349 0350 /// Set the tolerance. 0351 void SetTolerance(double tol) { fOptions.SetTolerance(tol); } 0352 0353 /// Set in the minimizer the objective function evaluation precision. 0354 /// (a value <=0 means the minimizer will choose its optimal value automatically, i.e. default case) 0355 void SetPrecision(double prec) { fOptions.SetPrecision(prec); } 0356 0357 /// Set the strategy. 0358 void SetStrategy(int strategyLevel) { fOptions.SetStrategy(strategyLevel); } 0359 0360 /// Set scale for calculating the errors. 0361 void SetErrorDef(double up) { fOptions.SetErrorDef(up); } 0362 0363 /// Flag to check if minimizer needs to perform accurate error analysis (e.g. run Hesse for Minuit). 0364 void SetValidError(bool on) { fValidError = on; } 0365 0366 /// Set all options in one go. 0367 void SetOptions(const MinimizerOptions & opt) { 0368 fOptions = opt; 0369 } 0370 0371 /// Set only the extra options. 0372 void SetExtraOptions(const IOptions & extraOptions) { fOptions.SetExtraOptions(extraOptions); } 0373 0374 /// Reset the default options (defined in MinimizerOptions). 0375 void SetDefaultOptions() { 0376 fOptions.ResetToDefaultOptions(); 0377 } 0378 0379 protected: 0380 0381 // keep protected to be accessible by the derived classes 0382 0383 bool fValidError = false; ///< flag to control if errors have been validated (Hesse has been run in case of Minuit) 0384 MinimizerOptions fOptions; ///< minimizer options 0385 int fStatus = -1; ///< status of minimizer 0386 }; 0387 0388 } // end namespace Math 0389 0390 } // end namespace ROOT 0391 0392 0393 #endif /* ROOT_Math_Minimizer */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
![]() ![]() |