Minimizer.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: Minimizer.h 36905 2010-11-24 15:44:34Z moneta $
00002 // Author: L. Moneta Fri Sep 22 15:06:47 2006
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Header file for class Minimizer
00012 
00013 #ifndef ROOT_Math_Minimizer
00014 #define ROOT_Math_Minimizer
00015 
00016 #ifndef ROOT_Math_IFunction
00017 #include "Math/IFunction.h"
00018 #endif
00019 
00020 #ifndef ROOT_Math_MinimizerOptions
00021 #include "Math/MinimizerOptions.h"
00022 #endif
00023 
00024 
00025 #include <vector> 
00026 #include <string> 
00027 
00028 #include <limits> 
00029 #include <cmath>
00030 
00031 
00032 namespace ROOT { 
00033    
00034 
00035    namespace Math { 
00036 
00037 /**
00038    @defgroup MultiMin Multi-dimensional Minimization
00039    @ingroup NumAlgo
00040 
00041    Classes implementing algorithms for multi-dimensional minimization 
00042  */
00043 
00044 
00045 
00046 //_______________________________________________________________________________
00047 /** 
00048    Abstract Minimizer class, defining  the interface for the various minimizer
00049    (like Minuit2, Minuit, GSL, etc..) 
00050    Plug-in's exist in ROOT to be able to instantiate the derived classes like 
00051    ROOT::Math::GSLMinimizer or ROOT::Math::Minuit2Minimizer via the 
00052    plug-in manager.
00053 
00054    Provides interface for setting the function to be minimized. 
00055    The function must  implemente the multi-dimensional generic interface
00056    ROOT::Math::IBaseFunctionMultiDim. 
00057    If the function provides gradient calculation 
00058    (implements the ROOT::Math::IGradientFunctionMultiDim interface) this will be 
00059    used by the Minimizer. 
00060 
00061    It Defines also interface for setting the initial values for the function variables (which are the parameters in 
00062    of the model function in case of solving for fitting) and especifying their limits. 
00063 
00064    It defines the interface to set and retrieve basic minimization parameters 
00065    (for specific Minimizer parameters one must use the derived classes). 
00066 
00067    Then it defines the interface to retrieve the result of minimization ( minimum X values, function value, 
00068    gradient, error on the mimnimum, etc...)
00069 
00070    @ingroup MultiMin
00071 */
00072  
00073 class Minimizer {
00074 
00075 public: 
00076 
00077    /** 
00078       Default constructor
00079    */ 
00080    Minimizer () : 
00081       fValidError(false),
00082       fDebug(MinimizerOptions::DefaultPrintLevel()), 
00083       fStrategy(MinimizerOptions::DefaultStrategy()), 
00084       fStatus(-1),
00085       fMaxCalls(MinimizerOptions::DefaultMaxFunctionCalls()), 
00086       fMaxIter(MinimizerOptions::DefaultMaxIterations()), 
00087       fTol(MinimizerOptions::DefaultTolerance()), 
00088       fPrec(MinimizerOptions::DefaultPrecision()), 
00089       fUp(MinimizerOptions::DefaultErrorDef() )
00090    {} 
00091 
00092    /** 
00093       Destructor (no operations)
00094    */ 
00095    virtual ~Minimizer ()  {}  
00096 
00097 
00098 
00099 
00100 private:
00101    // usually copying is non trivial, so we make this unaccessible
00102 
00103    /** 
00104       Copy constructor
00105    */ 
00106    Minimizer(const Minimizer &) {} 
00107 
00108    /** 
00109       Assignment operator
00110    */ 
00111    Minimizer & operator = (const Minimizer & rhs)  {
00112       if (this == &rhs) return *this;  // time saving self-test
00113       return *this;
00114    }
00115 
00116 public: 
00117    
00118    /// reset for consecutive minimizations - implement if needed 
00119    virtual void Clear() {}
00120 
00121    /// set the function to minimize
00122    virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) = 0; 
00123 
00124    /// set a function to minimize using gradient 
00125    virtual void SetFunction(const ROOT::Math::IMultiGradFunction & func) 
00126    {
00127       SetFunction(static_cast<const ::ROOT::Math::IMultiGenFunction &> (func));
00128    }
00129    
00130 
00131    /// add variables  . Return number of variables succesfully added
00132    template<class VariableIterator> 
00133    int SetVariables(const VariableIterator & begin, const VariableIterator & end) { 
00134       unsigned int ivar = 0; 
00135       for ( VariableIterator vitr = begin; vitr != end; ++vitr) { 
00136          bool iret = false; 
00137          if (vitr->IsFixed() )
00138             iret = SetFixedVariable(ivar,  vitr->Name(), vitr->Value() ); 
00139          else if (vitr->IsDoubleBound() )
00140             iret = SetLimitedVariable(ivar,  vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit(), vitr->UpperLimit() );
00141          else if (vitr->HasLowerLimit() )
00142             iret = SetLowerLimitedVariable(ivar,  vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->LowerLimit() );
00143          else if (vitr->HasUpperLimit() )
00144             iret = SetUpperLimitedVariable(ivar,  vitr->Name(), vitr->Value(), vitr->StepSize(), vitr->UpperLimit() );
00145          else 
00146             iret = SetVariable( ivar, vitr->Name(), vitr->Value(), vitr->StepSize() ); 
00147 
00148          if (iret) ivar++; 
00149 
00150          // an error message should be eventually be reported in the virtual single SetVariable methods
00151       }
00152       return ivar; 
00153    }
00154    /// set free variable 
00155    virtual bool SetVariable(unsigned int ivar, const std::string & name, double val, double step) = 0; 
00156    /// set lower limit variable  (override if minimizer supports them )
00157    virtual bool SetLowerLimitedVariable(unsigned int  ivar , const std::string & name , double val , double step , double lower ) { 
00158       return SetLimitedVariable(ivar, name, val, step, lower, std::numeric_limits<double>::infinity() );  
00159    } 
00160    /// set upper limit variable (override if minimizer supports them )
00161    virtual bool SetUpperLimitedVariable(unsigned int ivar , const std::string & name , double val , double step , double upper ) { 
00162       return SetLimitedVariable(ivar, name, val, step, - std::numeric_limits<double>::infinity(), upper );  
00163    } 
00164    /// set upper/lower limited variable (override if minimizer supports them )
00165    virtual bool SetLimitedVariable(unsigned int /* ivar */ , const std::string & /* name */ , double /*val */ , double /* step  */, double /* lower */, double /* upper */) { 
00166       return false;  
00167    }
00168    /// set fixed variable (override if minimizer supports them )
00169    virtual bool SetFixedVariable(unsigned int /* ivar */ , const std::string & /* name */ , double /* val */ ) { 
00170       return false; 
00171    }
00172    /// set the value of an existing variable 
00173    virtual bool SetVariableValue(unsigned int , double ) { return false;  }
00174    /// set the values of all existing variables (array must be dimensioned to the size of the existing parameters)
00175    virtual bool SetVariableValues(const double * x) { 
00176       bool ret = true; 
00177       unsigned int i = 0;
00178       while ( i <= NDim() && ret) { 
00179          SetVariableValue(i,x[i] ); i++; 
00180       }
00181       return ret; 
00182    }
00183 
00184    /// method to perform the minimization
00185    virtual  bool Minimize() = 0; 
00186 
00187    /// return minimum function value
00188    virtual double MinValue() const = 0; 
00189 
00190    /// return expected distance reached from the minimum
00191    virtual double Edm() const = 0; 
00192 
00193    /// return  pointer to X values at the minimum 
00194    virtual const double *  X() const = 0; 
00195 
00196    /// return pointer to gradient values at the minimum 
00197    virtual const double *  MinGradient() const = 0;  
00198 
00199    /// number of function calls to reach the minimum 
00200    virtual unsigned int NCalls() const = 0;    
00201 
00202    /// this is <= Function().NDim() which is the total 
00203    /// number of variables (free+ constrained ones) 
00204    virtual unsigned int NDim() const = 0;  
00205 
00206    /// number of free variables (real dimension of the problem) 
00207    /// this is <= Function().NDim() which is the total 
00208    virtual unsigned int NFree() const = 0;  
00209 
00210    /// minimizer provides error and error matrix
00211    virtual bool ProvidesError() const = 0; 
00212 
00213    /// return errors at the minimum 
00214    virtual const double * Errors() const = 0;
00215 
00216    /** return covariance matrices elements 
00217        if the variable is fixed the matrix is zero
00218        The ordering of the variables is the same as in errors
00219    */ 
00220    virtual double CovMatrix(unsigned int i, unsigned int j) const = 0;  
00221 
00222    ///return status of covariance matrix 
00223    /// using Minuit convention {0 not calculated 1 approximated 2 made pos def , 3 accurate}
00224    /// Minimizer who implements covariance matrix calculation will re-implement the method
00225    virtual int CovMatrixStatus() const {  return 0; }
00226 
00227    /**
00228       return correlation coefficient between variable i and j.
00229       If the variable is fixed or const the return value is zero
00230     */
00231    virtual double Correlation(unsigned int i, unsigned int j ) const { 
00232       double tmp = CovMatrix(i,i) * CovMatrix(j,j);
00233       return ( tmp < 0) ? 0 : CovMatrix(i,j) / std::sqrt( tmp );  
00234    }
00235 
00236    /**
00237       return global correlation coefficient for variable i
00238       This is a number between zero and one which gives 
00239       the correlation between the i-th parameter  and that linear combination of all 
00240       other parameters which is most strongly correlated with i.
00241       Minimizer must overload method if implemented 
00242     */
00243    virtual double GlobalCC(unsigned int ) const { return -1; }
00244 
00245    /**
00246       minos error for variable i, return false if Minos failed or not supported 
00247       and the lower and upper errors are returned in errLow and errUp
00248       An extra flag  specifies if only the lower (runopt=-1) or the upper (runopt=+1) error calculation is run
00249       (This feature isnot yet implemented)
00250    */
00251    virtual bool GetMinosError(unsigned int /* i */, double & errLow, double & errUp, int  = 0) { 
00252       errLow = 0; errUp = 0; 
00253       return false; 
00254    }  
00255 
00256    /**
00257       perform a full calculation of the Hessian matrix for error calculation
00258     */
00259    virtual bool Hesse() { return false; }
00260 
00261    /**
00262       scan function minimum for variable i. Variable and function must be set before using Scan 
00263       Return false if an error or if minimizer does not support this functionality
00264     */
00265    virtual bool Scan(unsigned int /* i */, unsigned int & /* nstep */, double * /* x */, double * /* y */, 
00266                      double /*xmin */ = 0, double /*xmax*/ = 0) {
00267       return false; 
00268    }
00269 
00270    /**
00271       find the contour points (xi,xj) of the function for parameter i and j around the minimum
00272       The contour will be find for value of the function = Min + ErrorUp();
00273     */
00274    virtual bool Contour(unsigned int /* i */, unsigned int /* j */, unsigned int &/* np */, 
00275                         double * /* xi */, double * /* xj */) { 
00276       return false; 
00277    }
00278 
00279    /// return reference to the objective function
00280    ///virtual const ROOT::Math::IGenFunction & Function() const = 0; 
00281 
00282    /// print the result according to set level (implemented for TMinuit for mantaining Minuit-style printing)
00283    virtual void PrintResults() {}
00284 
00285    /// get name of variables (override if minimizer support storing of variable names)
00286    /// return an empty string if variable is not found
00287    virtual std::string VariableName(unsigned int ) const { return std::string();}  // return empty string 
00288 
00289    /// get index of variable given a variable given a name
00290    /// return -1 if variable is not found
00291    virtual int VariableIndex(const std::string &) const { return -1; }
00292       
00293    /** minimizer configuration parameters **/
00294 
00295    /// set print level
00296    int PrintLevel() const { return fDebug; }
00297 
00298    ///  max number of function calls
00299    unsigned int MaxFunctionCalls() const { return fMaxCalls; } 
00300 
00301    /// max iterations
00302    unsigned int MaxIterations() const { return fMaxIter; } 
00303 
00304    /// absolute tolerance 
00305    double Tolerance() const { return  fTol; }
00306 
00307    /// precision of minimizer in the evaluation of the objective function
00308    /// ( a value <=0 corresponds to the let the minimizer choose its default one)
00309    double Precision() const { return fPrec; }
00310    
00311    /// strategy 
00312    int Strategy() const { return fStrategy; }
00313 
00314    /// status code of minimizer 
00315    int Status() const { return fStatus; } 
00316 
00317    /// return the statistical scale used for calculate the error
00318    /// is typically 1 for Chi2 and 0.5 for likelihood minimization
00319    double ErrorDef() const { return fUp; } 
00320 
00321    ///return true if Minimizer has performed a detailed error validation (e.g. run Hesse for Minuit)
00322    bool IsValidError() const { return fValidError; }
00323 
00324    /// retrieve the minimizer options (implement derived class if needed)
00325    virtual MinimizerOptions  Options() const { 
00326       MinimizerOptions opt; 
00327       opt.SetPrintLevel(fDebug);
00328       opt.SetStrategy(fStrategy);
00329       opt.SetMaxFunctionCalls(fMaxCalls);
00330       opt.SetMaxIterations(fMaxIter);
00331       opt.SetTolerance(fTol);
00332       opt.SetPrecision(fPrec);
00333       opt.SetErrorDef(fUp);
00334       return opt;
00335    }
00336 
00337    /// set print level
00338    void SetPrintLevel(int level) { fDebug = level; }
00339 
00340    ///set maximum of function calls 
00341    void SetMaxFunctionCalls(unsigned int maxfcn) { if (maxfcn > 0) fMaxCalls = maxfcn; }
00342 
00343    /// set maximum iterations (one iteration can have many function calls) 
00344    void SetMaxIterations(unsigned int maxiter) { if (maxiter > 0) fMaxIter = maxiter; } 
00345 
00346    /// set the tolerance
00347    void SetTolerance(double tol) { fTol = tol; }
00348 
00349    /// set in the minimizer the objective function evaluation precision 
00350    /// ( a value <=0 means the minimizer will choose its optimal value automatically, i.e. default case)
00351    void SetPrecision(double prec) { fPrec = prec; }
00352 
00353    ///set the strategy 
00354    void SetStrategy(int strategyLevel) { fStrategy = strategyLevel; }  
00355 
00356    /// set scale for calculating the errors
00357    void SetErrorDef(double up) { fUp = up; }
00358 
00359    /// flag to check if minimizer needs to perform accurate error analysis (e.g. run Hesse for Minuit)
00360    void SetValidError(bool on) { fValidError = on; } 
00361 
00362    /// set all options in one go
00363    void SetOptions(const MinimizerOptions & opt) { 
00364       fDebug = opt.PrintLevel();
00365       fStrategy = opt.Strategy();
00366       fMaxCalls = opt.MaxFunctionCalls();
00367       fMaxIter = opt.MaxIterations();
00368       fTol = opt.Tolerance();
00369       fPrec = opt.Precision();
00370       fUp = opt.ErrorDef();
00371    }
00372 
00373    /// reset the defaut options (defined in MinimizerOptions)
00374    void SetDefaultOptions() { 
00375       fDebug = MinimizerOptions::DefaultPrintLevel();
00376       fStrategy = MinimizerOptions::DefaultStrategy();
00377       fMaxCalls = MinimizerOptions::DefaultMaxFunctionCalls();
00378       fMaxIter = MinimizerOptions::DefaultMaxIterations();
00379       fTol = MinimizerOptions::DefaultTolerance();
00380       fPrec = MinimizerOptions::DefaultPrecision();
00381       fUp = MinimizerOptions::DefaultErrorDef();
00382    }
00383 
00384 protected: 
00385 
00386 
00387 //private: 
00388 
00389 
00390    // keep protected to be accessible by the derived classes 
00391  
00392 
00393    bool fValidError;            // flag to control if errors have been validated (Hesse has been run in case of Minuit)
00394    int fDebug;                  // print level
00395    int fStrategy;               // minimizer strategy
00396    int fStatus;                 // status of minimizer    
00397    unsigned int fMaxCalls;      // max number of function calls 
00398    unsigned int fMaxIter;       // max number or iterations used to find the minimum
00399    double fTol;                 // tolerance (absolute)
00400    double fPrec;                // precision
00401    double fUp;                  // error scale 
00402 
00403 }; 
00404 
00405    } // end namespace Math
00406 
00407 } // end namespace ROOT
00408 
00409 
00410 #endif /* ROOT_Math_Minimizer */

Generated on Tue Jul 5 14:25:35 2011 for ROOT_528-00b_version by  doxygen 1.5.1