xref: /aosp_15_r20/external/eigen/doc/TutorialReductionsVisitorsBroadcasting.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \eigenManualPage TutorialReductionsVisitorsBroadcasting Reductions, visitors and broadcasting
4*bf2c3715SXin Li
5*bf2c3715SXin LiThis page explains Eigen's reductions, visitors and broadcasting and how they are used with
6*bf2c3715SXin Li\link MatrixBase matrices \endlink and \link ArrayBase arrays \endlink.
7*bf2c3715SXin Li
8*bf2c3715SXin Li\eigenAutoToc
9*bf2c3715SXin Li
10*bf2c3715SXin Li\section TutorialReductionsVisitorsBroadcastingReductions Reductions
11*bf2c3715SXin LiIn Eigen, a reduction is a function taking a matrix or array, and returning a single
12*bf2c3715SXin Liscalar value. One of the most used reductions is \link DenseBase::sum() .sum() \endlink,
13*bf2c3715SXin Lireturning the sum of all the coefficients inside a given matrix or array.
14*bf2c3715SXin Li
15*bf2c3715SXin Li<table class="example">
16*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
17*bf2c3715SXin Li<tr><td>
18*bf2c3715SXin Li\include tut_arithmetic_redux_basic.cpp
19*bf2c3715SXin Li</td>
20*bf2c3715SXin Li<td>
21*bf2c3715SXin Li\verbinclude tut_arithmetic_redux_basic.out
22*bf2c3715SXin Li</td></tr></table>
23*bf2c3715SXin Li
24*bf2c3715SXin LiThe \em trace of a matrix, as returned by the function \c trace(), is the sum of the diagonal coefficients and can equivalently be computed <tt>a.diagonal().sum()</tt>.
25*bf2c3715SXin Li
26*bf2c3715SXin Li
27*bf2c3715SXin Li\subsection TutorialReductionsVisitorsBroadcastingReductionsNorm Norm computations
28*bf2c3715SXin Li
29*bf2c3715SXin LiThe (Euclidean a.k.a. \f$\ell^2\f$) squared norm of a vector can be obtained \link MatrixBase::squaredNorm() squaredNorm() \endlink. It is equal to the dot product of the vector by itself, and equivalently to the sum of squared absolute values of its coefficients.
30*bf2c3715SXin Li
31*bf2c3715SXin LiEigen also provides the \link MatrixBase::norm() norm() \endlink method, which returns the square root of \link MatrixBase::squaredNorm() squaredNorm() \endlink.
32*bf2c3715SXin Li
33*bf2c3715SXin LiThese operations can also operate on matrices; in that case, a n-by-p matrix is seen as a vector of size (n*p), so for example the \link MatrixBase::norm() norm() \endlink method returns the "Frobenius" or "Hilbert-Schmidt" norm. We refrain from speaking of the \f$\ell^2\f$ norm of a matrix because that can mean different things.
34*bf2c3715SXin Li
35*bf2c3715SXin LiIf you want other coefficient-wise \f$\ell^p\f$ norms, use the \link MatrixBase::lpNorm lpNorm<p>() \endlink method. The template parameter \a p can take the special value \a Infinity if you want the \f$\ell^\infty\f$ norm, which is the maximum of the absolute values of the coefficients.
36*bf2c3715SXin Li
37*bf2c3715SXin LiThe following example demonstrates these methods.
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_ReductionsVisitorsBroadcasting_reductions_norm.cpp
43*bf2c3715SXin Li</td>
44*bf2c3715SXin Li<td>
45*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.out
46*bf2c3715SXin Li</td></tr></table>
47*bf2c3715SXin Li
48*bf2c3715SXin Li\b Operator \b norm: The 1-norm and \f$\infty\f$-norm <a href="https://en.wikipedia.org/wiki/Operator_norm">matrix operator norms</a> can easily be computed as follows:
49*bf2c3715SXin Li<table class="example">
50*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
51*bf2c3715SXin Li<tr><td>
52*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_reductions_operatornorm.cpp
53*bf2c3715SXin Li</td>
54*bf2c3715SXin Li<td>
55*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_operatornorm.out
56*bf2c3715SXin Li</td></tr></table>
57*bf2c3715SXin LiSee below for more explanations on the syntax of these expressions.
58*bf2c3715SXin Li
59*bf2c3715SXin Li\subsection TutorialReductionsVisitorsBroadcastingReductionsBool Boolean reductions
60*bf2c3715SXin Li
61*bf2c3715SXin LiThe following reductions operate on boolean values:
62*bf2c3715SXin Li  - \link DenseBase::all() all() \endlink returns \b true if all of the coefficients in a given Matrix or Array evaluate to \b true .
63*bf2c3715SXin Li  - \link DenseBase::any() any() \endlink returns \b true if at least one of the coefficients in a given Matrix or Array evaluates to \b true .
64*bf2c3715SXin Li  - \link DenseBase::count() count() \endlink returns the number of coefficients in a given Matrix or Array that evaluate to  \b true.
65*bf2c3715SXin Li
66*bf2c3715SXin LiThese are typically used in conjunction with the coefficient-wise comparison and equality operators provided by Array. For instance, <tt>array > 0</tt> is an %Array of the same size as \c array , with \b true at those positions where the corresponding coefficient of \c array is positive. Thus, <tt>(array > 0).all()</tt> tests whether all coefficients of \c array are positive. This can be seen in the following example:
67*bf2c3715SXin Li
68*bf2c3715SXin Li<table class="example">
69*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
70*bf2c3715SXin Li<tr><td>
71*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp
72*bf2c3715SXin Li</td>
73*bf2c3715SXin Li<td>
74*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.out
75*bf2c3715SXin Li</td></tr></table>
76*bf2c3715SXin Li
77*bf2c3715SXin Li\subsection TutorialReductionsVisitorsBroadcastingReductionsUserdefined User defined reductions
78*bf2c3715SXin Li
79*bf2c3715SXin LiTODO
80*bf2c3715SXin Li
81*bf2c3715SXin LiIn the meantime you can have a look at the DenseBase::redux() function.
82*bf2c3715SXin Li
83*bf2c3715SXin Li\section TutorialReductionsVisitorsBroadcastingVisitors Visitors
84*bf2c3715SXin LiVisitors are useful when one wants to obtain the location of a coefficient inside
85*bf2c3715SXin Lia Matrix or Array. The simplest examples are
86*bf2c3715SXin Li\link MatrixBase::maxCoeff() maxCoeff(&x,&y) \endlink and
87*bf2c3715SXin Li\link MatrixBase::minCoeff() minCoeff(&x,&y)\endlink, which can be used to find
88*bf2c3715SXin Lithe location of the greatest or smallest coefficient in a Matrix or
89*bf2c3715SXin LiArray.
90*bf2c3715SXin Li
91*bf2c3715SXin LiThe arguments passed to a visitor are pointers to the variables where the
92*bf2c3715SXin Lirow and column position are to be stored. These variables should be of type
93*bf2c3715SXin Li\link Eigen::Index Index \endlink, as shown below:
94*bf2c3715SXin Li
95*bf2c3715SXin Li<table class="example">
96*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
97*bf2c3715SXin Li<tr><td>
98*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp
99*bf2c3715SXin Li</td>
100*bf2c3715SXin Li<td>
101*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_visitors.out
102*bf2c3715SXin Li</td></tr></table>
103*bf2c3715SXin Li
104*bf2c3715SXin LiBoth functions also return the value of the minimum or maximum coefficient.
105*bf2c3715SXin Li
106*bf2c3715SXin Li\section TutorialReductionsVisitorsBroadcastingPartialReductions Partial reductions
107*bf2c3715SXin LiPartial reductions are reductions that can operate column- or row-wise on a Matrix or
108*bf2c3715SXin LiArray, applying the reduction operation on each column or row and
109*bf2c3715SXin Lireturning a column or row vector with the corresponding values. Partial reductions are applied
110*bf2c3715SXin Liwith \link DenseBase::colwise() colwise() \endlink or \link DenseBase::rowwise() rowwise() \endlink.
111*bf2c3715SXin Li
112*bf2c3715SXin LiA simple example is obtaining the maximum of the elements
113*bf2c3715SXin Liin each column in a given matrix, storing the result in a row vector:
114*bf2c3715SXin Li
115*bf2c3715SXin Li<table class="example">
116*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
117*bf2c3715SXin Li<tr><td>
118*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp
119*bf2c3715SXin Li</td>
120*bf2c3715SXin Li<td>
121*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_colwise.out
122*bf2c3715SXin Li</td></tr></table>
123*bf2c3715SXin Li
124*bf2c3715SXin LiThe same operation can be performed row-wise:
125*bf2c3715SXin Li
126*bf2c3715SXin Li<table class="example">
127*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
128*bf2c3715SXin Li<tr><td>
129*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp
130*bf2c3715SXin Li</td>
131*bf2c3715SXin Li<td>
132*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_rowwise.out
133*bf2c3715SXin Li</td></tr></table>
134*bf2c3715SXin Li
135*bf2c3715SXin Li<b>Note that column-wise operations return a row vector, while row-wise operations return a column vector.</b>
136*bf2c3715SXin Li
137*bf2c3715SXin Li\subsection TutorialReductionsVisitorsBroadcastingPartialReductionsCombined Combining partial reductions with other operations
138*bf2c3715SXin LiIt is also possible to use the result of a partial reduction to do further processing.
139*bf2c3715SXin LiHere is another example that finds the column whose sum of elements is the maximum
140*bf2c3715SXin Li within a matrix. With column-wise partial reductions this can be coded as:
141*bf2c3715SXin Li
142*bf2c3715SXin Li<table class="example">
143*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
144*bf2c3715SXin Li<tr><td>
145*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp
146*bf2c3715SXin Li</td>
147*bf2c3715SXin Li<td>
148*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_maxnorm.out
149*bf2c3715SXin Li</td></tr></table>
150*bf2c3715SXin Li
151*bf2c3715SXin LiThe previous example applies the \link DenseBase::sum() sum() \endlink reduction on each column
152*bf2c3715SXin Lithough the \link DenseBase::colwise() colwise() \endlink visitor, obtaining a new matrix whose
153*bf2c3715SXin Lisize is 1x4.
154*bf2c3715SXin Li
155*bf2c3715SXin LiTherefore, if
156*bf2c3715SXin Li\f[
157*bf2c3715SXin Li\mbox{m} = \begin{bmatrix} 1 & 2 & 6 & 9 \\
158*bf2c3715SXin Li                    3 & 1 & 7 & 2 \end{bmatrix}
159*bf2c3715SXin Li\f]
160*bf2c3715SXin Li
161*bf2c3715SXin Lithen
162*bf2c3715SXin Li
163*bf2c3715SXin Li\f[
164*bf2c3715SXin Li\mbox{m.colwise().sum()} = \begin{bmatrix} 4 & 3 & 13 & 11 \end{bmatrix}
165*bf2c3715SXin Li\f]
166*bf2c3715SXin Li
167*bf2c3715SXin LiThe \link DenseBase::maxCoeff() maxCoeff() \endlink reduction is finally applied
168*bf2c3715SXin Lito obtain the column index where the maximum sum is found,
169*bf2c3715SXin Liwhich is the column index 2 (third column) in this case.
170*bf2c3715SXin Li
171*bf2c3715SXin Li
172*bf2c3715SXin Li\section TutorialReductionsVisitorsBroadcastingBroadcasting Broadcasting
173*bf2c3715SXin LiThe concept behind broadcasting is similar to partial reductions, with the difference that broadcasting
174*bf2c3715SXin Liconstructs an expression where a vector (column or row) is interpreted as a matrix by replicating it in
175*bf2c3715SXin Lione direction.
176*bf2c3715SXin Li
177*bf2c3715SXin LiA simple example is to add a certain column vector to each column in a matrix.
178*bf2c3715SXin LiThis can be accomplished with:
179*bf2c3715SXin Li
180*bf2c3715SXin Li<table class="example">
181*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
182*bf2c3715SXin Li<tr><td>
183*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp
184*bf2c3715SXin Li</td>
185*bf2c3715SXin Li<td>
186*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.out
187*bf2c3715SXin Li</td></tr></table>
188*bf2c3715SXin Li
189*bf2c3715SXin LiWe can interpret the instruction <tt>mat.colwise() += v</tt> in two equivalent ways. It adds the vector \c v
190*bf2c3715SXin Lito every column of the matrix. Alternatively, it can be interpreted as repeating the vector \c v four times to
191*bf2c3715SXin Liform a four-by-two matrix which is then added to \c mat:
192*bf2c3715SXin Li\f[
193*bf2c3715SXin Li\begin{bmatrix} 1 & 2 & 6 & 9 \\ 3 & 1 & 7 & 2 \end{bmatrix}
194*bf2c3715SXin Li+ \begin{bmatrix} 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 \end{bmatrix}
195*bf2c3715SXin Li= \begin{bmatrix} 1 & 2 & 6 & 9 \\ 4 & 2 & 8 & 3 \end{bmatrix}.
196*bf2c3715SXin Li\f]
197*bf2c3715SXin LiThe operators <tt>-=</tt>, <tt>+</tt> and <tt>-</tt> can also be used column-wise and row-wise. On arrays, we
198*bf2c3715SXin Lican also use the operators <tt>*=</tt>, <tt>/=</tt>, <tt>*</tt> and <tt>/</tt> to perform coefficient-wise
199*bf2c3715SXin Limultiplication and division column-wise or row-wise. These operators are not available on matrices because it
200*bf2c3715SXin Liis not clear what they would do. If you want multiply column 0 of a matrix \c mat with \c v(0), column 1 with
201*bf2c3715SXin Li\c v(1), and so on, then use <tt>mat = mat * v.asDiagonal()</tt>.
202*bf2c3715SXin Li
203*bf2c3715SXin LiIt is important to point out that the vector to be added column-wise or row-wise must be of type Vector,
204*bf2c3715SXin Liand cannot be a Matrix. If this is not met then you will get compile-time error. This also means that
205*bf2c3715SXin Libroadcasting operations can only be applied with an object of type Vector, when operating with Matrix.
206*bf2c3715SXin LiThe same applies for the Array class, where the equivalent for VectorXf is ArrayXf. As always, you should
207*bf2c3715SXin Linot mix arrays and matrices in the same expression.
208*bf2c3715SXin Li
209*bf2c3715SXin LiTo perform the same operation row-wise we can do:
210*bf2c3715SXin Li
211*bf2c3715SXin Li<table class="example">
212*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
213*bf2c3715SXin Li<tr><td>
214*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp
215*bf2c3715SXin Li</td>
216*bf2c3715SXin Li<td>
217*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.out
218*bf2c3715SXin Li</td></tr></table>
219*bf2c3715SXin Li
220*bf2c3715SXin Li\subsection TutorialReductionsVisitorsBroadcastingBroadcastingCombined Combining broadcasting with other operations
221*bf2c3715SXin LiBroadcasting can also be combined with other operations, such as Matrix or Array operations,
222*bf2c3715SXin Lireductions and partial reductions.
223*bf2c3715SXin Li
224*bf2c3715SXin LiNow that broadcasting, reductions and partial reductions have been introduced, we can dive into a more advanced example that finds
225*bf2c3715SXin Lithe nearest neighbour of a vector <tt>v</tt> within the columns of matrix <tt>m</tt>. The Euclidean distance will be used in this example,
226*bf2c3715SXin Licomputing the squared Euclidean distance with the partial reduction named \link MatrixBase::squaredNorm() squaredNorm() \endlink:
227*bf2c3715SXin Li
228*bf2c3715SXin Li<table class="example">
229*bf2c3715SXin Li<tr><th>Example:</th><th>Output:</th></tr>
230*bf2c3715SXin Li<tr><td>
231*bf2c3715SXin Li\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp
232*bf2c3715SXin Li</td>
233*bf2c3715SXin Li<td>
234*bf2c3715SXin Li\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.out
235*bf2c3715SXin Li</td></tr></table>
236*bf2c3715SXin Li
237*bf2c3715SXin LiThe line that does the job is
238*bf2c3715SXin Li\code
239*bf2c3715SXin Li  (m.colwise() - v).colwise().squaredNorm().minCoeff(&index);
240*bf2c3715SXin Li\endcode
241*bf2c3715SXin Li
242*bf2c3715SXin LiWe will go step by step to understand what is happening:
243*bf2c3715SXin Li
244*bf2c3715SXin Li  - <tt>m.colwise() - v</tt> is a broadcasting operation, subtracting <tt>v</tt> from each column in <tt>m</tt>. The result of this operation
245*bf2c3715SXin Liis a new matrix whose size is the same as matrix <tt>m</tt>: \f[
246*bf2c3715SXin Li  \mbox{m.colwise() - v} =
247*bf2c3715SXin Li  \begin{bmatrix}
248*bf2c3715SXin Li    -1 & 21 & 4 & 7 \\
249*bf2c3715SXin Li     0 & 8  & 4 & -1
250*bf2c3715SXin Li  \end{bmatrix}
251*bf2c3715SXin Li\f]
252*bf2c3715SXin Li
253*bf2c3715SXin Li  - <tt>(m.colwise() - v).colwise().squaredNorm()</tt> is a partial reduction, computing the squared norm column-wise. The result of
254*bf2c3715SXin Lithis operation is a row vector where each coefficient is the squared Euclidean distance between each column in <tt>m</tt> and <tt>v</tt>: \f[
255*bf2c3715SXin Li  \mbox{(m.colwise() - v).colwise().squaredNorm()} =
256*bf2c3715SXin Li  \begin{bmatrix}
257*bf2c3715SXin Li     1 & 505 & 32 & 50
258*bf2c3715SXin Li  \end{bmatrix}
259*bf2c3715SXin Li\f]
260*bf2c3715SXin Li
261*bf2c3715SXin Li  - Finally, <tt>minCoeff(&index)</tt> is used to obtain the index of the column in <tt>m</tt> that is closest to <tt>v</tt> in terms of Euclidean
262*bf2c3715SXin Lidistance.
263*bf2c3715SXin Li
264*bf2c3715SXin Li*/
265*bf2c3715SXin Li
266*bf2c3715SXin Li}
267