mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 19:59:05 +08:00
add initial versions of pages 2 and 3 of the tutorial: matrix arithmetic and the array class
This commit is contained in:
parent
4338834e33
commit
9d44005916
247
doc/C02_TutorialMatrixArithmetic.dox
Normal file
247
doc/C02_TutorialMatrixArithmetic.dox
Normal file
@ -0,0 +1,247 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \page TutorialMatrixArithmetic Tutorial - 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.
|
||||
|
||||
\b Table \b of \b contents
|
||||
- \ref TutorialMatrixArithmCommaInitializer
|
||||
- \ref TutorialMatrixArithmElementaryOperations
|
||||
- \ref TutorialMatrixArithmExamples
|
||||
- \ref TutorialMatrixArithmProduct
|
||||
- \ref TutorialMatrixArithmSimpleExample
|
||||
- \ref TutorialMatrixCombiningOperators
|
||||
- \ref TutorialMatrixOperatorValidity
|
||||
- \ref TutorialMatrixArithmReductionOperations
|
||||
|
||||
|
||||
\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:
|
||||
\code
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
\endcode
|
||||
</td></tr></table>
|
||||
|
||||
Moreover, Eigen also supports to load a matrix through a set of blocks:
|
||||
<table class="tutorial_code"><tr><td>
|
||||
\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;
|
||||
\endcode
|
||||
</td>
|
||||
<td>
|
||||
output:
|
||||
\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
|
||||
\endcode
|
||||
</td></tr></table>
|
||||
|
||||
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 TutorialMatrixArithmElementaryOperations Basic arithmetic operators
|
||||
|
||||
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.
|
||||
|
||||
\subsection TutorialMatrixArithmExamples Usage examples
|
||||
Some basic examples are presented in the following table, showing how easy it is to express arithmetic operations with Eigen.
|
||||
|
||||
<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.
|
||||
|
||||
<table class="tutorial_code" align="center">
|
||||
<tr><td align="center">\b Reduction \b operation</td><td align="center">\b Usage \b example</td></tr>
|
||||
<tr><td>
|
||||
Sum of all the coefficients in a matrix</td><td>\code
|
||||
MatrixXf m;
|
||||
float totalSum = m.sum();\endcode</td></tr>
|
||||
<tr><td>
|
||||
Maximum coefficient in a matrix</td><td>\code
|
||||
MatrixXf m;
|
||||
int row, col;
|
||||
|
||||
// minimum value will be stored in minValue
|
||||
// and the row and column where it was found in row and col,
|
||||
// (these two parameters are optional)
|
||||
float minValue = m.minCoeff(&row,&col);\endcode</td></tr>
|
||||
<tr><td>
|
||||
Maximum coefficient in a matrix</td><td>\code
|
||||
MatrixXf m;
|
||||
int row, col;
|
||||
|
||||
// maximum value will be stored in maxValue
|
||||
// and the row and column where it was found in row and col,
|
||||
// (these two parameters are optional)
|
||||
float maxValue = m.maxCoeff(&row,&col);\endcode</td></tr>
|
||||
<tr><td>
|
||||
Product between all coefficients in a matrix</td><td>\code
|
||||
MatrixXf m;
|
||||
|
||||
float product = m.prod();\endcode</td></tr>
|
||||
<tr><td>
|
||||
Mean of coefficients in a matrix</td><td>\code
|
||||
MatrixXf m;
|
||||
|
||||
float mean = m.mean();\endcode</td></tr>
|
||||
<tr><td>
|
||||
Matrix's trace</td><td>\code
|
||||
MatrixXf m;
|
||||
|
||||
float trace = m.trace();\endcode</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
}
|
190
doc/C03_TutorialArrayClass.dox
Normal file
190
doc/C03_TutorialArrayClass.dox
Normal file
@ -0,0 +1,190 @@
|
||||
namespace Eigen {
|
||||
|
||||
/** \page TutorialArrayClass Tutorial - The Array Class
|
||||
\ingroup Tutorial
|
||||
|
||||
This tutorial aims to provide an overview and explanations on how to use Eigen's \b Array class
|
||||
|
||||
\b Table \b of \b contents
|
||||
- \ref TutorialArrayClassWhatIs
|
||||
- \ref TutorialArrayClassTypes
|
||||
- \ref TutorialArrayClassAccess
|
||||
- \ref TutorialArrayClassCoeffWiseExamples
|
||||
- \ref TutorialArrayHowToUse
|
||||
- \ref TutorialArrayClassCoeffWiseOperators
|
||||
|
||||
\section TutorialArrayClassWhatIs What is the Array class?
|
||||
The \b Array class is provided by Eigen in order to perform coefficient-wise operations on matrices. As menioned in the previous section FIXME:link, only linear algebra operations are supported between matrices and vectors. The \b Array class provides a useful abstraction layer that allows the developer to perform a wide range of advanced operations on a matrix, such as coefficient-wise addition, division and multiplication.
|
||||
|
||||
\subsection TutorialArrayClassTypes Array type and predefined types
|
||||
The \b Array class is actually a template that works in a similar way as the \b Matrix one:
|
||||
|
||||
\code
|
||||
|
||||
//declaring an Array instance
|
||||
Array<type,numRows,numCols> a;
|
||||
\endcode
|
||||
|
||||
Eigen provides a bunch of predefined types to make instantiation easier. These types follow the same conventions as the ones available for the \b Matrix ones but with some slight differences, as shown in the following table:
|
||||
|
||||
FIXME: explain why these differences-
|
||||
|
||||
<table class="tutorial_code" align="center">
|
||||
<tr><td align="center">\b Type</td><td align="center">\b Typedef</td></tr>
|
||||
<tr><td>
|
||||
\code Array<double,Dynamic,Dynamic> \endcode</td>
|
||||
<td>
|
||||
\code ArrayXXd \endcode</td></tr>
|
||||
<tr><td>
|
||||
\code Array<double,3,3> \endcode</td>
|
||||
<td>
|
||||
\code Array33d \endcode</td></tr>
|
||||
<tr><td>
|
||||
\code Array<float,Dynamic,Dynamic> \endcode</td>
|
||||
<td>
|
||||
\code ArrayXXf \endcode</td></tr>
|
||||
<tr><td>
|
||||
\code Array<float,3,3> \endcode</td>
|
||||
<td>
|
||||
\code Array33f \endcode</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
\subsection TutorialArrayClassAccess Accessing values inside \b Array
|
||||
Write and read-access to coefficients inside \b Array is done in the same way as with \b Matrix. Here some examples are presented, just for clarification:
|
||||
|
||||
\code
|
||||
ArrayXXf m(2,2);
|
||||
|
||||
//assign some values coefficient by coefficient
|
||||
m(0,0) = 1.0; m(0,1) = 2.0;
|
||||
m(1,0) = 3.0; m(1,1) = 4.0;
|
||||
|
||||
//print values to standard output
|
||||
std::cout << m << std::endl;
|
||||
|
||||
// using the comma-initializer is also allowed
|
||||
m << 1.0,2.0,
|
||||
3.0,4.0;
|
||||
\endcode
|
||||
|
||||
\subsection TutorialArrayClassCoeffWiseExamples Simple coefficient-wise operations
|
||||
As said before, the \b Array class looks at operators from a coefficient-wise perspective. This makes an important difference with respect to \b Matrix algebraic operations, especially with the product operator. The following example performs coefficient-wise multiplication between two \b Array instances:
|
||||
|
||||
\code
|
||||
ArrayXXf m(4,4);
|
||||
ArrayXXf n(4,4);
|
||||
ArrayXXf result;
|
||||
|
||||
// after this operation is executed, result(i,j) = m(i,j) * n(i,j) for every position
|
||||
result = m * n;
|
||||
\endcode
|
||||
|
||||
|
||||
|
||||
Another example has to do with coefficient-wise addition:
|
||||
|
||||
\code
|
||||
ArrayXXf m(4,4);
|
||||
ArrayXXf result;
|
||||
|
||||
// after this operation is executed, result(i,j) = m(i,j) + 4
|
||||
result = m + 4;
|
||||
\endcode
|
||||
|
||||
\section TutorialArrayHowToUse Using arrays and matrices
|
||||
It is possible to treat the data inside a \b Matrix object as an \b Array and vice-versa. This allows the developer to perform a wide diversity of operators regardless of the actual type where the coefficients rely on.
|
||||
|
||||
The \b Matrix class provides a \p .array() method that 'converts' it into an \b Array type, so that coefficient-wise operations can be applied easily. On the other side, the \b Array class provides a \p .matrix() method. FIXME: note on overhead
|
||||
|
||||
An example using this 'interoperability' is presented below:
|
||||
|
||||
\code
|
||||
MatrixXf m(4,4);
|
||||
MatrixXf n(4,4);
|
||||
MatrixXf x(4,4);
|
||||
MatrixXf result;
|
||||
|
||||
//matrix multiplication (non coefficient-wise)
|
||||
result = m * n;
|
||||
|
||||
//coefficient-wise multiplication
|
||||
result = m.array() * n.array();
|
||||
|
||||
// --- More complex example ---
|
||||
// This will perform coefficient-wise multiplication between m and n
|
||||
// to later compute a matrix multiplication between that result and matrix x
|
||||
result = (m.array() * n.array()).matrix() * x;
|
||||
|
||||
\endcode
|
||||
|
||||
\b NOTE: there is no need to call \p .matrix() to assign a \b Array type to a \b Matrix or vice-versa.
|
||||
|
||||
\section TutorialArrayClassCoeffWiseOperators Array coefficient-wise operators
|
||||
<table class="noborder">
|
||||
<tr><td>
|
||||
<table class="tutorial_code" style="margin-right:10pt">
|
||||
<tr><td>Coefficient wise \link ArrayBase::operator*() product \arrayworld \endlink</td>
|
||||
<td>\code array3 = array1 * array2; \endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Add a scalar to all coefficients</td><td>\code
|
||||
array3 = array1 + scalar;
|
||||
array3 += scalar;
|
||||
array3 -= scalar;
|
||||
\endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Coefficient wise \link ArrayBase::operator/() division \endlink \arrayworld</td><td>\code
|
||||
array3 = array1 / array2; \endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Coefficient wise \link ArrayBase::inverse() reciprocal \endlink \arrayworld</td><td>\code
|
||||
array3 = array1.inverse(); \endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
Coefficient wise comparisons \arrayworld \n
|
||||
(support all operators)</td><td>\code
|
||||
array3 = array1 < array2;
|
||||
array3 = array1 <= array2;
|
||||
array3 = array1 > array2;
|
||||
etc.
|
||||
\endcode
|
||||
</td></tr></table>
|
||||
</td>
|
||||
<td><table class="tutorial_code">
|
||||
<tr><td>
|
||||
\b Trigo \arrayworld: \n
|
||||
\link ArrayBase::sin sin \endlink, \link ArrayBase::cos cos \endlink</td><td>\code
|
||||
array3 = array1.sin();
|
||||
etc.
|
||||
\endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
\b Power \arrayworld: \n \link ArrayBase::pow() pow \endlink,
|
||||
\link ArrayBase::square square \endlink,
|
||||
\link ArrayBase::cube cube \endlink, \n
|
||||
\link ArrayBase::sqrt sqrt \endlink,
|
||||
\link ArrayBase::exp exp \endlink,
|
||||
\link ArrayBase::log log \endlink </td><td>\code
|
||||
array3 = array1.square();
|
||||
array3 = array1.pow(5);
|
||||
array3 = array1.log();
|
||||
etc.
|
||||
\endcode
|
||||
</td></tr>
|
||||
<tr><td>
|
||||
\link ArrayBase::min min \endlink, \link ArrayBase::max max \endlink, \n
|
||||
absolute value (\link ArrayBase::abs() abs \endlink, \link ArrayBase::abs2() abs2 \endlink \arrayworld)
|
||||
</td><td>\code
|
||||
array3 = array1.min(array2);
|
||||
array3 = array1.max(array2);
|
||||
array3 = array1.abs();
|
||||
array3 = array1.abs2();
|
||||
\endcode</td></tr>
|
||||
</table>
|
||||
</td></tr></table>
|
||||
|
||||
|
||||
**/
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user