aboutsummaryrefslogtreecommitdiffhomepage
path: root/doc
diff options
context:
space:
mode:
authorGravatar Jitse Niesen <jitse@maths.leeds.ac.uk>2010-12-27 15:06:55 +0000
committerGravatar Jitse Niesen <jitse@maths.leeds.ac.uk>2010-12-27 15:06:55 +0000
commit42a050dc6881d00ed32ffe2b9d55192db8dca760 (patch)
treec2ffabd791fc1060ff62732d8b5a46fb67734154 /doc
parentdc3618a55727a0471940c42baacbe58629b348ca (diff)
Finish doc page on aliasing.
Diffstat (limited to 'doc')
-rw-r--r--doc/I11_Aliasing.dox46
-rw-r--r--doc/snippets/TopicAliasing_mult1.cpp4
-rw-r--r--doc/snippets/TopicAliasing_mult2.cpp10
-rw-r--r--doc/snippets/TopicAliasing_mult3.cpp4
4 files changed, 62 insertions, 2 deletions
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 <tt>matA = matA * matA;</tt> 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.
+
+<table class="example">
+<tr><th>Example</th><th>Output</th></tr>
+<tr><td>
+\include TopicAliasing_mult1.cpp
+</td>
+<td>
+\verbinclude TopicAliasing_mult1.out
+</td></tr></table>
+
+However, this comes at a price. When executing the expression <tt>matA = matA * matA</tt>, 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., <tt>matB = matA * matA</tt>). 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: <tt>matB.noalias() = matA * matA</tt>. This allows Eigen to evaluate the matrix product
+<tt>matA * matA</tt> directly into \c matB.
+
+<table class="example">
+<tr><th>Example</th><th>Output</th></tr>
+<tr><td>
+\include TopicAliasing_mult2.cpp
+</td>
+<td>
+\verbinclude TopicAliasing_mult2.out
+</td></tr></table>
+
+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:
+
+<table class="example">
+<tr><th>Example</th><th>Output</th></tr>
+<tr><td>
+\include TopicAliasing_mult3.cpp
+</td>
+<td>
+\verbinclude TopicAliasing_mult3.out
+</td></tr></table>
\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;