Dfinv.h

Go to the documentation of this file.
00001 // @(#)root/smatrix:$Id: Dfinv.h 20882 2007-11-19 11:31:26Z rdm $
00002 // Authors: T. Glebe, L. Moneta    2005  
00003 
00004 #ifndef ROOT_Math_Dfinv
00005 #define ROOT_Math_Dfinv
00006 // ********************************************************************
00007 //
00008 // source:
00009 //
00010 // type:      source code
00011 //
00012 // created:   03. 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: Matrix inversion
00023 //              Code was taken from CERNLIB::kernlib dfinv function, translated
00024 //              from FORTRAN to C++ and optimized.
00025 //
00026 // changes:
00027 // 03 Apr 2001 (TG) creation
00028 //
00029 // ********************************************************************
00030 
00031 
00032 namespace ROOT { 
00033 
00034   namespace Math { 
00035 
00036 
00037 
00038 
00039 /** Dfinv.
00040     Function to compute the inverse of a square matrix ($A^{-1}$) of
00041     dimension $idim$ and order $n$. The routine Dfactir must be called
00042     before Dfinv!
00043 
00044     @author T. Glebe
00045 */
00046 template <class Matrix, unsigned int n, unsigned int idim>
00047 bool Dfinv(Matrix& rhs, unsigned int* ir) {
00048 #ifdef XXX
00049   if (idim < n || n <= 0 || n==1) {
00050     return false;
00051   }
00052 #endif
00053 
00054   typename Matrix::value_type* a = rhs.Array();
00055 
00056   /* Local variables */
00057   static unsigned int nxch, i, j, k, m, ij;
00058   static unsigned int im2, nm1, nmi;
00059   static typename Matrix::value_type s31, s34, ti;
00060   
00061   /* Parameter adjustments */
00062   a -= idim + 1;
00063   --ir;
00064   
00065   /* Function Body */
00066   
00067   /* finv.inc */
00068 
00069   a[idim + 2] = -a[(idim << 1) + 2] * (a[idim + 1] * a[idim + 2]);
00070   a[(idim << 1) + 1] = -a[(idim << 1) + 1];
00071 
00072   if (n != 2) {
00073     for (i = 3; i <= n; ++i) {
00074       const unsigned int ii   = i * idim;
00075       const unsigned int iii  = i + ii;
00076       const unsigned int imi  = ii - idim;
00077       const unsigned int iimi = i + imi;
00078       im2 = i - 2;
00079       for (j = 1; j <= im2; ++j) {
00080         const unsigned int ji  = j * idim;
00081         const unsigned int jii = j + ii;
00082         s31 = 0.;
00083         for (k = j; k <= im2; ++k) {
00084           s31 += a[k + ji] * a[i + k * idim];
00085           a[jii] += a[j + (k + 1) * idim] * a[k + 1 + ii];
00086         } // for k
00087         a[i + ji] = -a[iii] * (a[i - 1 + ji] * a[iimi] + s31);
00088         a[jii] *= -1;
00089       } // for j
00090       a[iimi] = -a[iii] * (a[i - 1 + imi] * a[iimi]);
00091       a[i - 1 + ii] *= -1;
00092     } // for i
00093   } // if n!=2
00094 
00095   nm1 = n - 1;
00096   for (i = 1; i <= nm1; ++i) {
00097     const unsigned int ii = i * idim;
00098     nmi = n - i;
00099     for (j = 1; j <= i; ++j) {
00100       const unsigned int ji  = j * idim;
00101       const unsigned int iji = i + ji;
00102       for (k = 1; k <= nmi; ++k) {
00103         a[iji] += a[i + k + ji] * a[i + (i + k) * idim];
00104       } // for k
00105     } // for j
00106 
00107     for (j = 1; j <= nmi; ++j) {
00108       const unsigned int ji = j * idim;
00109       s34 = 0.;
00110       for (k = j; k <= nmi; ++k) {
00111         s34 += a[i + k + ii + ji] * a[i + (i + k) * idim];
00112       } // for k
00113       a[i + ii + ji] = s34;
00114     } // for j
00115   } // for i
00116 
00117   nxch = ir[n];
00118   if (nxch == 0) {
00119     return true;
00120   }
00121 
00122   for (m = 1; m <= nxch; ++m) {
00123     k = nxch - m + 1;
00124     ij = ir[k];
00125     i = ij / 4096;
00126     j = ij % 4096;
00127     const unsigned int ii = i * idim;
00128     const unsigned int ji = j * idim;
00129     for (k = 1; k <= n; ++k) {
00130       ti = a[k + ii];
00131       a[k + ii] = a[k + ji];
00132       a[k + ji] = ti;
00133     } // for k
00134   } // for m
00135 
00136   return true;
00137 } // Dfinv
00138 
00139 
00140   }  // namespace Math
00141 
00142 }  // namespace ROOT
00143           
00144 
00145 
00146 #endif  /* ROOT_Math_Dfinv */

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