TutorialSlicingIndexing.dox 8.0 KB

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