00001
00002
00003
00004 #ifndef ROOT_Math_Dfact
00005 #define ROOT_Math_Dfact
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <cmath>
00032
00033 #ifndef ROOT_Math_MatrixRepresentationsStatic
00034 #include "Math/MatrixRepresentationsStatic.h"
00035 #endif
00036
00037 namespace ROOT {
00038
00039 namespace Math {
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template <unsigned int n, unsigned int idim = n>
00051 class Determinant {
00052 public:
00053
00054 template <class T>
00055 static bool Dfact(MatRepStd<T,n,idim>& rhs, T& det) {
00056
00057 #ifdef XXX
00058 if (idim < n || n <= 0) {
00059 return false;
00060 }
00061 #endif
00062
00063
00064
00065
00066
00067
00068
00069 static unsigned int nxch, i, j, k, l;
00070
00071 static T p, q, tf;
00072
00073
00074
00075 static int arrayOffset = - int(idim+1);
00076
00077
00078
00079
00080 nxch = 0;
00081 det = 1.;
00082 for (j = 1; j <= n; ++j) {
00083 const unsigned int ji = j * idim;
00084 const unsigned int jj = j + ji;
00085
00086 k = j;
00087 p = std::abs(rhs[jj + arrayOffset]);
00088
00089 if (j != n) {
00090 for (i = j + 1; i <= n; ++i) {
00091 q = std::abs(rhs[i + ji + arrayOffset]);
00092 if (q > p) {
00093 k = i;
00094 p = q;
00095 }
00096 }
00097 if (k != j) {
00098 for (l = 1; l <= n; ++l) {
00099 const unsigned int li = l*idim;
00100 const unsigned int jli = j + li;
00101 const unsigned int kli = k + li;
00102 tf = rhs[jli + arrayOffset];
00103 rhs[jli + arrayOffset] = rhs[kli + arrayOffset];
00104 rhs[kli + arrayOffset] = tf;
00105 }
00106 ++nxch;
00107 }
00108 }
00109
00110 if (p <= 0.) {
00111 det = 0;
00112 return false;
00113 }
00114
00115 det *= rhs[jj + arrayOffset];
00116 #ifdef XXX
00117 t = std::abs(det);
00118 if (t < 1e-19 || t > 1e19) {
00119 det = 0;
00120 return false;
00121 }
00122 #endif
00123
00124 rhs[jj + arrayOffset] = 1.0f / rhs[jj + arrayOffset];
00125 if (j == n) {
00126 continue;
00127 }
00128
00129 const unsigned int jm1 = j - 1;
00130 const unsigned int jpi = (j + 1) * idim;
00131 const unsigned int jjpi = j + jpi;
00132
00133 for (k = j + 1; k <= n; ++k) {
00134 const unsigned int ki = k * idim;
00135 const unsigned int jki = j + ki;
00136 const unsigned int kji = k + jpi;
00137 if (j != 1) {
00138 for (i = 1; i <= jm1; ++i) {
00139 const unsigned int ii = i * idim;
00140 rhs[jki + arrayOffset] -= rhs[i + ki + arrayOffset] * rhs[j + ii + arrayOffset];
00141 rhs[kji + arrayOffset] -= rhs[i + jpi + arrayOffset] * rhs[k + ii + arrayOffset];
00142 }
00143 }
00144 rhs[jki + arrayOffset] *= rhs[jj + arrayOffset];
00145 rhs[kji + arrayOffset] -= rhs[jjpi + arrayOffset] * rhs[k + ji + arrayOffset];
00146 }
00147 }
00148
00149 if (nxch % 2 != 0) {
00150 det = -(det);
00151 }
00152 return true;
00153 }
00154
00155
00156
00157
00158 template <class T>
00159 static bool Dfact(MatRepSym<T,n> & rhs, T & det) {
00160
00161
00162 MatRepStd<T,n> tmp;
00163 for (unsigned int i = 0; i< n*n; ++i)
00164 tmp[i] = rhs[i];
00165 if (! Determinant<n>::Dfact(tmp,det) ) return false;
00166
00167
00168
00169
00170 return true;
00171 }
00172
00173 };
00174
00175
00176 }
00177
00178 }
00179
00180
00181
00182 #endif