Introduce a generic InnerIterator classes compatible with evaluators.

This commit is contained in:
Gael Guennebaud 2014-09-29 13:36:57 +02:00
parent 76c3cf6949
commit abd3502e9e
5 changed files with 123 additions and 42 deletions

View File

@ -17,9 +17,6 @@ namespace Eigen {
namespace internal { namespace internal {
struct IndexBased {};
struct IteratorBased {};
// This class returns the evaluator kind from the expression storage kind. // This class returns the evaluator kind from the expression storage kind.
// Default assumes index based accessors // Default assumes index based accessors
template<typename StorageKind> template<typename StorageKind>

View File

@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. // 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 // 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 // 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 /* This file contains the respective InnerIterator definition of the expressions defined in Eigen/Core
*/ */
/** \ingroup SparseCore_Module namespace internal {
* \class InnerIterator
* \brief An InnerIterator allows to loop over the element of a sparse (or dense) matrix or expression template<typename XprType, typename EvaluatorKind>
* class inner_iterator_selector;
* todo
}
/** \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>
// generic version for dense matrix and expressions class InnerIterator
template<typename Derived> class DenseBase<Derived>::InnerIterator
{ {
protected: protected:
typedef typename Derived::Scalar Scalar; typedef internal::inner_iterator_selector<XprType, typename internal::evaluator_traits<XprType>::Kind> IteratorType;
typedef typename Derived::Index Index; typedef typename internal::evaluator<XprType>::type EvaluatorType;
typedef typename internal::traits<XprType>::Scalar Scalar;
enum { IsRowMajor = (Derived::Flags&RowMajorBit)==RowMajorBit }; typedef typename internal::traits<XprType>::Index Index;
public: public:
EIGEN_STRONG_INLINE InnerIterator(const Derived& expr, Index outer) /** Construct an iterator over the \a outerId -th row or column of \a xpr */
: m_expression(expr), m_inner(0), m_outer(outer), m_end(expr.innerSize()) InnerIterator(const XprType &xpr, const Index &outerId)
{} : m_eval(xpr), m_iter(m_eval, outerId, xpr.innerSize())
{}
EIGEN_STRONG_INLINE Scalar value() const
{ /// \returns the value of the current coefficient.
return (IsRowMajor) ? m_expression.coeff(m_outer, m_inner) EIGEN_STRONG_INLINE Scalar value() const { return m_iter.value(); }
: m_expression.coeff(m_inner, m_outer); /** 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_inner++; return *this; } 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_inner; } EIGEN_STRONG_INLINE Index index() const { return m_iter.index(); }
inline Index row() const { return IsRowMajor ? m_outer : index(); } /// \returns the row index of the current coefficient.
inline Index col() const { return IsRowMajor ? index() : m_outer; } EIGEN_STRONG_INLINE Index row() const { return m_iter.row(); }
/// \returns the column index of the current coefficient.
EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } EIGEN_STRONG_INLINE Index col() const { return m_iter.col(); }
/// \returns \c true if the iterator \c *this still references a valid coefficient.
protected: EIGEN_STRONG_INLINE operator bool() const { return m_iter; }
const Derived& m_expression;
Index m_inner; protected:
const Index m_outer; EvaluatorType m_eval;
const Index m_end; 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 inner iterator implementation for dense objects
template<typename XprType>
class inner_iterator_selector<XprType, IndexBased>
{
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 } // end namespace Eigen
#endif // EIGEN_COREITERATORS_H #endif // EIGEN_COREITERATORS_H

View File

@ -50,7 +50,11 @@ template<typename Derived> class DenseBase
using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar, using internal::special_scalar_op_base<Derived,typename internal::traits<Derived>::Scalar,
typename NumTraits<typename internal::traits<Derived>::Scalar>::Real>::operator*; 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; typedef typename internal::traits<Derived>::StorageKind StorageKind;

View File

@ -468,6 +468,16 @@ struct SelfAdjointShape { static std::string debugName() { return "SelfAdj
struct PermutationShape { static std::string debugName() { return "PermutationShape"; } }; struct PermutationShape { static std::string debugName() { return "PermutationShape"; } };
struct SparseShape { static std::string debugName() { return "SparseShape"; } }; 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 } // end namespace Eigen
#endif // EIGEN_CONSTANTS_H #endif // EIGEN_CONSTANTS_H

View File

@ -137,6 +137,7 @@ template<typename MatrixType> struct CommaInitializer;
template<typename Derived> class ReturnByValue; template<typename Derived> class ReturnByValue;
template<typename ExpressionType> class ArrayWrapper; template<typename ExpressionType> class ArrayWrapper;
template<typename ExpressionType> class MatrixWrapper; template<typename ExpressionType> class MatrixWrapper;
template<typename XprType> class InnerIterator;
namespace internal { namespace internal {
template<typename DecompositionType> struct kernel_retval_base; template<typename DecompositionType> struct kernel_retval_base;