MOAB  4.9.3pre
SparseView.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) 2011-2014 Gael Guennebaud <[email protected]>
00005 // Copyright (C) 2010 Daniel Lowengrub <[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_SPARSEVIEW_H
00012 #define EIGEN_SPARSEVIEW_H
00013 
00014 namespace Eigen { 
00015 
00016 namespace internal {
00017 
00018 template<typename MatrixType>
00019 struct traits<SparseView<MatrixType> > : traits<MatrixType>
00020 {
00021   typedef typename MatrixType::StorageIndex StorageIndex;
00022   typedef Sparse StorageKind;
00023   enum {
00024     Flags = int(traits<MatrixType>::Flags) & (RowMajorBit)
00025   };
00026 };
00027 
00028 } // end namespace internal
00029 
00030 template<typename MatrixType>
00031 class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
00032 {
00033   typedef typename MatrixType::Nested MatrixTypeNested;
00034   typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
00035   typedef SparseMatrixBase<SparseView > Base;
00036 public:
00037   EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
00038   typedef typename internal::remove_all<MatrixType>::type NestedExpression;
00039 
00040   explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0),
00041                       const RealScalar &epsilon = NumTraits<Scalar>::dummy_precision())
00042     : m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {}
00043 
00044   inline Index rows() const { return m_matrix.rows(); }
00045   inline Index cols() const { return m_matrix.cols(); }
00046 
00047   inline Index innerSize() const { return m_matrix.innerSize(); }
00048   inline Index outerSize() const { return m_matrix.outerSize(); }
00049   
00051   const typename internal::remove_all<MatrixTypeNested>::type&
00052   nestedExpression() const { return m_matrix; }
00053   
00054   Scalar reference() const { return m_reference; }
00055   RealScalar epsilon() const { return m_epsilon; }
00056   
00057 protected:
00058   MatrixTypeNested m_matrix;
00059   Scalar m_reference;
00060   RealScalar m_epsilon;
00061 };
00062 
00063 namespace internal {
00064 
00065 // TODO find a way to unify the two following variants
00066 // This is tricky because implementing an inner iterator on top of an IndexBased evaluator is
00067 // not easy because the evaluators do not expose the sizes of the underlying expression.
00068   
00069 template<typename ArgType>
00070 struct unary_evaluator<SparseView<ArgType>, IteratorBased>
00071   : public evaluator_base<SparseView<ArgType> >
00072 {
00073     typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
00074   public:
00075     typedef SparseView<ArgType> XprType;
00076     
00077     class InnerIterator : public EvalIterator
00078     {
00079         typedef typename XprType::Scalar Scalar;
00080       public:
00081 
00082         EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer)
00083           : EvalIterator(sve.m_argImpl,outer), m_view(sve.m_view)
00084         {
00085           incrementToNonZero();
00086         }
00087 
00088         EIGEN_STRONG_INLINE InnerIterator& operator++()
00089         {
00090           EvalIterator::operator++();
00091           incrementToNonZero();
00092           return *this;
00093         }
00094 
00095         using EvalIterator::value;
00096 
00097       protected:
00098         const XprType &m_view;
00099 
00100       private:
00101         void incrementToNonZero()
00102         {
00103           while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon()))
00104           {
00105             EvalIterator::operator++();
00106           }
00107         }
00108     };
00109     
00110     enum {
00111       CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
00112       Flags = XprType::Flags
00113     };
00114     
00115     explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
00116 
00117   protected:
00118     evaluator<ArgType> m_argImpl;
00119     const XprType &m_view;
00120 };
00121 
00122 template<typename ArgType>
00123 struct unary_evaluator<SparseView<ArgType>, IndexBased>
00124   : public evaluator_base<SparseView<ArgType> >
00125 {
00126   public:
00127     typedef SparseView<ArgType> XprType;
00128   protected:
00129     enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
00130     typedef typename XprType::Scalar Scalar;
00131     typedef typename XprType::StorageIndex StorageIndex;
00132   public:
00133     
00134     class InnerIterator
00135     {
00136       public:
00137 
00138         EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer)
00139           : m_sve(sve), m_inner(0), m_outer(outer), m_end(sve.m_view.innerSize())
00140         {
00141           incrementToNonZero();
00142         }
00143 
00144         EIGEN_STRONG_INLINE InnerIterator& operator++()
00145         {
00146           m_inner++;
00147           incrementToNonZero();
00148           return *this;
00149         }
00150 
00151         EIGEN_STRONG_INLINE Scalar value() const
00152         {
00153           return (IsRowMajor) ? m_sve.m_argImpl.coeff(m_outer, m_inner)
00154                               : m_sve.m_argImpl.coeff(m_inner, m_outer);
00155         }
00156 
00157         EIGEN_STRONG_INLINE StorageIndex index() const { return m_inner; }
00158         inline Index row() const { return IsRowMajor ? m_outer : index(); }
00159         inline Index col() const { return IsRowMajor ? index() : m_outer; }
00160 
00161         EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
00162 
00163       protected:
00164         const unary_evaluator &m_sve;
00165         Index m_inner;
00166         const Index m_outer;
00167         const Index m_end;
00168 
00169       private:
00170         void incrementToNonZero()
00171         {
00172           while((bool(*this)) && internal::isMuchSmallerThan(value(), m_sve.m_view.reference(), m_sve.m_view.epsilon()))
00173           {
00174             m_inner++;
00175           }
00176         }
00177     };
00178     
00179     enum {
00180       CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
00181       Flags = XprType::Flags
00182     };
00183     
00184     explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
00185 
00186   protected:
00187     evaluator<ArgType> m_argImpl;
00188     const XprType &m_view;
00189 };
00190 
00191 } // end namespace internal
00192 
00193 template<typename Derived>
00194 const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference,
00195                                                           const typename NumTraits<Scalar>::Real& epsilon) const
00196 {
00197   return SparseView<Derived>(derived(), reference, epsilon);
00198 }
00199 
00212 template<typename Derived>
00213 const SparseView<Derived>
00214 SparseMatrixBase<Derived>::pruned(const Scalar& reference,
00215                                   const RealScalar& epsilon) const
00216 {
00217   return SparseView<Derived>(derived(), reference, epsilon);
00218 }
00219 
00220 } // end namespace Eigen
00221 
00222 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines