aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2014-09-29 13:36:57 +0200
committerGravatar Gael Guennebaud <g.gael@free.fr>2014-09-29 13:36:57 +0200
commitabd3502e9ea3e659c39dd5edc17d6deabd26e048 (patch)
tree0472dec53f1c07db5503602547fd3bfee5343346
parent76c3cf694987382c7d92c3fb7cdf65215bfdeb5e (diff)
Introduce a generic InnerIterator classes compatible with evaluators.
-rw-r--r--Eigen/src/Core/CoreEvaluators.h3
-rw-r--r--Eigen/src/Core/CoreIterators.h143
-rw-r--r--Eigen/src/Core/DenseBase.h6
-rw-r--r--Eigen/src/Core/util/Constants.h10
-rw-r--r--Eigen/src/Core/util/ForwardDeclarations.h1
5 files changed, 122 insertions, 41 deletions
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h
index ab4320c2a..50caf4bab 100644
--- a/Eigen/src/Core/CoreEvaluators.h
+++ b/Eigen/src/Core/CoreEvaluators.h
@@ -17,9 +17,6 @@ namespace Eigen {
namespace internal {
-struct IndexBased {};
-struct IteratorBased {};
-
// This class returns the evaluator kind from the expression storage kind.
// Default assumes index based accessors
template<typename StorageKind>
diff --git a/Eigen/src/Core/CoreIterators.h b/Eigen/src/Core/CoreIterators.h
index 6da4683d2..7feebc4e4 100644
--- a/Eigen/src/Core/CoreIterators.h
+++ b/Eigen/src/Core/CoreIterators.h
@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
-// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
+// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
@@ -15,47 +15,116 @@ namespace Eigen {
/* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
*/
-/** \ingroup SparseCore_Module
- * \class InnerIterator
- * \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression
- *
- * todo
+namespace internal {
+
+template<typename XprType, typename EvaluatorKind>
+class inner_iterator_selector;
+
+}
+
+/** \class InnerIterator
+ * \brief An InnerIterator allows to loop over the element of any matrix expression.
+ *
+ * \warning To be used with care because an evaluator is constructed every time an InnerIterator iterator is constructed.
+ *
+ * TODO: add a usage example
*/
+template<typename XprType>
+class InnerIterator
+{
+protected:
+ typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
+ typedef typename internal::evaluator<XprType>::type EvaluatorType;
+ typedef typename internal::traits<XprType>::Scalar Scalar;
+ typedef typename internal::traits<XprType>::Index Index;
+public:
+ /** Construct an iterator over the \a outerId -th row or column of \a xpr */
+ InnerIterator(const XprType &xpr, const Index &outerId)
+ : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
+ {}
+
+ /// \returns the value of the current coefficient.
+ EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); }
+ /** Increment the iterator \c *this to the next non-zero coefficient.
+ * Explicit zeros are not skipped over. To skip explicit zeros, see class SparseView
+ */
+ EIGEN_STRONG_INLINE InnerIterator& operator++() { m_iter.operator++(); return *this; }
+ /// \returns the column or row index of the current coefficient.
+ EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
+ /// \returns the row index of the current coefficient.
+ EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); }
+ /// \returns the column index of the current coefficient.
+ EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); }
+ /// \returns \c true if the iterator \c *this still references a valid coefficient.
+ EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
+
+protected:
+ EvaluatorType m_eval;
+ IteratorType m_iter;
+private:
+ // If you get here, then you're not using the right InnerIterator type, e.g.:
+ // SparseMatrix<double,RowMajor> A;
+ // SparseMatrix<double>::InnerIterator it(A,0);
+ template<typename T> InnerIterator(const EigenBase<T>&,Index outer);
+};
+
+namespace internal {
-// generic version for dense matrix and expressions
-template<typename Derived> class DenseBase<Derived>::InnerIterator
+// Generic inner iterator implementation for dense objects
+template<typename XprType>
+class inner_iterator_selector<XprType, IndexBased>
{
- protected:
- typedef typename Derived::Scalar Scalar;
- typedef typename Derived::Index Index;
-
- enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit };
- public:
- EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer)
- : m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize())
- {}
-
- EIGEN_STRONG_INLINE Scalar value() const
- {
- return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner)
- : m_expression.coeff(m_inner, m_outer);
- }
-
- EIGEN_STRONG_INLINE InnerIterator& operator++() { m_inner++; return *this; }
-
- EIGEN_STRONG_INLINE Index index() const { return m_inner; }
- inline Index row() const { return IsRowMajor ? m_outer : index(); }
- inline Index col() const { return IsRowMajor ? index() : m_outer; }
-
- EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
-
- protected:
- const Derived& m_expression;
- Index m_inner;
- const Index m_outer;
- const Index m_end;
+protected:
+ typedef typename evaluator<XprType>::type EvaluatorType;
+ typedef typename traits<XprType>::Scalar Scalar;
+ typedef typename traits<XprType>::Index Index;
+ enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
+
+public:
+ EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &innerSize)
+ : m_eval(eval), m_inner(0), m_outer(outerId), m_end(innerSize)
+ {}
+
+ EIGEN_STRONG_INLINE Scalar value() const
+ {
+ return (IsRowMajor) ? m_eval.coeff(m_outer, m_inner)
+ : m_eval.coeff(m_inner, m_outer);
+ }
+
+ EIGEN_STRONG_INLINE inner_iterator_selector& operator++() { m_inner++; return *this; }
+
+ EIGEN_STRONG_INLINE Index index() const { return m_inner; }
+ inline Index row() const { return IsRowMajor ? m_outer : index(); }
+ inline Index col() const { return IsRowMajor ? index() : m_outer; }
+
+ EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
+
+protected:
+ const EvaluatorType& m_eval;
+ Index m_inner;
+ const Index m_outer;
+ const Index m_end;
};
+// For iterator-based evaluator, inner-iterator is already implemented as
+// evaluator<>::InnerIterator
+template<typename XprType>
+class inner_iterator_selector<XprType, IteratorBased>
+ : public evaluator<XprType>::InnerIterator
+{
+protected:
+ typedef typename evaluator<XprType>::InnerIterator Base;
+ typedef typename evaluator<XprType>::type EvaluatorType;
+ typedef typename traits<XprType>::Index Index;
+
+public:
+ EIGEN_STRONG_INLINE inner_iterator_selector(const EvaluatorType &eval, const Index &outerId, const Index &/*innerSize*/)
+ : Base(eval, outerId)
+ {}
+};
+
+} // end namespace internal
+
} // end namespace Eigen
#endif // EIGEN_COREITERATORS_H
diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h
index 101ef6f20..c4128e192 100644
--- a/Eigen/src/Core/DenseBase.h
+++ b/Eigen/src/Core/DenseBase.h
@@ -50,7 +50,11 @@ template<typename Derived> class DenseBase
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*;
- class InnerIterator;
+
+ /** Inner iterator type to iterate over the coefficients of a row or column.
+ * \sa class InnerIterator
+ */
+ typedef InnerIterator<Derived> InnerIterator;
typedef typename internal::traits<Derived>::StorageKind StorageKind;
diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h
index 2c9fb443d..5c7d70af6 100644
--- a/Eigen/src/Core/util/Constants.h
+++ b/Eigen/src/Core/util/Constants.h
@@ -468,6 +468,16 @@ struct SelfAdjointShape { static std::string debugName() { return "SelfAdj
struct PermutationShape { static std::string debugName() { return "PermutationShape"; } };
struct SparseShape { static std::string debugName() { return "SparseShape"; } };
+namespace internal {
+
+ // random access iterators based on coeff*() accessors.
+struct IndexBased {};
+
+// evaluator based on iterators to access coefficients.
+struct IteratorBased {};
+
+} // end namespace internal
+
} // end namespace Eigen
#endif // EIGEN_CONSTANTS_H
diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h
index 9ec57468b..be156a44a 100644
--- a/Eigen/src/Core/util/ForwardDeclarations.h
+++ b/Eigen/src/Core/util/ForwardDeclarations.h
@@ -137,6 +137,7 @@ template<typename MatrixType> struct CommaInitializer;
template<typename Derived> class ReturnByValue;
template<typename ExpressionType> class ArrayWrapper;
template<typename ExpressionType> class MatrixWrapper;
+template<typename XprType> class InnerIterator;
namespace internal {
template<typename DecompositionType> struct kernel_retval_base;