mnvert.cxx

Go to the documentation of this file.
00001 // @(#)root/minuit2:$Id: mnvert.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/MnMatrix.h"
00011 
00012 #include <cmath>
00013 
00014 namespace ROOT {
00015 
00016    namespace Minuit2 {
00017 
00018 
00019 /** Inverts a symmetric matrix. Matrix is first scaled to have all ones on 
00020     the diagonal (equivalent to change of units) but no pivoting is done 
00021     since matrix is positive-definite. 
00022  */
00023 
00024 int mnvert(MnAlgebraicSymMatrix& a) {
00025   
00026    unsigned int nrow = a.Nrow();
00027    MnAlgebraicVector s(nrow);
00028    MnAlgebraicVector q(nrow);
00029    MnAlgebraicVector pp(nrow);
00030    
00031    for(unsigned int i = 0; i < nrow; i++) {
00032       double si = a(i,i);
00033       if (si < 0.) return 1;
00034       s(i) = 1./std::sqrt(si);
00035    }
00036    
00037    for(unsigned int i = 0; i < nrow; i++)
00038       for(unsigned int j = i; j < nrow; j++)
00039          a(i,j) *= (s(i)*s(j));
00040    
00041    for(unsigned i = 0; i < nrow; i++) {
00042       unsigned int k = i;
00043       if(a(k,k) == 0.) return 1;
00044       q(k) = 1./a(k,k);
00045       pp(k) = 1.;
00046       a(k,k) = 0.;
00047       unsigned int kp1 = k + 1;
00048       if(k != 0) {
00049          for(unsigned int j = 0; j < k; j++) {
00050             pp(j) = a(j,k);
00051             q(j) = a(j,k)*q(k);
00052             a(j,k) = 0.;
00053          }
00054       }
00055       if (k != nrow-1) {
00056          for(unsigned int j = kp1; j < nrow; j++) {
00057             pp(j) = a(k,j);
00058             q(j) = -a(k,j)*q(k);
00059             a(k,j) = 0.;
00060          }
00061       }
00062       for(unsigned int j = 0; j < nrow; j++)
00063          for(k = j; k < nrow; k++)
00064             a(j,k) += (pp(j)*q(k)); 
00065    }
00066    
00067    for(unsigned int j = 0; j < nrow; j++)
00068       for(unsigned int k = j; k < nrow; k++)
00069          a(j,k) *= (s(j)*s(k)); 
00070    
00071    return 0;
00072 }
00073 
00074    }  // namespace Minuit2
00075 
00076 }  // namespace ROOT

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