00001 #ifndef DataFormat_Math_invertPosDefMatrix_H
00002 #define DataFormat_Math_invertPosDefMatrix_H
00003
00004 #include "Math/SMatrix.h"
00005 #include "Math/CholeskyDecomp.h"
00006
00007
00008 template<typename T,unsigned int N>
00009 inline bool invertPosDefMatrix(ROOT::Math::SMatrix<T,N,N,ROOT::Math::MatRepSym<T,N> > & m) {
00010
00011 ROOT::Math::CholeskyDecomp<T,N> decomp(m);
00012 if (!decomp) {
00013 return m.Invert();
00014 } else
00015 decomp.Invert(m);
00016 return true;
00017
00018 }
00019
00020 template<typename T,unsigned int N>
00021 inline bool invertPosDefMatrix(ROOT::Math::SMatrix<T,N,N,ROOT::Math::MatRepSym<T,N> > const & mIn,
00022 ROOT::Math::SMatrix<T,N,N,ROOT::Math::MatRepSym<T,N> > & mOut) {
00023
00024 ROOT::Math::CholeskyDecomp<T,N> decomp(mIn);
00025 if (!decomp) {
00026 mOut=mIn;
00027 return mOut.Invert();
00028 } else
00029 decomp.Invert(mOut);
00030 return true;
00031
00032 }
00033
00034
00035 #if defined(__SSE3__)
00036 #include <pmmintrin.h>
00037
00038 namespace mathSSE {
00039 struct M2 {
00040
00041 struct M {double m00,m01,m11,m10;};
00042 union {
00043 double m[4];
00044 __m128d r[2];
00045 M mm;
00046 };
00047
00048
00049
00050 inline M2(double i00, double i01, double i10, double i11) {
00051 mm.m00=i00; mm.m01=i01; mm.m11=i11; mm.m10=i10; }
00052
00053 double & operator[](int i) { return m[i];}
00054 __m128d & r0() { return r[0]; }
00055 __m128d & r1() { return r[1]; }
00056
00057 double operator[](int i) const { return m[i];}
00058 __m128d const & r0() const { return r[0]; }
00059 __m128d const & r1() const { return r[1]; }
00060
00061
00062
00063 inline bool invert() {
00064 __m128d tmp = r1();
00065
00066 __m128d det = _mm_mul_pd(r0(),tmp);
00067 __m128d det2 = _mm_shuffle_pd(det,det,1);
00068
00069 det = _mm_sub_pd(det,det2);
00070
00071 r1() = _mm_div_pd(r0(),det);
00072
00073 r0() = _mm_div_pd(tmp,det);
00074 double d; _mm_store_sd(&d,det);
00075 return !(0.==d);
00076 }
00077
00078 } __attribute__ ((aligned (16))) ;
00079 }
00080
00081 template<>
00082 inline bool invertPosDefMatrix<double,2>(ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > & m) {
00083 mathSSE::M2 mm(m.Array()[0], m.Array()[1], m.Array()[1], m.Array()[2]);
00084
00085 bool ok = mm.invert();
00086 if (ok) {
00087 m.Array()[0] = mm[0];
00088 m.Array()[1] = mm[1];
00089 m.Array()[2] = mm[2];
00090 }
00091 return ok;
00092 }
00093
00094 template<>
00095 inline bool invertPosDefMatrix<double,2>(ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > const & mIn,
00096 ROOT::Math::SMatrix<double,2,2,ROOT::Math::MatRepSym<double,2> > & mOut) {
00097
00098 mathSSE::M2 mm(mIn.Array()[0], mIn.Array()[1], mIn.Array()[1], mIn.Array()[2]);
00099
00100 bool ok = mm.invert();
00101 mOut.Array()[0] = mm[0];
00102 mOut.Array()[1] = mm[1];
00103 mOut.Array()[2] = mm[2];
00104
00105 return ok;
00106 }
00107
00108 #endif
00109
00110
00111 #endif