From a9fe75efc484c1db35cc7e0132959863f5bdca03 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Sat, 31 Jul 2010 21:37:29 +0100 Subject: Documentation: Start special topic page on aliasing. --- doc/I11_Aliasing.dox | 83 ++++++++++++++++++++++++++++++++++-- doc/Overview.dox | 1 + doc/snippets/TopicAliasing_block.cpp | 5 +++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 doc/snippets/TopicAliasing_block.cpp (limited to 'doc') diff --git a/doc/I11_Aliasing.dox b/doc/I11_Aliasing.dox index 29092c508..9b3c00af1 100644 --- a/doc/I11_Aliasing.dox +++ b/doc/I11_Aliasing.dox @@ -2,11 +2,88 @@ namespace Eigen { /** \page TopicAliasing Aliasing -What is aliasing? The noalias() and eval() member functions. Which operations are safe and which are not. +In Eigen, aliasing refers to assignment statement in which the same matrix (or array or vector) appears on the +left and on the right of the assignment operators. Statements like mat = 2 * mat; or mat = +mat.transpose(); exhibit aliasing. The aliasing in the first example is harmless, but the aliasing in the +second example leads to unexpected results. This page explains what aliasing is, when it is harmful, and what +to do about it. -TODO: write this dox page! +Table of contents + - \ref TopicAliasingExamples + - \ref TopicAliasingSolution + - \ref TopicAliasingCwise + - \ref TopicAliasingMatrixMult + - \ref TopicAliasingSummary -Is linked from the tutorial on matrix arithmetic. + +\section TopicAliasingExamples Examples + +The following example exhibiting aliasing was mentioned in \ref TutorialMatrixArithmetic : + + +
+Example: \include tut_arithmetic_transpose_aliasing.cpp + +Output: \verbinclude tut_arithmetic_transpose_aliasing.out +
+ +The output is not what one would expect. In fact, the transpose of the matrix is +\f[ +\mbox{a.transpose()} = \begin{bmatrix} 1 & 3 \\ 2 & 4 \end{bmatrix}. +\f] +The problem here is that Eigen's implementation uses lazy evaluation +(see \ref TopicEigenExpressionTemplates). The result is similar to +\code +for (Matrix2i::Index j = 0; j < a.cols(); ++j) + for (Matrix2i::Index i = 0; i < a.rows(); ++i) + a(i,j) = a(j,i); +\endcode +Thus, when a(1,0) is written to, it uses the new value of a(0,1) instead of the old one, and +this leads to the wrong result. + +The next section explains how to solve this problem, but first we want to show one more example to illustrate +that aliasing can be a bit more subtle. + + +
+Example: \include TopicAliasing_block.cpp + +Output: \verbinclude TopicAliasing_block.out +
+ +The blocks mat.bottomRightCorner(2,2) and mat.topLeftCorner(2,2) overlap, because both +contain the coefficient mat(1,1) at the centre of the 3-by-3 matrix \c mat . Thus, this example +exhibits aliasing, and indeed the result is wrong: the (2,2) entry in the bottom right corner should be +5. However, if \c mat were a 4-by-4 matrix, then the blocks would not overlop, and there would be no aliasing. + + +\section TopicAliasingSolution Resolving aliasing issues + +Synopsis: xxxInPlace(), eval(). + + +\section TopicAliasingCwise Aliasing and component-wise operations + +Synopsis: Things like mat = 2 * mat, matA = matA + matB and arr = arr.sin() are safe. + + +\section TopicAliasingMatrixMult Aliasing and matrix multiplication + +Synopsis: %Matrix multiplication assumes aliasing by default. Use noalias() to improve performance if there is +no aliasing. + + +\section TopicAliasingSummary Summary + +Aliasing occurs when the same matrix or array coefficients appear both on the left- and the right-hand side of +an assignment operator. + - Aliasing is harmless with coefficient-wise computations; this includes scalar multiplication and matrix or + array addition. + - When you multiply two matrices, Eigen assumes that aliasing occurs. If you know that there is no aliasing, + then you can use \link MatrixBase::noalias() noalias()\endlink. + - In all other situations, Eigen assumes that there is no aliasing issue and thus gives the wrong result if + aliasing does in fact occur. To prevent this, you have to use \link DenseBase::eval() eval() \endlink or + one of the xxxInPlace() functions. */ } diff --git a/doc/Overview.dox b/doc/Overview.dox index 8cf4e098f..9071c0f15 100644 --- a/doc/Overview.dox +++ b/doc/Overview.dox @@ -29,6 +29,7 @@ For a first contact with Eigen, the best place is to have a look at the \ref Get - \ref TutorialSparse - \ref QuickRefPage - Advanced topics + - \ref TopicAliasing - \ref TopicLazyEvaluation - \ref TopicLinearAlgebraDecompositions - \ref TopicCustomizingEigen diff --git a/doc/snippets/TopicAliasing_block.cpp b/doc/snippets/TopicAliasing_block.cpp new file mode 100644 index 000000000..9e897d01c --- /dev/null +++ b/doc/snippets/TopicAliasing_block.cpp @@ -0,0 +1,5 @@ +Matrix3i mat; +mat << 1, 2, 3, 4, 5, 6, 7, 8, 9; +cout << "Here is the matrix mat:\n" << mat << endl; +mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2); +cout << "After the assignment, mat = \n" << mat << endl; -- cgit v1.2.3