mirror of
https://gitlab.com/libeigen/eigen.git
synced 2024-12-21 07:19:46 +08:00
7d3fe69eff
- update the tutorial - update doc of deprecated cwise function - update cwise doc snippets
762 lines
28 KiB
Plaintext
762 lines
28 KiB
Plaintext
namespace Eigen {
|
|
|
|
/** \page TutorialCore Tutorial 1/4 - Core features
|
|
\ingroup Tutorial
|
|
|
|
<div class="eimainmenu">\ref index "Overview"
|
|
| \b Core \b features
|
|
| \ref TutorialGeometry "Geometry"
|
|
| \ref TutorialAdvancedLinearAlgebra "Advanced linear algebra"
|
|
| \ref TutorialSparse "Sparse matrix"
|
|
</div>
|
|
|
|
\b Table \b of \b contents
|
|
- \ref TutorialCoreGettingStarted
|
|
- \ref TutorialCoreSimpleExampleFixedSize
|
|
- \ref TutorialCoreSimpleExampleDynamicSize
|
|
- \ref TutorialCoreMatrixTypes
|
|
- \ref TutorialCoreCoefficients
|
|
- \ref TutorialCoreMatrixInitialization
|
|
- \ref TutorialCoreArithmeticOperators
|
|
- \ref TutorialCoreReductions
|
|
- \ref TutorialCoreMatrixBlocks
|
|
- \ref TutorialCoreDiagonalMatrices
|
|
- \ref TutorialCoreTransposeAdjoint
|
|
- \ref TutorialCoreDotNorm
|
|
- \ref TutorialCoreTriangularMatrix
|
|
- \ref TutorialCoreSelfadjointMatrix
|
|
- \ref TutorialCoreSpecialTopics
|
|
\n
|
|
|
|
<hr>
|
|
|
|
\section TutorialCoreGettingStarted Getting started
|
|
|
|
In order to use Eigen, you just need to download and extract Eigen's source code. It is not necessary to use CMake or install anything.
|
|
|
|
Here are some quick compilation instructions with GCC. To quickly test an example program, just do
|
|
|
|
\code g++ -I /path/to/eigen/ my_program.cpp -o my_program \endcode
|
|
|
|
There is no library to link to. For good performance, add the \c -O2 compile-flag. Note however that this makes it impossible to debug inside Eigen code, as many functions get inlined. In some cases, performance can be further improved by disabling Eigen assertions: use \c -DEIGEN_NO_DEBUG or \c -DNDEBUG to disable them.
|
|
|
|
On the x86 architecture, the SSE2 instruction set is not enabled by default. Use \c -msse2 to enable it, and Eigen will then automatically enable its vectorized paths. On x86-64 and AltiVec-based architectures, vectorization is enabled by default. To turn off Eigen's vectorization use \c-DEIGEN_DONT_VECTORIZE.
|
|
|
|
\section TutorialCoreSimpleExampleFixedSize Simple example with fixed-size matrices and vectors
|
|
|
|
By fixed-size, we mean that the number of rows and columns are fixed at compile-time. In this case, Eigen avoids dynamic memory allocation, and unroll loops when that makes sense. This is useful for very small sizes: typically up to 4x4, sometimes up to 16x16.
|
|
|
|
<table class="tutorial_code"><tr><td>
|
|
\include Tutorial_simple_example_fixed_size.cpp
|
|
</td>
|
|
<td>
|
|
output:
|
|
\include Tutorial_simple_example_fixed_size.out
|
|
</td></tr></table>
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreSimpleExampleDynamicSize Simple example with dynamic-size matrices and vectors
|
|
|
|
By dynamic-size, we mean that the numbers of rows and columns are not fixed at compile-time. In this case, they are stored as runtime variables and the arrays are dynamically allocated.
|
|
|
|
<table class="tutorial_code"><tr><td>
|
|
\include Tutorial_simple_example_dynamic_size.cpp
|
|
</td>
|
|
<td>
|
|
output:
|
|
\include Tutorial_simple_example_dynamic_size.out
|
|
</td></tr></table>
|
|
|
|
<a name="warningarraymodule"></a>
|
|
\warning \redstar In most cases it is enough to include the \c Eigen/Core header only to get started with Eigen. However, some features presented in this tutorial require the Array module to be included (\c \#include \c <Eigen/Array>). Those features are highlighted with a red star \redstar. Notice that if you want to include all Eigen functionality at once, you can do:
|
|
\code
|
|
#include <Eigen/Eigen>
|
|
\endcode
|
|
This slows compilation down but at least you don't have to worry anymore about including the correct files! There also is the Eigen/Dense header including all dense functionality i.e. leaving out the Sparse module.
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreMatrixTypes Array, matrix and vector types
|
|
|
|
Eigen provides two kinds of dense objects: mathematical matrices and vectors which are both represented by the template class Matrix, and 1D and 2D arrays represented by the template class Array. While the former (Matrix) is specialized for the representation of mathematical objects, the latter (Array) represents a collection of scalar values arranged in a 1D or 2D fashion. As a major difference, all operations performed on arrays are coefficient wise. Matrix and Array have a lot of similarities since they both inherits the DenseBase and DenseStorageBase classes. In the rest of this tutorial we will use the following symbols to emphasize the features which are specifics to a given kind of object:
|
|
\li <a name="matrixonly"><a/>\matrixworld for matrix/vector only features
|
|
\li <a name="arrayonly"><a/>\arrayworld for array only features
|
|
|
|
Note that conversion between the two worlds can be done using the MatrixBase::array() and ArrayBase::matrix() functions respectively without any overhead.
|
|
|
|
In most cases, you can simply use one of the convenience typedefs for \ref matrixtypedefs "matrices" and \ref arraytypedefs "arrays".
|
|
|
|
The template class Matrix (just like the class Array) take a number of template parameters, but for now it is enough to understand the 3 first ones (and the others can then be left unspecified):
|
|
|
|
\code
|
|
Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime>
|
|
Array<Scalar, RowsAtCompileTime, ColsAtCompileTime>
|
|
\endcode
|
|
|
|
\li \c Scalar is the scalar type, i.e. the type of the coefficients. That is, if you want a vector of floats, choose \c float here.
|
|
\li \c RowsAtCompileTime and \c ColsAtCompileTime are the number of rows and columns of the matrix as known at compile-time.
|
|
|
|
For example, \c Vector3d is a typedef for \code Matrix<double, 3, 1> \endcode
|
|
|
|
For dynamic-size, that is in order to left the number of rows or of columns unspecified at compile-time, use the special value Eigen::Dynamic. For example, \c VectorXd is a typedef for \code Matrix<double, Dynamic, 1> \endcode
|
|
|
|
All combinations are allowed: you can have a matrix with a fixed number of rows and a dynamic number of columns, etc. The following are all valid:
|
|
|
|
\code
|
|
Matrix<double, 6, Dynamic> // Dynamic number of columns
|
|
Matrix<double, Dynamic, 2> // Dynamic number of rows
|
|
Matrix<double, Dynamic, Dynamic> // Fully dynamic
|
|
Matrix<double, 13, 3> // Fully fixed
|
|
\endcode
|
|
|
|
Fixed-size and partially-dynamic-size matrices may use all the same API calls as fully dynamic
|
|
matrices, but the fixed dimension(s) must remain constant, or an assertion failure will occur.
|
|
|
|
Finally, note that the default typedefs for array containers is slighlty different as we have to distinghish between 1D and 2D arrays:
|
|
\code
|
|
ArrayXf // 1D dynamic array of floats
|
|
Array2i // 1D array of integers of size 2
|
|
ArrayXXd // 2D fully dynamic array of doubles
|
|
Array44f // 2D array of floats of size 4x4
|
|
\endcode
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreCoefficients Coefficient access
|
|
|
|
Eigen supports the following syntaxes for read and write coefficient access of matrices, vectors and arrays:
|
|
|
|
\code
|
|
matrix(i,j);
|
|
vector(i)
|
|
vector[i]
|
|
\endcode
|
|
Vectors support also the following additional read-write accessors:
|
|
\code
|
|
vector.x() // first coefficient
|
|
vector.y() // second coefficient
|
|
vector.z() // third coefficient
|
|
vector.w() // fourth coefficient
|
|
\endcode
|
|
|
|
Notice that these coefficient access methods have assertions checking the ranges. So if you do a lot of coefficient access, these assertion can have an important cost. There are then two possibilities if you want avoid paying this cost:
|
|
\li Either you can disable assertions altogether, by defining EIGEN_NO_DEBUG or NDEBUG. Notice that some IDEs like MS Visual Studio define NDEBUG automatically in "Release Mode".
|
|
\li Or you can disable the checks on a case-by-case basis by using the coeff() and coeffRef() methods: see DenseBase::coeff(int,int) const, DenseBase::coeffRef(int,int), etc.
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreMatrixInitialization Matrix and vector creation and initialization
|
|
|
|
\subsection TutorialCtors Matrix constructors
|
|
|
|
The default constructor leaves coefficients uninitialized. Any dynamic size is set to 0, in which case the matrix/vector is considered uninitialized (no array is allocated).
|
|
|
|
\code
|
|
Matrix3f A; // construct 3x3 matrix with uninitialized coefficients
|
|
A(0,0) = 5; // OK
|
|
MatrixXf B; // construct 0x0 matrix without allocating anything
|
|
B(0,0) = 5; // Error, B is uninitialized, doesn't have any coefficients to address
|
|
\endcode
|
|
|
|
In the above example, B is an uninitialized matrix. What to do with such a matrix? You can call resize() on it, or you can assign another matrix to it. Like this:
|
|
|
|
\code
|
|
MatrixXf B; // uninitialized matrix
|
|
B.resize(3,5); // OK, now B is a 3x5 matrix with uninitialized coefficients
|
|
B(0,0) = 5; // OK
|
|
MatrixXf C; // uninitialized matrix
|
|
C = B; // OK, C is initialized as a copy of B
|
|
\endcode
|
|
|
|
There also are constructors taking size parameters, allowing to directly initialize dynamic-size matrices:
|
|
|
|
\code
|
|
MatrixXf B(3,5); // B is a 3x5 matrix with uninitialized coefficients
|
|
\endcode
|
|
|
|
Note that even if one of the dimensions is known at compile time, you must specify it. The only exception is vectors (i.e. matrices where one of the dimensions is known at compile time to be 1).
|
|
|
|
\code
|
|
VectorXf v(10); // OK, v is a vector of size 10 with uninitialized coefficients
|
|
Matrix<float,2,Dynamic> m(10); // Error: m is not a vector, must provide explicitly the 2 sizes
|
|
Matrix<float,2,Dynamic> m(2,10); // OK
|
|
Matrix2f m(2,2); // OK. Of course it's redundant to pass the parameters here, but it's allowed.
|
|
\endcode
|
|
|
|
For small fixed-size vectors, we also allow constructors passing the coefficients:
|
|
\code
|
|
Vector2f u(1.2f, 3.4f);
|
|
Vector3f v(1.2f, 3.4f, 5.6f);
|
|
Vector4f w(1.2f, 3.4f, 5.6f, 7.8f);
|
|
\endcode
|
|
|
|
\subsection TutorialPredefMat Predefined Matrices
|
|
Eigen offers several static methods to create special matrix expressions, and non-static methods to assign these expressions to existing matrices.
|
|
The following are
|
|
|
|
<table class="tutorial_code">
|
|
<tr>
|
|
<td>Fixed-size matrix or vector</td>
|
|
<td>Dynamic-size matrix</td>
|
|
<td>Dynamic-size vector</td>
|
|
</tr>
|
|
<tr style="border-bottom-style: none;">
|
|
<td>
|
|
\code
|
|
typedef {Matrix3f|Array33f} FixedXD;
|
|
FixedXD x;
|
|
|
|
x = FixedXD::Zero();
|
|
x = FixedXD::Ones();
|
|
x = FixedXD::Constant(value);
|
|
x = FixedXD::Identity();
|
|
x = FixedXD::Random();
|
|
|
|
x.setZero();
|
|
x.setOnes();
|
|
x.setIdentity();
|
|
x.setConstant(value);
|
|
x.setRandom();
|
|
\endcode
|
|
</td>
|
|
<td>
|
|
\code
|
|
typedef {MatrixXf|ArrayXXf} Dynamic2D;
|
|
Dynamic2D x;
|
|
|
|
x = Dynamic2D::Zero(rows, cols);
|
|
x = Dynamic2D::Ones(rows, cols);
|
|
x = Dynamic2D::Constant(rows, cols, value);
|
|
x = Dynamic2D::Identity(rows, cols);
|
|
x = Dynamic2D::Random(rows, cols);
|
|
|
|
x.setZero(rows, cols);
|
|
x.setOnes(rows, cols);
|
|
x.setConstant(rows, cols, value);
|
|
x.setIdentity(rows, cols);
|
|
x.setRandom(rows, cols);
|
|
\endcode
|
|
</td>
|
|
<td>
|
|
\code
|
|
typedef {VectorXf|ArrayXf} Dynamic1D;
|
|
Dynamic1D x;
|
|
|
|
x = Dynamic1D::Zero(size);
|
|
x = Dynamic1D::Ones(size);
|
|
x = Dynamic1D::Constant(size, value);
|
|
x = Dynamic1D::Identity(size);
|
|
x = Dynamic1D::Random(size);
|
|
|
|
x.setZero(size);
|
|
x.setOnes(size);
|
|
x.setConstant(size, value);
|
|
N/A
|
|
x.setRandom(size);
|
|
\endcode
|
|
</td>
|
|
</tr>
|
|
<tr style="border-top-style: none;"><td colspan="3">\redstar the Random() and setRandom() functions require the inclusion of the Array module (\c \#include \c <Eigen/Array>)</td></tr>
|
|
|
|
<tr><td colspan="3">The following are for matrix only: \matrixworld</td></tr>
|
|
<tr style="border-bottom-style: none;">
|
|
<td>
|
|
\code
|
|
x = FixedXD::Identity();
|
|
x.setIdentity();
|
|
\endcode
|
|
</td>
|
|
<td>
|
|
\code
|
|
x = Dynamic2D::Identity(rows, cols);
|
|
x.setIdentity(rows, cols);
|
|
\endcode
|
|
</td>
|
|
<td>
|
|
</td>
|
|
</tr>
|
|
<tr><td colspan="3">Basis vectors \matrixworld \link MatrixBase::Unit [details]\endlink</td></tr>
|
|
<tr><td>\code
|
|
Vector3f::UnitX() // 1 0 0
|
|
Vector3f::UnitY() // 0 1 0
|
|
Vector3f::UnitZ() // 0 0 1
|
|
\endcode</td><td></td><td>\code
|
|
VectorXf::Unit(size,i)
|
|
VectorXf::Unit(4,1) == Vector4f(0,1,0,0)
|
|
== Vector4f::UnitY()
|
|
\endcode
|
|
</table>
|
|
|
|
Here is an usage example:
|
|
<table class="tutorial_code"><tr><td>
|
|
\code
|
|
cout << MatrixXf::Constant(2, 3, sqrt(2)) << endl;
|
|
RowVector3i v;
|
|
v.setConstant(6);
|
|
cout << "v = " << v << endl;
|
|
\endcode
|
|
</td>
|
|
<td>
|
|
output:
|
|
\code
|
|
1.41 1.41 1.41
|
|
1.41 1.41 1.41
|
|
|
|
v = 6 6 6
|
|
\endcode
|
|
</td></tr></table>
|
|
|
|
|
|
\subsection TutorialCasting Casting
|
|
|
|
In Eigen, any matrices of same size and same scalar type are all naturally compatible. The scalar type can be explicitly casted to another one using the template DenseBase::cast() function:
|
|
\code
|
|
Matrix3d md(1,2,3);
|
|
Matrix3f mf = md.cast<float>();
|
|
\endcode
|
|
Note that casting to the same scalar type in an expression is free.
|
|
|
|
The destination matrix is automatically resized in any assignment:
|
|
\code
|
|
MatrixXf res(10,10);
|
|
Matrix3f a, b;
|
|
res = a+b; // OK: res is resized to size 3x3
|
|
\endcode
|
|
Of course, fixed-size matrices can't be resized.
|
|
|
|
An array object or expression can be directly assigned to a matrix, and vice versa:
|
|
\code
|
|
Matrix4f res;
|
|
Array44f a, b;
|
|
res = a * b;
|
|
\endcode
|
|
On the other hand, an array and a matrix expressions cannot be mixed in an expression, and one have to be converted to the other using the MatrixBase::array() \matrixworld and ArrayBase::matrix() \arrayworld functions respectively:
|
|
\code
|
|
Matrix4f m1, m2;
|
|
Array44f a1, a2;
|
|
m2 = a1 * m1.array(); // coeffwise product
|
|
a2 = a1.matrix() * m1; // matrix product
|
|
\endcode
|
|
Finally it is possible to declare a variable wrapping a matrix as an array object and vice versa:
|
|
\code
|
|
MatrixXf m1;
|
|
ArrayWrapper<MatrixXf> a1(m1); // a1 and m1 share the same coefficients
|
|
// now you can use a1 as an alias for m1.array()
|
|
ArrayXXf a2;
|
|
MatrixWrapper<ArrayXXf> m2(a1); // a2 and m2 share the same coefficients
|
|
// ...
|
|
\endcode
|
|
|
|
\subsection TutorialMap Map
|
|
Any memory buffer can be mapped as an Eigen expression using the Map() static method:
|
|
\code
|
|
std::vector<float> stlarray(10);
|
|
VectorXf::Map(&stlarray[0], stlarray.size()).squaredNorm();
|
|
\endcode
|
|
Here VectorXf::Map returns an object of class Map<VectorXf>, which behaves like a VectorXf except that it uses the existing array. You can write to this object, that will write to the existing array. You can also construct a named obtect to reuse it:
|
|
\code
|
|
float data[rows*cols];
|
|
Map<MatrixXf> m(data,rows,cols);
|
|
m = othermatrix1 * othermatrix2;
|
|
m.eigenvalues();
|
|
\endcode
|
|
In the fixed-size case, no need to pass sizes:
|
|
\code
|
|
float data[9];
|
|
Map<Matrix3d> m(data);
|
|
Matrix3d::Map(data).setIdentity();
|
|
\endcode
|
|
|
|
|
|
\subsection TutorialCommaInit Comma initializer
|
|
Eigen also offers a \ref MatrixBaseCommaInitRef "comma initializer syntax" which allows you to set all the coefficients of any dense objects (matrix, vector, array, block, etc.) to specific values:
|
|
<table class="tutorial_code"><tr><td>
|
|
\include Tutorial_commainit_01.cpp
|
|
</td>
|
|
<td>
|
|
output:
|
|
\verbinclude Tutorial_commainit_01.out
|
|
</td></tr></table>
|
|
|
|
Not excited by the above example? Then look at the following one where the matrix is set by blocks:
|
|
<table class="tutorial_code"><tr><td>
|
|
\include Tutorial_commainit_02.cpp
|
|
</td>
|
|
<td>
|
|
output:
|
|
\verbinclude Tutorial_commainit_02.out
|
|
</td></tr></table>
|
|
|
|
<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>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreArithmeticOperators Arithmetic Operators
|
|
|
|
In short, all arithmetic operators can be used right away as in the following example. Note however that for matrices and vectors arithmetic operators are only given their usual meaning from mathematics tradition while all array operators are performed coefficient wise.
|
|
|
|
Here is an example demonstrating basic arithmetic operators:
|
|
\code
|
|
mat4 -= mat1*1.5 + mat2 * (mat3/4);
|
|
\endcode
|
|
which includes two matrix scalar products ("mat1*1.5" and "mat3/4"), a matrix-matrix product ("mat2 * (mat3/4)"),
|
|
a matrix addition ("+") and subtraction with assignment ("-=").
|
|
|
|
<table class="tutorial_code">
|
|
<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</td><td>\code
|
|
mat3 = mat1 * s1; mat3 = s1 * mat1; mat3 *= s1;
|
|
mat3 = mat1 / s1; mat3 /= s1;\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Other coefficient wise operators</td><td>\code
|
|
mat1.cwiseProduct(mat2); mat1.cwiseQuotient(mat2);
|
|
mat1.cwiseMin(mat2); mat1.cwiseMax(mat2);
|
|
mat1.cwiseAbs2(); mat1.cwiseSqrt();
|
|
mat1.cwiseAbs();\endcode
|
|
</td></tr>
|
|
</table>
|
|
|
|
In addition to the above operators, array objects supports all kind of coefficient wise operators which usually apply to scalar values. Recall that those operators can be used on matrices by converting them to arrays using the array() function (see \ref TutorialCasting Casting).
|
|
<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>
|
|
|
|
So far, we saw the notation \code mat1*mat2 \endcode for matrix product, and \code array1*array2 \endcode for coefficient-wise product. What about other kinds of products, which in some other libraries also use arithmetic operators? In Eigen, they are accessed as follows -- note that here we are anticipating on further sections, for convenience.
|
|
<table class="tutorial_code">
|
|
<tr><td>\link MatrixBase::dot() dot product \endlink (inner product) \matrixworld</td><td>\code
|
|
scalar = vec1.dot(vec2);\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
outer product \matrixworld</td><td>\code
|
|
mat = vec1 * vec2.transpose();\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
\link MatrixBase::cross() cross product \endlink \matrixworld</td><td>\code
|
|
#include <Eigen/Geometry>
|
|
vec3 = vec1.cross(vec2);\endcode</td></tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreReductions Reductions
|
|
|
|
Eigen provides several reduction methods such as:
|
|
\link DenseBase::minCoeff() minCoeff() \endlink, \link DenseBase::maxCoeff() maxCoeff() \endlink,
|
|
\link DenseBase::sum() sum() \endlink, \link MatrixBase::trace() trace() \endlink \matrixworld,
|
|
\link MatrixBase::norm() norm() \endlink \matrixworld, \link MatrixBase::squaredNorm() squaredNorm() \endlink \matrixworld,
|
|
\link DenseBase::all() all() \endlink \redstar,and \link DenseBase::any() any() \endlink \redstar.
|
|
All reduction operations can be done matrix-wise,
|
|
\link DenseBase::colwise() column-wise \endlink \redstar or
|
|
\link DenseBase::rowwise() row-wise \endlink \redstar. Usage example:
|
|
<table class="tutorial_code">
|
|
<tr><td rowspan="3" style="border-right-style:dashed">\code
|
|
5 3 1
|
|
mat = 2 7 8
|
|
9 4 6 \endcode
|
|
</td> <td>\code mat.minCoeff(); \endcode</td><td>\code 1 \endcode</td></tr>
|
|
<tr><td>\code mat.colwise().minCoeff(); \endcode</td><td>\code 2 3 1 \endcode</td></tr>
|
|
<tr><td>\code mat.rowwise().minCoeff(); \endcode</td><td>\code
|
|
1
|
|
2
|
|
4
|
|
\endcode</td></tr>
|
|
</table>
|
|
|
|
Also note that maxCoeff and minCoeff can takes optional arguments returning the coordinates of the respective min/max coeff: \link DenseBase::maxCoeff(int*,int*) const maxCoeff(int* i, int* j) \endlink, \link DenseBase::minCoeff(int*,int*) const minCoeff(int* i, int* j) \endlink.
|
|
|
|
<span class="note">\b Side \b note: The all() and any() functions are especially useful in combination with coeff-wise comparison operators.</span>
|
|
|
|
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>\section TutorialCoreMatrixBlocks Matrix blocks
|
|
|
|
Read-write access to a \link DenseBase::col(int) column \endlink
|
|
or a \link DenseBase::row(int) row \endlink of a matrix (or array):
|
|
\code
|
|
mat1.row(i) = mat2.col(j);
|
|
mat1.col(j1).swap(mat1.col(j2));
|
|
\endcode
|
|
|
|
Read-write access to sub-vectors:
|
|
<table class="tutorial_code">
|
|
<tr>
|
|
<td>Default versions</td>
|
|
<td>Optimized versions when the size \n is known at compile time</td></tr>
|
|
<td></td>
|
|
|
|
<tr><td>\code vec1.head(n)\endcode</td><td>\code vec1.head<n>()\endcode</td><td>the first \c n coeffs </td></tr>
|
|
<tr><td>\code vec1.tail(n)\endcode</td><td>\code vec1.tail<n>()\endcode</td><td>the last \c n coeffs </td></tr>
|
|
<tr><td>\code vec1.segment(pos,n)\endcode</td><td>\code vec1.segment<n>(pos)\endcode</td>
|
|
<td>the \c size coeffs in \n the range [\c pos : \c pos + \c n [</td></tr>
|
|
<tr style="border-style: dashed none dashed none;"><td>
|
|
|
|
Read-write access to sub-matrices:</td><td></td><td></td></tr>
|
|
<tr>
|
|
<td>\code mat1.block(i,j,rows,cols)\endcode
|
|
\link DenseBase::block(int,int,int,int) (more) \endlink</td>
|
|
<td>\code mat1.block<rows,cols>(i,j)\endcode
|
|
\link DenseBase::block(int,int) (more) \endlink</td>
|
|
<td>the \c rows x \c cols sub-matrix \n starting from position (\c i,\c j)</td></tr><tr>
|
|
<td>\code
|
|
mat1.corner(TopLeft,rows,cols)
|
|
mat1.corner(TopRight,rows,cols)
|
|
mat1.corner(BottomLeft,rows,cols)
|
|
mat1.corner(BottomRight,rows,cols)\endcode
|
|
\link DenseBase::corner(CornerType,int,int) (more) \endlink</td>
|
|
<td>\code
|
|
mat1.corner<rows,cols>(TopLeft)
|
|
mat1.corner<rows,cols>(TopRight)
|
|
mat1.corner<rows,cols>(BottomLeft)
|
|
mat1.corner<rows,cols>(BottomRight)\endcode
|
|
\link DenseBase::corner(CornerType) (more) \endlink</td>
|
|
<td>the \c rows x \c cols sub-matrix \n taken in one of the four corners</td></tr>
|
|
<tr><td>\code
|
|
mat4x4.minor(i,j) = mat3x3;
|
|
mat3x3 = mat4x4.minor(i,j);\endcode
|
|
</td><td></td><td>
|
|
\link DenseBase::minor() minor \endlink (read-write)</td>
|
|
</tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>\section TutorialCoreDiagonalMatrices Diagonal matrices \matrixworld
|
|
|
|
<table class="tutorial_code">
|
|
<tr><td>
|
|
\link MatrixBase::asDiagonal() make a diagonal matrix \endlink from a vector \n
|
|
<em class="note">this product is automatically optimized !</em></td><td>\code
|
|
mat3 = mat1 * vec2.asDiagonal();\endcode
|
|
</td></tr>
|
|
<tr><td>Access \link MatrixBase::diagonal() the diagonal of a matrix \endlink as a vector (read/write)</td>
|
|
<td>\code
|
|
vec1 = mat1.diagonal();
|
|
mat1.diagonal() = vec1;
|
|
\endcode
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreTransposeAdjoint Transpose and Adjoint operations
|
|
|
|
<table class="tutorial_code">
|
|
<tr><td>
|
|
\link DenseBase::transpose() transposition \endlink (read-write)</td><td>\code
|
|
mat3 = mat1.transpose() * mat2;
|
|
mat3.transpose() = mat1 * mat2.transpose();
|
|
\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
\link MatrixBase::adjoint() adjoint \endlink (read only) \matrixworld\n</td><td>\code
|
|
mat3 = mat1.adjoint() * mat2;
|
|
\endcode
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreDotNorm Dot-product, vector norm, normalization \matrixworld
|
|
|
|
<table class="tutorial_code">
|
|
<tr><td>
|
|
\link MatrixBase::dot() Dot-product \endlink of two vectors
|
|
</td><td>\code vec1.dot(vec2);\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
\link MatrixBase::norm() norm \endlink of a vector \n
|
|
\link MatrixBase::squaredNorm() squared norm \endlink of a vector
|
|
</td><td>\code vec.norm(); \endcode \n \code vec.squaredNorm() \endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
returns a \link MatrixBase::normalized() normalized \endlink vector \n
|
|
\link MatrixBase::normalize() normalize \endlink a vector
|
|
</td><td>\code
|
|
vec3 = vec1.normalized();
|
|
vec1.normalize();\endcode
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreTriangularMatrix Dealing with triangular matrices \matrixworld
|
|
|
|
Currently, Eigen does not provide any explicit triangular matrix, with storage class. Instead, we
|
|
can reference a triangular part of a square matrix or expression to perform special treatment on it.
|
|
This is achieved by the class TriangularView and the MatrixBase::triangularView template function.
|
|
Note that the opposite triangular part of the matrix is never referenced, and so it can, e.g., store
|
|
a second triangular matrix.
|
|
|
|
<table class="tutorial_code">
|
|
<tr><td>
|
|
Reference a read/write triangular part of a given \n
|
|
matrix (or expression) m with optional unit diagonal:
|
|
</td><td>\code
|
|
m.triangularView<Eigen::UpperTriangular>()
|
|
m.triangularView<Eigen::UnitUpperTriangular>()
|
|
m.triangularView<Eigen::LowerTriangular>()
|
|
m.triangularView<Eigen::UnitLowerTriangular>()\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Writing to a specific triangular part:\n (only the referenced triangular part is evaluated)
|
|
</td><td>\code
|
|
m1.triangularView<Eigen::LowerTriangular>() = m2 + m3 \endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Conversion to a dense matrix setting the opposite triangular part to zero:
|
|
</td><td>\code
|
|
m2 = m1.triangularView<Eigen::UnitUpperTriangular>()\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Products:
|
|
</td><td>\code
|
|
m3 += s1 * m1.adjoint().triangularView<Eigen::UnitUpperTriangular>() * m2
|
|
m3 -= s1 * m2.conjugate() * m1.adjoint().triangularView<Eigen::LowerTriangular>() \endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Solving linear equations:\n(\f$ m_2 := m_1^{-1} m_2 \f$)
|
|
</td><td>\code
|
|
m1.triangularView<Eigen::UnitLowerTriangular>().solveInPlace(m2)
|
|
m1.adjoint().triangularView<Eigen::UpperTriangular>().solveInPlace(m2)\endcode
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreSelfadjointMatrix Dealing with symmetric/selfadjoint matrices \matrixworld
|
|
|
|
Just as for triangular matrix, you can reference any triangular part of a square matrix to see it a selfadjoint
|
|
matrix to perform special and optimized operations. Again the opposite triangular is never referenced and can be
|
|
used to store other information.
|
|
|
|
<table class="tutorial_code">
|
|
<tr><td>
|
|
Conversion to a dense matrix:
|
|
</td><td>\code
|
|
m2 = m.selfadjointView<Eigen::LowerTriangular>();\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Product with another general matrix or vector:
|
|
</td><td>\code
|
|
m3 = s1 * m1.conjugate().selfadjointView<Eigen::UpperTriangular>() * m3;
|
|
m3 -= s1 * m3.adjoint() * m1.selfadjointView<Eigen::UpperTriangular>();\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Rank 1 and rank K update:
|
|
</td><td>\code
|
|
// fast version of m1 += s1 * m2 * m2.adjoint():
|
|
m1.selfadjointView<Eigen::UpperTriangular>().rankUpdate(m2,s1);
|
|
// fast version of m1 -= m2.adjoint() * m2:
|
|
m1.selfadjointView<Eigen::LowerTriangular>().rankUpdate(m2.adjoint(),-1); \endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Rank 2 update: (\f$ m += s u v^* + s v u^* \f$)
|
|
</td><td>\code
|
|
m.selfadjointView<Eigen::UpperTriangular>().rankUpdate(u,v,s);
|
|
\endcode
|
|
</td></tr>
|
|
<tr><td>
|
|
Solving linear equations:\n(\f$ m_2 := m_1^{-1} m_2 \f$)
|
|
</td><td>\code
|
|
// via a standard Cholesky factorization
|
|
m1.selfadjointView<Eigen::UpperTriangular>().llt().solveInPlace(m2);
|
|
// via a Cholesky factorization with pivoting
|
|
m1.selfadjointView<Eigen::UpperTriangular>().ldlt().solveInPlace(m2);
|
|
\endcode
|
|
</td></tr>
|
|
</table>
|
|
|
|
|
|
<a href="#" class="top">top</a>
|
|
\section TutorialCoreSpecialTopics Special Topics
|
|
|
|
\ref TopicLazyEvaluation "Lazy Evaluation and Aliasing": Thanks to expression templates, Eigen is able to apply lazy evaluation wherever that is beneficial.
|
|
|
|
*/
|
|
|
|
}
|