blob: 80e695d12cd817db7923199257d9a273ea7f23a9 [file] [log] [blame]
 // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008 Benoit Jacob // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_DETERMINANT_H #define EIGEN_DETERMINANT_H #include "./InternalHeaderCheck.h" namespace Eigen { namespace internal { template EIGEN_DEVICE_FUNC inline const typename Derived::Scalar bruteforce_det3_helper (const MatrixBase& matrix, int a, int b, int c) { return matrix.coeff(0,a) * (matrix.coeff(1,b) * matrix.coeff(2,c) - matrix.coeff(1,c) * matrix.coeff(2,b)); } template struct determinant_impl { static inline typename traits::Scalar run(const Derived& m) { if(Derived::ColsAtCompileTime==Dynamic && m.rows()==0) return typename traits::Scalar(1); return m.partialPivLu().determinant(); } }; template struct determinant_impl { static inline EIGEN_DEVICE_FUNC typename traits::Scalar run(const Derived& m) { return m.coeff(0,0); } }; template struct determinant_impl { static inline EIGEN_DEVICE_FUNC typename traits::Scalar run(const Derived& m) { return m.coeff(0,0) * m.coeff(1,1) - m.coeff(1,0) * m.coeff(0,1); } }; template struct determinant_impl { static inline EIGEN_DEVICE_FUNC typename traits::Scalar run(const Derived& m) { return bruteforce_det3_helper(m,0,1,2) - bruteforce_det3_helper(m,1,0,2) + bruteforce_det3_helper(m,2,0,1); } }; template struct determinant_impl { typedef typename traits::Scalar Scalar; static EIGEN_DEVICE_FUNC Scalar run(const Derived& m) { Scalar d2_01 = det2(m, 0, 1); Scalar d2_02 = det2(m, 0, 2); Scalar d2_03 = det2(m, 0, 3); Scalar d2_12 = det2(m, 1, 2); Scalar d2_13 = det2(m, 1, 3); Scalar d2_23 = det2(m, 2, 3); Scalar d3_0 = det3(m, 1,d2_23, 2,d2_13, 3,d2_12); Scalar d3_1 = det3(m, 0,d2_23, 2,d2_03, 3,d2_02); Scalar d3_2 = det3(m, 0,d2_13, 1,d2_03, 3,d2_01); Scalar d3_3 = det3(m, 0,d2_12, 1,d2_02, 2,d2_01); return internal::pmadd(static_cast(-m(0,3)),d3_0, static_cast(m(1,3)*d3_1)) + internal::pmadd(static_cast(-m(2,3)),d3_2, static_cast(m(3,3)*d3_3)); } protected: static EIGEN_DEVICE_FUNC Scalar det2(const Derived& m, Index i0, Index i1) { return m(i0,0) * m(i1,1) - m(i1,0) * m(i0,1); } static EIGEN_DEVICE_FUNC Scalar det3(const Derived& m, Index i0, const Scalar& d0, Index i1, const Scalar& d1, Index i2, const Scalar& d2) { return internal::pmadd(m(i0,2), d0, internal::pmadd(static_cast(-m(i1,2)), d1, static_cast(m(i2,2)*d2))); } }; } // end namespace internal /** \lu_module * * \returns the determinant of this matrix */ template EIGEN_DEVICE_FUNC inline typename internal::traits::Scalar MatrixBase::determinant() const { eigen_assert(rows() == cols()); typedef typename internal::nested_eval::type Nested; return internal::determinant_impl>::run(derived()); } } // end namespace Eigen #endif // EIGEN_DETERMINANT_H