cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

CoreIterators.h (4745B)


      1 // This file is part of Eigen, a lightweight C++ template library
      2 // for linear algebra.
      3 //
      4 // Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
      5 //
      6 // This Source Code Form is subject to the terms of the Mozilla
      7 // Public License v. 2.0. If a copy of the MPL was not distributed
      8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9 
     10 #ifndef EIGEN_COREITERATORS_H
     11 #define EIGEN_COREITERATORS_H
     12 
     13 namespace Eigen { 
     14 
     15 /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
     16  */
     17 
     18 namespace internal {
     19 
     20 template<typename XprType, typename EvaluatorKind>
     21 class inner_iterator_selector;
     22 
     23 }
     24 
     25 /** \class InnerIterator
     26   * \brief An InnerIterator allows to loop over the element of any matrix expression.
     27   * 
     28   * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed.
     29   * 
     30   * TODO: add a usage example
     31   */
     32 template<typename XprType>
     33 class InnerIterator
     34 {
     35 protected:
     36   typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
     37   typedef internal::evaluator<XprType> EvaluatorType;
     38   typedef typename internal::traits<XprType>::Scalar Scalar;
     39 public:
     40   /** Construct an iterator over the \a outerId -th row or column of \a xpr */
     41   InnerIterator(const XprType &xpr, const Index &outerId)
     42     : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
     43   {}
     44   
     45   /// \returns the value of the current coefficient.
     46   EIGEN_STRONG_INLINE Scalar value() const          { return m_iter.value(); }
     47   /** Increment the iterator \c *this to the next non-zero coefficient.
     48     * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
     49     */
     50   EIGEN_STRONG_INLINE InnerIterator& operator++()   { m_iter.operator++(); return *this; }
     51   EIGEN_STRONG_INLINE InnerIterator& operator+=(Index i) { m_iter.operator+=(i); return *this; }
     52   EIGEN_STRONG_INLINE InnerIterator operator+(Index i) 
     53   { InnerIterator result(*this); result+=i; return result; }
     54     
     55 
     56   /// \returns the column or row index of the current coefficient.
     57   EIGEN_STRONG_INLINE Index index() const           { return m_iter.index(); }
     58   /// \returns the row index of the current coefficient.
     59   EIGEN_STRONG_INLINE Index row() const             { return m_iter.row(); }
     60   /// \returns the column index of the current coefficient.
     61   EIGEN_STRONG_INLINE Index col() const             { return m_iter.col(); }
     62   /// \returns \c true if the iterator \c *this still references a valid coefficient.
     63   EIGEN_STRONG_INLINE operator bool() const         { return m_iter; }
     64   
     65 protected:
     66   EvaluatorType m_eval;
     67   IteratorType m_iter;
     68 private:
     69   // If you get here, then you're not using the right InnerIterator type, e.g.:
     70   //   SparseMatrix<double,RowMajor> A;
     71   //   SparseMatrix<double>::InnerIterator it(A,0);
     72   template<typename T> InnerIterator(const EigenBase<T>&,Index outer);
     73 };
     74 
     75 namespace internal {
     76 
     77 // Generic inner iterator implementation for dense objects
     78 template<typename XprType>
     79 class inner_iterator_selector<XprType, IndexBased>
     80 {
     81 protected:
     82   typedef evaluator<XprType> EvaluatorType;
     83   typedef typename traits<XprType>::Scalar Scalar;
     84   enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
     85   
     86 public:
     87   EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
     88     : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize)
     89   {}
     90 
     91   EIGEN_STRONG_INLINE Scalar value() const
     92   {
     93     return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner)
     94                         : m_eval.coeff(m_inner, m_outer);
     95   }
     96 
     97   EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; }
     98 
     99   EIGEN_STRONG_INLINE Index index() const { return m_inner; }
    100   inline Index row() const { return IsRowMajor ? m_outer : index(); }
    101   inline Index col() const { return IsRowMajor ? index() : m_outer; }
    102 
    103   EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
    104 
    105 protected:
    106   const EvaluatorType& m_eval;
    107   Index m_inner;
    108   const Index m_outer;
    109   const Index m_end;
    110 };
    111 
    112 // For iterator-based evaluator, inner-iterator is already implemented as
    113 // evaluator<>::InnerIterator
    114 template<typename XprType>
    115 class inner_iterator_selector<XprType, IteratorBased>
    116  : public evaluator<XprType>::InnerIterator
    117 {
    118 protected:
    119   typedef typename evaluator<XprType>::InnerIterator Base;
    120   typedef evaluator<XprType> EvaluatorType;
    121   
    122 public:
    123   EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/)
    124     : Base(eval, outerId)
    125   {}  
    126 };
    127 
    128 } // end namespace internal
    129 
    130 } // end namespace Eigen
    131 
    132 #endif // EIGEN_COREITERATORS_H