big improvements to tutorial, especially page 2 (matrix arithmetic).
add placeholders for some 'special topic' pages.
diff --git a/doc/C02_TutorialMatrixArithmetic.dox b/doc/C02_TutorialMatrixArithmetic.dox
index 431ef59..10156d5 100644
--- a/doc/C02_TutorialMatrixArithmetic.dox
+++ b/doc/C02_TutorialMatrixArithmetic.dox
@@ -1,202 +1,125 @@
namespace Eigen {
-/** \page TutorialMatrixArithmetic Tutorial - Matrix and vector arithmetic
+/** \page TutorialMatrixArithmetic Tutorial page 2 - %Matrix and vector arithmetic
\ingroup Tutorial
-This tutorial aims to provide an overview and some details on how to perform arithmetic between matrices, vectors and scalars with Eigen.
+\li \b Previous: \ref TutorialMatrixClass
+\li \b Next: \ref TutorialArrayClass
+
+This tutorial aims to provide an overview and some details on how to perform arithmetic
+between matrices, vectors and scalars with Eigen.
\b Table \b of \b contents
- - \ref TutorialMatrixArithmCommaInitializer
- - \ref TutorialMatrixArithmElementaryOperations
- - \ref TutorialMatrixArithmExamples
- - \ref TutorialMatrixArithmProduct
- - \ref TutorialMatrixArithmSimpleExample
- - \ref TutorialMatrixCombiningOperators
- - \ref TutorialMatrixOperatorValidity
- - \ref TutorialMatrixArithmReductionOperations
+ - \ref TutorialArithmeticIntroduction
+ - \ref TutorialArithmeticMentionCommaInitializer
+ - \ref TutorialArithmeticAddSub
+ - \ref TutorialArithmeticScalarMulDiv
+ - \ref TutorialArithmeticMentionXprTemplates
+ - \ref TutorialArithmeticMatrixMul
+ - \ref TutorialArithmeticDotAndCross
+ - \ref TutorialArithmeticRedux
+ - \ref TutorialArithmeticValidity
+\section TutorialArithmeticIntroduction Introduction
-\section TutorialMatrixArithmCommaInitializer Comma initializer
-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:
-<table class="tutorial_code"><tr><td>
-\code Matrix3f m;
-m << 1, 2, 3,
- 4, 5, 6,
- 7, 8, 9;
-cout << m;
-\endcode
-</td>
-<td>
-output:
+Eigen offers matrix/vector arithmetic operations either through overloads of common C++ arithmetic operators such as +, -, *,
+or through special methods such as dot(), cross(), etc.
+For the Matrix class (matrices and vectors), operators are only overloaded to support
+linear-algebraic operations. For example, \c matrix1 \c * \c matrix2 means matrix-matrix product,
+and \c vector \c + \c scalar is just not allowed. If you want to perform all kinds of array operations,
+not linear algebra, see \ref TutorialArrayClass "next page".
+
+\section TutorialArithmeticMentionCommaInitializer A note about comma-initialization
+
+In examples below, we'll be initializing matrices with a very convenient device known as the \em comma-initializer.
+For now, it is enough to know this example:
+\include Tutorial_commainit_01.cpp
+Output: \verbinclude Tutorial_commainit_01.out
+The comma initializer is discussed in \ref TutorialAdvancedInitialization "this page".
+
+\section TutorialArithmeticAddSub Addition and substraction
+
+The left hand side and right hand side must, of course, have the same numbers of rows and of columns. They must
+also have the same \c Scalar type, as Eigen doesn't do automatic type promotion. The operators at hand here are:
+\li binary operator + as in \c a+b
+\li binary operator - as in \c a-b
+\li unary operator - as in \c -a
+\li compound operator += as in \c a+=b
+\li compound operator -= as in \c a-=b
+
+Example: \include tut_arithmetic_add_sub.cpp
+Output: \verbinclude tut_arithmetic_add_sub.out
+
+\section TutorialArithmeticScalarMulDiv Scalar multiplication and division
+
+Multiplication and division by a scalar is very simple too. The operators at hand here are:
+\li binary operator * as in \c matrix*scalar
+\li binary operator * as in \c scalar*matrix
+\li binary operator / as in \c matrix/scalar
+\li compound operator *= as in \c matrix*=scalar
+\li compound operator /= as in \c matrix/=scalar
+
+Example: \include tut_arithmetic_scalar_mul_div.cpp
+Output: \verbinclude tut_arithmetic_scalar_mul_div.out
+
+\section TutorialArithmeticMentionXprTemplates A note about expression templates
+
+This is an advanced topic that we explain in \ref TopicEigenExpressionTemplates "this page",
+but it is useful to just mention it now. In Eigen, arithmetic operators such as \c operator+ don't
+perform any computation by themselves, they just return an "expression object" describing the computation to be
+performed. The actual computation happens later, when the whole expression is evaluated, typically in \c operator=.
+While this might sound heavy, any modern optimizing compiler is able to optimize away that abstraction and
+the result is perfectly optimized code. For example, when you do:
\code
-1 2 3
-4 5 6
-7 8 9
+VectorXf a(50), b(50), c(50), d(50);
+...
+a = 3*b + 4*c + 5*d;
\endcode
-</td></tr></table>
-
-Moreover, Eigen also supports to load a matrix through a set of blocks:
-<table class="tutorial_code"><tr><td>
+Eigen compiles it to just one for loop, so that the arrays are traversed only once. Simplyfying (e.g. ignoring
+SIMD optimizations), this loop looks like this:
\code
-int rows=5, cols=5;
-MatrixXf m(rows,cols);
-m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),
- MatrixXf::Zero(3,cols-3),
- MatrixXf::Zero(rows-3,3),
- MatrixXf::Identity(rows-3,cols-3);
-cout << m;
+for(int i = 0; i < 50; ++i)
+ a[i] = 3*b[i] + 4*c[i] + 5*d[i];
\endcode
-</td>
-<td>
-output:
+Thus, you should not be afraid of using relatively large arithmetic expressions with Eigen: it only gives Eigen
+more opportunities for optimization.
+
+\section TutorialArithmeticMatrixMul Matrix-matrix and matrix-vector multiplication
+
+Matrix-matrix multiplication is again done with \c operator*. Since vectors are a special
+case of matrices, they are implicitly handled there too, so matrix-vector product is really just a special
+case of matrix-matrix product, and so is vector-vector outer product. Thus, all these cases are handled by just
+two operators:
+\li binary operator * as in \c a*b
+\li compound operator *= as in \c a*=b
+
+Example: \include tut_arithmetic_matrix_mul.cpp
+Output: \verbinclude tut_arithmetic_matrix_mul.out
+
+Note: if you read the above paragraph on expression templates and are worried that doing \c m=m*m might cause
+aliasing issues, be reassured for now: Eigen treats matrix multiplication as a special case and takes care of
+introducing a temporary here, so it will compile \c m=m*m as:
\code
-1 2 3 0 0
-4 5 6 0 0
-7 8 9 0 0
-0 0 0 1 0
-0 0 0 0 1
+tmp = m*m;
+m = tmp;
\endcode
-</td></tr></table>
+For more details on this topic, see \ref TopicEigenExpressionTemplates "this page".
-FIXME: is this still needed?
-<span class="note">\b Side \b note: here \link CommaInitializer::finished() .finished() \endlink
-is used to get the actual matrix object once the comma initialization
-of our temporary submatrix is done. Note that despite the apparent complexity of such an expression,
-Eigen's comma initializer usually compiles to very optimized code without any overhead.</span>
+\section TutorialArithmeticDotAndCross Dot product and cross product
-\section TutorialMatrixArithmElementaryOperations Basic arithmetic operators
+The above-discussed \c operator* does not allow to compute dot and cross products. For that, you need the dot() and cross() methods.
+Example: \include tut_arithmetic_dot_cross.cpp
+Output: \verbinclude tut_arithmetic_dot_cross.out
-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.
+Remember that cross product is only for vectors of size 3. Dot product is for vectors of any sizes.
+When using complex numbers, Eigen's dot product is conjugate-linear in the first variable and linear in the
+second variable.
-\subsection TutorialMatrixArithmExamples Usage examples
-Some basic examples are presented in the following table, showing how easy it is to express arithmetic operations with Eigen.
+\section TutorialArithmeticRedux Basic arithmetic reduction operations
+Eigen also provides some reduction operations to obtain values such as the sum or the maximum
+or minimum of all the coefficients in a given matrix or vector.
-<table class="tutorial_code" align="center">
-<tr><td>
-matrix/vector product \matrixworld</td><td>\code
-col2 = mat1 * col1;
-row2 = row1 * mat1; row1 *= mat1;
-mat3 = mat1 * mat2; mat3 *= mat1; \endcode
-</td></tr>
-<tr><td>
-add/subtract</td><td>\code
-mat3 = mat1 + mat2; mat3 += mat1;
-mat3 = mat1 - mat2; mat3 -= mat1;\endcode
-</td></tr>
-<tr><td>
-scalar product/division</td><td>\code
-mat3 = mat1 * s1; mat3 = s1 * mat1; mat3 *= s1;
-mat3 = mat1 / s1; mat3 /= s1;\endcode
-</td></tr>
-</table>
-
-\subsection TutorialMatrixArithmProduct Product types
-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:
-
-\code
- Matrix3f m1,m2,m3;
- Vector3f v1,v2,v3;
-
- // matrix product
- m1 = m2 * m3;
-
- // vector cross product: v1 = v2 X v3
- v1 = v2.cross(v3);
-
- // vector dot product: v2 . v3 (returns scalar)
- float dotResult = v2.dot(v3);
-\endcode
-
-<strong> Note:</strong> cross product is only defined for 3-dimensional vectors.
-
-\subsection TutorialMatrixArithmSimpleExample A simple example with matrix linear algebra
-
-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.
-
-\code
- #include <Eigen/Dense>
- #include <iostream>
-
- using namespace Eigen;
-
- int main()
- {
- MatrixXf m(3,3); // Matrix m is 3x3
- VectorXf n(3,3); // 3-component vector
-
- m << 1,2,3, // Assign some values to m
- 4,5,6,
- 7,8,9;
-
- n << 10,11,12, // Assign some values to n
- 13,14,15,
- 16,17,18;
-
-
- // simple matrix-product-scalar
- std::cout << "3*m = " << 3*m << std::endl;
-
- // simple matrix-divided-by-scalar
- std::cout << "m/3 = " << m/3 << std::endl;
-
- // matrix multiplication
- std::cout << "m*n = " << m*n << std::endl;
-
- return 0;
- }
-\endcode
-
-
-\subsection TutorialMatrixCombiningOperators Combining operators in a single statement
-
-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?) :
-
-\code
- MatrixXf m(3,3), n(3,3);
- MatrixXf q(3,3), p(3,3);
-
- // initialize... etc
- .....
-
- // METHOD 1: use temporary allocation
- {
- MatrixXf tempMatrix;
-
- tempMatrix = m + 3*n;
- p = tempMatrix * q;
- }
-
- // METHOD 2: avoids extra memory allocation if possible
- // (Eigen will take care of that automatically)
- p = (m + 3*n) * q; // matrix addition and multiplication by a vector
-
-\endcode
-
-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?
-
-
-\subsection TutorialMatrixOperatorValidity Validity of operations
-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:
-
-\code
- Matrix3f m;
- Vector4f v;
-
- v = m*v; // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
-\endcode
-
-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?
-
-\code
- MatrixXf m(3,3);
- VectorXf v(4);
-
- v = m * v; // Run-time assertion: "invalid matrix product"
-\endcode
-
-
-\section TutorialMatrixArithmReductionOperations Basic arithmetic reduction operations
-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.
+TODO: convert this from table format to tutorial/examples format.
<table class="tutorial_code" align="center">
<tr><td align="center">\b Reduction \b operation</td><td align="center">\b Usage \b example</td></tr>
@@ -239,8 +162,29 @@
float trace = m.trace();\endcode</td></tr>
</table>
+\subsection TutorialArithmeticValidity Validity of operations
+Eigen checks the validity of the operations that you perform. When possible,
+it checks them at compile-time, producing compilation errors. These error messages can be long and ugly,
+but Eigen writes the important message in UPPERCASE_LETTERS_SO_IT_STANDS_OUT. For example:
+\code
+ Matrix3f m;
+ Vector4f v;
+ v = m*v; // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES
+\endcode
+Of course, in many cases, for example when checking dynamic sizes, the check cannot be performed at compile time.
+Eigen then uses runtime assertions. This means that executing an illegal operation will result in a crash at runtime,
+with an error message.
+\code
+ MatrixXf m(3,3);
+ VectorXf v(4);
+ v = m * v; // Run-time assertion failure here: "invalid matrix product"
+\endcode
+
+For more details on this topic, see \ref TopicAssertions "this page".
+
+\li \b Next: \ref TutorialArrayClass
*/