1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 42b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// Copyright (C) 2009-2015 Gael Guennebaud <gael.guennebaud@inria.fr> 57faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr> 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SPARSE_TRIANGULARVIEW_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSE_TRIANGULARVIEW_H 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace Eigen { 152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang/** \ingroup SparseCore_Module 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \brief Base class for a triangular part in a \b sparse matrix 192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * This class is an abstract base class of class TriangularView, and objects of type TriangularViewImpl cannot be instantiated. 212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * It extends class TriangularView with additional methods which are available for sparse expressions only. 222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * \sa class TriangularView, SparseMatrixBase::triangularView() 242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang */ 252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename MatrixType, unsigned int Mode> class TriangularViewImpl<MatrixType,Mode,Sparse> 262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : public SparseMatrixBase<TriangularView<MatrixType,Mode> > 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit)) 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || ((Mode&Upper) && (MatrixType::Flags&RowMajorBit)), 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SkipLast = !SkipFirst, 317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SkipDiag = (Mode&ZeroDiag) ? 1 : 0, 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TriangularView<MatrixType,Mode> TriangularViewType; 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 382b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang // dummy solve function to make TriangularView happy. 392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang void solve() const; 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 412b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef SparseMatrixBase<TriangularViewType> Base; 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_SPARSE_PUBLIC_INTERFACE(TriangularViewType) 452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename MatrixType::Nested MatrixTypeNested; 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef; 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 502b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename RhsType, typename DstType> 512b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_DEVICE_FUNC 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const { 532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(!(internal::is_same<RhsType,DstType>::value && internal::extract_data(dst) == internal::extract_data(rhs))) 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang dst = rhs; 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang this->solveInPlace(dst); 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 582b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Applies the inverse of \c *this to the dense vector or matrix \a other, "in-place" */ 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const; 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang /** Applies the inverse of \c *this to the sparse vector or matrix \a other, "in-place" */ 622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const; 632b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<typename ArgType, unsigned int Mode> 692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct unary_evaluator<TriangularView<ArgType,Mode>, IteratorBased> 702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : evaluator_base<TriangularView<ArgType,Mode> > 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef TriangularView<ArgType,Mode> XprType; 732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangprotected: 752b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::Scalar Scalar; 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename XprType::StorageIndex StorageIndex; 782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 792b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { SkipFirst = ((Mode&Lower) && !(ArgType::Flags&RowMajorBit)) 812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang || ((Mode&Upper) && (ArgType::Flags&RowMajorBit)), 822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang SkipLast = !SkipFirst, 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang SkipDiag = (Mode&ZeroDiag) ? 1 : 0, 842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang HasUnitDiag = (Mode&UnitDiag) ? 1 : 0 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangpublic: 882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang enum { 902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoeffReadCost = evaluator<ArgType>::CoeffReadCost, 912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Flags = XprType::Flags 922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang explicit unary_evaluator(const XprType &xpr) : m_argImpl(xpr.nestedExpression()), m_arg(xpr.nestedExpression()) {} 952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline Index nonZerosEstimate() const { 972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return m_argImpl.nonZerosEstimate(); 982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1002b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang class InnerIterator : public EvalIterator 1012b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef EvalIterator Base; 1032b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang public: 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& xprEval, Index outer) 1062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang : Base(xprEval.m_argImpl,outer), m_returnOne(false), m_containsDiag(Base::outer()<xprEval.m_arg.innerSize()) 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1082b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(SkipFirst) 1092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang while((*this) && ((HasUnitDiag||SkipDiag) ? this->index()<=outer : this->index()<outer)) 1112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Base::operator++(); 1122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag) 1132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_returnOne = m_containsDiag; 1142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer())) 1162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if((!SkipFirst) && Base::operator bool()) 1182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Base::operator++(); 1192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_returnOne = m_containsDiag; 1202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE InnerIterator& operator++() 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag && m_returnOne) 1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_returnOne = false; 1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else 1282b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Base::operator++(); 1302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer())) 1312b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang { 1322b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if((!SkipFirst) && Base::operator bool()) 1332b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Base::operator++(); 1342b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang m_returnOne = m_containsDiag; 1352b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang } 1372b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return *this; 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1402b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang EIGEN_STRONG_INLINE operator bool() const 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1422b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag && m_returnOne) 1432b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return true; 1442b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(SkipFirst) return Base::operator bool(); 1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if (SkipDiag) return (Base::operator bool() && this->index() < this->outer()); 1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else return (Base::operator bool() && this->index() <= this->outer()); 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// inline Index row() const { return (ArgType::Flags&RowMajorBit ? Base::outer() : this->index()); } 1532b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang// inline Index col() const { return (ArgType::Flags&RowMajorBit ? this->index() : Base::outer()); } 1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline StorageIndex index() const 1557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag && m_returnOne) return internal::convert_index<StorageIndex>(Base::outer()); 1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else return Base::index(); 1587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 1592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang inline Scalar value() const 1607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 1612b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang if(HasUnitDiag && m_returnOne) return Scalar(1); 1622b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang else return Base::value(); 1637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 1642b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1652b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang protected: 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool m_returnOne; 1672b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang bool m_containsDiag; 1682b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang private: 1692b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Scalar& valueRef(); 1702b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang }; 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangprotected: 1732b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang evaluator<ArgType> m_argImpl; 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const ArgType& m_arg; 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode> 1812b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wanginline const TriangularView<const Derived, Mode> 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSparseMatrixBase<Derived>::triangularView() const 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1842b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang return TriangularView<const Derived, Mode>(derived()); 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSE_TRIANGULARVIEW_H 190