TutorialSlicingIndexing.dox (8209B)
1 namespace Eigen { 2 3 /** \eigenManualPage TutorialSlicingIndexing Slicing and Indexing 4 5 This page presents the numerous possibilities offered by `operator()` to index sub-set of rows and columns. 6 This API has been introduced in %Eigen 3.4. 7 It supports all the feature proposed by the \link TutorialBlockOperations block API \endlink, and much more. 8 In 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 14 All the aforementioned operations are handled through the generic DenseBase::operator()(const RowIndices&, const ColIndices&) method. 15 Each 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. 18 - An ArithmeticSequence as constructed by the Eigen::seq, Eigen::seqN, or Eigen::lastN functions. 19 - 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 21 More 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 26 where `<integral type>` stands for any integer type compatible with Eigen::Index (i.e. `std::ptrdiff_t`). 27 28 \section TutorialSlicingBasic Basic slicing 29 30 Taking 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 60 The \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 Here 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 115 As seen in the last exemple, referencing the <i> last n </i> elements (or rows/columns) is a bit cumbersome to write. 116 This becomes even more tricky and error prone with a non-default increment. 117 Here comes \link Eigen::lastN(SizeType) Eigen::lastN(size) \endlink, and \link Eigen::lastN(SizeType,IncrType) Eigen::lastN(size,incr) \endlink: 118 119 <table class="manual"> 120 <tr> 121 <th>Intent</th> 122 <th>Code</th> 123 <th>Block-API equivalence</th> 124 </tr> 125 <tr> 126 <td>Last \c n elements of v</td> 127 <td>\code v(lastN(n)) \endcode</td> 128 <td>\code v.tail(n) \endcode</td> 129 </tr> 130 <tr> 131 <td>Bottom-right corner of A of size \c m times \c n</td> 132 <td>\code v(lastN(m), lastN(n)) \endcode</td> 133 <td>\code A.bottomRightCorner(m,n) \endcode</td> 134 </tr> 135 <tr> 136 <td>Bottom-right corner of A of size \c m times \c n</td> 137 <td>\code v(lastN(m), lastN(n)) \endcode</td> 138 <td>\code A.bottomRightCorner(m,n) \endcode</td> 139 </tr> 140 <tr> 141 <td>Last \c n columns taking 1 column over 3</td> 142 <td>\code A(all, lastN(n,3)) \endcode</td> 143 <td></td> 144 </tr> 145 </table> 146 147 \section TutorialSlicingFixed Compile time size and increment 148 149 In terms of performance, %Eigen and the compiler can take advantage of compile-time size and increment. 150 To this end, you can enforce compile-time parameters using Eigen::fix<val>. 151 Such compile-time value can be combined with the Eigen::last symbol: 152 \code v(seq(last-fix<7>, last-fix<2>)) 153 \endcode 154 In this example %Eigen knowns at compile-time that the returned expression has 6 elements. 155 It is equivalent to: 156 \code v(seqN(last-7, fix<6>)) 157 \endcode 158 159 We can revisit the <i>even columns of A</i> example as follows: 160 \code A(all, seq(0,last,fix<2>)) 161 \endcode 162 163 164 \section TutorialSlicingReverse Reverse order 165 166 Row/column indices can also be enumerated in decreasing order using a negative increment. 167 For instance, one over two columns of A from the column 20 to 10: 168 \code A(all, seq(20, 10, fix<-2>)) 169 \endcode 170 The last \c n rows starting from the last one: 171 \code A(seqN(last, n, fix<-1>), all) 172 \endcode 173 You can also use the ArithmeticSequence::reverse() method to reverse its order. 174 The previous example can thus also be written as: 175 \code A(lastN(n).reverse(), all) 176 \endcode 177 178 179 \section TutorialSlicingArray Array of indices 180 181 The 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 183 <table class="example"> 184 <tr><th>Example:</th><th>Output:</th></tr> 185 <tr><td> 186 \include Slicing_stdvector_cxx11.cpp 187 </td> 188 <td> 189 \verbinclude Slicing_stdvector_cxx11.out 190 </td></tr></table> 191 192 You can also directly pass a static array: 193 <table class="example"> 194 <tr><th>Example:</th><th>Output:</th></tr> 195 <tr><td> 196 \include Slicing_rawarray_cxx11.cpp 197 </td> 198 <td> 199 \verbinclude Slicing_rawarray_cxx11.out 200 </td></tr></table> 201 202 or expressions: 203 <table class="example"> 204 <tr><th>Example:</th><th>Output:</th></tr> 205 <tr><td> 206 \include Slicing_arrayexpr.cpp 207 </td> 208 <td> 209 \verbinclude Slicing_arrayexpr.out 210 </td></tr></table> 211 212 When 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 214 \section TutorialSlicingCustomArray Custom index list 215 216 More generally, `operator()` can accept as inputs any object \c ind of type \c T compatible with: 217 \code 218 Index s = ind.size(); or Index s = size(ind); 219 Index i; 220 i = ind[i]; 221 \endcode 222 223 This means you can easily build your own fancy sequence generator and pass it to `operator()`. 224 Here is an exemple enlarging a given matrix while padding the additional first rows and columns through repetition: 225 226 <table class="example"> 227 <tr><th>Example:</th><th>Output:</th></tr> 228 <tr><td> 229 \include Slicing_custom_padding_cxx11.cpp 230 </td> 231 <td> 232 \verbinclude Slicing_custom_padding_cxx11.out 233 </td></tr></table> 234 235 <br> 236 237 */ 238 239 /* 240 TODO add: 241 so_repeat_inner.cpp 242 so_repeleme.cpp 243 */ 244 }