MnCovarianceSqueeze.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: MnCovarianceSqueeze.cxx 20880 2007-11-19 11:23:41Z rdm $
00002 // Authors: M. Winkler, F. James, L. Moneta, A. Zsenei   2003-2005  
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2005 LCG ROOT Math team,  CERN/PH-SFT                *
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    // squeeze MnUserCovariance class 
00026    // MnUserCovariance contasins the error matrix. Need to invert first to get the hessian, then 
00027    // after having squuezed the hessian, need to invert again to get the new error matrix
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    // squueze the minimum error class
00072    // Remove index-row on the Hessian matrix and the get the new correct error matrix 
00073    // (inverse of new Hessian)
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    // squueze a symmetrix matrix (remove entire row and column n)
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    }  // namespace Minuit2
00111 
00112 }  // namespace ROOT

Generated on Tue Jul 5 14:37:10 2011 for ROOT_528-00b_version by  doxygen 1.5.1