xref: /aosp_15_r20/external/eigen/doc/TutorialBlockOperations.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \eigenManualPage TutorialBlockOperations Block operations
4*bf2c3715SXin Li
5*bf2c3715SXin LiThis page explains the essentials of block operations.
6*bf2c3715SXin LiA block is a rectangular part of a matrix or array. Blocks expressions can be used both
7*bf2c3715SXin Lias rvalues and as lvalues. As usual with Eigen expressions, this abstraction has zero runtime cost
8*bf2c3715SXin Liprovided that you let your compiler optimize.
9*bf2c3715SXin Li
10*bf2c3715SXin Li\eigenAutoToc
11*bf2c3715SXin Li
12*bf2c3715SXin Li\section TutorialBlockOperationsUsing Using block operations
13*bf2c3715SXin Li
14*bf2c3715SXin LiThe most general block operation in Eigen is called \link DenseBase::block() .block() \endlink.
15*bf2c3715SXin LiThere are two versions, whose syntax is as follows:
16*bf2c3715SXin Li
17*bf2c3715SXin Li<table class="manual">
18*bf2c3715SXin Li<tr><th>\b %Block \b operation</td>
19*bf2c3715SXin Li<th>Version constructing a \n dynamic-size block expression</th>
20*bf2c3715SXin Li<th>Version constructing a \n fixed-size block expression</th></tr>
21*bf2c3715SXin Li<tr><td>%Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>
22*bf2c3715SXin Li    <td>\code
23*bf2c3715SXin Limatrix.block(i,j,p,q);\endcode </td>
24*bf2c3715SXin Li    <td>\code
25*bf2c3715SXin Limatrix.block<p,q>(i,j);\endcode </td>
26*bf2c3715SXin Li</tr>
27*bf2c3715SXin Li</table>
28*bf2c3715SXin Li
29*bf2c3715SXin LiAs always in Eigen, indices start at 0.
30*bf2c3715SXin Li
31*bf2c3715SXin LiBoth versions can be used on fixed-size and dynamic-size matrices and arrays.
32*bf2c3715SXin LiThese two expressions are semantically equivalent.
33*bf2c3715SXin LiThe only difference is that the fixed-size version will typically give you faster code if the block size is small,
34*bf2c3715SXin Libut requires this size to be known at compile time.
35*bf2c3715SXin Li
36*bf2c3715SXin LiThe following program uses the dynamic-size and fixed-size versions to print the values of several blocks inside a
37*bf2c3715SXin Limatrix.
38*bf2c3715SXin Li
39*bf2c3715SXin Li<table class="example">
40*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
41*bf2c3715SXin Li<tr><td>
42*bf2c3715SXin Li\include Tutorial_BlockOperations_print_block.cpp
43*bf2c3715SXin Li</td>
44*bf2c3715SXin Li<td>
45*bf2c3715SXin Li\verbinclude Tutorial_BlockOperations_print_block.out
46*bf2c3715SXin Li</td></tr></table>
47*bf2c3715SXin Li
48*bf2c3715SXin LiIn the above example the \link DenseBase::block() .block() \endlink function was employed as a \em rvalue, i.e.
49*bf2c3715SXin Liit was only read from. However, blocks can also be used as \em lvalues, meaning that you can assign to a block.
50*bf2c3715SXin Li
51*bf2c3715SXin LiThis is illustrated in the following example. This example also demonstrates blocks in arrays, which works exactly like the above-demonstrated blocks in matrices.
52*bf2c3715SXin Li
53*bf2c3715SXin Li<table class="example">
54*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
55*bf2c3715SXin Li<tr><td>
56*bf2c3715SXin Li\include Tutorial_BlockOperations_block_assignment.cpp
57*bf2c3715SXin Li</td>
58*bf2c3715SXin Li<td>
59*bf2c3715SXin Li\verbinclude Tutorial_BlockOperations_block_assignment.out
60*bf2c3715SXin Li</td></tr></table>
61*bf2c3715SXin Li
62*bf2c3715SXin LiWhile the \link DenseBase::block() .block() \endlink method can be used for any block operation, there are
63*bf2c3715SXin Liother methods for special cases, providing more specialized API and/or better performance. On the topic of performance, all what
64*bf2c3715SXin Limatters is that you give Eigen as much information as possible at compile time. For example, if your block is a single whole column in a matrix,
65*bf2c3715SXin Liusing the specialized \link DenseBase::col() .col() \endlink function described below lets Eigen know that, which can give it optimization opportunities.
66*bf2c3715SXin Li
67*bf2c3715SXin LiThe rest of this page describes these specialized methods.
68*bf2c3715SXin Li
69*bf2c3715SXin Li\section TutorialBlockOperationsSyntaxColumnRows Columns and rows
70*bf2c3715SXin Li
71*bf2c3715SXin LiIndividual columns and rows are special cases of blocks. Eigen provides methods to easily address them:
72*bf2c3715SXin Li\link DenseBase::col() .col() \endlink and \link DenseBase::row() .row()\endlink.
73*bf2c3715SXin Li
74*bf2c3715SXin Li<table class="manual">
75*bf2c3715SXin Li<tr><th>%Block operation</th>
76*bf2c3715SXin Li<th>Method</th>
77*bf2c3715SXin Li<tr><td>i<sup>th</sup> row
78*bf2c3715SXin Li                    \link DenseBase::row() * \endlink</td>
79*bf2c3715SXin Li    <td>\code
80*bf2c3715SXin Limatrix.row(i);\endcode </td>
81*bf2c3715SXin Li</tr>
82*bf2c3715SXin Li<tr><td>j<sup>th</sup> column
83*bf2c3715SXin Li                    \link DenseBase::col() * \endlink</td>
84*bf2c3715SXin Li    <td>\code
85*bf2c3715SXin Limatrix.col(j);\endcode </td>
86*bf2c3715SXin Li</tr>
87*bf2c3715SXin Li</table>
88*bf2c3715SXin Li
89*bf2c3715SXin LiThe argument for \p col() and \p row() is the index of the column or row to be accessed. As always in Eigen, indices start at 0.
90*bf2c3715SXin Li
91*bf2c3715SXin Li<table class="example">
92*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
93*bf2c3715SXin Li<tr><td>
94*bf2c3715SXin Li\include Tutorial_BlockOperations_colrow.cpp
95*bf2c3715SXin Li</td>
96*bf2c3715SXin Li<td>
97*bf2c3715SXin Li\verbinclude Tutorial_BlockOperations_colrow.out
98*bf2c3715SXin Li</td></tr></table>
99*bf2c3715SXin Li
100*bf2c3715SXin LiThat example also demonstrates that block expressions (here columns) can be used in arithmetic like any other expression.
101*bf2c3715SXin Li
102*bf2c3715SXin Li
103*bf2c3715SXin Li\section TutorialBlockOperationsSyntaxCorners Corner-related operations
104*bf2c3715SXin Li
105*bf2c3715SXin LiEigen also provides special methods for blocks that are flushed against one of the corners or sides of a
106*bf2c3715SXin Limatrix or array. For instance, \link DenseBase::topLeftCorner() .topLeftCorner() \endlink can be used to refer
107*bf2c3715SXin Lito a block in the top-left corner of a matrix.
108*bf2c3715SXin Li
109*bf2c3715SXin LiThe different possibilities are summarized in the following table:
110*bf2c3715SXin Li
111*bf2c3715SXin Li<table class="manual">
112*bf2c3715SXin Li<tr><th>%Block \b operation</td>
113*bf2c3715SXin Li<th>Version constructing a \n dynamic-size block expression</th>
114*bf2c3715SXin Li<th>Version constructing a \n fixed-size block expression</th></tr>
115*bf2c3715SXin Li<tr><td>Top-left p by q block \link DenseBase::topLeftCorner() * \endlink</td>
116*bf2c3715SXin Li    <td>\code
117*bf2c3715SXin Limatrix.topLeftCorner(p,q);\endcode </td>
118*bf2c3715SXin Li    <td>\code
119*bf2c3715SXin Limatrix.topLeftCorner<p,q>();\endcode </td>
120*bf2c3715SXin Li</tr>
121*bf2c3715SXin Li<tr><td>Bottom-left p by q block
122*bf2c3715SXin Li              \link DenseBase::bottomLeftCorner() * \endlink</td>
123*bf2c3715SXin Li    <td>\code
124*bf2c3715SXin Limatrix.bottomLeftCorner(p,q);\endcode </td>
125*bf2c3715SXin Li    <td>\code
126*bf2c3715SXin Limatrix.bottomLeftCorner<p,q>();\endcode </td>
127*bf2c3715SXin Li</tr>
128*bf2c3715SXin Li<tr><td>Top-right p by q block
129*bf2c3715SXin Li              \link DenseBase::topRightCorner() * \endlink</td>
130*bf2c3715SXin Li    <td>\code
131*bf2c3715SXin Limatrix.topRightCorner(p,q);\endcode </td>
132*bf2c3715SXin Li    <td>\code
133*bf2c3715SXin Limatrix.topRightCorner<p,q>();\endcode </td>
134*bf2c3715SXin Li</tr>
135*bf2c3715SXin Li<tr><td>Bottom-right p by q block
136*bf2c3715SXin Li               \link DenseBase::bottomRightCorner() * \endlink</td>
137*bf2c3715SXin Li    <td>\code
138*bf2c3715SXin Limatrix.bottomRightCorner(p,q);\endcode </td>
139*bf2c3715SXin Li    <td>\code
140*bf2c3715SXin Limatrix.bottomRightCorner<p,q>();\endcode </td>
141*bf2c3715SXin Li</tr>
142*bf2c3715SXin Li<tr><td>%Block containing the first q rows
143*bf2c3715SXin Li                   \link DenseBase::topRows() * \endlink</td>
144*bf2c3715SXin Li    <td>\code
145*bf2c3715SXin Limatrix.topRows(q);\endcode </td>
146*bf2c3715SXin Li    <td>\code
147*bf2c3715SXin Limatrix.topRows<q>();\endcode </td>
148*bf2c3715SXin Li</tr>
149*bf2c3715SXin Li<tr><td>%Block containing the last q rows
150*bf2c3715SXin Li                    \link DenseBase::bottomRows() * \endlink</td>
151*bf2c3715SXin Li    <td>\code
152*bf2c3715SXin Limatrix.bottomRows(q);\endcode </td>
153*bf2c3715SXin Li    <td>\code
154*bf2c3715SXin Limatrix.bottomRows<q>();\endcode </td>
155*bf2c3715SXin Li</tr>
156*bf2c3715SXin Li<tr><td>%Block containing the first p columns
157*bf2c3715SXin Li                    \link DenseBase::leftCols() * \endlink</td>
158*bf2c3715SXin Li    <td>\code
159*bf2c3715SXin Limatrix.leftCols(p);\endcode </td>
160*bf2c3715SXin Li    <td>\code
161*bf2c3715SXin Limatrix.leftCols<p>();\endcode </td>
162*bf2c3715SXin Li</tr>
163*bf2c3715SXin Li<tr><td>%Block containing the last q columns
164*bf2c3715SXin Li                    \link DenseBase::rightCols() * \endlink</td>
165*bf2c3715SXin Li    <td>\code
166*bf2c3715SXin Limatrix.rightCols(q);\endcode </td>
167*bf2c3715SXin Li    <td>\code
168*bf2c3715SXin Limatrix.rightCols<q>();\endcode </td>
169*bf2c3715SXin Li</tr>
170*bf2c3715SXin Li<tr><td>%Block containing the q columns starting from i
171*bf2c3715SXin Li                    \link DenseBase::middleCols() * \endlink</td>
172*bf2c3715SXin Li    <td>\code
173*bf2c3715SXin Limatrix.middleCols(i,q);\endcode </td>
174*bf2c3715SXin Li    <td>\code
175*bf2c3715SXin Limatrix.middleCols<q>(i);\endcode </td>
176*bf2c3715SXin Li</tr>
177*bf2c3715SXin Li<tr><td>%Block containing the q rows starting from i
178*bf2c3715SXin Li                    \link DenseBase::middleRows() * \endlink</td>
179*bf2c3715SXin Li    <td>\code
180*bf2c3715SXin Limatrix.middleRows(i,q);\endcode </td>
181*bf2c3715SXin Li    <td>\code
182*bf2c3715SXin Limatrix.middleRows<q>(i);\endcode </td>
183*bf2c3715SXin Li</tr>
184*bf2c3715SXin Li</table>
185*bf2c3715SXin Li
186*bf2c3715SXin LiHere is a simple example illustrating the use of the operations presented above:
187*bf2c3715SXin Li
188*bf2c3715SXin Li<table class="example">
189*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
190*bf2c3715SXin Li<tr><td>
191*bf2c3715SXin Li\include Tutorial_BlockOperations_corner.cpp
192*bf2c3715SXin Li</td>
193*bf2c3715SXin Li<td>
194*bf2c3715SXin Li\verbinclude Tutorial_BlockOperations_corner.out
195*bf2c3715SXin Li</td></tr></table>
196*bf2c3715SXin Li
197*bf2c3715SXin Li
198*bf2c3715SXin Li\section TutorialBlockOperationsSyntaxVectors Block operations for vectors
199*bf2c3715SXin Li
200*bf2c3715SXin LiEigen also provides a set of block operations designed specifically for the special case of vectors and one-dimensional arrays:
201*bf2c3715SXin Li
202*bf2c3715SXin Li<table class="manual">
203*bf2c3715SXin Li<tr><th> %Block operation</th>
204*bf2c3715SXin Li<th>Version constructing a \n dynamic-size block expression</th>
205*bf2c3715SXin Li<th>Version constructing a \n fixed-size block expression</th></tr>
206*bf2c3715SXin Li<tr><td>%Block containing the first \p n elements
207*bf2c3715SXin Li                    \link DenseBase::head() * \endlink</td>
208*bf2c3715SXin Li    <td>\code
209*bf2c3715SXin Livector.head(n);\endcode </td>
210*bf2c3715SXin Li    <td>\code
211*bf2c3715SXin Livector.head<n>();\endcode </td>
212*bf2c3715SXin Li</tr>
213*bf2c3715SXin Li<tr><td>%Block containing the last \p n elements
214*bf2c3715SXin Li                    \link DenseBase::tail() * \endlink</td>
215*bf2c3715SXin Li    <td>\code
216*bf2c3715SXin Livector.tail(n);\endcode </td>
217*bf2c3715SXin Li    <td>\code
218*bf2c3715SXin Livector.tail<n>();\endcode </td>
219*bf2c3715SXin Li</tr>
220*bf2c3715SXin Li<tr><td>%Block containing \p n elements, starting at position \p i
221*bf2c3715SXin Li                    \link DenseBase::segment() * \endlink</td>
222*bf2c3715SXin Li    <td>\code
223*bf2c3715SXin Livector.segment(i,n);\endcode </td>
224*bf2c3715SXin Li    <td>\code
225*bf2c3715SXin Livector.segment<n>(i);\endcode </td>
226*bf2c3715SXin Li</tr>
227*bf2c3715SXin Li</table>
228*bf2c3715SXin Li
229*bf2c3715SXin Li
230*bf2c3715SXin LiAn example is presented below:
231*bf2c3715SXin Li<table class="example">
232*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
233*bf2c3715SXin Li<tr><td>
234*bf2c3715SXin Li\include Tutorial_BlockOperations_vector.cpp
235*bf2c3715SXin Li</td>
236*bf2c3715SXin Li<td>
237*bf2c3715SXin Li\verbinclude Tutorial_BlockOperations_vector.out
238*bf2c3715SXin Li</td></tr></table>
239*bf2c3715SXin Li
240*bf2c3715SXin Li*/
241*bf2c3715SXin Li
242*bf2c3715SXin Li}
243