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
ivcRow(const Indices & indices)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
ivcCol(const Indices & indices)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
ivcSize(const Indices & indices)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
operator()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
operator()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
operator()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>
operator()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]>
operator()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]>
operator()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
operator()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
operator()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
operator()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
operator()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
operator()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
operator()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
263