ROOT logo
// @(#)root/mathcore:$Id: FitResult.h 39474 2011-05-30 07:48:13Z moneta $
// Author: L. Moneta Wed Aug 30 11:05:34 2006

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for class FitResult

#ifndef ROOT_Fit_FitResult
#define ROOT_Fit_FitResult

#ifndef ROOT_Fit_IFunctionfwd
#include "Math/IFunctionfwd.h"
#endif
#ifndef ROOT_Fit_IParamFunctionfwd
#include "Math/IParamFunctionfwd.h"
#endif

#include <vector>
#include <map>
#include <string>
#include <cmath>
#include <cassert>

namespace ROOT { 

   namespace Math { 
      class Minimizer; 
   }


   namespace Fit { 

      class FitConfig; 
      class BinData;

//___________________________________________________________________________________
/** 
   class containg the result of the fit and all the related information 
   (fitted parameter values, error, covariance matrix and minimizer result information)
   Contains a pointer also to the fitted (model) function, modified with the fit parameter values.  
   When the fit is valid, it is constructed from a  Minimizer and a model function pointer 

   @ingroup FitMain
*/ 
class FitResult {

public: 

   typedef  ROOT::Math::IParamMultiFunction IModelFunction; 

   /** 
      Default constructor for an empty (non valid) fit result
   */ 
   FitResult (); 

   /** 
      Constructor from a fit-config for a dummy fit 
      (e.g. when only one fcn evaluation is done)
   */ 
   FitResult (const FitConfig & fconfig);

   /**
      Construct from a Minimizer instance after fitting
      Run also Minos if requested from the configuration
    */
   FitResult(ROOT::Math::Minimizer & min, const FitConfig & fconfig, const IModelFunction * f, bool isValid, unsigned int sizeOfData = 0, bool binFit = true, const ROOT::Math::IMultiGenFunction * chi2func = 0, unsigned int ncalls = 0);

   /** 
      Copy constructor. 
   */ 
   FitResult(const FitResult &);

   /** 
      Assignment operator
   */ 
   FitResult & operator = (const FitResult & rhs);  

   /** 
      Destructor 
   */ 
   ~FitResult (); 


public: 

   /**
      Update the fit result with a new minimization status
      To be run only if same fit is performed with same configuration 
      Note that in this case MINOS is not re-run. If one wants to run also MINOS
      a new result must be created 
    */
   bool Update(const ROOT::Math::Minimizer & min, bool isValid, unsigned int ncalls = 0 );

   /** minimization quantities **/

   /// minimizer type 
   const std::string & MinimizerType() const { return fMinimType; } 

   /// True if fit successful, otherwise false.
   bool IsValid() const { return fValid; }

   /// True if a fit result does not exist (even invalid) with parameter values 
   bool IsEmpty() const { return (fParams.size() == 0);  }
 
   /// Return value of the objective function (chi2 or likelihood) used in the fit
   double MinFcnValue() const { return fVal; } 

   ///Number of function calls to find minimum
   unsigned int NCalls() const { return fNCalls; }
   
   ///Expected distance from minimum 
   double Edm() const { return fEdm; }

   ///   get total number of parameters 
   unsigned int NTotalParameters() const { return fParams.size(); } 
   /// total number of parameters (abbreviation)
   unsigned int NPar() const { return NTotalParameters(); }
   
   /// get total number of free parameters
   unsigned int NFreeParameters() const { return fNFree; }

   /// minimizer status code 
   int Status() const { return fStatus; } 

   ///covariance matrix status code
   /// using Minuit convention : =0 not calculated, =1 approximated, =2 made pos def , =3 accurate

   int CovMatrixStatus() const { return fCovStatus; }
 
   /** fitting quantities **/

   /// Return pointer to model (fit) function with fitted parameter values.
   const IModelFunction * FittedFunction() const { return fFitFunc; }

   /// Chi2 fit value
   /// in case of likelihood must be computed ? 
   double Chi2() const { return fChi2; } 

   /// Number of degree of freedom
   unsigned int Ndf() const { return fNdf; } 

   /// p value of the fit (chi2 probability)
   double Prob() const;  

