xref: /aosp_15_r20/external/eigen/doc/TutorialSlicingIndexing.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \eigenManualPage TutorialSlicingIndexing Slicing and Indexing
4*bf2c3715SXin Li
5*bf2c3715SXin LiThis page presents the numerous possibilities offered by `operator()` to index sub-set of rows and columns.
6*bf2c3715SXin LiThis API has been introduced in %Eigen 3.4.
7*bf2c3715SXin LiIt supports all the feature proposed by the \link TutorialBlockOperations block API \endlink, and much more.
8*bf2c3715SXin LiIn particular, it supports \b slicing that consists in taking a set of rows, columns, or elements, uniformly spaced within a matrix or indexed from an array of indices.
9*bf2c3715SXin Li
10*bf2c3715SXin Li\eigenAutoToc
11*bf2c3715SXin Li
12*bf2c3715SXin Li\section TutorialSlicingOverview Overview
13*bf2c3715SXin Li
14*bf2c3715SXin LiAll the aforementioned operations are handled through the generic DenseBase::operator()(const RowIndices&, const ColIndices&) method.
15*bf2c3715SXin LiEach argument can be:
16*bf2c3715SXin Li  - An integer indexing a single row or column, including symbolic indices.
17*bf2c3715SXin Li  - The symbol Eigen::all representing the whole set of respective rows or columns in increasing order.
18*bf2c3715SXin Li  - An ArithmeticSequence as constructed by the Eigen::seq, Eigen::seqN, or Eigen::lastN functions.
19*bf2c3715SXin Li  - Any 1D vector/array of integers including %Eigen's vector/array, expressions, std::vector, std::array, as well as plain C arrays: `int[N]`.
20*bf2c3715SXin Li
21*bf2c3715SXin LiMore generally, it can accepts any object exposing the following two member functions:
22*bf2c3715SXin Li  \code
23*bf2c3715SXin Li  <integral type> operator[](<integral type>) const;
24*bf2c3715SXin Li  <integral type> size() const;
25*bf2c3715SXin Li  \endcode
26*bf2c3715SXin Liwhere `<integral type>` stands for any integer type compatible with Eigen::Index (i.e. `std::ptrdiff_t`).
27*bf2c3715SXin Li
28*bf2c3715SXin Li\section TutorialSlicingBasic Basic slicing
29*bf2c3715SXin Li
30*bf2c3715SXin LiTaking a set of rows, columns, or elements, uniformly spaced within a matrix or vector is achieved through the Eigen::seq or Eigen::seqN functions where "seq" stands for arithmetic sequence. Their signatures are summarized below:
31*bf2c3715SXin Li
32*bf2c3715SXin Li<table class="manual">
33*bf2c3715SXin Li<tr>
34*bf2c3715SXin Li  <th>function</th>
35*bf2c3715SXin Li  <th>description</th>
36*bf2c3715SXin Li  <th>example</th>
37*bf2c3715SXin Li</tr>
38*bf2c3715SXin Li<tr>
39*bf2c3715SXin Li  <td>\code seq(firstIdx,lastIdx) \endcode</td>
40*bf2c3715SXin Li  <td>represents the sequence of integers ranging from \c firstIdx to \c lastIdx</td>
41*bf2c3715SXin Li  <td>\code seq(2,5) <=> {2,3,4,5} \endcode</td>
42*bf2c3715SXin Li</tr>
43*bf2c3715SXin Li<tr>
44*bf2c3715SXin Li  <td>\code seq(firstIdx,lastIdx,incr) \endcode</td>
45*bf2c3715SXin Li  <td>same but using the increment \c incr to advance from one index to the next</td>
46*bf2c3715SXin Li  <td>\code seq(2,8,2) <=> {2,4,6,8} \endcode</td>
47*bf2c3715SXin Li</tr>
48*bf2c3715SXin Li<tr>
49*bf2c3715SXin Li  <td>\code seqN(firstIdx,size) \endcode</td>
50*bf2c3715SXin Li  <td>represents the sequence of \c size integers starting from \c firstIdx</td>
51*bf2c3715SXin Li  <td>\code seqN(2,5) <=> {2,3,4,5,6} \endcode</td>
52*bf2c3715SXin Li</tr>
53*bf2c3715SXin Li<tr>
54*bf2c3715SXin Li  <td>\code seqN(firstIdx,size,incr) \endcode</td>
55*bf2c3715SXin Li  <td>same but using the increment \c incr to advance from one index to the next</td>
56*bf2c3715SXin Li  <td>\code seqN(2,3,3) <=> {2,5,8} \endcode</td>
57*bf2c3715SXin Li</tr>
58*bf2c3715SXin Li</table>
59*bf2c3715SXin Li
60*bf2c3715SXin LiThe \c firstIdx and \c lastIdx parameters can also be defined with the help of the Eigen::last symbol representing the index of the last row, column or element of the underlying matrix/vector once the arithmetic sequence is passed to it through operator().
61*bf2c3715SXin LiHere are some examples for a 2D array/matrix \c A and a 1D array/vector \c v.
62*bf2c3715SXin Li<table class="manual">
63*bf2c3715SXin Li<tr>
64*bf2c3715SXin Li  <th>Intent</th>
65*bf2c3715SXin Li  <th>Code</th>
66*bf2c3715SXin Li  <th>Block-API equivalence</th>
67*bf2c3715SXin Li</tr>
68*bf2c3715SXin Li<tr>
69*bf2c3715SXin Li  <td>Bottom-left corner starting at row \c i with \c n columns</td>
70*bf2c3715SXin Li  <td>\code A(seq(i,last), seqN(0,n)) \endcode</td>
71*bf2c3715SXin Li  <td>\code A.bottomLeftCorner(A.rows()-i,n) \endcode</td>
72*bf2c3715SXin Li</tr>
73*bf2c3715SXin Li<tr>
74*bf2c3715SXin Li  <td>%Block starting at \c i,j having \c m rows, and \c n columns</td>
75*bf2c3715SXin Li  <td>\code A(seqN(i,m), seqN(i,n) \endcode</td>
76*bf2c3715SXin Li  <td>\code A.block(i,j,m,n) \endcode</td>
77*bf2c3715SXin Li</tr>
78*bf2c3715SXin Li<tr>
79*bf2c3715SXin Li  <td>%Block starting at \c i0,j0 and ending at \c i1,j1</td>
80*bf2c3715SXin Li  <td>\code A(seq(i0,i1), seq(j0,j1) \endcode</td>
81*bf2c3715SXin Li  <td>\code A.block(i0,j0,i1-i0+1,j1-j0+1) \endcode</td>
82*bf2c3715SXin Li</tr>
83*bf2c3715SXin Li<tr>
84*bf2c3715SXin Li  <td>Even columns of A</td>
85*bf2c3715SXin Li  <td>\code A(all, seq(0,last,2)) \endcode</td>
86*bf2c3715SXin Li  <td></td>
87*bf2c3715SXin Li</tr>
88*bf2c3715SXin Li<tr>
89*bf2c3715SXin Li  <td>First \c n odd rows A</td>
90*bf2c3715SXin Li  <td>\code A(seqN(1,n,2), all) \endcode</td>
91*bf2c3715SXin Li  <td></td>
92*bf2c3715SXin Li</tr>
93*bf2c3715SXin Li<tr>
94*bf2c3715SXin Li  <td>The last past one column</td>
95*bf2c3715SXin Li  <td>\code A(all, last-1) \endcode</td>
96*bf2c3715SXin Li  <td>\code A.col(A.cols()-2) \endcode</td>
97*bf2c3715SXin Li</tr>
98*bf2c3715SXin Li<tr>
99*bf2c3715SXin Li  <td>The middle row</td>
100*bf2c3715SXin Li  <td>\code A(last/2,all) \endcode</td>
101*bf2c3715SXin Li  <td>\code A.row((A.rows()-1)/2) \endcode</td>
102*bf2c3715SXin Li</tr>
103*bf2c3715SXin Li<tr>
104*bf2c3715SXin Li  <td>Last elements of v starting at i</td>
105*bf2c3715SXin Li  <td>\code v(seq(i,last)) \endcode</td>
106*bf2c3715SXin Li  <td>\code v.tail(v.size()-i) \endcode</td>
107*bf2c3715SXin Li</tr>
108*bf2c3715SXin Li<tr>
109*bf2c3715SXin Li  <td>Last \c n elements of v</td>
110*bf2c3715SXin Li  <td>\code v(seq(last+1-n,last)) \endcode</td>
111*bf2c3715SXin Li  <td>\code v.tail(n) \endcode</td>
112*bf2c3715SXin Li</tr>
113*bf2c3715SXin Li</table>
114*bf2c3715SXin Li
115*bf2c3715SXin LiAs seen in the last exemple, referencing the <i> last n </i> elements (or rows/columns) is a bit cumbersome to write.
116*bf2c3715SXin LiThis becomes even more tricky and error prone with a non-default increment.
117*bf2c3715SXin LiHere comes \link Eigen::lastN(SizeType) Eigen::lastN(size) \endlink, and \link Eigen::lastN(SizeType,IncrType) Eigen::lastN(size,incr) \endlink:
118*bf2c3715SXin Li
119*bf2c3715SXin Li<table class="manual">
120*bf2c3715SXin Li<tr>
121*bf2c3715SXin Li  <th>Intent</th>
122*bf2c3715SXin Li  <th>Code</th>
123*bf2c3715SXin Li  <th>Block-API equivalence</th>
124*bf2c3715SXin Li</tr>
125*bf2c3715SXin Li<tr>
126*bf2c3715SXin Li  <td>Last \c n elements of v</td>
127*bf2c3715SXin Li  <td>\code v(lastN(n)) \endcode</td>
128*bf2c3715SXin Li  <td>\code v.tail(n) \endcode</td>
129*bf2c3715SXin Li</tr>
130*bf2c3715SXin Li<tr>
131*bf2c3715SXin Li  <td>Bottom-right corner of A of size \c m times \c n</td>
132*bf2c3715SXin Li  <td>\code v(lastN(m), lastN(n)) \endcode</td>
133*bf2c3715SXin Li  <td>\code A.bottomRightCorner(m,n) \endcode</td>
134*bf2c3715SXin Li</tr>
135*bf2c3715SXin Li<tr>
136*bf2c3715SXin Li  <td>Bottom-right corner of A of size \c m times \c n</td>
137*bf2c3715SXin Li  <td>\code v(lastN(m), lastN(n)) \endcode</td>
138*bf2c3715SXin Li  <td>\code A.bottomRightCorner(m,n) \endcode</td>
139*bf2c3715SXin Li</tr>
140*bf2c3715SXin Li<tr>
141*bf2c3715SXin Li  <td>Last \c n columns taking 1 column over 3</td>
142*bf2c3715SXin Li  <td>\code A(all, lastN(n,3)) \endcode</td>
143*bf2c3715SXin Li  <td></td>
144*bf2c3715SXin Li</tr>
145*bf2c3715SXin Li</table>
146*bf2c3715SXin Li
147*bf2c3715SXin Li\section TutorialSlicingFixed Compile time size and increment
148*bf2c3715SXin Li
149*bf2c3715SXin LiIn terms of performance, %Eigen and the compiler can take advantage of compile-time size and increment.
150*bf2c3715SXin LiTo this end, you can enforce compile-time parameters using Eigen::fix<val>.
151*bf2c3715SXin LiSuch compile-time value can be combined with the Eigen::last symbol:
152*bf2c3715SXin Li\code v(seq(last-fix<7>, last-fix<2>))
153*bf2c3715SXin Li\endcode
154*bf2c3715SXin LiIn this example %Eigen knowns at compile-time that the returned expression has 6 elements.
155*bf2c3715SXin LiIt is equivalent to:
156*bf2c3715SXin Li\code v(seqN(last-7, fix<6>))
157*bf2c3715SXin Li\endcode
158*bf2c3715SXin Li
159*bf2c3715SXin LiWe can revisit the <i>even columns of A</i> example as follows:
160*bf2c3715SXin Li\code A(all, seq(0,last,fix<2>))
161*bf2c3715SXin Li\endcode
162*bf2c3715SXin Li
163*bf2c3715SXin Li
164*bf2c3715SXin Li\section TutorialSlicingReverse Reverse order
165*bf2c3715SXin Li
166*bf2c3715SXin LiRow/column indices can also be enumerated in decreasing order using a negative increment.
167*bf2c3715SXin LiFor instance, one over two columns of A from the column 20 to 10:
168*bf2c3715SXin Li\code A(all, seq(20, 10, fix<-2>))
169*bf2c3715SXin Li\endcode
170*bf2c3715SXin LiThe last \c n rows starting from the last one:
171*bf2c3715SXin Li\code A(seqN(last, n, fix<-1>), all)
172*bf2c3715SXin Li\endcode
173*bf2c3715SXin LiYou can also use the ArithmeticSequence::reverse() method to reverse its order.
174*bf2c3715SXin LiThe previous example can thus also be written as:
175*bf2c3715SXin Li\code A(lastN(n).reverse(), all)
176*bf2c3715SXin Li\endcode
177*bf2c3715SXin Li
178*bf2c3715SXin Li
179*bf2c3715SXin Li\section TutorialSlicingArray Array of indices
180*bf2c3715SXin Li
181*bf2c3715SXin LiThe generic `operator()` can also takes as input an arbitrary list of row or column indices stored as either an `ArrayXi`, a `std::vector<int>`, `std::array<int,N>`, etc.
182*bf2c3715SXin Li
183*bf2c3715SXin Li<table class="example">
184*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
185*bf2c3715SXin Li<tr><td>
186*bf2c3715SXin Li\include Slicing_stdvector_cxx11.cpp
187*bf2c3715SXin Li</td>
188*bf2c3715SXin Li<td>
189*bf2c3715SXin Li\verbinclude Slicing_stdvector_cxx11.out
190*bf2c3715SXin Li</td></tr></table>
191*bf2c3715SXin Li
192*bf2c3715SXin LiYou can also directly pass a static array:
193*bf2c3715SXin Li<table class="example">
194*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
195*bf2c3715SXin Li<tr><td>
196*bf2c3715SXin Li\include Slicing_rawarray_cxx11.cpp
197*bf2c3715SXin Li</td>
198*bf2c3715SXin Li<td>
199*bf2c3715SXin Li\verbinclude Slicing_rawarray_cxx11.out
200*bf2c3715SXin Li</td></tr></table>
201*bf2c3715SXin Li
202*bf2c3715SXin Lior expressions:
203*bf2c3715SXin Li<table class="example">
204*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
205*bf2c3715SXin Li<tr><td>
206*bf2c3715SXin Li\include Slicing_arrayexpr.cpp
207*bf2c3715SXin Li</td>
208*bf2c3715SXin Li<td>
209*bf2c3715SXin Li\verbinclude Slicing_arrayexpr.out
210*bf2c3715SXin Li</td></tr></table>
211*bf2c3715SXin Li
212*bf2c3715SXin LiWhen passing an object with a compile-time size such as `Array4i`, `std::array<int,N>`, or a static array, then the returned expression also exhibit compile-time dimensions.
213*bf2c3715SXin Li
214*bf2c3715SXin Li\section TutorialSlicingCustomArray Custom index list
215*bf2c3715SXin Li
216*bf2c3715SXin LiMore generally, `operator()` can accept as inputs any object \c ind of type \c T compatible with:
217*bf2c3715SXin Li\code
218*bf2c3715SXin LiIndex s = ind.size(); or Index s = size(ind);
219*bf2c3715SXin LiIndex i;
220*bf2c3715SXin Lii = ind[i];
221*bf2c3715SXin Li\endcode
222*bf2c3715SXin Li
223*bf2c3715SXin LiThis means you can easily build your own fancy sequence generator and pass it to `operator()`.
224*bf2c3715SXin LiHere is an exemple enlarging a given matrix while padding the additional first rows and columns through repetition:
225*bf2c3715SXin Li
226*bf2c3715SXin Li<table class="example">
227*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
228*bf2c3715SXin Li<tr><td>
229*bf2c3715SXin Li\include Slicing_custom_padding_cxx11.cpp
230*bf2c3715SXin Li</td>
231*bf2c3715SXin Li<td>
232*bf2c3715SXin Li\verbinclude Slicing_custom_padding_cxx11.out
233*bf2c3715SXin Li</td></tr></table>
234*bf2c3715SXin Li
235*bf2c3715SXin Li<br>
236*bf2c3715SXin Li
237*bf2c3715SXin Li*/
238*bf2c3715SXin Li
239*bf2c3715SXin Li/*
240*bf2c3715SXin LiTODO add:
241*bf2c3715SXin Liso_repeat_inner.cpp
242*bf2c3715SXin Liso_repeleme.cpp
243*bf2c3715SXin Li*/
244*bf2c3715SXin Li}
245