File indexing completed on 2025-09-18 09:31:44
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef ROOT_Minuit2_MinimumError
0011 #define ROOT_Minuit2_MinimumError
0012
0013 #include "Minuit2/MnConfig.h"
0014 #include "Minuit2/MnMatrix.h"
0015 #include "Minuit2/MnPrint.h"
0016
0017 #include <memory>
0018
0019 namespace ROOT {
0020
0021 namespace Minuit2 {
0022
0023
0024
0025
0026
0027 class MinimumError {
0028
0029 public:
0030 enum Status {
0031 MnUnset,
0032 MnPosDef,
0033 MnMadePosDef,
0034 MnNotPosDef,
0035 MnHesseFailed,
0036 MnInvertFailed,
0037 MnReachedCallLimit,
0038 };
0039
0040 public:
0041 MinimumError(unsigned int n) : fPtr{new Data{{n}, {0}, 1.0, MnUnset}} {}
0042
0043 MinimumError(const MnAlgebraicSymMatrix &mat, double dcov) : fPtr{new Data{mat, {0}, dcov, MnPosDef}} {}
0044
0045 MinimumError(const MnAlgebraicSymMatrix &mat, const MnAlgebraicSymMatrix &hess, double dcov) : fPtr{new Data{mat, hess, dcov, MnPosDef}} {}
0046
0047 MinimumError(const MnAlgebraicSymMatrix &mat, Status status) : fPtr{new Data{mat, {0}, 1.0, status}} {}
0048
0049 MnAlgebraicSymMatrix Matrix() const { return 2. * fPtr->fMatrix; }
0050
0051 const MnAlgebraicSymMatrix &InvHessian() const { return fPtr->fMatrix; }
0052
0053
0054 const MnAlgebraicSymMatrix & Hessian() const
0055 {
0056 if (fPtr->fHessian.size() == 0)
0057 fPtr->fHessian = InvertMatrix(fPtr->fMatrix);
0058 return fPtr->fHessian;
0059 }
0060
0061 static MnAlgebraicSymMatrix InvertMatrix(const MnAlgebraicSymMatrix & matrix, int & ifail) {
0062
0063 MnAlgebraicSymMatrix tmp(matrix);
0064 ifail = ROOT::Minuit2::Invert(tmp);
0065 if (ifail != 0) {
0066 MnPrint print("MinimumError::Invert");
0067 print.Warn("Inversion fails; return diagonal matrix");
0068 for (unsigned int i = 0; i < matrix.Nrow(); ++i)
0069 for (unsigned int j = 0; j <= i; j++)
0070 tmp(i, j) = i == j ? 1. / matrix(i, i) : 0;
0071 }
0072 return tmp;
0073 }
0074 static MnAlgebraicSymMatrix InvertMatrix(const MnAlgebraicSymMatrix & matrix) {
0075 int ifail = 0;
0076 return InvertMatrix(matrix, ifail);
0077 }
0078
0079 double Dcovar() const { return fPtr->fDCovar; }
0080 Status GetStatus() const { return fPtr->fStatus; }
0081
0082 bool IsValid() const { return IsAvailable() && (IsPosDef() || IsMadePosDef() || IsNotPosDef()); }
0083 bool IsAccurate() const { return IsPosDef() && Dcovar() < 0.1; }
0084
0085 bool IsPosDef() const { return GetStatus() == MnPosDef; }
0086 bool IsMadePosDef() const { return GetStatus() == MnMadePosDef; }
0087 bool IsNotPosDef() const { return GetStatus() == MnNotPosDef; }
0088 bool HesseFailed() const { return GetStatus() == MnHesseFailed; }
0089 bool InvertFailed() const { return GetStatus() == MnInvertFailed; }
0090 bool HasReachedCallLimit() const { return GetStatus() == MnReachedCallLimit; }
0091 bool IsAvailable() const { return GetStatus() != MnUnset; }
0092
0093 private:
0094 struct Data {
0095 MnAlgebraicSymMatrix fMatrix;
0096 MnAlgebraicSymMatrix fHessian;
0097 double fDCovar;
0098 Status fStatus;
0099 };
0100
0101 std::shared_ptr<Data> fPtr;
0102 };
0103
0104 }
0105
0106 }
0107
0108 #endif