   /// parameter errors (return st::vector) 
   const std::vector<double> & Errors() const { return fErrors; }
   /// parameter errors (return const pointer)
   const double * GetErrors() const { return (fErrors.empty()) ? 0 : &fErrors.front(); }

   /// parameter values (return std::vector)
   const std::vector<double> & Parameters() const { return fParams; }
   /// parameter values (return const pointer)
   const double * GetParams() const { return &fParams.front(); }

   /// parameter value by index
   double Value(unsigned int i) const { return fParams[i]; }
   /// parameter value by index 
   double Parameter(unsigned int i) const { return fParams[i]; }

   /// parameter error by index 
   // (NOTE: this due to conflict with TObject::Error cannot used in derived class which 
   // inherits from TObject. Use instead ParError (or Errors()[i] )
   double Error(unsigned int i) const { 
      return (i < fErrors.size() ) ? fErrors[i] : 0; 
   } 
   /// parameter error by index 
   double ParError(unsigned int i) const {
      return (i < fErrors.size() ) ? fErrors[i] : 0; 
   }

   /// name of the parameter
   std::string ParName(unsigned int i) const; 

   /// set the Minos errors for parameter i (called by the Fitter class when running Minos)
   void SetMinosError(unsigned int i, double elow, double eup);

   /// query if parameter i has the Minos error
   bool HasMinosError(unsigned int i) const;

   /// lower Minos error. If Minos has not run for parameter i return the parabolic error 
   double LowerError(unsigned int i) const;

   /// upper Minos error. If Minos has not run for parameter i return the parabolic error 
   double UpperError(unsigned int i) const;
   
   /// parameter global correlation coefficient 
   double GlobalCC(unsigned int i) const { 
      return (i < fGlobalCC.size() ) ? fGlobalCC[i] : -1; 
   } 


   /// retrieve covariance matrix element 
   double CovMatrix (unsigned int i, unsigned int j) const { 
      if ( i >= fErrors.size() || j >= fErrors.size() ) return 0; 
      if (fCovMatrix.size() == 0) return 0; // no matrix is available in case of non-valid fits
      if ( j < i ) 
         return fCovMatrix[j + i* (i+1) / 2];
      else 
         return fCovMatrix[i + j* (j+1) / 2];
   }

   /// retrieve correlation elements 
   double Correlation(unsigned int i, unsigned int j ) const { 
      if ( i >= fErrors.size() || j >= fErrors.size() ) return 0; 
      if (fCovMatrix.size() == 0) return 0; // no matrix is available in case of non-valid fits
      double tmp = CovMatrix(i,i)*CovMatrix(j,j); 
      return ( tmp > 0) ? CovMatrix(i,j)/ std::sqrt(tmp) : 0; 
   }
   
   /// fill covariance matrix elements using a generic matrix class implementing operator(i,j)
   /// the matrix must be previously allocates with right size (npar * npar) 
   template<class Matrix> 
   void GetCovarianceMatrix(Matrix & mat) const { 
      unsigned int npar = fErrors.size();
      if (fCovMatrix.size() != npar*(npar+1)/2 ) return; // do nothing 
      for (unsigned int i = 0; i< npar; ++i) { 
         for (unsigned int j = 0; j<=i; ++j) { 
            mat(i,j) = fCovMatrix[j + i*(i+1)/2 ];
            if (i != j) mat(j,i) = mat(i,j);  
         }
      }
   }

   /// fill a correlation matrix elements using a generic symmetric matrix class implementing operator(i,j)
   /// the matrix must be previously allocates with right size (npar * npar) 
   template<class Matrix> 
   void GetCorrelationMatrix(Matrix & mat) const { 
      unsigned int npar = fErrors.size(); 
      if (fCovMatrix.size() != npar*(npar+1)/2) return; // do nothing
      for (unsigned int i = 0; i< npar; ++i) { 
         for (unsigned int j = 0; j<=i; ++j) { 
            double tmp = fCovMatrix[i * (i +3)/2 ] * fCovMatrix[ j * (j+3)/2 ]; 
            mat(i,j) = (tmp > 0) ? fCovMatrix[j + i*(i+1)/2 ] / std::sqrt(tmp) : 0; 
            if (i != j) mat(j,i) = mat(i,j); 
         }
      }
   }

