123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- // This file is part of Eigen, a lightweight C++ template library
- // for linear algebra.
- //
- // Copyright (C) 2017 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
- // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
- #ifndef EIGEN_INDEXED_VIEW_H
- #define EIGEN_INDEXED_VIEW_H
- namespace Eigen {
- namespace internal {
- template<typename XprType, typename RowIndices, typename ColIndices>
- struct traits<IndexedView<XprType, RowIndices, ColIndices> >
- : traits<XprType>
- {
- enum {
- RowsAtCompileTime = int(array_size<RowIndices>::value),
- ColsAtCompileTime = int(array_size<ColIndices>::value),
- MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : Dynamic,
- MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : Dynamic,
- XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
- IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
- : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
- : XprTypeIsRowMajor,
- RowIncr = int(get_compile_time_incr<RowIndices>::value),
- ColIncr = int(get_compile_time_incr<ColIndices>::value),
- InnerIncr = IsRowMajor ? ColIncr : RowIncr,
- OuterIncr = IsRowMajor ? RowIncr : ColIncr,
- HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
- XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret),
- XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret),
- InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime,
- IsBlockAlike = InnerIncr==1 && OuterIncr==1,
- IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value,
- InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr,
- OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr,
- ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value,
- ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike,
- ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock),
- // FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag,
- // but this is too strict regarding negative strides...
- DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0,
- FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
- FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
- FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
- Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask )) | FlagsLvalueBit | FlagsRowMajorBit | FlagsLinearAccessBit
- };
- typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType;
- };
- }
- template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
- class IndexedViewImpl;
- /** \class IndexedView
- * \ingroup Core_Module
- *
- * \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices
- *
- * \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns
- * \tparam RowIndices the type of the object defining the sequence of row indices
- * \tparam ColIndices the type of the object defining the sequence of column indices
- *
- * This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection
- * of sub-sets of rows and columns, that are themself defined by generic sequences of row indices \f$ \{r_0,r_1,..r_{m-1}\} \f$
- * and column indices \f$ \{c_0,c_1,..c_{n-1} \}\f$. Let \f$ A \f$ be the nested matrix, then the resulting matrix \f$ B \f$ has \c m
- * rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$.
- *
- * The \c RowIndices and \c ColIndices types must be compatible with the following API:
- * \code
- * <integral type> operator[](Index) const;
- * Index size() const;
- * \endcode
- *
- * Typical supported types thus include:
- * - std::vector<int>
- * - std::valarray<int>
- * - std::array<int>
- * - Plain C arrays: int[N]
- * - Eigen::ArrayXi
- * - decltype(ArrayXi::LinSpaced(...))
- * - Any view/expressions of the previous types
- * - Eigen::ArithmeticSequence
- * - Eigen::internal::AllRange (helper for Eigen::all)
- * - Eigen::internal::SingleRange (helper for single index)
- * - etc.
- *
- * In typical usages of %Eigen, this class should never be used directly. It is the return type of
- * DenseBase::operator()(const RowIndices&, const ColIndices&).
- *
- * \sa class Block
- */
- template<typename XprType, typename RowIndices, typename ColIndices>
- class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>
- {
- public:
- typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base;
- EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView)
- EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView)
- typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested;
- typedef typename internal::remove_all<XprType>::type NestedExpression;
- template<typename T0, typename T1>
- IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices)
- : m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices)
- {}
- /** \returns number of rows */
- Index rows() const { return internal::size(m_rowIndices); }
- /** \returns number of columns */
- Index cols() const { return internal::size(m_colIndices); }
- /** \returns the nested expression */
- const typename internal::remove_all<XprType>::type&
- nestedExpression() const { return m_xpr; }
- /** \returns the nested expression */
- typename internal::remove_reference<XprType>::type&
- nestedExpression() { return m_xpr; }
- /** \returns a const reference to the object storing/generating the row indices */
- const RowIndices& rowIndices() const { return m_rowIndices; }
- /** \returns a const reference to the object storing/generating the column indices */
- const ColIndices& colIndices() const { return m_colIndices; }
- protected:
- MatrixTypeNested m_xpr;
- RowIndices m_rowIndices;
- ColIndices m_colIndices;
- };
- // Generic API dispatcher
- template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind>
- class IndexedViewImpl
- : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type
- {
- public:
- typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base;
- };
- namespace internal {
- template<typename ArgType, typename RowIndices, typename ColIndices>
- struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased>
- : evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> >
- {
- typedef IndexedView<ArgType, RowIndices, ColIndices> XprType;
- enum {
- CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */,
- FlagsLinearAccessBit = (traits<XprType>::RowsAtCompileTime == 1 || traits<XprType>::ColsAtCompileTime == 1) ? LinearAccessBit : 0,
- FlagsRowMajorBit = traits<XprType>::FlagsRowMajorBit,
- Flags = (evaluator<ArgType>::Flags & (HereditaryBits & ~RowMajorBit /*| LinearAccessBit | DirectAccessBit*/)) | FlagsLinearAccessBit | FlagsRowMajorBit,
- Alignment = 0
- };
- EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr)
- {
- EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
- }
- typedef typename XprType::Scalar Scalar;
- typedef typename XprType::CoeffReturnType CoeffReturnType;
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- CoeffReturnType coeff(Index row, Index col) const
- {
- return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Scalar& coeffRef(Index row, Index col)
- {
- return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- Scalar& coeffRef(Index index)
- {
- EIGEN_STATIC_ASSERT_LVALUE(XprType)
- Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
- Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
- return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const Scalar& coeffRef(Index index) const
- {
- Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
- Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
- return m_argImpl.coeffRef( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
- EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
- const CoeffReturnType coeff(Index index) const
- {
- Index row = XprType::RowsAtCompileTime == 1 ? 0 : index;
- Index col = XprType::RowsAtCompileTime == 1 ? index : 0;
- return m_argImpl.coeff( m_xpr.rowIndices()[row], m_xpr.colIndices()[col]);
- }
- protected:
- evaluator<ArgType> m_argImpl;
- const XprType& m_xpr;
- };
- } // end namespace internal
- } // end namespace Eigen
- #endif // EIGEN_INDEXED_VIEW_H
|