Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:08

0001 // @(#)root/mathcore:$Id$
0002 // Author: L. Moneta Wed Aug 30 11:05:34 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class FitResult
0012 
0013 #ifndef ROOT_Fit_FitResult
0014 #define ROOT_Fit_FitResult
0015 
0016 #include "Math/IFunctionfwd.h"
0017 #include "Math/IParamFunctionfwd.h"
0018 
0019 #include <vector>
0020 #include <map>
0021 #include <string>
0022 #include <cmath>
0023 #include <memory>
0024 
0025 namespace ROOT {
0026 
0027    namespace Math {
0028       class Minimizer;
0029    }
0030 
0031 
0032    namespace Fit {
0033 
0034       class FitConfig;
0035       class FitData;
0036       class BinData;
0037 
0038 //___________________________________________________________________________________
0039 /**
0040    class containing the result of the fit and all the related information
0041    (fitted parameter values, error, covariance matrix and minimizer result information)
0042    Contains a pointer also to the fitted (model) function, modified with the fit parameter values.
0043    When the fit is valid, it is constructed from a  Minimizer and a model function pointer
0044 
0045    @ingroup FitMain
0046 */
0047 class FitResult {
0048 
0049 public:
0050 
0051    typedef  ROOT::Math::IParamMultiFunction IModelFunction;
0052 
0053    /**
0054       Default constructor for an empty (non valid) fit result
0055    */
0056    FitResult ();
0057 
0058    /**
0059       Constructor from a fit-config for a dummy fit
0060       (e.g. when only one fcn evaluation is done)
0061    */
0062    FitResult (const FitConfig & fconfig);
0063 
0064    // default copy constructor and assignment can be used
0065 
0066    /**
0067       Destructor
0068    */
0069    virtual ~FitResult () {}
0070 
0071 
0072 public:
0073 
0074    /**
0075       Fill the fit result from a Minimizer instance after fitting
0076       Run also Minos if requested from the configuration
0077     */
0078    void FillResult(const std::shared_ptr<ROOT::Math::Minimizer> & min, const FitConfig & fconfig,  const std::shared_ptr<IModelFunction> & f,
0079               bool isValid, unsigned int sizeOfData = 0, int fitType = 1, const ROOT::Math::IMultiGenFunction *chi2func = nullptr, unsigned int ncalls = 0);
0080 
0081 
0082    /**
0083       Update the fit result with a new minimization status
0084       To be run only if same fit is performed with same configuration
0085       Note that in this case MINOS is not re-run. If one wants to run also MINOS
0086       a new result must be created
0087     */
0088    bool Update(const std::shared_ptr<ROOT::Math::Minimizer> & min, const ROOT::Fit::FitConfig & fconfig, bool isValid, unsigned int ncalls = 0);
0089 
0090    /** minimization quantities **/
0091 
0092    /// minimizer type
0093    const std::string & MinimizerType() const { return fMinimType; }
0094 
0095    /**
0096        True if fit successful, otherwise false.
0097        A fit is considered successful if the minimizer succeeded in finding the
0098        minimum. It could happen that subsequent operations like error analysis (e.g. Minos)
0099        failed. In that case the status can be still true if the original minimization algorithm
0100        succeeded in finding the minimum.
0101        One can query in that case the minimizer return status using Status().
0102        It is responsibility to the Minimizer class to tag a found minimum as valid or not
0103        and to produce also a status code.
0104    */
0105    bool IsValid() const { return fValid; }
0106 
0107    /// True if a fit result does not exist (even invalid) with parameter values
0108    bool IsEmpty() const { return (fParams.empty());  }
0109 
0110    /// Return value of the objective function (chi2 or likelihood) used in the fit
0111    double MinFcnValue() const { return fVal; }
0112 
0113    ///Number of function calls to find minimum
0114    unsigned int NCalls() const { return fNCalls; }
0115 
0116    ///Expected distance from minimum
0117    double Edm() const { return fEdm; }
0118 
0119    ///   get total number of parameters
0120    unsigned int NTotalParameters() const { return fParams.size(); }
0121    /// total number of parameters (abbreviation)
0122    unsigned int NPar() const { return NTotalParameters(); }
0123 
0124    /// get total number of free parameters
0125    unsigned int NFreeParameters() const { return fNFree; }
0126 
0127    /// minimizer status code
0128    int Status() const { return fStatus; }
0129 
0130    ///covariance matrix status code
0131    /// using Minuit convention : =0 not calculated, =1 approximated, =2 made pos def , =3 accurate
0132 
0133    int CovMatrixStatus() const { return fCovStatus; }
0134 
0135    /** fitting quantities **/
0136 
0137    /// Return pointer to model (fit) function with fitted parameter values.
0138    /// Pointer is managed internally. I must not be deleted
0139    const IModelFunction * FittedFunction() const {
0140       return fFitFunc.get();
0141    }
0142 
0143    /// return BinData used in the fit (return a nullptr in case a different fit is done
0144    /// or the data are not available
0145    /// Pointer is managed internally, it must not be deleted
0146    const BinData * FittedBinData() const;
0147 
0148 
0149    /// Return the Chi2 value after fitting
0150    /// In case of unbinned fits (or not defined one, see the documentation of Fitter::FitFCN) return -1
0151    /// In case of binned likelihood fits (Poisson Likelihood) return the 2 * negative log-likelihood ratio
0152    /// using the definition of Baker-Cousins
0153    double Chi2() const { return fChi2; }
0154 
0155    /// Number of degree of freedom
0156    unsigned int Ndf() const { return fNdf; }
0157 
0158    /// p value of the fit (chi2 probability)
0159    double Prob() const;
0160 
0161    /// parameter errors (return st::vector)
0162    const std::vector<double> & Errors() const { return fErrors; }
0163    /// parameter errors (return const pointer)
0164    const double * GetErrors() const { return fErrors.empty() ? nullptr : &fErrors.front(); }
0165 
0166    /// parameter values (return std::vector)
0167    const std::vector<double> & Parameters() const { return fParams; }
0168    /// parameter values (return const pointer)
0169    const double * GetParams() const { return &fParams.front(); }
0170 
0171    /// parameter value by index
0172    double Value(unsigned int i) const { return fParams[i]; }
0173    /// parameter value by index
0174    double Parameter(unsigned int i) const { return fParams[i]; }
0175 
0176    /// parameter error by index
0177    // (NOTE: this due to conflict with TObject::Error cannot used in derived class which
0178    // inherits from TObject. Use instead ParError (or Errors()[i] )
0179    double Error(unsigned int i) const {
0180       return (i < fErrors.size() ) ? fErrors[i] : 0;
0181    }
0182    /// parameter error by index
0183    double ParError(unsigned int i) const {
0184       return (i < fErrors.size() ) ? fErrors[i] : 0;
0185    }
0186 
0187    /// name of the parameter
0188    std::string ParName(unsigned int i) const;
0189 
0190    /// set the Minos errors for parameter i (called by the Fitter class when running Minos)
0191    void SetMinosError(unsigned int i, double elow, double eup);
0192 
0193    /// Set the chi2 and the ndf
0194    /// This function should be called when using an external FCN for fitting
0195    /// and one provides the chi2 and the number of fitting data points) to store
0196    /// and have them printed in the FitResult class
0197    void SetChi2AndNdf(double chi2, unsigned int npoints);
0198 
0199    /// query if parameter i has the Minos error
0200    bool HasMinosError(unsigned int i) const;
0201 
0202    /// lower Minos error. If Minos has not run for parameter i return the parabolic error
0203    double LowerError(unsigned int i) const;
0204 
0205    /// upper Minos error. If Minos has not run for parameter i return the parabolic error
0206    double UpperError(unsigned int i) const;
0207 
0208    /// parameter global correlation coefficient
0209    double GlobalCC(unsigned int i) const {
0210       return (i < fGlobalCC.size() ) ? fGlobalCC[i] : -1;
0211    }
0212 
0213 
0214    /// retrieve covariance matrix element
0215    double CovMatrix (unsigned int i, unsigned int j) const {
0216       if ( i >= fErrors.size() || j >= fErrors.size() ) return 0;
0217       if (fCovMatrix.empty()) return 0; // no matrix is available in case of non-valid fits
0218       if ( j < i )
0219          return fCovMatrix[j + i* (i+1) / 2];
0220       else
0221          return fCovMatrix[i + j* (j+1) / 2];
0222    }
0223 
0224    /// retrieve correlation elements
0225    double Correlation(unsigned int i, unsigned int j ) const {
0226       if ( i >= fErrors.size() || j >= fErrors.size() ) return 0;
0227       if (fCovMatrix.empty()) return 0; // no matrix is available in case of non-valid fits
0228       double tmp = CovMatrix(i,i)*CovMatrix(j,j);
0229       return ( tmp > 0) ? CovMatrix(i,j)/ std::sqrt(tmp) : 0;
0230    }
0231 
0232    /// fill covariance matrix elements using a generic matrix class implementing operator(i,j)
0233    /// the matrix must be previously allocates with right size (npar * npar)
0234    template<class Matrix>
0235    void GetCovarianceMatrix(Matrix & mat) const {
0236       unsigned int npar = fErrors.size();
0237       if (fCovMatrix.size() != npar*(npar+1)/2 ) return; // do nothing
0238       for (unsigned int i = 0; i< npar; ++i) {
0239          for (unsigned int j = 0; j<=i; ++j) {
0240             mat(i,j) = fCovMatrix[j + i*(i+1)/2 ];
0241             if (i != j) mat(j,i) = mat(i,j);
0242          }
0243       }
0244    }
0245 
0246    /// fill a correlation matrix elements using a generic symmetric matrix class implementing operator(i,j)
0247    /// the matrix must be previously allocates with right size (npar * npar)
0248    template<class Matrix>
0249    void GetCorrelationMatrix(Matrix & mat) const {
0250       unsigned int npar = fErrors.size();
0251       if (fCovMatrix.size() != npar*(npar+1)/2) return; // do nothing
0252       for (unsigned int i = 0; i< npar; ++i) {
0253          for (unsigned int j = 0; j<=i; ++j) {
0254             double tmp = fCovMatrix[i * (i +3)/2 ] * fCovMatrix[ j * (j+3)/2 ];
0255             mat(i,j) = (tmp > 0) ? fCovMatrix[j + i*(i+1)/2 ] / std::sqrt(tmp) : 0;
0256             if (i != j) mat(j,i) = mat(i,j);
0257          }
0258       }
0259    }
0260 
0261    /**
0262       get confidence intervals for an array of n points x.
0263       stride1 indicates the stride in the coordinate space while stride2 the stride in dimension space.
0264       For 1-dim points : stride1=1, stride2=1
0265       for multi-dim points arranged as (x0,x1,...,xN,y0,....yN)          stride1=1      stride2=n
0266       for multi-dim points arranged  as (x0,y0,..,x1,y1,...,xN,yN,..)     stride1=ndim,  stride2=1
0267 
0268       the confidence interval are returned in the array ci
0269       cl is the desired confidence interval value
0270       norm is a flag to control if the intervals need to be normalized to the chi2/ndf value
0271       The intervals can be corrected optionally using the chi2/ndf value of the fit if a chi2 fit is performed.
0272       This has changed since ROOT 6.14, before the interval were corrected by default.
0273     */
0274    void GetConfidenceIntervals(unsigned int n, unsigned int stride1, unsigned int stride2, const double * x,  double * ci, double cl=0.95, bool norm = false ) const;
0275 
0276    /**
0277       evaluate confidence interval for the point specified in the passed data sets
0278       the confidence interval are returned in the array ci
0279       cl is the desired confidence interval value.
0280       This method is maintained for backward compatibility and will be deprecated
0281    */
0282    void GetConfidenceIntervals(const BinData & data, double * ci, double cl=0.95, bool norm = false ) const;
0283 
0284    /**
0285       evaluate confidence interval for the data set used in the last fit
0286       the confidence interval are returned as a vector of data points
0287     */
0288    std::vector<double> GetConfidenceIntervals(double cl=0.95, bool norm = false ) const;
0289 
0290    /**
0291       scan likelihood value of  parameter and fill the given graph.
0292     */
0293    bool Scan(unsigned int ipar, unsigned int &npoints, double *pntsx, double *pntsy, double xmin = 0, double xmax = 0);
0294 
0295    /**
0296       create contour of two parameters around the minimum
0297       pass as option confidence level:  default is a value of 0.683
0298    */
0299    bool Contour(unsigned int ipar, unsigned int jpar, unsigned int &npoints, double *pntsx, double *pntsy, double confLevel = 0.683);
0300 
0301    /// get index for parameter name (return -1 if not found)
0302    int Index(const std::string & name) const;
0303 
0304    ///normalize errors using chi2/ndf for chi2 fits
0305    void NormalizeErrors();
0306 
0307    /// flag to check if errors are normalized
0308    bool NormalizedErrors() const { return fNormalized; }
0309 
0310    /// print the result and optionally covariance matrix and correlations
0311    void Print(std::ostream & os, bool covmat = false) const;
0312 
0313    ///print error matrix and correlations
0314    void PrintCovMatrix(std::ostream & os) const;
0315 
0316    /// query if a parameter is bound
0317    bool IsParameterBound(unsigned int ipar) const;
0318 
0319    /// query if a parameter is fixed
0320    bool IsParameterFixed(unsigned int ipar) const;
0321 
0322    /// retrieve parameter bounds - return false if parameter is not bound
0323    bool ParameterBounds(unsigned int ipar, double &lower, double &upper) const;
0324 
0325 
0326    /// get name of parameter (deprecated)
0327    std::string GetParameterName(unsigned int ipar) const {
0328       return ParName(ipar);
0329    }
0330 
0331 
0332 protected:
0333 
0334 
0335    /// Return pointer non const pointer to model (fit) function with fitted parameter values.
0336    /// used by Fitter class
0337    std::shared_ptr<IModelFunction> ModelFunction()  { return fFitFunc; }
0338    void SetModelFunction(const std::shared_ptr<IModelFunction> & func) { fFitFunc = func; }
0339 
0340    friend class Fitter;
0341 
0342 
0343    bool fValid;             ///< flag for indicating valid fit
0344    bool fNormalized;        ///< flag for indicating is errors are normalized
0345    unsigned int fNFree;     ///< number of fit free parameters (total parameters are in size of parameter vector)
0346    unsigned int fNdf;       ///< number of degree of freedom
0347    unsigned int fNCalls;    ///< number of function calls
0348    int fStatus;             ///< minimizer status code
0349    int fCovStatus;          ///< covariance matrix status code
0350    double fVal;             ///< minimum function value
0351    double fEdm;             ///< expected distance from minimum
0352    double fChi2;            ///< fit chi2 value (different than fval in case of chi2 fits)
0353    std::shared_ptr<ROOT::Math::Minimizer> fMinimizer;       ///<! minimizer object used for fitting
0354    std::shared_ptr<ROOT::Math::IMultiGenFunction> fObjFunc; ///<! objective function used for fitting
0355    std::shared_ptr<IModelFunction> fFitFunc;                ///<! model function resulting  from the fit.
0356    std::shared_ptr<FitData>    fFitData;                    ///<! data set used in the fit
0357    std::map<unsigned int, bool>           fFixedParams;     ///< list of fixed parameters
0358    std::map<unsigned int, unsigned int>   fBoundParams;     ///< list of limited parameters
0359    std::vector<std::pair<double,double> >  fParamBounds;    ///< parameter bounds
0360    std::vector<double>         fParams;    ///< parameter values. Size is total number of parameters
0361    std::vector<double>         fErrors;    ///< errors
0362    std::vector<double>         fCovMatrix; ///< covariance matrix (size is npar*(npar+1)/2) where npar is total parameters
0363    std::vector<double>         fGlobalCC;  ///< global Correlation coefficient
0364    std::map<unsigned int, std::pair<double,double> > fMinosErrors; ///< map contains the two Minos errors
0365    std::string fMinimType;              ///< string indicating type of minimizer
0366    std::vector<std::string> fParNames;  ///< parameter names (only with FCN only fits, when fFitFunc=0)
0367 
0368 };
0369 
0370 
0371    } // end namespace Fit
0372 
0373 } // end namespace ROOT
0374 
0375 
0376 
0377 
0378 
0379 #endif /* ROOT_Fit_FitResult */