2010-07-09 00:42:23 +08:00
namespace Eigen {
/** \page TutorialReductionsVisitorsBroadcasting Tutorial page 7 - Reductions, visitors and broadcasting
\ingroup Tutorial
2010-07-09 18:59:29 +08:00
\li \b Previous: \ref TutorialLinearAlgebra
\li \b Next: \ref TutorialGeometry
2010-07-09 00:42:23 +08:00
This tutorial explains Eigen's reductions, visitors and broadcasting and how they are used with
\link MatrixBase matrices \endlink and \link ArrayBase arrays \endlink.
\b Table \b of \b contents
- \ref TutorialReductionsVisitorsBroadcastingReductions
2010-07-09 01:16:39 +08:00
- \ref TutorialReductionsVisitorsBroadcastingReductionsNorm
- \ref TutorialReductionsVisitorsBroadcastingReductionsBool
2010-10-19 17:40:49 +08:00
- \ref TutorialReductionsVisitorsBroadcastingReductionsUserdefined
2010-07-09 00:42:23 +08:00
- \ref TutorialReductionsVisitorsBroadcastingVisitors
- \ref TutorialReductionsVisitorsBroadcastingPartialReductions
- \ref TutorialReductionsVisitorsBroadcastingPartialReductionsCombined
- \ref TutorialReductionsVisitorsBroadcastingBroadcasting
- \ref TutorialReductionsVisitorsBroadcastingBroadcastingCombined
\section TutorialReductionsVisitorsBroadcastingReductions Reductions
2010-10-18 21:09:30 +08:00
In Eigen, a reduction is a function taking a matrix or array, and returning a single
scalar value. One of the most used reductions is \link DenseBase::sum() .sum() \endlink,
returning the sum of all the coefficients inside a given matrix or array.
2010-07-09 00:42:23 +08:00
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include tut_arithmetic_redux_basic.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
2010-10-19 17:40:49 +08:00
\verbinclude tut_arithmetic_redux_basic.out
2010-07-09 00:42:23 +08:00
</td></tr></table>
2010-10-18 21:09:30 +08:00
The \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>.
2010-07-09 00:42:23 +08:00
2010-07-09 01:16:39 +08:00
2010-10-18 21:09:30 +08:00
\subsection TutorialReductionsVisitorsBroadcastingReductionsNorm Norm computations
The (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.
Eigen also provides the \link MatrixBase::norm() norm() \endlink method, which returns the square root of \link MatrixBase::squaredNorm() squaredNorm() \endlink.
These 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.
If you want other \f$\ell^p\f$ norms, use the \link MatrixBase::lpNorm() lpNnorm<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.
The following example demonstrates these methods.
2010-07-09 01:16:39 +08:00
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp
2010-07-09 01:16:39 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.out
</td></tr></table>
2010-10-18 21:09:30 +08:00
\subsection TutorialReductionsVisitorsBroadcastingReductionsBool Boolean reductions
2010-07-09 01:16:39 +08:00
2010-10-18 21:09:30 +08:00
The following reductions operate on boolean values:
- \link DenseBase::all() all() \endlink returns \b true if all of the coefficients in a given Matrix or Array evaluate to \b true .
- \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 .
- \link DenseBase::count() count() \endlink returns the number of coefficients in a given Matrix or Array that evaluate to \b true.
2010-07-09 01:16:39 +08:00
2010-07-24 02:20:10 +08:00
These 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:
2010-07-09 01:16:39 +08:00
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp
2010-07-09 01:16:39 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.out
</td></tr></table>
2010-10-19 17:40:49 +08:00
\subsection TutorialReductionsVisitorsBroadcastingReductionsUserdefined User defined reductions
TODO
In the meantime you can have a look at the DenseBase::redux() function.
2010-07-09 01:16:39 +08:00
2010-07-09 00:42:23 +08:00
\section TutorialReductionsVisitorsBroadcastingVisitors Visitors
2010-07-24 02:20:10 +08:00
Visitors are useful when one wants to obtain the location of a coefficient inside
a Matrix or Array. The simplest examples are
2010-07-09 00:42:23 +08:00
\link MatrixBase::maxCoeff() maxCoeff(&x,&y) \endlink and
2010-07-24 02:20:10 +08:00
\link MatrixBase::minCoeff() minCoeff(&x,&y)\endlink, which can be used to find
2010-07-09 00:42:23 +08:00
the location of the greatest or smallest coefficient in a Matrix or
2010-07-24 02:20:10 +08:00
Array.
2010-07-09 00:42:23 +08:00
The arguments passed to a visitor are pointers to the variables where the
2010-07-24 02:20:10 +08:00
row and column position are to be stored. These variables should be of type
2010-07-09 01:16:39 +08:00
\link DenseBase::Index Index \endlink (FIXME: link ok?), as shown below:
2010-07-09 00:42:23 +08:00
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_visitors.out
</td></tr></table>
Note that both functions also return the value of the minimum or maximum coefficient if needed,
as if it was a typical reduction operation.
\section TutorialReductionsVisitorsBroadcastingPartialReductions Partial reductions
Partial reductions are reductions that can operate column- or row-wise on a Matrix or
2010-07-24 02:20:10 +08:00
Array, applying the reduction operation on each column or row and
2010-07-09 00:42:23 +08:00
returning a column or row-vector with the corresponding values. Partial reductions are applied
with \link DenseBase::colwise() colwise() \endlink or \link DenseBase::rowwise() rowwise() \endlink.
2010-07-24 02:20:10 +08:00
A simple example is obtaining the maximum of the elements
2010-07-09 00:42:23 +08:00
in each column in a given matrix, storing the result in a row-vector:
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_colwise.out
</td></tr></table>
The same operation can be performed row-wise:
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_rowwise.out
</td></tr></table>
<b>Note that column-wise operations return a 'row-vector' while row-wise operations
return a 'column-vector'</b>
\subsection TutorialReductionsVisitorsBroadcastingPartialReductionsCombined Combining partial reductions with other operations
It is also possible to use the result of a partial reduction to do further processing.
2010-07-24 02:20:10 +08:00
Here is another example that aims to find the column whose sum of elements is the maximum
2010-07-09 00:42:23 +08:00
within a matrix. With column-wise partial reductions this can be coded as:
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_maxnorm.out
</td></tr></table>
The previous example applies the \link DenseBase::sum() sum() \endlink reduction on each column
though the \link DenseBase::colwise() colwise() \endlink visitor, obtaining a new matrix whose
size is 1x4.
Therefore, if
\f[
\mbox{m} = \begin{bmatrix} 1 & 2 & 6 & 9 \\
3 & 1 & 7 & 2 \end{bmatrix}
\f]
then
\f[
\mbox{m.colwise().sum()} = \begin{bmatrix} 4 & 3 & 13 & 11 \end{bmatrix}
\f]
The \link DenseBase::maxCoeff() maxCoeff() \endlink reduction is finally applied
to obtain the column index where the maximum sum is found,
which is the column index 2 (third column) in this case.
\section TutorialReductionsVisitorsBroadcastingBroadcasting Broadcasting
The concept behind broadcasting is similar to partial reductions, with the difference that broadcasting
constructs an expression where a vector (column or row) is interpreted as a matrix by replicating it in
one direction.
A simple example is to add a certain column-vector to each column in a matrix.
This can be accomplished with:
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.out
</td></tr></table>
It is important to point out that the vector to be added column-wise or row-wise must be of type Vector,
and cannot be a Matrix. If this is not met then you will get compile-time error. This also means that
broadcasting operations can only be applied with an object of type Vector, when operating with Matrix.
2010-07-24 02:20:10 +08:00
The same applies for the Array class, where the equivalent for VectorXf is ArrayXf.
2010-07-09 00:42:23 +08:00
Therefore, to perform the same operation row-wise we can do:
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.out
</td></tr></table>
\subsection TutorialReductionsVisitorsBroadcastingBroadcastingCombined Combining broadcasting with other operations
2010-07-24 02:20:10 +08:00
Broadcasting can also be combined with other operations, such as Matrix or Array operations,
2010-07-09 00:42:23 +08:00
reductions and partial reductions.
Now that broadcasting, reductions and partial reductions have been introduced, we can dive into a more advanced example that finds
the 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,
2010-07-26 03:29:07 +08:00
computing the squared Euclidean distance with the partial reduction named \link MatrixBase::squaredNorm() squaredNorm() \endlink:
2010-07-09 00:42:23 +08:00
2010-10-19 17:40:49 +08:00
<table class="example">
<tr><th>Example:</th><th>Output:</th></tr>
<tr><td>
\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp
2010-07-09 00:42:23 +08:00
</td>
<td>
\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.out
</td></tr></table>
The line that does the job is
\code
(m.colwise() - v).colwise().squaredNorm().minCoeff(&index);
\endcode
We will go step by step to understand what is happening:
2010-07-24 02:20:10 +08:00
- <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
is a new matrix whose size is the same as matrix <tt>m</tt>: \f[
2010-07-09 00:42:23 +08:00
\mbox{m.colwise() - v} =
\begin{bmatrix}
-1 & 21 & 4 & 7 \\
0 & 8 & 4 & -1
\end{bmatrix}
\f]
- <tt>(m.colwise() - v).colwise().squaredNorm()</tt> is a partial reduction, computing the squared norm column-wise. The result of
2010-07-24 02:20:10 +08:00
this 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[
2010-07-09 00:42:23 +08:00
\mbox{(m.colwise() - v).colwise().squaredNorm()} =
\begin{bmatrix}
1 & 505 & 32 & 50
\end{bmatrix}
\f]
2010-07-24 02:20:10 +08:00
- 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
2010-07-09 00:42:23 +08:00
distance.
2010-07-09 18:59:29 +08:00
\li \b Next: \ref TutorialGeometry
2010-07-09 00:42:23 +08:00
*/
}