Eigen  3.3.3
SparseView.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 // Copyright (C) 2010 Daniel Lowengrub <lowdanie@gmail.com>
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 
00044 template<typename MatrixType>
00045 class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
00046 {
00047   typedef typename MatrixType::Nested MatrixTypeNested;
00048   typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
00049   typedef SparseMatrixBase<SparseView > Base;
00050 public:
00051   EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
00052   typedef typename internal::remove_all<MatrixType>::type NestedExpression;
00053 
00054   explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0),
00055                       const RealScalar &epsilon = NumTraits<Scalar>::dummy_precision())
00056     : m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {}
00057 
00058   inline Index rows() const { return m_matrix.rows(); }
00059   inline Index cols() const { return m_matrix.cols(); }
00060 
00061   inline Index innerSize() const { return m_matrix.innerSize(); }
00062   inline Index outerSize() const { return m_matrix.outerSize(); }
00063   
00065   const typename internal::remove_all<MatrixTypeNested>::type&
00066   nestedExpression() const { return m_matrix; }
00067   
00068   Scalar reference() const { return m_reference; }
00069   RealScalar epsilon() const { return m_epsilon; }
00070   
00071 protected:
00072   MatrixTypeNested m_matrix;
00073   Scalar m_reference;
00074   RealScalar m_epsilon;
00075 };
00076 
00077 namespace internal {
00078 
00079 // TODO find a way to unify the two following variants
00080 // This is tricky because implementing an inner iterator on top of an IndexBased evaluator is
00081 // not easy because the evaluators do not expose the sizes of the underlying expression.
00082   
00083 template<typename ArgType>
00084 struct unary_evaluator<SparseView<ArgType>, IteratorBased>
00085   : public evaluator_base<SparseView<ArgType> >
00086 {
00087     typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
00088   public:
00089     typedef SparseView<ArgType> XprType;
00090     
00091     class InnerIterator : public EvalIterator
00092     {
00093         typedef typename XprType::Scalar Scalar;
00094       public:
00095 
00096         EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer)
00097           : EvalIterator(sve.m_argImpl,outer), m_view(sve.m_view)
00098         {
00099           incrementToNonZero();
00100         }
00101 
00102         EIGEN_STRONG_INLINE InnerIterator& operator++()
00103         {
00104           EvalIterator::operator++();
00105           incrementToNonZero();
00106           return *this;
00107         }
00108 
00109         using EvalIterator::value;
00110 
00111       protected:
00112         const XprType &m_view;
00113 
00114       private:
00115         void incrementToNonZero()
00116         {
00117           while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon()))
00118           {
00119             EvalIterator::operator++();
00120           }
00121         }
00122     };
00123     
00124     enum {
00125       CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
00126       Flags = XprType::Flags
00127     };
00128     
00129     explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
00130 
00131   protected:
00132     evaluator<ArgType> m_argImpl;
00133     const XprType &m_view;
00134 };
00135 
00136 template<typename ArgType>
00137 struct unary_evaluator<SparseView<ArgType>, IndexBased>
00138   : public evaluator_base<SparseView<ArgType> >
00139 {
00140   public:
00141     typedef SparseView<ArgType> XprType;
00142   protected:
00143     enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
00144     typedef typename XprType::Scalar Scalar;
00145     typedef typename XprType::StorageIndex StorageIndex;
00146   public:
00147     
00148     class InnerIterator
00149     {
00150       public:
00151 
00152         EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer)
00153           : m_sve(sve), m_inner(0), m_outer(outer), m_end(sve.m_view.innerSize())
00154         {
00155           incrementToNonZero();
00156         }
00157 
00158         EIGEN_STRONG_INLINE InnerIterator& operator++()
00159         {
00160           m_inner++;
00161           incrementToNonZero();
00162           return *this;
00163         }
00164 
00165         EIGEN_STRONG_INLINE Scalar value() const
00166         {
00167           return (IsRowMajor) ? m_sve.m_argImpl.coeff(m_outer, m_inner)
00168                               : m_sve.m_argImpl.coeff(m_inner, m_outer);
00169         }
00170 
00171         EIGEN_STRONG_INLINE StorageIndex index() const { return m_inner; }
00172         inline Index row() const { return IsRowMajor ? m_outer : index(); }
00173         inline Index col() const { return IsRowMajor ? index() : m_outer; }
00174 
00175         EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
00176 
00177       protected:
00178         const unary_evaluator &m_sve;
00179         Index m_inner;
00180         const Index m_outer;
00181         const Index m_end;
00182 
00183       private:
00184         void incrementToNonZero()
00185         {
00186           while((bool(*this)) && internal::isMuchSmallerThan(value(), m_sve.m_view.reference(), m_sve.m_view.epsilon()))
00187           {
00188             m_inner++;
00189           }
00190         }
00191     };
00192     
00193     enum {
00194       CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
00195       Flags = XprType::Flags
00196     };
00197     
00198     explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
00199 
00200   protected:
00201     evaluator<ArgType> m_argImpl;
00202     const XprType &m_view;
00203 };
00204 
00205 } // end namespace internal
00206 
00224 template<typename Derived>
00225 const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference,
00226                                                           const typename NumTraits<Scalar>::Real& epsilon) const
00227 {
00228   return SparseView<Derived>(derived(), reference, epsilon);
00229 }
00230 
00243 template<typename Derived>
00244 const SparseView<Derived>
00245 SparseMatrixBase<Derived>::pruned(const Scalar& reference,
00246                                   const RealScalar& epsilon) const
00247 {
00248   return SparseView<Derived>(derived(), reference, epsilon);
00249 }
00250 
00251 } // end namespace Eigen
00252 
00253 #endif
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends