|
| 1 | +// This file is part of Eigen, a lightweight C++ template library |
| 2 | +// for linear algebra. |
| 3 | +// |
| 4 | +// Copyright (C) 2017 Gael Guennebaud <[email protected]> |
| 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_INDEXED_VIEW_H |
| 11 | +#define EIGEN_INDEXED_VIEW_H |
| 12 | + |
| 13 | +namespace Eigen { |
| 14 | + |
| 15 | +namespace internal { |
| 16 | + |
| 17 | +template<typename XprType, typename RowIndices, typename ColIndices> |
| 18 | +struct traits<IndexedView<XprType, RowIndices, ColIndices> > |
| 19 | + : traits<XprType> |
| 20 | +{ |
| 21 | + enum { |
| 22 | + RowsAtCompileTime = int(array_size<RowIndices>::value), |
| 23 | + ColsAtCompileTime = int(array_size<ColIndices>::value), |
| 24 | + MaxRowsAtCompileTime = RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) : Dynamic, |
| 25 | + MaxColsAtCompileTime = ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : Dynamic, |
| 26 | + |
| 27 | + XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0, |
| 28 | + IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 |
| 29 | + : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 |
| 30 | + : XprTypeIsRowMajor, |
| 31 | + |
| 32 | + RowIncr = int(get_compile_time_incr<RowIndices>::value), |
| 33 | + ColIncr = int(get_compile_time_incr<ColIndices>::value), |
| 34 | + InnerIncr = IsRowMajor ? ColIncr : RowIncr, |
| 35 | + OuterIncr = IsRowMajor ? RowIncr : ColIncr, |
| 36 | + |
| 37 | + HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), |
| 38 | + XprInnerStride = HasSameStorageOrderAsXprType ? int(inner_stride_at_compile_time<XprType>::ret) : int(outer_stride_at_compile_time<XprType>::ret), |
| 39 | + XprOuterstride = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType>::ret) : int(inner_stride_at_compile_time<XprType>::ret), |
| 40 | + |
| 41 | + InnerSize = XprTypeIsRowMajor ? ColsAtCompileTime : RowsAtCompileTime, |
| 42 | + IsBlockAlike = InnerIncr==1 && OuterIncr==1, |
| 43 | + IsInnerPannel = HasSameStorageOrderAsXprType && is_same<AllRange<InnerSize>,typename conditional<XprTypeIsRowMajor,ColIndices,RowIndices>::type>::value, |
| 44 | + |
| 45 | + InnerStrideAtCompileTime = InnerIncr<0 || InnerIncr==DynamicIndex || XprInnerStride==Dynamic ? Dynamic : XprInnerStride * InnerIncr, |
| 46 | + OuterStrideAtCompileTime = OuterIncr<0 || OuterIncr==DynamicIndex || XprOuterstride==Dynamic ? Dynamic : XprOuterstride * OuterIncr, |
| 47 | + |
| 48 | + ReturnAsScalar = is_same<RowIndices,SingleRange>::value && is_same<ColIndices,SingleRange>::value, |
| 49 | + ReturnAsBlock = (!ReturnAsScalar) && IsBlockAlike, |
| 50 | + ReturnAsIndexedView = (!ReturnAsScalar) && (!ReturnAsBlock), |
| 51 | + |
| 52 | + // FIXME we deal with compile-time strides if and only if we have DirectAccessBit flag, |
| 53 | + // but this is too strict regarding negative strides... |
| 54 | + DirectAccessMask = (int(InnerIncr)!=UndefinedIncr && int(OuterIncr)!=UndefinedIncr && InnerIncr>=0 && OuterIncr>=0) ? DirectAccessBit : 0, |
| 55 | + FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, |
| 56 | + FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0, |
| 57 | + Flags = (traits<XprType>::Flags & (HereditaryBits | DirectAccessMask)) | FlagsLvalueBit | FlagsRowMajorBit |
| 58 | + }; |
| 59 | + |
| 60 | + typedef Block<XprType,RowsAtCompileTime,ColsAtCompileTime,IsInnerPannel> BlockType; |
| 61 | +}; |
| 62 | + |
| 63 | +} |
| 64 | + |
| 65 | +template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind> |
| 66 | +class IndexedViewImpl; |
| 67 | + |
| 68 | + |
| 69 | +/** \class IndexedView |
| 70 | + * \ingroup Core_Module |
| 71 | + * |
| 72 | + * \brief Expression of a non-sequential sub-matrix defined by arbitrary sequences of row and column indices |
| 73 | + * |
| 74 | + * \tparam XprType the type of the expression in which we are taking the intersections of sub-rows and sub-columns |
| 75 | + * \tparam RowIndices the type of the object defining the sequence of row indices |
| 76 | + * \tparam ColIndices the type of the object defining the sequence of column indices |
| 77 | + * |
| 78 | + * This class represents an expression of a sub-matrix (or sub-vector) defined as the intersection |
| 79 | + * 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$ |
| 80 | + * 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 |
| 81 | + * rows and \c n columns, and its entries are given by: \f$ B(i,j) = A(r_i,c_j) \f$. |
| 82 | + * |
| 83 | + * The \c RowIndices and \c ColIndices types must be compatible with the following API: |
| 84 | + * \code |
| 85 | + * <integral type> operator[](Index) const; |
| 86 | + * Index size() const; |
| 87 | + * \endcode |
| 88 | + * |
| 89 | + * Typical supported types thus include: |
| 90 | + * - std::vector<int> |
| 91 | + * - std::valarray<int> |
| 92 | + * - std::array<int> |
| 93 | + * - Plain C arrays: int[N] |
| 94 | + * - Eigen::ArrayXi |
| 95 | + * - decltype(ArrayXi::LinSpaced(...)) |
| 96 | + * - Any view/expressions of the previous types |
| 97 | + * - Eigen::ArithmeticSequence |
| 98 | + * - Eigen::internal::AllRange (helper for Eigen::all) |
| 99 | + * - Eigen::internal::SingleRange (helper for single index) |
| 100 | + * - etc. |
| 101 | + * |
| 102 | + * In typical usages of %Eigen, this class should never be used directly. It is the return type of |
| 103 | + * DenseBase::operator()(const RowIndices&, const ColIndices&). |
| 104 | + * |
| 105 | + * \sa class Block |
| 106 | + */ |
| 107 | +template<typename XprType, typename RowIndices, typename ColIndices> |
| 108 | +class IndexedView : public IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind> |
| 109 | +{ |
| 110 | +public: |
| 111 | + typedef typename IndexedViewImpl<XprType, RowIndices, ColIndices, typename internal::traits<XprType>::StorageKind>::Base Base; |
| 112 | + EIGEN_GENERIC_PUBLIC_INTERFACE(IndexedView) |
| 113 | + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(IndexedView) |
| 114 | + |
| 115 | + typedef typename internal::ref_selector<XprType>::non_const_type MatrixTypeNested; |
| 116 | + typedef typename internal::remove_all<XprType>::type NestedExpression; |
| 117 | + |
| 118 | + template<typename T0, typename T1> |
| 119 | + IndexedView(XprType& xpr, const T0& rowIndices, const T1& colIndices) |
| 120 | + : m_xpr(xpr), m_rowIndices(rowIndices), m_colIndices(colIndices) |
| 121 | + {} |
| 122 | + |
| 123 | + /** \returns number of rows */ |
| 124 | + Index rows() const { return internal::size(m_rowIndices); } |
| 125 | + |
| 126 | + /** \returns number of columns */ |
| 127 | + Index cols() const { return internal::size(m_colIndices); } |
| 128 | + |
| 129 | + /** \returns the nested expression */ |
| 130 | + const typename internal::remove_all<XprType>::type& |
| 131 | + nestedExpression() const { return m_xpr; } |
| 132 | + |
| 133 | + /** \returns the nested expression */ |
| 134 | + typename internal::remove_reference<XprType>::type& |
| 135 | + nestedExpression() { return m_xpr; } |
| 136 | + |
| 137 | + /** \returns a const reference to the object storing/generating the row indices */ |
| 138 | + const RowIndices& rowIndices() const { return m_rowIndices; } |
| 139 | + |
| 140 | + /** \returns a const reference to the object storing/generating the column indices */ |
| 141 | + const ColIndices& colIndices() const { return m_colIndices; } |
| 142 | + |
| 143 | +protected: |
| 144 | + MatrixTypeNested m_xpr; |
| 145 | + RowIndices m_rowIndices; |
| 146 | + ColIndices m_colIndices; |
| 147 | +}; |
| 148 | + |
| 149 | + |
| 150 | +// Generic API dispatcher |
| 151 | +template<typename XprType, typename RowIndices, typename ColIndices, typename StorageKind> |
| 152 | +class IndexedViewImpl |
| 153 | + : public internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type |
| 154 | +{ |
| 155 | +public: |
| 156 | + typedef typename internal::generic_xpr_base<IndexedView<XprType, RowIndices, ColIndices> >::type Base; |
| 157 | +}; |
| 158 | + |
| 159 | +namespace internal { |
| 160 | + |
| 161 | + |
| 162 | +template<typename ArgType, typename RowIndices, typename ColIndices> |
| 163 | +struct unary_evaluator<IndexedView<ArgType, RowIndices, ColIndices>, IndexBased> |
| 164 | + : evaluator_base<IndexedView<ArgType, RowIndices, ColIndices> > |
| 165 | +{ |
| 166 | + typedef IndexedView<ArgType, RowIndices, ColIndices> XprType; |
| 167 | + |
| 168 | + enum { |
| 169 | + CoeffReadCost = evaluator<ArgType>::CoeffReadCost /* TODO + cost of row/col index */, |
| 170 | + |
| 171 | + Flags = (evaluator<ArgType>::Flags & (HereditaryBits /*| LinearAccessBit | DirectAccessBit*/)), |
| 172 | + |
| 173 | + Alignment = 0 |
| 174 | + }; |
| 175 | + |
| 176 | + EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_xpr(xpr) |
| 177 | + { |
| 178 | + EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost); |
| 179 | + } |
| 180 | + |
| 181 | + typedef typename XprType::Scalar Scalar; |
| 182 | + typedef typename XprType::CoeffReturnType CoeffReturnType; |
| 183 | + |
| 184 | + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE |
| 185 | + CoeffReturnType coeff(Index row, Index col) const |
| 186 | + { |
| 187 | + return m_argImpl.coeff(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]); |
| 188 | + } |
| 189 | + |
| 190 | + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE |
| 191 | + Scalar& coeffRef(Index row, Index col) |
| 192 | + { |
| 193 | + return m_argImpl.coeffRef(m_xpr.rowIndices()[row], m_xpr.colIndices()[col]); |
| 194 | + } |
| 195 | + |
| 196 | +protected: |
| 197 | + |
| 198 | + evaluator<ArgType> m_argImpl; |
| 199 | + const XprType& m_xpr; |
| 200 | + |
| 201 | +}; |
| 202 | + |
| 203 | +} // end namespace internal |
| 204 | + |
| 205 | +} // end namespace Eigen |
| 206 | + |
| 207 | +#endif // EIGEN_INDEXED_VIEW_H |
0 commit comments