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 template<typename Derived>
00029 inline const typename Derived::Scalar ei_bruteforce_det3_helper
00030 (const MatrixBase<Derived>& matrix, int a, int b, int c)
00031 {
00032 return matrix.coeff(0,a)
00033 * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b));
00034 }
00035
00036 template<typename Derived>
00037 const typename Derived::Scalar ei_bruteforce_det4_helper
00038 (const MatrixBase<Derived>& matrix, int j, int k, int m, int n)
00039 {
00040 return (matrix.coeff(j,0) * matrix.coeff(k,1) - matrix.coeff(k,0) * matrix.coeff(j,1))
00041 * (matrix.coeff(m,2) * matrix.coeff(n,3) - matrix.coeff(n,2) * matrix.coeff(m,3));
00042 }
00043
00044 const int TriangularDeterminant = 0;
00045
00046 template<typename Derived,
00047 int DeterminantType =
00048 (Derived::Flags & (UpperTriangularBit | LowerTriangularBit))
00049 ? TriangularDeterminant : Derived::RowsAtCompileTime
00050 > struct ei_determinant_impl
00051 {
00052 static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
00053 {
00054 return m.lu().determinant();
00055 }
00056 };
00057
00058 template<typename Derived> struct ei_determinant_impl<Derived, TriangularDeterminant>
00059 {
00060 static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
00061 {
00062 if (Derived::Flags & UnitDiagBit)
00063 return 1;
00064 else if (Derived::Flags & ZeroDiagBit)
00065 return 0;
00066 else
00067 return m.diagonal().redux(ei_scalar_product_op<typename ei_traits<Derived>::Scalar>());
00068 }
00069 };
00070
00071 template<typename Derived> struct ei_determinant_impl<Derived, 1>
00072 {
00073 static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
00074 {
00075 return m.coeff(0,0);
00076 }
00077 };
00078
00079 template<typename Derived> struct ei_determinant_impl<Derived, 2>
00080 {
00081 static inline typename ei_traits<Derived>::Scalar run(const Derived& m)
00082 {
00083 return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1);
00084 }
00085 };
00086
00087 template<typename Derived> struct ei_determinant_impl<Derived, 3>
00088 {
00089 static typename ei_traits<Derived>::Scalar run(const Derived& m)
00090 {
00091 return ei_bruteforce_det3_helper(m,0,1,2)
00092 - ei_bruteforce_det3_helper(m,1,0,2)
00093 + ei_bruteforce_det3_helper(m,2,0,1);
00094 }
00095 };
00096
00097 template<typename Derived> struct ei_determinant_impl<Derived, 4>
00098 {
00099 static typename ei_traits<Derived>::Scalar run(const Derived& m)
00100 {
00101
00102 return ei_bruteforce_det4_helper(m,0,1,2,3)
00103 - ei_bruteforce_det4_helper(m,0,2,1,3)
00104 + ei_bruteforce_det4_helper(m,0,3,1,2)
00105 + ei_bruteforce_det4_helper(m,1,2,0,3)
00106 - ei_bruteforce_det4_helper(m,1,3,0,2)
00107 + ei_bruteforce_det4_helper(m,2,3,0,1);
00108 }
00109 };
00110
00115 template<typename Derived>
00116 inline typename ei_traits<Derived>::Scalar MatrixBase<Derived>::determinant() const
00117 {
00118 assert(rows() == cols());
00119 return ei_determinant_impl<Derived>::run(derived());
00120 }
00121
00122 #endif // EIGEN_DETERMINANT_H