   /**
      get confidence intervals for an array of n points x. 
      stride1 indicates the stride in the coordinate space while stride2 the stride in dimension space. 
      For 1-dim points : stride1=1, stride2=1
      for multi-dim points arranged as (x0,x1,...,xN,y0,....yN)          stride1=1      stride2=n
      for multi-dim points arraged  as (x0,y0,..,x1,y1,...,xN,yN,..)     stride1=ndim,  stride2=1
      
      the confidence interval are returned in the array ci
      cl is the desired confidedence interval value
      norm is a flag to control if the intervals need to be normalized to the chi2/ndf value
      By default the intervals are corrected using the chi2/ndf value of the fit if a chi2 fit is performed
    */
   void GetConfidenceIntervals(unsigned int n, unsigned int stride1, unsigned int stride2, const double * x,  double * ci, double cl=0.95, bool norm = true ) const;     

   /**
      evaluate confidence interval for the point specified in the passed data sets
      the confidence interval are returned in the array ci
      cl is the desired confidence interval value
    */
   void GetConfidenceIntervals(const BinData & data, double * ci, double cl=0.95, bool norm = true ) const;


   /// get index for parameter name (return -1 if not found)
   int Index(const std::string & name) const; 


   ///normalize errors using chi2/ndf for chi2 fits
   void NormalizeErrors();

   /// flag to chek if errors are normalized
   bool NormalizedErrors() const { return fNormalized; }

   /// print the result and optionaly covariance matrix and correlations
   void Print(std::ostream & os, bool covmat = false) const;

   ///print error matrix and correlations
   void PrintCovMatrix(std::ostream & os) const; 

   /// query if a parameter is bound 
   bool IsParameterBound(unsigned int ipar) const; 

   /// query if a parameter is fixed 
   bool IsParameterFixed(unsigned int ipar) const; 

   /// get name of parameter (deprecated)
   std::string GetParameterName(unsigned int ipar) const { 
      return ParName(ipar);
   }


protected: 


   /// Return pointer non const pointer to model (fit) function with fitted parameter values.
   /// used by Fitter class 
   IModelFunction * ModelFunction()  { return fFitFunc; }
   void SetModelFunction(IModelFunction * func) { fFitFunc = func; }

   friend class Fitter; 


   bool fValid;             // flag for indicating valid fit
   bool fNormalized;        // flag for indicating is errors are normalized
   unsigned int fNFree;     // number of fit free parameters (total parameters are in size of parameter vector)  
   unsigned int fNdf;       // number of degree of freedom
   unsigned int fNCalls;    // number of function calls
   int fStatus;             // minimizer status code
   int fCovStatus;          // covariance matrix status code
   double fVal;             // minimum function value
   double fEdm;             // expected distance from mimimum
   double fChi2;            // fit chi2 value (different than fval in case of chi2 fits)
   IModelFunction * fFitFunc; //! model function resulting  from the fit. It is given by Fitter but it is managed by FitResult
   std::vector<unsigned int>   fFixedParams; // list of fixed parameters
   std::vector<unsigned int>   fBoundParams; // list of limited parameters
   std::vector<double>         fParams;  // parameter values. Size is total number of parameters
   std::vector<double>         fErrors;  // errors 
   std::vector<double>         fCovMatrix;  // covariance matrix (size is npar*(npar+1)/2) where npar is total parameters
   std::vector<double>         fGlobalCC;   // global Correlation coefficient
   std::map<unsigned int, std::pair<double,double> > fMinosErrors;   // map contains the two Minos errors
   std::string fMinimType;              // string indicating type of minimizer
   std::vector<std::string> fParNames;  // parameter names (only with FCN only fits, when fFitFunc=0)

}; 

   } // end namespace Fit

} // end namespace ROOT


