00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "Minuit2/MnCovarianceSqueeze.h"
00011 #include "Minuit2/MnUserCovariance.h"
00012 #include "Minuit2/MinimumError.h"
00013
00014 #if defined(DEBUG) || defined(WARNINGMSG)
00015 #include "Minuit2/MnPrint.h"
00016 #endif
00017
00018
00019 namespace ROOT {
00020
00021 namespace Minuit2 {
00022
00023
00024 MnUserCovariance MnCovarianceSqueeze::operator()(const MnUserCovariance& cov, unsigned int n) const {
00025
00026
00027
00028 assert(cov.Nrow() > 0);
00029 assert(n < cov.Nrow());
00030
00031 MnAlgebraicSymMatrix hess(cov.Nrow());
00032 for(unsigned int i = 0; i < cov.Nrow(); i++) {
00033 for(unsigned int j = i; j < cov.Nrow(); j++) {
00034 hess(i,j) = cov(i,j);
00035 }
00036 }
00037
00038 int ifail = Invert(hess);
00039
00040 if(ifail != 0) {
00041 #ifdef WARNINGMSG
00042 MN_INFO_MSG("MnUserCovariance inversion failed; return diagonal matrix;");
00043 #endif
00044 MnUserCovariance result(cov.Nrow() - 1);
00045 for(unsigned int i = 0, j =0; i < cov.Nrow(); i++) {
00046 if(i == n) continue;
00047 result(j,j) = cov(i,i);
00048 j++;
00049 }
00050 return result;
00051 }
00052
00053 MnAlgebraicSymMatrix squeezed = (*this)(hess, n);
00054
00055 ifail = Invert(squeezed);
00056 if(ifail != 0) {
00057 #ifdef WARNINGMSG
00058 MN_INFO_MSG("MnUserCovariance back-inversion failed; return diagonal matrix;");
00059 #endif
00060 MnUserCovariance result(squeezed.Nrow());
00061 for(unsigned int i = 0; i < squeezed.Nrow(); i++) {
00062 result(i,i) = 1./squeezed(i,i);
00063 }
00064 return result;
00065 }
00066
00067 return MnUserCovariance(std::vector<double>(squeezed.Data(), squeezed.Data() + squeezed.size()), squeezed.Nrow());
00068 }
00069
00070 MinimumError MnCovarianceSqueeze::operator()(const MinimumError& err, unsigned int n) const {
00071
00072
00073
00074 MnAlgebraicSymMatrix hess = err.Hessian();
00075 MnAlgebraicSymMatrix squeezed = (*this)(hess, n);
00076 int ifail = Invert(squeezed);
00077 if(ifail != 0) {
00078 #ifdef WARNINGMSG
00079 MN_INFO_MSG("MnCovarianceSqueeze: MinimumError inversion fails; return diagonal matrix.");
00080 #endif
00081 MnAlgebraicSymMatrix tmp(squeezed.Nrow());
00082 for(unsigned int i = 0; i < squeezed.Nrow(); i++) {
00083 tmp(i,i) = 1./squeezed(i,i);
00084 }
00085 return MinimumError(tmp, MinimumError::MnInvertFailed());
00086 }
00087
00088 return MinimumError(squeezed, err.Dcovar());
00089 }
00090
00091 MnAlgebraicSymMatrix MnCovarianceSqueeze::operator()(const MnAlgebraicSymMatrix& hess, unsigned int n) const {
00092
00093 assert(hess.Nrow() > 0);
00094 assert(n < hess.Nrow());
00095
00096 MnAlgebraicSymMatrix hs(hess.Nrow() - 1);
00097 for(unsigned int i = 0, j = 0; i < hess.Nrow(); i++) {
00098 if(i == n) continue;
00099 for(unsigned int k = i, l = j; k < hess.Nrow(); k++) {
00100 if(k == n) continue;
00101 hs(j,l) = hess(i,k);
00102 l++;
00103 }
00104 j++;
00105 }
00106
00107 return hs;
00108 }
00109
00110 }
00111
00112 }