Carlos Becker | 9d44005 | 2010-06-25 20:16:12 -0400 | [diff] [blame] | 1 | namespace Eigen { |
| 2 | |
| 3 | /** \page TutorialMatrixArithmetic Tutorial - Matrix and vector arithmetic |
| 4 | \ingroup Tutorial |
| 5 | |
| 6 | This tutorial aims to provide an overview and some details on how to perform arithmetic between matrices, vectors and scalars with Eigen. |
| 7 | |
| 8 | \b Table \b of \b contents |
| 9 | - \ref TutorialMatrixArithmCommaInitializer |
| 10 | - \ref TutorialMatrixArithmElementaryOperations |
| 11 | - \ref TutorialMatrixArithmExamples |
| 12 | - \ref TutorialMatrixArithmProduct |
| 13 | - \ref TutorialMatrixArithmSimpleExample |
| 14 | - \ref TutorialMatrixCombiningOperators |
| 15 | - \ref TutorialMatrixOperatorValidity |
| 16 | - \ref TutorialMatrixArithmReductionOperations |
| 17 | |
| 18 | |
| 19 | \section TutorialMatrixArithmCommaInitializer Comma initializer |
| 20 | Eigen offers a comma initializer syntax which allows to set all the coefficients of any dense objects (matrix, vector, array, block, etc.) to specific values: |
| 21 | <table class="tutorial_code"><tr><td> |
| 22 | \code Matrix3f m; |
| 23 | m << 1, 2, 3, |
| 24 | 4, 5, 6, |
| 25 | 7, 8, 9; |
| 26 | cout << m; |
| 27 | \endcode |
| 28 | </td> |
| 29 | <td> |
| 30 | output: |
| 31 | \code |
| 32 | 1 2 3 |
| 33 | 4 5 6 |
| 34 | 7 8 9 |
| 35 | \endcode |
| 36 | </td></tr></table> |
| 37 | |
| 38 | Moreover, Eigen also supports to load a matrix through a set of blocks: |
| 39 | <table class="tutorial_code"><tr><td> |
| 40 | \code |
| 41 | int rows=5, cols=5; |
| 42 | MatrixXf m(rows,cols); |
| 43 | m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(), |
| 44 | MatrixXf::Zero(3,cols-3), |
| 45 | MatrixXf::Zero(rows-3,3), |
| 46 | MatrixXf::Identity(rows-3,cols-3); |
| 47 | cout << m; |
| 48 | \endcode |
| 49 | </td> |
| 50 | <td> |
| 51 | output: |
| 52 | \code |
| 53 | 1 2 3 0 0 |
| 54 | 4 5 6 0 0 |
| 55 | 7 8 9 0 0 |
| 56 | 0 0 0 1 0 |
| 57 | 0 0 0 0 1 |
| 58 | \endcode |
| 59 | </td></tr></table> |
| 60 | |
| 61 | FIXME: is this still needed? |
| 62 | <span class="note">\b Side \b note: here \link CommaInitializer::finished() .finished() \endlink |
| 63 | is used to get the actual matrix object once the comma initialization |
| 64 | of our temporary submatrix is done. Note that despite the apparent complexity of such an expression, |
| 65 | Eigen's comma initializer usually compiles to very optimized code without any overhead.</span> |
| 66 | |
| 67 | \section TutorialMatrixArithmElementaryOperations Basic arithmetic operators |
| 68 | |
| 69 | Eigen takes advantage of C++ operator overloading to make arithmetic operations intuitive. In the case of matrices and vectors, Eigen only supports arithmetic operations that have a linear-algebraic meaning. Therefore, adding an scalar to a vector or matrix cannot be written as \p scalar \p + \p matrix . Nonetheless, Eigen provides an Array class that is able to perform other types of operations such as column-wise and row-wise addition, substraction, etc. For more information see FIXME:link to Array class. |
| 70 | |
| 71 | \subsection TutorialMatrixArithmExamples Usage examples |
| 72 | Some basic examples are presented in the following table, showing how easy it is to express arithmetic operations with Eigen. |
| 73 | |
| 74 | <table class="tutorial_code" align="center"> |
| 75 | <tr><td> |
| 76 | matrix/vector product \matrixworld</td><td>\code |
| 77 | col2 = mat1 * col1; |
| 78 | row2 = row1 * mat1; row1 *= mat1; |
| 79 | mat3 = mat1 * mat2; mat3 *= mat1; \endcode |
| 80 | </td></tr> |
| 81 | <tr><td> |
| 82 | add/subtract</td><td>\code |
| 83 | mat3 = mat1 + mat2; mat3 += mat1; |
| 84 | mat3 = mat1 - mat2; mat3 -= mat1;\endcode |
| 85 | </td></tr> |
| 86 | <tr><td> |
| 87 | scalar product/division</td><td>\code |
| 88 | mat3 = mat1 * s1; mat3 = s1 * mat1; mat3 *= s1; |
| 89 | mat3 = mat1 / s1; mat3 /= s1;\endcode |
| 90 | </td></tr> |
| 91 | </table> |
| 92 | |
| 93 | \subsection TutorialMatrixArithmProduct Product types |
| 94 | It is important to point out that the product operation can be understood in different ways between matrices and vectors. Eigen treats the \p * \operator as matrix product or multiplication by a scalar. However, dot and cross products are also supported through the \p .dot() and \p .cross() operations: |
| 95 | |
| 96 | \code |
| 97 | Matrix3f m1,m2,m3; |
| 98 | Vector3f v1,v2,v3; |
| 99 | |
| 100 | // matrix product |
| 101 | m1 = m2 * m3; |
| 102 | |
| 103 | // vector cross product: v1 = v2 X v3 |
| 104 | v1 = v2.cross(v3); |
| 105 | |
| 106 | // vector dot product: v2 . v3 (returns scalar) |
| 107 | float dotResult = v2.dot(v3); |
| 108 | \endcode |
| 109 | |
| 110 | <strong> Note:</strong> cross product is only defined for 3-dimensional vectors. |
| 111 | |
| 112 | \subsection TutorialMatrixArithmSimpleExample A simple example with matrix linear algebra |
| 113 | |
| 114 | The next piece of code shows a simple program that creates two dynamic 3x3 matrices and initializes them, performing some simple operations and displaying the results at each step. |
| 115 | |
| 116 | \code |
| 117 | #include <Eigen/Dense> |
| 118 | #include <iostream> |
| 119 | |
| 120 | using namespace Eigen; |
| 121 | |
| 122 | int main() |
| 123 | { |
| 124 | MatrixXf m(3,3); // Matrix m is 3x3 |
| 125 | VectorXf n(3,3); // 3-component vector |
| 126 | |
| 127 | m << 1,2,3, // Assign some values to m |
| 128 | 4,5,6, |
| 129 | 7,8,9; |
| 130 | |
| 131 | n << 10,11,12, // Assign some values to n |
| 132 | 13,14,15, |
| 133 | 16,17,18; |
| 134 | |
| 135 | |
| 136 | // simple matrix-product-scalar |
| 137 | std::cout << "3*m = " << 3*m << std::endl; |
| 138 | |
| 139 | // simple matrix-divided-by-scalar |
| 140 | std::cout << "m/3 = " << m/3 << std::endl; |
| 141 | |
| 142 | // matrix multiplication |
| 143 | std::cout << "m*n = " << m*n << std::endl; |
| 144 | |
| 145 | return 0; |
| 146 | } |
| 147 | \endcode |
| 148 | |
| 149 | |
| 150 | \subsection TutorialMatrixCombiningOperators Combining operators in a single statement |
| 151 | |
| 152 | As said before, Eigen's classes already provide implementations for linear-algebra operations. Combining operators in more complex expressions is posssible and often desirable, since it may help to avoid temporary memory allocations, making code execution faster (FIXME: add reference to lazy evaluation?) : |
| 153 | |
| 154 | \code |
| 155 | MatrixXf m(3,3), n(3,3); |
| 156 | MatrixXf q(3,3), p(3,3); |
| 157 | |
| 158 | // initialize... etc |
| 159 | ..... |
| 160 | |
| 161 | // METHOD 1: use temporary allocation |
| 162 | { |
| 163 | MatrixXf tempMatrix; |
| 164 | |
| 165 | tempMatrix = m + 3*n; |
| 166 | p = tempMatrix * q; |
| 167 | } |
| 168 | |
| 169 | // METHOD 2: avoids extra memory allocation if possible |
| 170 | // (Eigen will take care of that automatically) |
| 171 | p = (m + 3*n) * q; // matrix addition and multiplication by a vector |
| 172 | |
| 173 | \endcode |
| 174 | |
| 175 | Eigen will try to do its best in order to avoid temporary allocation and evaluate the expressions as fast as possible. FIXME: anything else to say here, is this correct? |
| 176 | |
| 177 | |
| 178 | \subsection TutorialMatrixOperatorValidity Validity of operations |
| 179 | The validity of the operations between matrices depend on the data type. In order to report whether an operation is valid or not, Eigen makes use of both compile-time and run-time information. In the case that the size of the matrices and vectors involved in the operations are known at compile time (fixed-size matrices such as \p Matrix3f), Eigen will be able to perfom a compile-time check and stop the compiler with an error if one of the operations is not possible: |
| 180 | |
| 181 | \code |
| 182 | Matrix3f m; |
| 183 | Vector4f v; |
| 184 | |
| 185 | v = m*v; // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES |
| 186 | \endcode |
| 187 | |
| 188 | On the other hand, operations between dynamic-size matrices will take place at run-time, generating a run-time assertion if invalid operands are detected. FIXME: link to how to change the handler? |
| 189 | |
| 190 | \code |
| 191 | MatrixXf m(3,3); |
| 192 | VectorXf v(4); |
| 193 | |
| 194 | v = m * v; // Run-time assertion: "invalid matrix product" |
| 195 | \endcode |
| 196 | |
| 197 | |
| 198 | \section TutorialMatrixArithmReductionOperations Basic arithmetic reduction operations |
| 199 | Eigen also provides some basic but extremely useful reduction arithmetic operators to obtain values such as the sum or the maximum or minimum of all the coefficients in a given matrix or vector. The following table presents the basic arithmetic reduction operations and their syntax. |
| 200 | |
| 201 | <table class="tutorial_code" align="center"> |
| 202 | <tr><td align="center">\b Reduction \b operation</td><td align="center">\b Usage \b example</td></tr> |
| 203 | <tr><td> |
| 204 | Sum of all the coefficients in a matrix</td><td>\code |
| 205 | MatrixXf m; |
| 206 | float totalSum = m.sum();\endcode</td></tr> |
| 207 | <tr><td> |
| 208 | Maximum coefficient in a matrix</td><td>\code |
| 209 | MatrixXf m; |
| 210 | int row, col; |
| 211 | |
| 212 | // minimum value will be stored in minValue |
| 213 | // and the row and column where it was found in row and col, |
| 214 | // (these two parameters are optional) |
| 215 | float minValue = m.minCoeff(&row,&col);\endcode</td></tr> |
| 216 | <tr><td> |
| 217 | Maximum coefficient in a matrix</td><td>\code |
| 218 | MatrixXf m; |
| 219 | int row, col; |
| 220 | |
| 221 | // maximum value will be stored in maxValue |
| 222 | // and the row and column where it was found in row and col, |
| 223 | // (these two parameters are optional) |
| 224 | float maxValue = m.maxCoeff(&row,&col);\endcode</td></tr> |
| 225 | <tr><td> |
| 226 | Product between all coefficients in a matrix</td><td>\code |
| 227 | MatrixXf m; |
| 228 | |
| 229 | float product = m.prod();\endcode</td></tr> |
| 230 | <tr><td> |
| 231 | Mean of coefficients in a matrix</td><td>\code |
| 232 | MatrixXf m; |
| 233 | |
| 234 | float mean = m.mean();\endcode</td></tr> |
| 235 | <tr><td> |
| 236 | Matrix's trace</td><td>\code |
| 237 | MatrixXf m; |
| 238 | |
| 239 | float trace = m.trace();\endcode</td></tr> |
| 240 | </table> |
| 241 | |
| 242 | |
| 243 | |
| 244 | |
| 245 | */ |
| 246 | |
| 247 | } |