blob: 57cc4017b2a49f8919ecf2db58eb78f396a12d35 [file] [log] [blame]
Gael Guennebaudd7c64422018-11-09 11:35:27 +01001namespace Eigen {
2
3/** \eigenManualPage TutorialSlicingIndexing Slicing and Indexing
4
Christoph Hertzberg806352d2018-11-23 12:34:27 +00005This page presents the numerous possibilities offered by `operator()` to index sub-set of rows and columns.
Gael Guennebaudd7c64422018-11-09 11:35:27 +01006This API has been introduced in %Eigen 3.4.
7It supports all the feature proposed by the \link TutorialBlockOperations block API \endlink, and much more.
8In 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
10\eigenAutoToc
11
12\section TutorialSlicingOverview Overview
13
14All the aforementioned operations are handled through the generic DenseBase::operator()(const RowIndices&, const ColIndices&) method.
15Each argument can be:
16 - An integer indexing a single row or column, including symbolic indices.
17 - The symbol Eigen::all representing the whole set of respective rows or columns in increasing order.
Antonio Sanchez5dac0b52021-09-15 14:10:29 -070018 - An ArithmeticSequence as constructed by the Eigen::seq, Eigen::seqN, or Eigen::placeholders::lastN functions.
Gael Guennebaudd7c64422018-11-09 11:35:27 +010019 - 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
21More generally, it can accepts any object exposing the following two member functions:
22 \code
23 <integral type> operator[](<integral type>) const;
24 <integral type> size() const;
25 \endcode
26where `<integral type>` stands for any integer type compatible with Eigen::Index (i.e. `std::ptrdiff_t`).
27
28\section TutorialSlicingBasic Basic slicing
29
30Taking 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
32<table class="manual">
33<tr>
34 <th>function</th>
35 <th>description</th>
36 <th>example</th>
37</tr>
38<tr>
39 <td>\code seq(firstIdx,lastIdx) \endcode</td>
40 <td>represents the sequence of integers ranging from \c firstIdx to \c lastIdx</td>
41 <td>\code seq(2,5) <=> {2,3,4,5} \endcode</td>
42</tr>
43<tr>
44 <td>\code seq(firstIdx,lastIdx,incr) \endcode</td>
45 <td>same but using the increment \c incr to advance from one index to the next</td>
46 <td>\code seq(2,8,2) <=> {2,4,6,8} \endcode</td>
47</tr>
48<tr>
49 <td>\code seqN(firstIdx,size) \endcode</td>
50 <td>represents the sequence of \c size integers starting from \c firstIdx</td>
51 <td>\code seqN(2,5) <=> {2,3,4,5,6} \endcode</td>
52</tr>
53<tr>
54 <td>\code seqN(firstIdx,size,incr) \endcode</td>
55 <td>same but using the increment \c incr to advance from one index to the next</td>
56 <td>\code seqN(2,3,3) <=> {2,5,8} \endcode</td>
57</tr>
58</table>
59
60The \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().
61Here are some examples for a 2D array/matrix \c A and a 1D array/vector \c v.
62<table class="manual">
63<tr>
64 <th>Intent</th>
65 <th>Code</th>
66 <th>Block-API equivalence</th>
67</tr>
68<tr>
69 <td>Bottom-left corner starting at row \c i with \c n columns</td>
70 <td>\code A(seq(i,last), seqN(0,n)) \endcode</td>
71 <td>\code A.bottomLeftCorner(A.rows()-i,n) \endcode</td>
72</tr>
73<tr>
74 <td>%Block starting at \c i,j having \c m rows, and \c n columns</td>
75 <td>\code A(seqN(i,m), seqN(i,n) \endcode</td>
76 <td>\code A.block(i,j,m,n) \endcode</td>
77</tr>
78<tr>
79 <td>%Block starting at \c i0,j0 and ending at \c i1,j1</td>
80 <td>\code A(seq(i0,i1), seq(j0,j1) \endcode</td>
81 <td>\code A.block(i0,j0,i1-i0+1,j1-j0+1) \endcode</td>
82</tr>
83<tr>
84 <td>Even columns of A</td>
85 <td>\code A(all, seq(0,last,2)) \endcode</td>
86 <td></td>
87</tr>
88<tr>
89 <td>First \c n odd rows A</td>
90 <td>\code A(seqN(1,n,2), all) \endcode</td>
91 <td></td>
92</tr>
93<tr>
94 <td>The last past one column</td>
95 <td>\code A(all, last-1) \endcode</td>
96 <td>\code A.col(A.cols()-2) \endcode</td>
97</tr>
98<tr>
99 <td>The middle row</td>
100 <td>\code A(last/2,all) \endcode</td>
101 <td>\code A.row((A.rows()-1)/2) \endcode</td>
102</tr>
103<tr>
104 <td>Last elements of v starting at i</td>
105 <td>\code v(seq(i,last)) \endcode</td>
106 <td>\code v.tail(v.size()-i) \endcode</td>
107</tr>
108<tr>
109 <td>Last \c n elements of v</td>
110 <td>\code v(seq(last+1-n,last)) \endcode</td>
111 <td>\code v.tail(n) \endcode</td>
112</tr>
113</table>
114
sciencewhiz4b6036e2021-09-22 16:15:06 +0000115As seen in the last example, referencing the <i> last n </i> elements (or rows/columns) is a bit cumbersome to write.
Gael Guennebaudd7c64422018-11-09 11:35:27 +0100116This becomes even more tricky and error prone with a non-default increment.
Antonio Sanchez5dac0b52021-09-15 14:10:29 -0700117Here comes \link Eigen::placeholders::lastN(SizeType) Eigen::placeholders::lastN(size) \endlink, and
118\link Eigen::placeholders::lastN(SizeType,IncrType) Eigen::placeholders::lastN(size,incr) \endlink:
Gael Guennebaudd7c64422018-11-09 11:35:27 +0100119
120<table class="manual">
121<tr>
122 <th>Intent</th>
123 <th>Code</th>
124 <th>Block-API equivalence</th>
125</tr>
126<tr>
127 <td>Last \c n elements of v</td>
128 <td>\code v(lastN(n)) \endcode</td>
129 <td>\code v.tail(n) \endcode</td>
130</tr>
131<tr>
132 <td>Bottom-right corner of A of size \c m times \c n</td>
133 <td>\code v(lastN(m), lastN(n)) \endcode</td>
134 <td>\code A.bottomRightCorner(m,n) \endcode</td>
135</tr>
136<tr>
137 <td>Bottom-right corner of A of size \c m times \c n</td>
138 <td>\code v(lastN(m), lastN(n)) \endcode</td>
139 <td>\code A.bottomRightCorner(m,n) \endcode</td>
140</tr>
141<tr>
142 <td>Last \c n columns taking 1 column over 3</td>
143 <td>\code A(all, lastN(n,3)) \endcode</td>
144 <td></td>
145</tr>
146</table>
147
148\section TutorialSlicingFixed Compile time size and increment
149
150In terms of performance, %Eigen and the compiler can take advantage of compile-time size and increment.
151To this end, you can enforce compile-time parameters using Eigen::fix<val>.
152Such compile-time value can be combined with the Eigen::last symbol:
153\code v(seq(last-fix<7>, last-fix<2>))
154\endcode
155In this example %Eigen knowns at compile-time that the returned expression has 6 elements.
156It is equivalent to:
157\code v(seqN(last-7, fix<6>))
158\endcode
159
160We can revisit the <i>even columns of A</i> example as follows:
161\code A(all, seq(0,last,fix<2>))
162\endcode
163
164
165\section TutorialSlicingReverse Reverse order
166
167Row/column indices can also be enumerated in decreasing order using a negative increment.
168For instance, one over two columns of A from the column 20 to 10:
169\code A(all, seq(20, 10, fix<-2>))
170\endcode
171The last \c n rows starting from the last one:
172\code A(seqN(last, n, fix<-1>), all)
173\endcode
174You can also use the ArithmeticSequence::reverse() method to reverse its order.
175The previous example can thus also be written as:
176\code A(lastN(n).reverse(), all)
177\endcode
178
179
180\section TutorialSlicingArray Array of indices
181
182The 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.
183
184<table class="example">
185<tr><th>Example:</th><th>Output:</th></tr>
186<tr><td>
187\include Slicing_stdvector_cxx11.cpp
188</td>
189<td>
190\verbinclude Slicing_stdvector_cxx11.out
191</td></tr></table>
192
193You can also directly pass a static array:
194<table class="example">
195<tr><th>Example:</th><th>Output:</th></tr>
196<tr><td>
197\include Slicing_rawarray_cxx11.cpp
198</td>
199<td>
200\verbinclude Slicing_rawarray_cxx11.out
201</td></tr></table>
202
203or expressions:
204<table class="example">
205<tr><th>Example:</th><th>Output:</th></tr>
206<tr><td>
207\include Slicing_arrayexpr.cpp
208</td>
209<td>
210\verbinclude Slicing_arrayexpr.out
211</td></tr></table>
212
213When 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.
214
215\section TutorialSlicingCustomArray Custom index list
216
217More generally, `operator()` can accept as inputs any object \c ind of type \c T compatible with:
218\code
219Index s = ind.size(); or Index s = size(ind);
220Index i;
221i = ind[i];
222\endcode
223
224This means you can easily build your own fancy sequence generator and pass it to `operator()`.
sciencewhiz4b6036e2021-09-22 16:15:06 +0000225Here is an example enlarging a given matrix while padding the additional first rows and columns through repetition:
Gael Guennebaudd7c64422018-11-09 11:35:27 +0100226
227<table class="example">
228<tr><th>Example:</th><th>Output:</th></tr>
229<tr><td>
230\include Slicing_custom_padding_cxx11.cpp
231</td>
232<td>
233\verbinclude Slicing_custom_padding_cxx11.out
234</td></tr></table>
235
236<br>
237
238*/
239
240/*
241TODO add:
242so_repeat_inner.cpp
243so_repeleme.cpp
244*/
245}