Dsfact.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: Dsfact.h 20882 2007-11-19 11:31:26Z rdm $
00002 // Authors: T. Glebe, L. Moneta    2005  
00003 
00004 #ifndef ROOT_Math_Dsfact
00005 #define ROOT_Math_Dsfact
00006 // ********************************************************************
00007 //
00008 // source:
00009 //
00010 // type:      source code
00011 //
00012 // created:   22. Mar 2001
00013 //
00014 // author:    Thorsten Glebe
00015 //            HERA-B Collaboration
00016 //            Max-Planck-Institut fuer Kernphysik
00017 //            Saupfercheckweg 1
00018 //            69117 Heidelberg
00019 //            Germany
00020 //            E-mail: T.Glebe@mpi-hd.mpg.de
00021 //
00022 // Description: Determinant of a symmetric, positive definite matrix.
00023 //              Code was taken from CERNLIB::kernlib dsfact function, translated
00024 //              from FORTRAN to C++ and optimized.
00025 //
00026 // changes:
00027 // 22 Mar 2001 (TG) creation
00028 // 18 Apr 2001 (TG) removed internal copying of array.
00029 //
00030 // ********************************************************************
00031 
00032 
00033 namespace ROOT { 
00034 
00035   namespace Math { 
00036 
00037 
00038 
00039 
00040 /** Dsfact.
00041     Compute determinant of a symmetric, positive definite matrix of dimension
00042     $idim$ and order $n$.
00043     
00044     @author T. Glebe
00045 */
00046 
00047 template <unsigned int n, unsigned int idim =n>
00048 class SDeterminant { 
00049 
00050 public: 
00051 template <class T>
00052 static bool Dsfact(MatRepStd<T,n,idim>& rhs, T& det) {
00053 
00054 #ifdef XXX
00055   /* Function Body */
00056   if (idim < n || n <= 0) {
00057     return false;
00058   }
00059 #endif
00060 
00061 #ifdef OLD_IMPL
00062   typename MatrixRep::value_type* a = rhs.Array();
00063 #endif
00064 
00065 #ifdef XXX
00066   const typename MatrixRep::value_type* A = rhs.Array();
00067   typename MatrixRep::value_type array[MatrixRep::kSize];
00068   typename MatrixRep::value_type* a = array;
00069 
00070   // copy contents of matrix to working place
00071   for(unsigned int i=0; i<MatrixRep::kSize; ++i) {
00072     array[i] = A[i];
00073   }
00074 #endif
00075 
00076   /* Local variables */
00077   static unsigned int i, j, l;
00078 
00079   /* Parameter adjustments */
00080   //  a -= idim + 1;
00081   static int arrayOffset = -(idim+1);
00082   /* sfactd.inc */
00083   det = 1.;
00084   for (j = 1; j <= n; ++j) {
00085     const unsigned int ji = j * idim;
00086     const unsigned int jj = j + ji;
00087 
00088     if (rhs[jj + arrayOffset] <= 0.) {
00089       det = 0.;
00090       return false;
00091     }
00092 
00093     const unsigned int jp1 = j + 1;
00094     const unsigned int jpi = jp1 * idim;
00095 
00096     det *= rhs[jj + arrayOffset];
00097     rhs[jj + arrayOffset] = 1. / rhs[jj + arrayOffset];
00098 
00099     for (l = jp1; l <= n; ++l) {
00100       rhs[j + l * idim + arrayOffset] = rhs[jj + arrayOffset] * rhs[l + ji + arrayOffset];
00101 
00102       const unsigned int lj = l + jpi;
00103 
00104       for (i = 1; i <= j; ++i) {
00105         rhs[lj + arrayOffset] -= rhs[l + i * idim + arrayOffset] * rhs[i + jpi + arrayOffset];
00106       } // for i
00107     } // for l
00108   } // for j
00109 
00110   return true;
00111 } // end of Dsfact
00112 
00113 
00114    // t.b.d re-implement methods for symmetric
00115   // symmetric function (copy in a general  one) 
00116   template <class T>
00117   static bool Dsfact(MatRepSym<T,n> & rhs,  T & det) {
00118     // not very efficient but need to re-do Dsinv for new storage of 
00119     // symmetric matrices
00120     MatRepStd<T,n> tmp; 
00121     for (unsigned int i = 0; i< n*n; ++i) 
00122       tmp[i] = rhs[i];
00123     if (!  SDeterminant<n>::Dsfact(tmp,det) ) return false;
00124 //     // recopy the data
00125 //     for (int i = 0; i< idim*n; ++i) 
00126 //       rhs[i] = tmp[i];
00127 
00128     return true; 
00129   }
00130 
00131 
00132 };  // end of clas Sdeterminant
00133 
00134   }  // namespace Math
00135 
00136 }  // namespace ROOT
00137 
00138 #endif  /* ROOT_Math_Dsfact */
00139 

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