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