00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #ifdef _MSC_VER
00031 # pragma once
00032 # pragma warning( push )
00033 # pragma warning( disable : 4127 4786 )
00034 #endif // _MSC_VER
00035
00036 #ifndef EXMAT_MATH_DETERMINANT_H
00037 #define EXMAT_MATH_DETERMINANT_H
00038
00039
00040 namespace exmat {
00041
00042 namespace PNS {
00044 template<size_t N> struct DeterminantComplexity {
00045 enum {
00046 RET = N * (DeterminantComplexity<N-1>::RET + 3)
00047 };
00048 };
00049 template<> struct DeterminantComplexity<1>
00050 { enum { RET = 0 }; };
00051 template<> struct DeterminantComplexity<2>
00052 { enum { RET = 3 }; };
00053 template<> struct DeterminantComplexity<3>
00054 { enum { RET = 17 }; };
00055
00056 template<class Rep, class ErrChk>
00057 EXMAT_INLINE1 static typename Rep::value_type
00058 determinant(const Mat<Rep,ErrChk>& m, Int2Type<0>) {
00059 switch(m.rows()) {
00060 case 1:
00061 return determinant(m, Int2Type<1>()); break;
00062 case 2:
00063 return determinant(m, Int2Type<2>()); break;
00064 case 3:
00065 return determinant(m, Int2Type<3>()); break;
00066 default:
00067 THROWMSG(true, "Sorry not yet implemented", __FILE__);
00068 break;
00069 }
00070 return 0;
00071 }
00072 template<class Rep, class ErrChk>
00073 EXMAT_INLINE2 static typename Rep::value_type
00074 determinant(const Mat<Rep,ErrChk>& m, Int2Type<1>) {
00075 return m.getAt(0,0);
00076 }
00077 template<class Rep, class ErrChk>
00078 EXMAT_INLINE2 static typename Rep::value_type
00079 determinant(const Mat<Rep,ErrChk>& m, Int2Type<2>) {
00080 return m.getAt(0,0) * m.getAt(1,1) - m.getAt(1,0) * m.getAt(0,1);
00081 }
00082 template<class Rep, class ErrChk>
00083 EXMAT_INLINE1 static typename Rep::value_type
00084 determinant(const Mat<Rep,ErrChk>& m, Int2Type<3>) {
00085 return
00086 m.getAt(0,0) * m.getAt(1,1) * m.getAt(2,2) +
00087 m.getAt(0,1) * m.getAt(1,2) * m.getAt(2,0) +
00088 m.getAt(0,2) * m.getAt(1,0) * m.getAt(2,1) -
00089 m.getAt(0,2) * m.getAt(1,1) * m.getAt(2,0) -
00090 m.getAt(0,0) * m.getAt(1,2) * m.getAt(2,1) -
00091 m.getAt(0,1) * m.getAt(1,0) * m.getAt(2,2);
00092 }
00093 #if HAVE_PARTIAL_SPECIALIZATION
00094 template<class Rep, class ErrChk, size_t I>
00095 EXMAT_INLINE1 static typename Rep::value_type
00096 determinant(const Mat<Rep,ErrChk>& m, Int2Type<I>);
00097 #endif
00098 }
00099
00105 template<class Rep, class ErrChk>
00106 EXMAT_INLINE2 static typename Rep::value_type
00107 determinant(const Mat<Rep,ErrChk>& m) {
00108 typedef typename Rep::value_type value_type;
00109 THROWMSG(m.rows() != 0 && m.rows() == m.cols(), IncompatibleErrMsg, __FILE__);
00110 return exmat::PNS::determinant(m, Int2Type<HAVE_PARTIAL_SPECIALIZATION ? Rep::ROWS : 0>());
00111 }
00112
00113
00114 }
00115
00116 #ifdef _MSC_VER
00117 # pragma warning( pop )
00118 #endif // _MSC_VER
00119
00120 #endif // EXMAT_MATH_DETERMINANT_H