diff --git a/Eigen/Core b/Eigen/Core index 245604465..474ef5f8f 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -365,6 +365,7 @@ using std::ptrdiff_t; #include "src/Core/GeneralProduct.h" #ifdef EIGEN_ENABLE_EVALUATORS #include "src/Core/Solve.h" +#include "src/Core/Inverse.h" #endif #include "src/Core/TriangularMatrix.h" #include "src/Core/SelfAdjointView.h" diff --git a/Eigen/LU b/Eigen/LU index db5795504..fac80024f 100644 --- a/Eigen/LU +++ b/Eigen/LU @@ -25,7 +25,7 @@ #include "src/LU/PartialPivLU_MKL.h" #endif #include "src/LU/Determinant.h" -#include "src/LU/Inverse.h" +#include "src/LU/InverseImpl.h" #if defined EIGEN_VECTORIZE_SSE #include "src/LU/arch/Inverse_SSE.h" diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h new file mode 100644 index 000000000..0cfc71d34 --- /dev/null +++ b/Eigen/src/Core/Inverse.h @@ -0,0 +1,131 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2014 Gael Guennebaud +// +// 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_INVERSE_H +#define EIGEN_INVERSE_H + +namespace Eigen { + +#ifdef EIGEN_TEST_EVALUATORS + +// TODO move the general declaration in Core, and rename this file DenseInverseImpl.h, or something like this... + +template class InverseImpl; + +namespace internal { + +template +struct traits > + : traits +{ + typedef typename XprType::PlainObject PlainObject; + typedef traits BaseTraits; + enum { + Flags = BaseTraits::Flags & RowMajorBit, + CoeffReadCost = Dynamic + }; +}; + +} // end namespace internal + +/** \class Inverse + * + * \brief Expression of the inverse of another expression + * + * \tparam XprType the type of the expression we are taking the inverse + * + * This class represents an abstract expression of A.inverse() + * and most of the time this is the only way it is used. + * + */ +template +class Inverse : public InverseImpl::StorageKind> +{ +public: + typedef typename XprType::Index Index; + typedef typename XprType::PlainObject PlainObject; + typedef typename internal::nested::type XprTypeNested; + typedef typename internal::remove_all::type XprTypeNestedCleaned; + + Inverse(const XprType &xpr) + : m_xpr(xpr) + {} + + EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); } + EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); } + + EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; } + +protected: + XprTypeNested &m_xpr; +}; + +/** \internal + * Specialization of the Inverse expression for dense expressions. + * Direct access to the coefficients are discared. + * FIXME this intermediate class is probably not needed anymore. + */ +template +class InverseImpl + : public MatrixBase > +{ + typedef Inverse Derived; + +public: + + typedef MatrixBase Base; + EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + +private: + + Scalar coeff(Index row, Index col) const; + Scalar coeff(Index i) const; +}; + +namespace internal { + +/** \internal + * \brief Default evaluator for Inverse expression. + * + * This default evaluator for Inverse expression simply evaluate the inverse into a temporary + * by a call to internal::call_assignment_no_alias. + * Therefore, inverse implementers only have to specialize Assignment, ...> for + * there own nested expression. + * + * \sa class Inverse + */ +template +struct evaluator > + : public evaluator::PlainObject>::type +{ + typedef Inverse InverseType; + typedef typename InverseType::PlainObject PlainObject; + typedef typename evaluator::type Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const InverseType& inv_xpr) + : m_result(inv_xpr.rows(), inv_xpr.cols()) + { + ::new (static_cast(this)) Base(m_result); + internal::call_assignment_no_alias(m_result, inv_xpr); + } + +protected: + PlainObject m_result; +}; + +} // end namespace internal + +#endif + +} // end namespace Eigen + +#endif // EIGEN_INVERSE_H diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/InverseImpl.h similarity index 83% rename from Eigen/src/LU/Inverse.h rename to Eigen/src/LU/InverseImpl.h index db053406e..174dfbac5 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/InverseImpl.h @@ -2,13 +2,14 @@ // for linear algebra. // // Copyright (C) 2008-2010 Benoit Jacob +// Copyright (C) 2014 Gael Guennebaud // // 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_INVERSE_H -#define EIGEN_INVERSE_H +#ifndef EIGEN_INVERSE_IMPL_H +#define EIGEN_INVERSE_IMPL_H namespace Eigen { @@ -324,117 +325,9 @@ struct inverse_impl : public ReturnByValue > #ifdef EIGEN_TEST_EVALUATORS -// TODO move the general declaration in Core, and rename this file DenseInverseImpl.h, or something like this... - -template class InverseImpl; - namespace internal { -template -struct traits > - : traits -{ - typedef typename XprType::PlainObject PlainObject; - typedef traits BaseTraits; - enum { - Flags = BaseTraits::Flags & RowMajorBit, - CoeffReadCost = Dynamic - }; -}; - -} // end namespace internal - -/** \class Inverse - * \ingroup LU_Module - * - * \brief Expression of the inverse of another expression - * - * \tparam XprType the type of the expression we are taking the inverse - * - * This class represents an abstract expression of A.inverse() - * and most of the time this is the only way it is used. - * - */ -template -class Inverse : public InverseImpl::StorageKind> -{ -public: - typedef typename XprType::Index Index; - typedef typename XprType::PlainObject PlainObject; - typedef typename internal::nested::type XprTypeNested; - typedef typename internal::remove_all::type XprTypeNestedCleaned; - - Inverse(const XprType &xpr) - : m_xpr(xpr) - {} - - EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); } - EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); } - - EIGEN_DEVICE_FUNC const XprTypeNestedCleaned& nestedExpression() const { return m_xpr; } - -protected: - XprTypeNested &m_xpr; -}; - -/** \internal - * Specialization of the Inverse expression for dense expressions. - * Direct access to the coefficients are discared. - * FIXME this intermediate class is probably not needed anymore. - */ -template -class InverseImpl - : public MatrixBase > -{ - typedef Inverse Derived; - -public: - - typedef MatrixBase Base; - EIGEN_DENSE_PUBLIC_INTERFACE(Derived) - -private: - - Scalar coeff(Index row, Index col) const; - Scalar coeff(Index i) const; -}; - -namespace internal { - -/** \internal - * \brief Default evaluator for Inverse expression. - * - * This default evaluator for Inverse expression simply evaluate the inverse into a temporary - * by a call to internal::call_assignment_no_alias. - * Therefore, inverse implementers only have to specialize Assignment, ...> for - * there own nested expression. - * - * \sa class Inverse - */ -template -struct evaluator > - : public evaluator::PlainObject>::type -{ - typedef Inverse InverseType; - typedef typename InverseType::PlainObject PlainObject; - typedef typename evaluator::type Base; - - typedef evaluator type; - typedef evaluator nestedType; - - evaluator(const InverseType& inv_xpr) - : m_result(inv_xpr.rows(), inv_xpr.cols()) - { - ::new (static_cast(this)) Base(m_result); - internal::call_assignment_no_alias(m_result, inv_xpr); - } - -protected: - PlainObject m_result; -}; - -// Specialization for "dst = xpr.inverse()" -// NOTE we need to specialize it for Dense2Dense to avoid ambiguous specialization error and a Sparse2Sparse specialization must exist somewhere +// Specialization for "dense = dense_xpr.inverse()" template struct Assignment, internal::assign_op, Dense2Dense, Scalar> { @@ -569,4 +462,4 @@ inline void MatrixBase::computeInverseWithCheck( } // end namespace Eigen -#endif // EIGEN_INVERSE_H +#endif // EIGEN_INVERSE_IMPL_H