00001
00002
00003
00004 #ifndef ROOT_Math_Dinv
00005 #define ROOT_Math_Dinv
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
00032 #ifdef OLD_IMPL
00033 #include "Math/Dfactir.h"
00034 #include "Math/Dfinv.h"
00035 #include "Math/Dsinv.h"
00036 #endif
00037
00038 #ifndef ROOT_Math_CholeskyDecomp
00039 #include "Math/CholeskyDecomp.h"
00040 #endif
00041
00042
00043
00044
00045
00046
00047
00048 namespace ROOT {
00049
00050 namespace Math {
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 template <unsigned int idim, unsigned int n = idim>
00069 class Inverter {
00070 public:
00071
00072
00073
00074 template <class MatrixRep>
00075 static bool Dinv(MatrixRep& rhs) {
00076
00077
00078
00079 unsigned int work[n+1] = {0};
00080
00081 static typename MatrixRep::value_type det(0);
00082
00083 if (DfactMatrix(rhs,det,work) != 0) {
00084 std::cerr << "Dfact_matrix failed!!" << std::endl;
00085 return false;
00086 }
00087
00088 int ifail = DfinvMatrix(rhs,work);
00089 if (ifail == 0) return true;
00090 return false;
00091 }
00092
00093
00094
00095
00096
00097 template <class T>
00098 static bool Dinv(MatRepSym<T,idim> & rhs) {
00099 int ifail = 0;
00100 InvertBunchKaufman(rhs,ifail);
00101 if (ifail == 0) return true;
00102 return false;
00103 }
00104
00105
00106
00107
00108
00109
00110 template <class T>
00111 static int DfactMatrix(MatRepStd<T,idim,n> & rhs, T & det, unsigned int * work);
00112
00113
00114
00115
00116 template <class T>
00117 static int DfinvMatrix(MatRepStd<T,idim,n> & rhs, unsigned int * work);
00118
00119
00120
00121
00122 template <class T>
00123 static void InvertBunchKaufman(MatRepSym<T,idim> & rhs, int &ifail);
00124
00125
00126
00127 };
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 template <unsigned int idim, unsigned int n = idim>
00144 class FastInverter {
00145 public:
00146
00147 template <class MatrixRep>
00148 static bool Dinv(MatrixRep& rhs) {
00149 return Inverter<idim,n>::Dinv(rhs);
00150 }
00151 template <class T>
00152 static bool Dinv(MatRepSym<T,idim> & rhs) {
00153 return Inverter<idim,n>::Dinv(rhs);
00154 }
00155 };
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 template <>
00167 class Inverter<0> {
00168 public:
00169
00170 template <class MatrixRep>
00171 inline static bool Dinv(MatrixRep&) { return true; }
00172 };
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 template <>
00184 class Inverter<1> {
00185 public:
00186
00187 template <class MatrixRep>
00188 static bool Dinv(MatrixRep& rhs) {
00189
00190 if (rhs[0] == 0.) {
00191 return false;
00192 }
00193 rhs[0] = 1. / rhs[0];
00194 return true;
00195 }
00196 };
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 template <>
00209 class Inverter<2> {
00210 public:
00211
00212 template <class MatrixRep>
00213 static bool Dinv(MatrixRep& rhs) {
00214
00215 typedef typename MatrixRep::value_type T;
00216 T det = rhs[0] * rhs[3] - rhs[2] * rhs[1];
00217
00218 if (det == T(0.) ) { return false; }
00219
00220 T s = T(1.0) / det;
00221
00222 T c11 = s * rhs[3];
00223
00224
00225 rhs[2] = -s * rhs[2];
00226 rhs[1] = -s * rhs[1];
00227 rhs[3] = s * rhs[0];
00228 rhs[0] = c11;
00229
00230
00231 return true;
00232 }
00233
00234
00235 template <class T>
00236 static bool Dinv(MatRepSym<T,2> & rep) {
00237
00238 T * rhs = rep.Array();
00239
00240 T det = rhs[0] * rhs[2] - rhs[1] * rhs[1];
00241
00242
00243 if (det == T(0.)) { return false; }
00244
00245 T s = T(1.0) / det;
00246 T c11 = s * rhs[2];
00247
00248 rhs[1] = -s * rhs[1];
00249 rhs[2] = s * rhs[0];
00250 rhs[0] = c11;
00251 return true;
00252 }
00253
00254 };
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 template <>
00266 class FastInverter<3> {
00267 public:
00268
00269
00270 template <class MatrixRep>
00271 static bool Dinv(MatrixRep& rhs);
00272
00273 template <class T>
00274 static bool Dinv(MatRepSym<T,3> & rhs);
00275
00276 };
00277
00278
00279
00280
00281 template <>
00282 class FastInverter<4> {
00283 public:
00284
00285 template <class MatrixRep>
00286 static bool Dinv(MatrixRep& rhs);
00287
00288 template <class T>
00289 static bool Dinv(MatRepSym<T,4> & rhs);
00290
00291 };
00292
00293
00294
00295
00296 template <>
00297 class FastInverter<5> {
00298 public:
00299
00300 template <class MatrixRep>
00301 static bool Dinv(MatrixRep& rhs);
00302
00303 template <class T>
00304 static bool Dinv(MatRepSym<T,5> & rhs);
00305
00306 };
00307
00308
00309
00310
00311
00312 template <unsigned int idim>
00313 class CholInverter {
00314 public:
00315
00316 template <class MatrixRep>
00317 static bool Dinv(MatrixRep&) {
00318 STATIC_CHECK( false, Error_cholesky_SMatrix_type_is_not_symmetric );
00319 return false;
00320 }
00321 template <class T>
00322 inline static bool Dinv(MatRepSym<T,idim> & rhs) {
00323 CholeskyDecomp<T, idim> decomp(rhs);
00324 return decomp.Invert(rhs);
00325 }
00326 };
00327
00328
00329 }
00330
00331 }
00332
00333 #ifndef ROOT_Math_CramerInversion_icc
00334 #include "CramerInversion.icc"
00335 #endif
00336 #ifndef ROOT_Math_CramerInversionSym_icc
00337 #include "CramerInversionSym.icc"
00338 #endif
00339 #ifndef ROOT_Math_MatrixInversion_icc
00340 #include "MatrixInversion.icc"
00341 #endif
00342
00343 #endif