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