123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- // This file is part of Eigen, a lightweight C++ template library
- // for linear algebra.
- //
- // Copyright (C) 2009-2015 Gael Guennebaud <gael.guennebaud@inria.fr>
- // Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>
- //
- // 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_SPARSE_TRIANGULARVIEW_H
- #define EIGEN_SPARSE_TRIANGULARVIEW_H
- namespace Eigen {
- /** \ingroup SparseCore_Module
- *
- * \brief Base class for a triangular part in a \b sparse matrix
- *
- * This class is an abstract base class of class TriangularView, and objects of type TriangularViewImpl cannot be instantiated.
- * It extends class TriangularView with additional methods which are available for sparse expressions only.
- *
- * \sa class TriangularView, SparseMatrixBase::triangularView()
- */
- template<typename MatrixType, unsigned int Mode> class TriangularViewImpl<MatrixType,Mode,Sparse>
- : public SparseMatrixBase<TriangularView<MatrixType,Mode> >
- {
- enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
- || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)),
- SkipLast = !SkipFirst,
- SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
- HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
- };
-
- typedef TriangularView<MatrixType,Mode> TriangularViewType;
-
- protected:
- // dummy solve function to make TriangularView happy.
- void solve() const;
- typedef SparseMatrixBase<TriangularViewType> Base;
- public:
-
- EIGEN_SPARSE_PUBLIC_INTERFACE(TriangularViewType)
-
- typedef typename MatrixType::Nested MatrixTypeNested;
- typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
- typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
- template<typename RhsType, typename DstType>
- EIGEN_DEVICE_FUNC
- EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
- if(!(internal::is_same<RhsType,DstType>::value && internal::extract_data(dst) == internal::extract_data(rhs)))
- dst = rhs;
- this->solveInPlace(dst);
- }
- /** Applies the inverse of \c *this to the dense vector or matrix \a other, "in-place" */
- template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
- /** Applies the inverse of \c *this to the sparse vector or matrix \a other, "in-place" */
- template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
-
- };
- namespace internal {
- template<typename ArgType, unsigned int Mode>
- struct unary_evaluator<TriangularView<ArgType,Mode>, IteratorBased>
- : evaluator_base<TriangularView<ArgType,Mode> >
- {
- typedef TriangularView<ArgType,Mode> XprType;
-
- protected:
-
- typedef typename XprType::Scalar Scalar;
- typedef typename XprType::StorageIndex StorageIndex;
- typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
-
- enum { SkipFirst = ((Mode&Lower) && !(ArgType::Flags&RowMajorBit))
- || ((Mode&Upper) && (ArgType::Flags&RowMajorBit)),
- SkipLast = !SkipFirst,
- SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
- HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
- };
-
- public:
-
- enum {
- CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
- Flags = XprType::Flags
- };
-
- explicit unary_evaluator(const XprType &xpr) : m_argImpl(xpr.nestedExpression()), m_arg(xpr.nestedExpression()) {}
-
- inline Index nonZerosEstimate() const {
- return m_argImpl.nonZerosEstimate();
- }
-
- class InnerIterator : public EvalIterator
- {
- typedef EvalIterator Base;
- public:
- EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& xprEval, Index outer)
- : Base(xprEval.m_argImpl,outer), m_returnOne(false), m_containsDiag(Base::outer()<xprEval.m_arg.innerSize())
- {
- if(SkipFirst)
- {
- while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer))
- Base::operator++();
- if(HasUnitDiag)
- m_returnOne = m_containsDiag;
- }
- else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer()))
- {
- if((!SkipFirst) && Base::operator bool())
- Base::operator++();
- m_returnOne = m_containsDiag;
- }
- }
- EIGEN_STRONG_INLINE InnerIterator& operator++()
- {
- if(HasUnitDiag && m_returnOne)
- m_returnOne = false;
- else
- {
- Base::operator++();
- if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer()))
- {
- if((!SkipFirst) && Base::operator bool())
- Base::operator++();
- m_returnOne = m_containsDiag;
- }
- }
- return *this;
- }
-
- EIGEN_STRONG_INLINE operator bool() const
- {
- if(HasUnitDiag && m_returnOne)
- return true;
- if(SkipFirst) return Base::operator bool();
- else
- {
- if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
- else return (Base::operator bool() && this->index() <= this->outer());
- }
- }
- // inline Index row() const { return (ArgType::Flags&RowMajorBit ? Base::outer() : this->index()); }
- // inline Index col() const { return (ArgType::Flags&RowMajorBit ? this->index() : Base::outer()); }
- inline StorageIndex index() const
- {
- if(HasUnitDiag && m_returnOne) return internal::convert_index<StorageIndex>(Base::outer());
- else return Base::index();
- }
- inline Scalar value() const
- {
- if(HasUnitDiag && m_returnOne) return Scalar(1);
- else return Base::value();
- }
- protected:
- bool m_returnOne;
- bool m_containsDiag;
- private:
- Scalar& valueRef();
- };
-
- protected:
- evaluator<ArgType> m_argImpl;
- const ArgType& m_arg;
- };
- } // end namespace internal
- template<typename Derived>
- template<int Mode>
- inline const TriangularView<const Derived, Mode>
- SparseMatrixBase<Derived>::triangularView() const
- {
- return TriangularView<const Derived, Mode>(derived());
- }
- } // end namespace Eigen
- #endif // EIGEN_SPARSE_TRIANGULARVIEW_H
|