cart-elc

Source code for CART-ELC
git clone git://git.laack.co/cart-elc.git
Log | Files | Refs | README | LICENSE

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 }