Dfactir.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: Dfactir.h 20882 2007-11-19 11:31:26Z rdm $
00002 // Authors: T. Glebe, L. Moneta    2005  
00003 
00004 #ifndef ROOT_Math_Dfactir
00005 #define ROOT_Math_Dfactir
00006 // ********************************************************************
00007 //
00008 // source:
00009 //
00010 // type:      source code
00011 //
00012 // created:   02. Apr 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 square matrix, needed for Dfinv()
00023 //              Code was taken from CERNLIB::kernlib dfact function, translated
00024 //              from FORTRAN to C++ and optimized.
00025 //
00026 // changes:
00027 // 02 Apr 2001 (TG) creation
00028 //
00029 // ********************************************************************
00030 
00031 #include <cmath>
00032 
00033 namespace ROOT { 
00034 
00035   namespace Math { 
00036 
00037 
00038 /** Dfactir.
00039     Function to compute the determinant from a square matrix, Det(A) of
00040     dimension idim and order n. A working area ir is returned which is
00041     needed by the Dfinv routine.
00042 
00043     @author T. Glebe
00044 */
00045 template <class Matrix, unsigned int n, unsigned int idim>
00046 bool Dfactir(Matrix& rhs, typename Matrix::value_type& det, unsigned int* ir)
00047   // int *n, float *a, int *idim, int *ir, int *ifail, float *det, int *jfail)
00048 {
00049 
00050 #ifdef XXX
00051   if (idim < n || n <= 0) {
00052     return false;
00053   }
00054 #endif
00055 
00056 
00057   /* Initialized data */
00058   typename Matrix::value_type* a = rhs.Array();
00059 
00060   /* Local variables */
00061   static unsigned int nxch, i, j, k, l;
00062   static typename Matrix::value_type p, q, tf;
00063   
00064   /* Parameter adjustments */
00065   a -= idim + 1;
00066   --ir;
00067 
00068   /* Function Body */
00069   
00070   // fact.inc
00071   nxch = 0;
00072   det = 1.;
00073   for (j = 1; j <= n; ++j) {
00074     const unsigned int ji = j * idim;
00075     const unsigned int jj = j + ji;
00076 
00077     k = j;
00078     p = std::abs(a[jj]);
00079 
00080     if (j != n) {
00081       for (i = j + 1; i <= n; ++i) {
00082         q = std::abs(a[i + ji]);
00083         if (q > p) {
00084           k = i;
00085           p = q;
00086         }
00087       } // for i
00088 
00089       if (k != j) {
00090         for (l = 1; l <= n; ++l) {
00091           const unsigned int li = l*idim;
00092           const unsigned int jli = j + li;
00093           const unsigned int kli = k + li;
00094           tf = a[jli];
00095           a[jli] = a[kli];
00096           a[kli] = tf;
00097         } // for l
00098         ++nxch;
00099         ir[nxch] = (j << 12) + k;
00100       } // if k != j
00101     } // if j!=n
00102 
00103     if (p <= 0.) {
00104       det = 0;
00105       return false;
00106     }
00107 
00108     det *= a[jj];
00109 #ifdef XXX
00110     t = std::abs(det);
00111     if (t < 1e-19 || t > 1e19) {
00112       det = 0;
00113       return false;
00114     }
00115 #endif
00116 
00117     a[jj] = 1. / a[jj];
00118     if (j == n) {
00119       continue;
00120     }
00121 
00122     const unsigned int jm1 = j - 1;
00123     const unsigned int jpi = (j + 1) * idim;
00124     const unsigned int jjpi = j + jpi;
00125 
00126     for (k = j + 1; k <= n; ++k) {
00127       const unsigned int ki  = k * idim;
00128       const unsigned int jki = j + ki;
00129       const unsigned int kji = k + jpi;
00130       if (j != 1) {
00131         for (i = 1; i <= jm1; ++i) {
00132           const unsigned int ii = i * idim;
00133           a[jki] -= a[i + ki] * a[j + ii];
00134           a[kji] -= a[i + jpi] * a[k + ii];
00135         } // for i
00136       }
00137       a[jki] *= a[jj];
00138       a[kji] -= a[jjpi] * a[k + ji];
00139     } // for k
00140   } // for j
00141 
00142   if (nxch % 2 != 0) {
00143     det = -(det);
00144   }
00145   ir[n] = nxch;
00146   return true;
00147 } // end of Dfact
00148 
00149 
00150   }  // namespace Math
00151 
00152 }  // namespace ROOT
00153           
00154 
00155 
00156 #endif /* ROOT_Math_Dfactir */

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