00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_DETERMINANT_H
00026 #define EIGEN_DETERMINANT_H
00027
00028 namespace internal {
00029
00030 template<typename Derived>
00031 inline const typename Derived::Scalar bruteforce_det3_helper
00032 (const MatrixBase<Derived>& matrix, int a, int b, int c)
00033 {
00034 return matrix.coeff(0,a)
00035 * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b));
00036 }
00037
00038 template<typename Derived>
00039 const typename Derived::Scalar bruteforce_det4_helper
00040 (const MatrixBase<Derived>& matrix, int j, int k, int m, int n)
00041 {
00042 return (matrix.coeff(j,0) * matrix.coeff(k,1) - matrix.coeff(k,0) * matrix.coeff(j,1))
00043 * (matrix.coeff(m,2) * matrix.coeff(n,3) - matrix.coeff(n,2) * matrix.coeff(m,3));
00044 }
00045
00046 template<typename Derived,
00047 int DeterminantType = Derived::RowsAtCompileTime
00048 > struct determinant_impl
00049 {
00050 static inline typename traits<Derived>::Scalar run(const Derived& m)
00051 {
00052 if(Derived::ColsAtCompileTime==Dynamic && m.rows()==0)
00053 return typename traits<Derived>::Scalar(1);
00054 return m.partialPivLu().determinant();
00055 }
00056 };
00057
00058 template<typename Derived> struct determinant_impl<Derived, 1>
00059 {
00060 static inline typename traits<Derived>::Scalar run(const Derived& m)
00061 {
00062 return m.coeff(0,0);
00063 }
00064 };
00065
00066 template<typename Derived> struct determinant_impl<Derived, 2>
00067 {
00068 static inline typename traits<Derived>::Scalar run(const Derived& m)
00069 {
00070 return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1);
00071 }
00072 };
00073
00074 template<typename Derived> struct determinant_impl<Derived, 3>
00075 {
00076 static inline typename traits<Derived>::Scalar run(const Derived& m)
00077 {
00078 return bruteforce_det3_helper(m,0,1,2)
00079 - bruteforce_det3_helper(m,1,0,2)
00080 + bruteforce_det3_helper(m,2,0,1);
00081 }
00082 };
00083
00084 template<typename Derived> struct determinant_impl<Derived, 4>
00085 {
00086 static typename traits<Derived>::Scalar run(const Derived& m)
00087 {
00088
00089 return bruteforce_det4_helper(m,0,1,2,3)
00090 - bruteforce_det4_helper(m,0,2,1,3)
00091 + bruteforce_det4_helper(m,0,3,1,2)
00092 + bruteforce_det4_helper(m,1,2,0,3)
00093 - bruteforce_det4_helper(m,1,3,0,2)
00094 + bruteforce_det4_helper(m,2,3,0,1);
00095 }
00096 };
00097
00098 }
00099
00104 template<typename Derived>
00105 inline typename internal::traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
00106 {
00107 assert(rows() == cols());
00108 typedef typename internal::nested<Derived,Base::RowsAtCompileTime>::type Nested;
00109 return internal::determinant_impl<typename internal::remove_all<Nested>::type>::run(derived());
00110 }
00111
00112 #endif // EIGEN_DETERMINANT_H