From 42a050dc6881d00ed32ffe2b9d55192db8dca760 Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Mon, 27 Dec 2010 15:06:55 +0000 Subject: [PATCH] Finish doc page on aliasing. --- doc/I11_Aliasing.dox | 46 ++++++++++++++++++++++++++-- doc/snippets/TopicAliasing_mult1.cpp | 4 +++ doc/snippets/TopicAliasing_mult2.cpp | 10 ++++++ doc/snippets/TopicAliasing_mult3.cpp | 4 +++ 4 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 doc/snippets/TopicAliasing_mult1.cpp create mode 100644 doc/snippets/TopicAliasing_mult2.cpp create mode 100644 doc/snippets/TopicAliasing_mult3.cpp diff --git a/doc/I11_Aliasing.dox b/doc/I11_Aliasing.dox index c7e984cf3..b5b5a3b59 100644 --- a/doc/I11_Aliasing.dox +++ b/doc/I11_Aliasing.dox @@ -152,8 +152,50 @@ not necessary to evaluate the right-hand side explicitly. \section TopicAliasingMatrixMult Aliasing and matrix multiplication -Synopsis: %Matrix multiplication assumes aliasing by default. Use noalias() to improve performance if there is -no aliasing. +Matrix multiplication is the only operation in Eigen that assumes aliasing by default. Thus, if \c matA is a +matrix, then the statement matA = matA * matA; is safe. All other operations in Eigen assume that +there are no aliasing problems, either because the result is assigned to a different matrix or because it is a +component-wise operation. + + + + +
ExampleOutput
+\include TopicAliasing_mult1.cpp + +\verbinclude TopicAliasing_mult1.out +
+ +However, this comes at a price. When executing the expression matA = matA * matA, Eigen evaluates the +product in a temporary matrix which is assigned to \c matA after the computation. This is fine. But Eigen does +the same when the product is assigned to a different matrix (e.g., matB = matA * matA). In that case, +it is more efficient to evaluate the product directly into \c matB instead of evaluating it first into a +temporary matrix and copying that matrix to \c matB. + +The user can indicate with the \link MatrixBase::noalias() noalias()\endlink function that there is no +aliasing, as follows: matB.noalias() = matA * matA. This allows Eigen to evaluate the matrix product +matA * matA directly into \c matB. + + + + +
ExampleOutput
+\include TopicAliasing_mult2.cpp + +\verbinclude TopicAliasing_mult2.out +
+ +Of course, you should not use \c noalias() when there is in fact aliasing taking place. If you do, then you +may get wrong results: + + + + +
ExampleOutput
+\include TopicAliasing_mult3.cpp + +\verbinclude TopicAliasing_mult3.out +
\section TopicAliasingSummary Summary diff --git a/doc/snippets/TopicAliasing_mult1.cpp b/doc/snippets/TopicAliasing_mult1.cpp new file mode 100644 index 000000000..cd7e9004c --- /dev/null +++ b/doc/snippets/TopicAliasing_mult1.cpp @@ -0,0 +1,4 @@ +MatrixXf matA(2,2); +matA << 2, 0, 0, 2; +matA = matA * matA; +cout << matA; diff --git a/doc/snippets/TopicAliasing_mult2.cpp b/doc/snippets/TopicAliasing_mult2.cpp new file mode 100644 index 000000000..a3ff56851 --- /dev/null +++ b/doc/snippets/TopicAliasing_mult2.cpp @@ -0,0 +1,10 @@ +MatrixXf matA(2,2), matB(2,2); +matA << 2, 0, 0, 2; + +// Simple but not quite as efficient +matB = matA * matA; +cout << matB << endl << endl; + +// More complicated but also more efficient +matB.noalias() = matA * matA; +cout << matB; diff --git a/doc/snippets/TopicAliasing_mult3.cpp b/doc/snippets/TopicAliasing_mult3.cpp new file mode 100644 index 000000000..1d12a6c67 --- /dev/null +++ b/doc/snippets/TopicAliasing_mult3.cpp @@ -0,0 +1,4 @@ +MatrixXf matA(2,2); +matA << 2, 0, 0, 2; +matA.noalias() = matA * matA; +cout << matA;