mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-11-27 06:30:28 +08:00
Small changes to tutorial page 2 (matrix arithmetic):
* slightly more extensive discussion of aliasing * layout: put example code and output side-by-side * add some links, etc
This commit is contained in:
parent
551cb9b7b4
commit
2c03ca3325
@ -27,7 +27,7 @@ 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".
|
||||
not linear algebra, see the \ref TutorialArrayClass "next page".
|
||||
|
||||
\section TutorialArithmeticAddSub Addition and subtraction
|
||||
|
||||
@ -39,8 +39,12 @@ also have the same \c Scalar type, as Eigen doesn't do automatic type promotion.
|
||||
\li compound operator += as in \c a+=b
|
||||
\li compound operator -= as in \c a-=b
|
||||
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_add_sub.cpp
|
||||
Output: \verbinclude tut_arithmetic_add_sub.out
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_add_sub.out
|
||||
</td></tr></table>
|
||||
|
||||
\section TutorialArithmeticScalarMulDiv Scalar multiplication and division
|
||||
|
||||
@ -51,12 +55,17 @@ Multiplication and division by a scalar is very simple too. The operators at han
|
||||
\li compound operator *= as in \c matrix*=scalar
|
||||
\li compound operator /= as in \c matrix/=scalar
|
||||
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_scalar_mul_div.cpp
|
||||
Output: \verbinclude tut_arithmetic_scalar_mul_div.out
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_scalar_mul_div.out
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
\section TutorialArithmeticMentionXprTemplates A note about expression templates
|
||||
|
||||
This is an advanced topic that we explain in \ref TopicEigenExpressionTemplates "this page",
|
||||
This is an advanced topic that we explain on \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=.
|
||||
@ -78,7 +87,7 @@ more opportunities for optimization.
|
||||
|
||||
\section TutorialArithmeticTranspose Transposition and conjugation
|
||||
|
||||
The \c transpose \f$ a^T \f$, \c conjugate \f$ \bar{a} \f$, and the \c adjoint (i.e., conjugate transpose) of the matrix or vector \f$ a \f$, are simply obtained by the functions of the same names.
|
||||
The transpose \f$ a^T \f$, conjugate \f$ \bar{a} \f$, and adjoint (i.e., conjugate transpose) \f$ a^* \f$ of a matrix or vector \f$ a \f$ are obtained by the member functions \link DenseBase::transpose() transpose()\endlink, \link MatrixBase::conjugate() conjugate()\endlink, and \link MatrixBase::adjoint() adjoint()\endlink, respectively.
|
||||
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_transpose_conjugate.cpp
|
||||
@ -89,21 +98,23 @@ Output: \include tut_arithmetic_transpose_conjugate.out
|
||||
|
||||
For real matrices, \c conjugate() is a no-operation, and so \c adjoint() is 100% equivalent to \c transpose().
|
||||
|
||||
As for basic arithmetic operators, \c transpose and \c adjoint simply return a proxy object without doing the actual transposition. Therefore, <tt>a=a.transpose()</tt> leads to an unexpected result:
|
||||
As for basic arithmetic operators, \c transpose() and \c adjoint() simply return a proxy object without doing the actual transposition. If you do <tt>b = a.transpose()</tt>, then the transpose is evaluated at the same time as the result is written into \c b. However, there is a complication here. If you do <tt>a = a.transpose()</tt>, then Eigen starts writing the result into \c a before the evaluation of the transpose is finished. Therefore, the instruction <tt>a = a.transpose()</tt> does not replace \c a with its transpose, as one would expect:
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_transpose_aliasing.cpp
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_transpose_aliasing.out
|
||||
</td></tr></table>
|
||||
In "debug mode", i.e., when assertions have not been disabled, such common pitfalls are automatically detected. For \em in-place transposition, simply use the transposeInPlace() function:
|
||||
This is the so-called \ref TopicAliasing "aliasing issue". In "debug mode", i.e., when \ref TopicAssertions "assertions" have not been disabled, such common pitfalls are automatically detected.
|
||||
|
||||
For \em in-place transposition, as for instance in <tt>a = a.transpose()</tt>, simply use the \link DenseBase::transposeInPlace() transposeInPlace()\endlink function:
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_transpose_inplace.cpp
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_transpose_inplace.out
|
||||
</td></tr></table>
|
||||
There is also the adjointInPlace() function for complex matrix.
|
||||
There is also the \link MatrixBase::adjointInPlace() adjointInPlace()\endlink function for complex matrices.
|
||||
|
||||
\section TutorialArithmeticMatrixMul Matrix-matrix and matrix-vector multiplication
|
||||
|
||||
@ -112,10 +123,14 @@ case of matrices, they are implicitly handled there too, so matrix-vector produc
|
||||
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
|
||||
\li compound operator *= as in \c a*=b (this multiplies on the right: \c a*=b is equivalent to <tt>a = a*b</tt>)
|
||||
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_matrix_mul.cpp
|
||||
Output: \verbinclude tut_arithmetic_matrix_mul.out
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_matrix_mul.out
|
||||
</td></tr></table>
|
||||
|
||||
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
|
||||
@ -124,7 +139,7 @@ introducing a temporary here, so it will compile \c m=m*m as:
|
||||
tmp = m*m;
|
||||
m = tmp;
|
||||
\endcode
|
||||
If you know your matrix product can be safely evaluated into the destination matrix without aliasing issue, then you can use the \c noalias() function to avoid the temporary, e.g.:
|
||||
If you know your matrix product can be safely evaluated into the destination matrix without aliasing issue, then you can use the \link MatrixBase::noalias() noalias()\endlink function to avoid the temporary, e.g.:
|
||||
\code
|
||||
c.noalias() += a * b;
|
||||
\endcode
|
||||
@ -134,16 +149,20 @@ For more details on this topic, see \ref TopicEigenExpressionTemplates "this pag
|
||||
|
||||
\section TutorialArithmeticDotAndCross Dot product and cross product
|
||||
|
||||
The above-discussed \c operator* does not allow to compute dot and cross products. For that, you need the dot() and cross() methods.
|
||||
The above-discussed \c operator* cannot be used to compute dot and cross products directly. For that, you need the \link MatrixBase::dot() dot()\endlink and \link MatrixBase::cross() cross()\endlink methods.
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_dot_cross.cpp
|
||||
Output: \verbinclude tut_arithmetic_dot_cross.out
|
||||
</td>
|
||||
<td>
|
||||
Output: \include tut_arithmetic_dot_cross.out
|
||||
</td></tr></table>
|
||||
|
||||
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.
|
||||
|
||||
\section TutorialArithmeticRedux Basic arithmetic reduction operations
|
||||
Eigen also provides some reduction operations to reduce a given matrix or vector to a single value such as the sum (<tt>a.sum()</tt>), product (<tt>a.prod()</tt>), or the maximum (<tt>a.maxCoeff()</tt>) and minimum (<tt>a.minCoeff()</tt>) of all its coefficients.
|
||||
Eigen also provides some reduction operations to reduce a given matrix or vector to a single value such as the sum (computed by \link DenseBase::sum() sum()\endlink), product (\link DenseBase::prod() prod()\endlink), or the maximum (\link DenseBase::maxCoeff() maxCoeff()\endlink) and minimum (\link DenseBase::minCoeff() minCoeff()\endlink) of all its coefficients.
|
||||
|
||||
<table class="tutorial_code"><tr><td>
|
||||
Example: \include tut_arithmetic_redux_basic.cpp
|
||||
@ -152,7 +171,7 @@ Example: \include tut_arithmetic_redux_basic.cpp
|
||||
Output: \include tut_arithmetic_redux_basic.out
|
||||
</td></tr></table>
|
||||
|
||||
The \em trace of a matrix, as returned by the function \c trace(), is the sum of the diagonal coefficients and can also be computed as efficiently using <tt>a.diagonal().sum()</tt>, as we will see later on.
|
||||
The \em trace of a matrix, as returned by the function \link MatrixBase::trace() trace()\endlink, is the sum of the diagonal coefficients and can also be computed as efficiently using <tt>a.diagonal().sum()</tt>, as we will see later on.
|
||||
|
||||
There also exist variants of the \c minCoeff and \c maxCoeff functions returning the coordinates of the respective coefficient via the arguments:
|
||||
|
||||
@ -166,7 +185,7 @@ Output: \include tut_arithmetic_redux_minmax.out
|
||||
|
||||
\section 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,
|
||||
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;
|
||||
@ -175,8 +194,7 @@ but Eigen writes the important message in UPPERCASE_LETTERS_SO_IT_STANDS_OUT. Fo
|
||||
\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.
|
||||
Eigen then uses runtime assertions. This means that the program will abort with an error message when executing an illegal operation if it is run in "debug mode", and it will probably crash if assertions are turned off.
|
||||
|
||||
\code
|
||||
MatrixXf m(3,3);
|
||||
|
12
doc/I11_Aliasing.dox
Normal file
12
doc/I11_Aliasing.dox
Normal file
@ -0,0 +1,12 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \page TopicAliasing Aliasing
|
||||
|
||||
What is aliasing? The noalias() and eval() member functions. Which operations are safe and which are not.
|
||||
|
||||
TODO: write this dox page!
|
||||
|
||||
Is linked from the tutorial on matrix arithmetic.
|
||||
|
||||
*/
|
||||
}
|
@ -2,9 +2,11 @@
|
||||
std::ptrdiff_t i, j;
|
||||
float minOfM = m.minCoeff(&i,&j);
|
||||
cout << "Here is the matrix m:\n" << m << endl;
|
||||
cout << "Its minimum coefficient (" << minOfM << ") is at position (" << i << "," << j << ")\n\n";
|
||||
cout << "Its minimum coefficient (" << minOfM
|
||||
<< ") is at position (" << i << "," << j << ")\n\n";
|
||||
|
||||
RowVector4i v = RowVector4i::Random();
|
||||
int maxOfV = v.maxCoeff(&i);
|
||||
cout << "Here is the vector v: " << v << endl;
|
||||
cout << "Its maximum coefficient (" << maxOfV << ") is at position " << i << endl;
|
||||
cout << "Its maximum coefficient (" << maxOfV
|
||||
<< ") is at position " << i << endl;
|
||||
|
Loading…
Reference in New Issue
Block a user