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