CoreIterators.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. #ifndef EIGEN_COREITERATORS_H
  10. #define EIGEN_COREITERATORS_H
  11. namespace Eigen {
  12. /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
  13. */
  14. namespace internal {
  15. template<typename XprType, typename EvaluatorKind>
  16. class inner_iterator_selector;
  17. }
  18. /** \class InnerIterator
  19. * \brief An InnerIterator allows to loop over the element of any matrix expression.
  20. *
  21. * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed.
  22. *
  23. * TODO: add a usage example
  24. */
  25. template<typename XprType>
  26. class InnerIterator
  27. {
  28. protected:
  29. typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
  30. typedef internal::evaluator<XprType> EvaluatorType;
  31. typedef typename internal::traits<XprType>::Scalar Scalar;
  32. public:
  33. /** Construct an iterator over the \a outerId -th row or column of \a xpr */
  34. InnerIterator(const XprType &xpr, const Index &outerId)
  35. : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
  36. {}
  37. /// \returns the value of the current coefficient.
  38. EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); }
  39. /** Increment the iterator \c *this to the next non-zero coefficient.
  40. * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
  41. */
  42. EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
  43. /// \returns the column or row index of the current coefficient.
  44. EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
  45. /// \returns the row index of the current coefficient.
  46. EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); }
  47. /// \returns the column index of the current coefficient.
  48. EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); }
  49. /// \returns \c true if the iterator \c *this still references a valid coefficient.
  50. EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
  51. protected:
  52. EvaluatorType m_eval;
  53. IteratorType m_iter;
  54. private:
  55. // If you get here, then you're not using the right InnerIterator type, e.g.:
  56. // SparseMatrix<double,RowMajor> A;
  57. // SparseMatrix<double>::InnerIterator it(A,0);
  58. template<typename T> InnerIterator(const EigenBase<T>&,Index outer);
  59. };
  60. namespace internal {
  61. // Generic inner iterator implementation for dense objects
  62. template<typename XprType>
  63. class inner_iterator_selector<XprType, IndexBased>
  64. {
  65. protected:
  66. typedef evaluator<XprType> EvaluatorType;
  67. typedef typename traits<XprType>::Scalar Scalar;
  68. enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
  69. public:
  70. EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
  71. : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize)
  72. {}
  73. EIGEN_STRONG_INLINE Scalar value() const
  74. {
  75. return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner)
  76. : m_eval.coeff(m_inner, m_outer);
  77. }
  78. EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; }
  79. EIGEN_STRONG_INLINE Index index() const { return m_inner; }
  80. inline Index row() const { return IsRowMajor ? m_outer : index(); }
  81. inline Index col() const { return IsRowMajor ? index() : m_outer; }
  82. EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
  83. protected:
  84. const EvaluatorType& m_eval;
  85. Index m_inner;
  86. const Index m_outer;
  87. const Index m_end;
  88. };
  89. // For iterator-based evaluator, inner-iterator is already implemented as
  90. // evaluator<>::InnerIterator
  91. template<typename XprType>
  92. class inner_iterator_selector<XprType, IteratorBased>
  93. : public evaluator<XprType>::InnerIterator
  94. {
  95. protected:
  96. typedef typename evaluator<XprType>::InnerIterator Base;
  97. typedef evaluator<XprType> EvaluatorType;
  98. public:
  99. EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/)
  100. : Base(eval, outerId)
  101. {}
  102. };
  103. } // end namespace internal
  104. } // end namespace Eigen
  105. #endif // EIGEN_COREITERATORS_H