// @(#)root/mathcore:$Id$
// 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
   */
   virtual ~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.
       A fit is considered successful if the minimizer succeded in finding the
       minimum. It could happen that subsequent operations like error analysis (e.g. Minos)
       failed. In that case the status can be still true if the original minimization algorithm
       succeeded in finding the minimum.
       One can query in that case the minimizer return status using Status().
       It is responability to the Minimizer class to tag a found minimum as valid or not
       and to produce also a status code.
   */
   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;

   /// retrieve parameter bounds - return false if parameter is not bound
   bool ParameterBounds(unsigned int ipar, double &lower, double &upper) 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::map<unsigned int, bool>           fFixedParams; // list of fixed parameters
   std::map<unsigned int, unsigned int>   fBoundParams; // list of limited parameters
   std::vector<std::pair<double,double> >  fParamBounds; // parameter bounds
   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
 FitResult.h:334
 FitResult.h:335
 FitResult.h:336
 FitResult.h:337
 FitResult.h:338
 FitResult.h:339
 FitResult.h:340
 FitResult.h:341
 FitResult.h:342
 FitResult.h:343
 FitResult.h:344
 FitResult.h:345
 FitResult.h:346
 FitResult.h:347