#endif /* ROOT_Fit_FitResult */
 FitResult.h:1
 FitResult.h:2
 FitResult.h:3
 FitResult.h:4
 FitResult.h:5
 FitResult.h:6
 FitResult.h:7
 FitResult.h:8
 FitResult.h:9
 FitResult.h:10
 FitResult.h:11
 FitResult.h:12
 FitResult.h:13
 FitResult.h:14
 FitResult.h:15
 FitResult.h:16
 FitResult.h:17
 FitResult.h:18
 FitResult.h:19
 FitResult.h:20
 FitResult.h:21
 FitResult.h:22
 FitResult.h:23
 FitResult.h:24
 FitResult.h:25
 FitResult.h:26
 FitResult.h:27
 FitResult.h:28
 FitResult.h:29
 FitResult.h:30
 FitResult.h:31
 FitResult.h:32
 FitResult.h:33
 FitResult.h:34
 FitResult.h:35
 FitResult.h:36
 FitResult.h:37
 FitResult.h:38
 FitResult.h:39
 FitResult.h:40
 FitResult.h:41
 FitResult.h:42
 FitResult.h:43
 FitResult.h:44
 FitResult.h:45
 FitResult.h:46
 FitResult.h:47
 FitResult.h:48
 FitResult.h:49
 FitResult.h:50
 FitResult.h:51
 FitResult.h:52
 FitResult.h:53
 FitResult.h:54
 FitResult.h:55
 FitResult.h:56
 FitResult.h:57
 FitResult.h:58
 FitResult.h:59
 FitResult.h:60
 FitResult.h:61
 FitResult.h:62
 FitResult.h:63
 FitResult.h:64
 FitResult.h:65
 FitResult.h:66
 FitResult.h:67
 FitResult.h:68
 FitResult.h:69
 FitResult.h:70
 FitResult.h:71
 FitResult.h:72
 FitResult.h:73
 FitResult.h:74
 FitResult.h:75
 FitResult.h:76
 FitResult.h:77
 FitResult.h:78
 FitResult.h:79
 FitResult.h:80
 FitResult.h:81
 FitResult.h:82
 FitResult.h:83
 FitResult.h:84
 FitResult.h:85
 FitResult.h:86
 FitResult.h:87
 FitResult.h:88
 FitResult.h:89
 FitResult.h:90
 FitResult.h:91
 FitResult.h:92
 FitResult.h:93
 FitResult.h:94
 FitResult.h:95
 FitResult.h:96
 FitResult.h:97
 FitResult.h:98
 FitResult.h:99
 FitResult.h:100
 FitResult.h:101
 FitResult.h:102
 FitResult.h:103
 FitResult.h:104
 FitResult.h:105
 FitResult.h:106
 FitResult.h:107
 FitResult.h:108
 FitResult.h:109
 FitResult.h:110
 FitResult.h:111
 FitResult.h:112
 FitResult.h:113
 FitResult.h:114
 FitResult.h:115
 FitResult.h:116
 FitResult.h:117
 FitResult.h:118
 FitResult.h:119
 FitResult.h:120
 FitResult.h:121
 FitResult.h:122
 FitResult.h:123
 FitResult.h:124
 FitResult.h:125
 FitResult.h:126
 FitResult.h:127
 FitResult.h:128
 FitResult.h:129
 FitResult.h:130
 FitResult.h:131
 FitResult.h:132
 FitResult.h:133
 FitResult.h:134
 FitResult.h:135
 FitResult.h:136
 FitResult.h:137
 FitResult.h:138
 FitResult.h:139
 FitResult.h:140
 FitResult.h:141
 FitResult.h:142
 FitResult.h:143
 FitResult.h:144
 FitResult.h:145
 FitResult.h:146
 FitResult.h:147
 FitResult.h:148
 FitResult.h:149
 FitResult.h:150
 FitResult.h:151
 FitResult.h:152
 FitResult.h:153
 FitResult.h:154
 FitResult.h:155
 FitResult.h:156
 FitResult.h:157
 FitResult.h:158
 FitResult.h:159
 FitResult.h:160
 FitResult.h:161
 FitResult.h:162
 FitResult.h:163
 FitResult.h:164
 FitResult.h:165
 FitResult.h:166
 FitResult.h:167
 FitResult.h:168
 FitResult.h:169
 FitResult.h:170
 FitResult.h:171
 FitResult.h:172
 FitResult.h:173
 FitResult.h:174
 FitResult.h:175
 FitResult.h:176
 FitResult.h:177
 FitResult.h:178
 FitResult.h:179
 FitResult.h:180
 FitResult.h:181
 FitResult.h:182
 FitResult.h:183
 FitResult.h:184
 FitResult.h:185
 FitResult.h:186
 FitResult.h:187
 FitResult.h:188
 FitResult.h:189
 FitResult.h:190
 FitResult.h:191
 FitResult.h:192
 FitResult.h:193
 FitResult.h:194
 FitResult.h:195
 FitResult.h:196
 FitResult.h:197
 FitResult.h:198
 FitResult.h:199
 FitResult.h:200
 FitResult.h:201
 FitResult.h:202
 FitResult.h:203
 FitResult.h:204
 FitResult.h:205
 FitResult.h:206
 FitResult.h:207
 FitResult.h:208
 FitResult.h:209
 FitResult.h:210
 FitResult.h:211
 FitResult.h:212
 FitResult.h:213
 FitResult.h:214
 FitResult.h:215
 FitResult.h:216
 FitResult.h:217
 FitResult.h:218
 FitResult.h:219
 FitResult.h:220
 FitResult.h:221
 FitResult.h:222
 FitResult.h:223
 FitResult.h:224
 FitResult.h:225
 FitResult.h:226
 FitResult.h:227
 FitResult.h:228
 FitResult.h:229
 FitResult.h:230
 FitResult.h:231
 FitResult.h:232
 FitResult.h:233
 FitResult.h:234
 FitResult.h:235
 FitResult.h:236
 FitResult.h:237
 FitResult.h:238
 FitResult.h:239
 FitResult.h:240
 FitResult.h:241
 FitResult.h:242
 FitResult.h:243
 FitResult.h:244
 FitResult.h:245
 FitResult.h:246
 FitResult.h:247
 FitResult.h:248
 FitResult.h:249
 FitResult.h:250
 FitResult.h:251
 FitResult.h:252
 FitResult.h:253
 FitResult.h:254
 FitResult.h:255
 FitResult.h:256
 FitResult.h:257
 FitResult.h:258
 FitResult.h:259
 FitResult.h:260
 FitResult.h:261
 FitResult.h:262
 FitResult.h:263
 FitResult.h:264
 FitResult.h:265
 FitResult.h:266
 FitResult.h:267
 FitResult.h:268
 FitResult.h:269
 FitResult.h:270
 FitResult.h:271
 FitResult.h:272
 FitResult.h:273
 FitResult.h:274
 FitResult.h:275
 FitResult.h:276
 FitResult.h:277
 FitResult.h:278
 FitResult.h:279
 FitResult.h:280
 FitResult.h:281
 FitResult.h:282
 FitResult.h:283
 FitResult.h:284
 FitResult.h:285
 FitResult.h:286
 FitResult.h:287
 FitResult.h:288
 FitResult.h:289
 FitResult.h:290
 FitResult.h:291
 FitResult.h:292
 FitResult.h:293
 FitResult.h:294
 FitResult.h:295
 FitResult.h:296
 FitResult.h:297
 FitResult.h:298
 FitResult.h:299
 FitResult.h:300
 FitResult.h:301
 FitResult.h:302
 FitResult.h:303
 FitResult.h:304
 FitResult.h:305
 FitResult.h:306
 FitResult.h:307
 FitResult.h:308
 FitResult.h:309
 FitResult.h:310
 FitResult.h:311
 FitResult.h:312
 FitResult.h:313
 FitResult.h:314
 FitResult.h:315
 FitResult.h:316
 FitResult.h:317
 FitResult.h:318
 FitResult.h:319
 FitResult.h:320
 FitResult.h:321
 FitResult.h:322
 FitResult.h:323
 FitResult.h:324
 FitResult.h:325
 FitResult.h:326
 FitResult.h:327
 FitResult.h:328
 FitResult.h:329
 FitResult.h:330
 FitResult.h:331
 FitResult.h:332
 FitResult.h:333