IndexedViewMethods.h (12283B)
1 // This file is part of Eigen, a lightweight C++ template library 2 // for linear algebra. 3 // 4 // Copyright (C) 2017 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 #if !defined(EIGEN_PARSED_BY_DOXYGEN) 11 12 // This file is automatically included twice to generate const and non-const versions 13 14 #ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS 15 #define EIGEN_INDEXED_VIEW_METHOD_CONST const 16 #define EIGEN_INDEXED_VIEW_METHOD_TYPE ConstIndexedViewType 17 #else 18 #define EIGEN_INDEXED_VIEW_METHOD_CONST 19 #define EIGEN_INDEXED_VIEW_METHOD_TYPE IndexedViewType 20 #endif 21 22 #ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS 23 protected: 24 25 // define some aliases to ease readability 26 27 template<typename Indices> 28 struct IvcRowType : public internal::IndexedViewCompatibleType<Indices,RowsAtCompileTime> {}; 29 30 template<typename Indices> 31 struct IvcColType : public internal::IndexedViewCompatibleType<Indices,ColsAtCompileTime> {}; 32 33 template<typename Indices> 34 struct IvcType : public internal::IndexedViewCompatibleType<Indices,SizeAtCompileTime> {}; 35 36 typedef typename internal::IndexedViewCompatibleType<Index,1>::type IvcIndex; 37 38 template<typename Indices> 39 typename IvcRowType<Indices>::type 40 ivcRow(const Indices& indices) const { 41 return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,RowsAtCompileTime>(derived().rows()),Specialized); 42 } 43 44 template<typename Indices> 45 typename IvcColType<Indices>::type 46 ivcCol(const Indices& indices) const { 47 return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,ColsAtCompileTime>(derived().cols()),Specialized); 48 } 49 50 template<typename Indices> 51 typename IvcColType<Indices>::type 52 ivcSize(const Indices& indices) const { 53 return internal::makeIndexedViewCompatible(indices, internal::variable_if_dynamic<Index,SizeAtCompileTime>(derived().size()),Specialized); 54 } 55 56 public: 57 58 #endif 59 60 template<typename RowIndices, typename ColIndices> 61 struct EIGEN_INDEXED_VIEW_METHOD_TYPE { 62 typedef IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived, 63 typename IvcRowType<RowIndices>::type, 64 typename IvcColType<ColIndices>::type> type; 65 }; 66 67 // This is the generic version 68 69 template<typename RowIndices, typename ColIndices> 70 typename internal::enable_if<internal::valid_indexed_view_overload<RowIndices,ColIndices>::value 71 && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsIndexedView, 72 typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type >::type 73 operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST 74 { 75 return typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type 76 (derived(), ivcRow(rowIndices), ivcCol(colIndices)); 77 } 78 79 // The following overload returns a Block<> object 80 81 template<typename RowIndices, typename ColIndices> 82 typename internal::enable_if<internal::valid_indexed_view_overload<RowIndices,ColIndices>::value 83 && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsBlock, 84 typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType>::type 85 operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST 86 { 87 typedef typename internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::BlockType BlockType; 88 typename IvcRowType<RowIndices>::type actualRowIndices = ivcRow(rowIndices); 89 typename IvcColType<ColIndices>::type actualColIndices = ivcCol(colIndices); 90 return BlockType(derived(), 91 internal::first(actualRowIndices), 92 internal::first(actualColIndices), 93 internal::size(actualRowIndices), 94 internal::size(actualColIndices)); 95 } 96 97 // The following overload returns a Scalar 98 99 template<typename RowIndices, typename ColIndices> 100 typename internal::enable_if<internal::valid_indexed_view_overload<RowIndices,ColIndices>::value 101 && internal::traits<typename EIGEN_INDEXED_VIEW_METHOD_TYPE<RowIndices,ColIndices>::type>::ReturnAsScalar, 102 CoeffReturnType >::type 103 operator()(const RowIndices& rowIndices, const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST 104 { 105 return Base::operator()(internal::eval_expr_given_size(rowIndices,rows()),internal::eval_expr_given_size(colIndices,cols())); 106 } 107 108 #if EIGEN_HAS_STATIC_ARRAY_TEMPLATE 109 110 // The following three overloads are needed to handle raw Index[N] arrays. 111 112 template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndices> 113 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type> 114 operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndices& colIndices) EIGEN_INDEXED_VIEW_METHOD_CONST 115 { 116 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],typename IvcColType<ColIndices>::type> 117 (derived(), rowIndices, ivcCol(colIndices)); 118 } 119 120 template<typename RowIndices, typename ColIndicesT, std::size_t ColIndicesN> 121 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type, const ColIndicesT (&)[ColIndicesN]> 122 operator()(const RowIndices& rowIndices, const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST 123 { 124 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcRowType<RowIndices>::type,const ColIndicesT (&)[ColIndicesN]> 125 (derived(), ivcRow(rowIndices), colIndices); 126 } 127 128 template<typename RowIndicesT, std::size_t RowIndicesN, typename ColIndicesT, std::size_t ColIndicesN> 129 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN], const ColIndicesT (&)[ColIndicesN]> 130 operator()(const RowIndicesT (&rowIndices)[RowIndicesN], const ColIndicesT (&colIndices)[ColIndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST 131 { 132 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const RowIndicesT (&)[RowIndicesN],const ColIndicesT (&)[ColIndicesN]> 133 (derived(), rowIndices, colIndices); 134 } 135 136 #endif // EIGEN_HAS_STATIC_ARRAY_TEMPLATE 137 138 // Overloads for 1D vectors/arrays 139 140 template<typename Indices> 141 typename internal::enable_if< 142 IsRowMajor && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_valid_index_type<Indices>::value)), 143 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type> >::type 144 operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST 145 { 146 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 147 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,typename IvcType<Indices>::type> 148 (derived(), IvcIndex(0), ivcCol(indices)); 149 } 150 151 template<typename Indices> 152 typename internal::enable_if< 153 (!IsRowMajor) && (!(internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1 || internal::is_valid_index_type<Indices>::value)), 154 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex> >::type 155 operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST 156 { 157 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 158 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,typename IvcType<Indices>::type,IvcIndex> 159 (derived(), ivcRow(indices), IvcIndex(0)); 160 } 161 162 template<typename Indices> 163 typename internal::enable_if< 164 (internal::get_compile_time_incr<typename IvcType<Indices>::type>::value==1) && (!internal::is_valid_index_type<Indices>::value) && (!symbolic::is_symbolic<Indices>::value), 165 VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value> >::type 166 operator()(const Indices& indices) EIGEN_INDEXED_VIEW_METHOD_CONST 167 { 168 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 169 typename IvcType<Indices>::type actualIndices = ivcSize(indices); 170 return VectorBlock<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,internal::array_size<Indices>::value> 171 (derived(), internal::first(actualIndices), internal::size(actualIndices)); 172 } 173 174 template<typename IndexType> 175 typename internal::enable_if<symbolic::is_symbolic<IndexType>::value, CoeffReturnType >::type 176 operator()(const IndexType& id) EIGEN_INDEXED_VIEW_METHOD_CONST 177 { 178 return Base::operator()(internal::eval_expr_given_size(id,size())); 179 } 180 181 #if EIGEN_HAS_STATIC_ARRAY_TEMPLATE 182 183 template<typename IndicesT, std::size_t IndicesN> 184 typename internal::enable_if<IsRowMajor, 185 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]> >::type 186 operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST 187 { 188 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 189 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,IvcIndex,const IndicesT (&)[IndicesN]> 190 (derived(), IvcIndex(0), indices); 191 } 192 193 template<typename IndicesT, std::size_t IndicesN> 194 typename internal::enable_if<!IsRowMajor, 195 IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex> >::type 196 operator()(const IndicesT (&indices)[IndicesN]) EIGEN_INDEXED_VIEW_METHOD_CONST 197 { 198 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 199 return IndexedView<EIGEN_INDEXED_VIEW_METHOD_CONST Derived,const IndicesT (&)[IndicesN],IvcIndex> 200 (derived(), indices, IvcIndex(0)); 201 } 202 203 #endif // EIGEN_HAS_STATIC_ARRAY_TEMPLATE 204 205 #undef EIGEN_INDEXED_VIEW_METHOD_CONST 206 #undef EIGEN_INDEXED_VIEW_METHOD_TYPE 207 208 #ifndef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS 209 #define EIGEN_INDEXED_VIEW_METHOD_2ND_PASS 210 #include "IndexedViewMethods.h" 211 #undef EIGEN_INDEXED_VIEW_METHOD_2ND_PASS 212 #endif 213 214 #else // EIGEN_PARSED_BY_DOXYGEN 215 216 /** 217 * \returns a generic submatrix view defined by the rows and columns indexed \a rowIndices and \a colIndices respectively. 218 * 219 * Each parameter must either be: 220 * - An integer indexing a single row or column 221 * - Eigen::all indexing the full set of respective rows or columns in increasing order 222 * - An ArithmeticSequence as returned by the Eigen::seq and Eigen::seqN functions 223 * - Any %Eigen's vector/array of integers or expressions 224 * - Plain C arrays: \c int[N] 225 * - And more generally any type exposing the following two member functions: 226 * \code 227 * <integral type> operator[](<integral type>) const; 228 * <integral type> size() const; 229 * \endcode 230 * where \c <integral \c type> stands for any integer type compatible with Eigen::Index (i.e. \c std::ptrdiff_t). 231 * 232 * The last statement implies compatibility with \c std::vector, \c std::valarray, \c std::array, many of the Range-v3's ranges, etc. 233 * 234 * If the submatrix can be represented using a starting position \c (i,j) and positive sizes \c (rows,columns), then this 235 * method will returns a Block object after extraction of the relevant information from the passed arguments. This is the case 236 * when all arguments are either: 237 * - An integer 238 * - Eigen::all 239 * - An ArithmeticSequence with compile-time increment strictly equal to 1, as returned by Eigen::seq(a,b), and Eigen::seqN(a,N). 240 * 241 * Otherwise a more general IndexedView<Derived,RowIndices',ColIndices'> object will be returned, after conversion of the inputs 242 * to more suitable types \c RowIndices' and \c ColIndices'. 243 * 244 * For 1D vectors and arrays, you better use the operator()(const Indices&) overload, which behave the same way but taking a single parameter. 245 * 246 * See also this <a href="https://stackoverflow.com/questions/46110917/eigen-replicate-items-along-one-dimension-without-useless-allocations">question</a> and its answer for an example of how to duplicate coefficients. 247 * 248 * \sa operator()(const Indices&), class Block, class IndexedView, DenseBase::block(Index,Index,Index,Index) 249 */ 250 template<typename RowIndices, typename ColIndices> 251 IndexedView_or_Block 252 operator()(const RowIndices& rowIndices, const ColIndices& colIndices); 253 254 /** This is an overload of operator()(const RowIndices&, const ColIndices&) for 1D vectors or arrays 255 * 256 * \only_for_vectors 257 */ 258 template<typename Indices> 259 IndexedView_or_VectorBlock 260 operator()(const Indices& indices); 261 262 #endif // EIGEN_PARSED_BY_DOXYGEN