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 | /// \returns the column or row index of the current coefficient. |
52 | EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); } |
53 | /// \returns the row index of the current coefficient. |
54 | EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); } |
55 | /// \returns the column index of the current coefficient. |
56 | EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); } |
57 | /// \returns \c true if the iterator \c *this still references a valid coefficient. |
58 | EIGEN_STRONG_INLINE operator bool() const { return m_iter; } |
59 | |
60 | protected: |
61 | EvaluatorType m_eval; |
62 | IteratorType m_iter; |
63 | private: |
64 | // If you get here, then you're not using the right InnerIterator type, e.g.: |
65 | // SparseMatrix<double,RowMajor> A; |
66 | // SparseMatrix<double>::InnerIterator it(A,0); |
67 | template<typename T> InnerIterator(const EigenBase<T>&,Index outer); |
68 | }; |
69 | |
70 | namespace internal { |
71 | |
72 | // Generic inner iterator implementation for dense objects |
73 | template<typename XprType> |
74 | class inner_iterator_selector<XprType, IndexBased> |
75 | { |
76 | protected: |
77 | typedef evaluator<XprType> EvaluatorType; |
78 | typedef typename traits<XprType>::Scalar Scalar; |
79 | enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit }; |
80 | |
81 | public: |
82 | EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize) |
83 | : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize) |
84 | {} |
85 | |
86 | EIGEN_STRONG_INLINE Scalar value() const |
87 | { |
88 | return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner) |
89 | : m_eval.coeff(m_inner, m_outer); |
90 | } |
91 | |
92 | EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; } |
93 | |
94 | EIGEN_STRONG_INLINE Index index() const { return m_inner; } |
95 | inline Index row() const { return IsRowMajor ? m_outer : index(); } |
96 | inline Index col() const { return IsRowMajor ? index() : m_outer; } |
97 | |
98 | EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } |
99 | |
100 | protected: |
101 | const EvaluatorType& m_eval; |
102 | Index m_inner; |
103 | const Index m_outer; |
104 | const Index m_end; |
105 | }; |
106 | |
107 | // For iterator-based evaluator, inner-iterator is already implemented as |
108 | // evaluator<>::InnerIterator |
109 | template<typename XprType> |
110 | class inner_iterator_selector<XprType, IteratorBased> |
111 | : public evaluator<XprType>::InnerIterator |
112 | { |
113 | protected: |
114 | typedef typename evaluator<XprType>::InnerIterator Base; |
115 | typedef evaluator<XprType> EvaluatorType; |
116 | |
117 | public: |
118 | EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/) |
119 | : Base(eval, outerId) |
120 | {} |
121 | }; |
122 | |
123 | } // end namespace internal |
124 | |
125 | } // end namespace Eigen |
126 | |
127 | #endif // EIGEN_COREITERATORS_H |
128 | |