1namespace Eigen { 2 3/** \eigenManualPage TutorialReductionsVisitorsBroadcasting Reductions, visitors and broadcasting 4 5This page explains Eigen's reductions, visitors and broadcasting and how they are used with 6\link MatrixBase matrices \endlink and \link ArrayBase arrays \endlink. 7 8\eigenAutoToc 9 10\section TutorialReductionsVisitorsBroadcastingReductions Reductions 11In Eigen, a reduction is a function taking a matrix or array, and returning a single 12scalar value. One of the most used reductions is \link DenseBase::sum() .sum() \endlink, 13returning the sum of all the coefficients inside a given matrix or array. 14 15<table class="example"> 16<tr><th>Example:</th><th>Output:</th></tr> 17<tr><td> 18\include tut_arithmetic_redux_basic.cpp 19</td> 20<td> 21\verbinclude tut_arithmetic_redux_basic.out 22</td></tr></table> 23 24The \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 26 27\subsection TutorialReductionsVisitorsBroadcastingReductionsNorm Norm computations 28 29The (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 31Eigen also provides the \link MatrixBase::norm() norm() \endlink method, which returns the square root of \link MatrixBase::squaredNorm() squaredNorm() \endlink. 32 33These 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 35If 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. 36 37The following example demonstrates these methods. 38 39<table class="example"> 40<tr><th>Example:</th><th>Output:</th></tr> 41<tr><td> 42\include Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp 43</td> 44<td> 45\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.out 46</td></tr></table> 47 48\subsection TutorialReductionsVisitorsBroadcastingReductionsBool Boolean reductions 49 50The following reductions operate on boolean values: 51 - \link DenseBase::all() all() \endlink returns \b true if all of the coefficients in a given Matrix or Array evaluate to \b true . 52 - \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 . 53 - \link DenseBase::count() count() \endlink returns the number of coefficients in a given Matrix or Array that evaluate to \b true. 54 55These 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: 56 57<table class="example"> 58<tr><th>Example:</th><th>Output:</th></tr> 59<tr><td> 60\include Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp 61</td> 62<td> 63\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.out 64</td></tr></table> 65 66\subsection TutorialReductionsVisitorsBroadcastingReductionsUserdefined User defined reductions 67 68TODO 69 70In the meantime you can have a look at the DenseBase::redux() function. 71 72\section TutorialReductionsVisitorsBroadcastingVisitors Visitors 73Visitors are useful when one wants to obtain the location of a coefficient inside 74a Matrix or Array. The simplest examples are 75\link MatrixBase::maxCoeff() maxCoeff(&x,&y) \endlink and 76\link MatrixBase::minCoeff() minCoeff(&x,&y)\endlink, which can be used to find 77the location of the greatest or smallest coefficient in a Matrix or 78Array. 79 80The arguments passed to a visitor are pointers to the variables where the 81row and column position are to be stored. These variables should be of type 82\link DenseBase::Index Index \endlink, as shown below: 83 84<table class="example"> 85<tr><th>Example:</th><th>Output:</th></tr> 86<tr><td> 87\include Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp 88</td> 89<td> 90\verbinclude Tutorial_ReductionsVisitorsBroadcasting_visitors.out 91</td></tr></table> 92 93Note that both functions also return the value of the minimum or maximum coefficient if needed, 94as if it was a typical reduction operation. 95 96\section TutorialReductionsVisitorsBroadcastingPartialReductions Partial reductions 97Partial reductions are reductions that can operate column- or row-wise on a Matrix or 98Array, applying the reduction operation on each column or row and 99returning a column or row-vector with the corresponding values. Partial reductions are applied 100with \link DenseBase::colwise() colwise() \endlink or \link DenseBase::rowwise() rowwise() \endlink. 101 102A simple example is obtaining the maximum of the elements 103in each column in a given matrix, storing the result in a row-vector: 104 105<table class="example"> 106<tr><th>Example:</th><th>Output:</th></tr> 107<tr><td> 108\include Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp 109</td> 110<td> 111\verbinclude Tutorial_ReductionsVisitorsBroadcasting_colwise.out 112</td></tr></table> 113 114The same operation can be performed row-wise: 115 116<table class="example"> 117<tr><th>Example:</th><th>Output:</th></tr> 118<tr><td> 119\include Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp 120</td> 121<td> 122\verbinclude Tutorial_ReductionsVisitorsBroadcasting_rowwise.out 123</td></tr></table> 124 125<b>Note that column-wise operations return a 'row-vector' while row-wise operations 126return a 'column-vector'</b> 127 128\subsection TutorialReductionsVisitorsBroadcastingPartialReductionsCombined Combining partial reductions with other operations 129It is also possible to use the result of a partial reduction to do further processing. 130Here is another example that finds the column whose sum of elements is the maximum 131 within a matrix. With column-wise partial reductions this can be coded as: 132 133<table class="example"> 134<tr><th>Example:</th><th>Output:</th></tr> 135<tr><td> 136\include Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp 137</td> 138<td> 139\verbinclude Tutorial_ReductionsVisitorsBroadcasting_maxnorm.out 140</td></tr></table> 141 142The previous example applies the \link DenseBase::sum() sum() \endlink reduction on each column 143though the \link DenseBase::colwise() colwise() \endlink visitor, obtaining a new matrix whose 144size is 1x4. 145 146Therefore, if 147\f[ 148\mbox{m} = \begin{bmatrix} 1 & 2 & 6 & 9 \\ 149 3 & 1 & 7 & 2 \end{bmatrix} 150\f] 151 152then 153 154\f[ 155\mbox{m.colwise().sum()} = \begin{bmatrix} 4 & 3 & 13 & 11 \end{bmatrix} 156\f] 157 158The \link DenseBase::maxCoeff() maxCoeff() \endlink reduction is finally applied 159to obtain the column index where the maximum sum is found, 160which is the column index 2 (third column) in this case. 161 162 163\section TutorialReductionsVisitorsBroadcastingBroadcasting Broadcasting 164The concept behind broadcasting is similar to partial reductions, with the difference that broadcasting 165constructs an expression where a vector (column or row) is interpreted as a matrix by replicating it in 166one direction. 167 168A simple example is to add a certain column-vector to each column in a matrix. 169This can be accomplished with: 170 171<table class="example"> 172<tr><th>Example:</th><th>Output:</th></tr> 173<tr><td> 174\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp 175</td> 176<td> 177\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.out 178</td></tr></table> 179 180We can interpret the instruction <tt>mat.colwise() += v</tt> in two equivalent ways. It adds the vector \c v 181to every column of the matrix. Alternatively, it can be interpreted as repeating the vector \c v four times to 182form a four-by-two matrix which is then added to \c mat: 183\f[ 184\begin{bmatrix} 1 & 2 & 6 & 9 \\ 3 & 1 & 7 & 2 \end{bmatrix} 185+ \begin{bmatrix} 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 \end{bmatrix} 186= \begin{bmatrix} 1 & 2 & 6 & 9 \\ 4 & 2 & 8 & 3 \end{bmatrix}. 187\f] 188The operators <tt>-=</tt>, <tt>+</tt> and <tt>-</tt> can also be used column-wise and row-wise. On arrays, we 189can also use the operators <tt>*=</tt>, <tt>/=</tt>, <tt>*</tt> and <tt>/</tt> to perform coefficient-wise 190multiplication and division column-wise or row-wise. These operators are not available on matrices because it 191is not clear what they would do. If you want multiply column 0 of a matrix \c mat with \c v(0), column 1 with 192\c v(1), and so on, then use <tt>mat = mat * v.asDiagonal()</tt>. 193 194It is important to point out that the vector to be added column-wise or row-wise must be of type Vector, 195and cannot be a Matrix. If this is not met then you will get compile-time error. This also means that 196broadcasting operations can only be applied with an object of type Vector, when operating with Matrix. 197The same applies for the Array class, where the equivalent for VectorXf is ArrayXf. As always, you should 198not mix arrays and matrices in the same expression. 199 200To perform the same operation row-wise we can do: 201 202<table class="example"> 203<tr><th>Example:</th><th>Output:</th></tr> 204<tr><td> 205\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp 206</td> 207<td> 208\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.out 209</td></tr></table> 210 211\subsection TutorialReductionsVisitorsBroadcastingBroadcastingCombined Combining broadcasting with other operations 212Broadcasting can also be combined with other operations, such as Matrix or Array operations, 213reductions and partial reductions. 214 215Now that broadcasting, reductions and partial reductions have been introduced, we can dive into a more advanced example that finds 216the 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, 217computing the squared Euclidean distance with the partial reduction named \link MatrixBase::squaredNorm() squaredNorm() \endlink: 218 219<table class="example"> 220<tr><th>Example:</th><th>Output:</th></tr> 221<tr><td> 222\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp 223</td> 224<td> 225\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.out 226</td></tr></table> 227 228The line that does the job is 229\code 230 (m.colwise() - v).colwise().squaredNorm().minCoeff(&index); 231\endcode 232 233We will go step by step to understand what is happening: 234 235 - <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 236is a new matrix whose size is the same as matrix <tt>m</tt>: \f[ 237 \mbox{m.colwise() - v} = 238 \begin{bmatrix} 239 -1 & 21 & 4 & 7 \\ 240 0 & 8 & 4 & -1 241 \end{bmatrix} 242\f] 243 244 - <tt>(m.colwise() - v).colwise().squaredNorm()</tt> is a partial reduction, computing the squared norm column-wise. The result of 245this 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[ 246 \mbox{(m.colwise() - v).colwise().squaredNorm()} = 247 \begin{bmatrix} 248 1 & 505 & 32 & 50 249 \end{bmatrix} 250\f] 251 252 - 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 253distance. 254 255*/ 256 257} 258