MOAB  4.9.3pre
SparseTriangularView.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2009-2015 Gael Guennebaud <[email protected]>
00005 // Copyright (C) 2012 Désiré Nuentsa-Wakam <[email protected]>
00006 //
00007 // This Source Code Form is subject to the terms of the Mozilla
00008 // Public License v. 2.0. If a copy of the MPL was not distributed
00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00010 
00011 #ifndef EIGEN_SPARSE_TRIANGULARVIEW_H
00012 #define EIGEN_SPARSE_TRIANGULARVIEW_H
00013 
00014 namespace Eigen {
00015 
00025 template<typename MatrixType, unsigned int Mode> class TriangularViewImpl<MatrixType,Mode,Sparse>
00026   : public SparseMatrixBase<TriangularView<MatrixType,Mode> >
00027 {
00028     enum { SkipFirst = ((Mode&Lower) && !(MatrixType::Flags&RowMajorBit))
00029                     || ((Mode&Upper) &&  (MatrixType::Flags&RowMajorBit)),
00030            SkipLast = !SkipFirst,
00031            SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
00032            HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
00033     };
00034     
00035     typedef TriangularView<MatrixType,Mode> TriangularViewType;
00036     
00037   protected:
00038     // dummy solve function to make TriangularView happy.
00039     void solve() const;
00040 
00041     typedef SparseMatrixBase<TriangularViewType> Base;
00042   public:
00043     
00044     EIGEN_SPARSE_PUBLIC_INTERFACE(TriangularViewType)
00045     
00046     typedef typename MatrixType::Nested MatrixTypeNested;
00047     typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
00048     typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
00049 
00050     template<typename RhsType, typename DstType>
00051     EIGEN_DEVICE_FUNC
00052     EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
00053       if(!(internal::is_same<RhsType,DstType>::value && internal::extract_data(dst) == internal::extract_data(rhs)))
00054         dst = rhs;
00055       this->solveInPlace(dst);
00056     }
00057 
00058     template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
00059     template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
00060   
00061 };
00062 
00063 namespace internal {
00064 
00065 template<typename ArgType, unsigned int Mode>
00066 struct unary_evaluator<TriangularView<ArgType,Mode>, IteratorBased>
00067  : evaluator_base<TriangularView<ArgType,Mode> >
00068 {
00069   typedef TriangularView<ArgType,Mode> XprType;
00070   
00071 protected:
00072   
00073   typedef typename XprType::Scalar Scalar;
00074   typedef typename XprType::StorageIndex StorageIndex;
00075   typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
00076   
00077   enum { SkipFirst = ((Mode&Lower) && !(ArgType::Flags&RowMajorBit))
00078                     || ((Mode&Upper) &&  (ArgType::Flags&RowMajorBit)),
00079          SkipLast = !SkipFirst,
00080          SkipDiag = (Mode&ZeroDiag) ? 1 : 0,
00081          HasUnitDiag = (Mode&UnitDiag) ? 1 : 0
00082   };
00083   
00084 public:
00085   
00086   enum {
00087     CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
00088     Flags = XprType::Flags
00089   };
00090     
00091   explicit unary_evaluator(const XprType &xpr) : m_argImpl(xpr.nestedExpression()), m_arg(xpr.nestedExpression()) {}
00092   
00093   inline Index nonZerosEstimate() const {
00094     return m_argImpl.nonZerosEstimate();
00095   }
00096   
00097   class InnerIterator : public EvalIterator
00098   {
00099       typedef EvalIterator Base;
00100     public:
00101 
00102       EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& xprEval, Index outer)
00103         : Base(xprEval.m_argImpl,outer), m_returnOne(false), m_containsDiag(Base::outer()<xprEval.m_arg.innerSize())
00104       {
00105         if(SkipFirst)
00106         {
00107           while((*this) && ((HasUnitDiag||SkipDiag)  ? this->index()<=outer : this->index()<outer))
00108             Base::operator++();
00109           if(HasUnitDiag)
00110             m_returnOne = m_containsDiag;
00111         }
00112         else if(HasUnitDiag && ((!Base::operator bool()) || Base::index()>=Base::outer()))
00113         {
00114           if((!SkipFirst) && Base::operator bool())
00115             Base::operator++();
00116           m_returnOne = m_containsDiag;
00117         }
00118       }
00119 
00120       EIGEN_STRONG_INLINE InnerIterator& operator++()
00121       {
00122         if(HasUnitDiag && m_returnOne)
00123           m_returnOne = false;
00124         else
00125         {
00126           Base::operator++();
00127           if(HasUnitDiag && (!SkipFirst) && ((!Base::operator bool()) || Base::index()>=Base::outer()))
00128           {
00129             if((!SkipFirst) && Base::operator bool())
00130               Base::operator++();
00131             m_returnOne = m_containsDiag;
00132           }
00133         }
00134         return *this;
00135       }
00136       
00137       EIGEN_STRONG_INLINE operator bool() const
00138       {
00139         if(HasUnitDiag && m_returnOne)
00140           return true;
00141         if(SkipFirst) return  Base::operator bool();
00142         else
00143         {
00144           if (SkipDiag) return (Base::operator bool() && this->index() < this->outer());
00145           else return (Base::operator bool() && this->index() <= this->outer());
00146         }
00147       }
00148 
00149 //       inline Index row() const { return (ArgType::Flags&RowMajorBit ? Base::outer() : this->index()); }
00150 //       inline Index col() const { return (ArgType::Flags&RowMajorBit ? this->index() : Base::outer()); }
00151       inline StorageIndex index() const
00152       {
00153         if(HasUnitDiag && m_returnOne)  return internal::convert_index<StorageIndex>(Base::outer());
00154         else                            return Base::index();
00155       }
00156       inline Scalar value() const
00157       {
00158         if(HasUnitDiag && m_returnOne)  return Scalar(1);
00159         else                            return Base::value();
00160       }
00161 
00162     protected:
00163       bool m_returnOne;
00164       bool m_containsDiag;
00165     private:
00166       Scalar& valueRef();
00167   };
00168   
00169 protected:
00170   evaluator<ArgType> m_argImpl;
00171   const ArgType& m_arg;
00172 };
00173 
00174 } // end namespace internal
00175 
00176 template<typename Derived>
00177 template<int Mode>
00178 inline const TriangularView<const Derived, Mode>
00179 SparseMatrixBase<Derived>::triangularView() const
00180 {
00181   return TriangularView<const Derived, Mode>(derived());
00182 }
00183 
00184 } // end namespace Eigen
00185 
00186 #endif // EIGEN_SPARSE_TRIANGULARVIEW_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines