This commit is contained in:
Gael Guennebaud 2010-07-14 22:51:53 +02:00
commit b6fac91998
20 changed files with 288 additions and 356 deletions

View File

@ -132,13 +132,15 @@ Vector4d c(5.0, 6.0, 7.0, 8.0);
The primary coefficient accessors and mutators in Eigen are the overloaded parenthesis operators.
For matrices, the row index is always passed first. For vectors, just pass one index.
The numbering starts at 0. This example is self-explanatory:
\include tut_matrix_coefficient_accessors.cpp
Output: \verbinclude tut_matrix_coefficient_accessors.out
Note that the syntax
\code
m(index)
\endcode
<table class="tutorial_code"><tr><td>
Example: \include tut_matrix_coefficient_accessors.cpp
</td>
<td>
Output: \verbinclude tut_matrix_coefficient_accessors.out
</td></tr></table>
Note that the syntax <tt> m(index) </tt>
is not restricted to vectors, it is also available for general matrices, meaning index-based access
in the array of coefficients. This however depends on the matrix's storage order. All Eigen matrices default to
column-major storage order, but this can be changed to row-major, see \ref TopicStorageOrders "Storage orders".
@ -149,17 +151,29 @@ would make matrix[i,j] compile to the same thing as matrix[j] !
\section TutorialMatrixCommaInitializer Comma-initialization
Matrix and vector coefficients can be conveniently set using the so-called \em comma-initializer syntax.
%Matrix and vector coefficients can be conveniently set using the so-called \em comma-initializer syntax.
For now, it is enough to know this example:
\include Tutorial_commainit_01.cpp
<table class="tutorial_code"><tr><td>
Example: \include Tutorial_commainit_01.cpp
</td>
<td>
Output: \verbinclude Tutorial_commainit_01.out
</td></tr></table>
The right-hand side can also contain matrix expressions as discussed in \ref TutorialAdvancedInitialization "this page".
\section TutorialMatrixSizesResizing Resizing
The current size of a matrix can be retrieved by \link EigenBase::rows() rows()\endlink, \link EigenBase::cols() cols() \endlink and \link EigenBase::size() size()\endlink. These methods return the number of rows, the number of columns and the number of coefficients, respectively. Resizing a dynamic-size matrix is done by the \link DenseStorageBase::resize(Index,Index) resize() \endlink method.
For example: \include tut_matrix_resize.cpp
<table class="tutorial_code"><tr><td>
Example: \include tut_matrix_resize.cpp
</td>
<td>
Output: \verbinclude tut_matrix_resize.out
</td></tr></table>
The resize() method is a no-operation if the actual matrix size doesn't change; otherwise it is destructive: the values of the coefficients may change.
If you want a conservative variant of resize() which does not change the coefficients, use \link DenseStorageBase::conservativeResize() conservativeResize()\endlink, see \ref TopicResizing "this page" for more details.
@ -167,14 +181,25 @@ If you want a conservative variant of resize() which does not change the coeffic
All these methods are still available on fixed-size matrices, for the sake of API uniformity. Of course, you can't actually
resize a fixed-size matrix. Trying to change a fixed size to an actually different value will trigger an assertion failure;
but the following code is legal:
\include tut_matrix_resize_fixed_size.cpp
<table class="tutorial_code"><tr><td>
Example: \include tut_matrix_resize_fixed_size.cpp
</td>
<td>
Output: \verbinclude tut_matrix_resize_fixed_size.out
</td></tr></table>
\section TutorialMatrixAssignment Assignment and resizing
Assignment is the action of copying a matrix into another, using \c operator=. Eigen resizes the matrix on the left-hand side automatically so that it matches the size of the matrix on the right-hand size. For example:
\include tut_matrix_assignment_resizing.cpp
<table class="tutorial_code"><tr><td>
Example: \include tut_matrix_assignment_resizing.cpp
</td>
<td>
Output: \verbinclude tut_matrix_assignment_resizing.out
</td></tr></table>
Of course, if the left-hand side is of fixed size, resizing it is not allowed.

View File

@ -43,7 +43,7 @@ also have the same \c Scalar type, as Eigen doesn't do automatic type promotion.
Example: \include tut_arithmetic_add_sub.cpp
</td>
<td>
Output: \include tut_arithmetic_add_sub.out
Output: \verbinclude tut_arithmetic_add_sub.out
</td></tr></table>
\section TutorialArithmeticScalarMulDiv Scalar multiplication and division
@ -59,7 +59,7 @@ Multiplication and division by a scalar is very simple too. The operators at han
Example: \include tut_arithmetic_scalar_mul_div.cpp
</td>
<td>
Output: \include tut_arithmetic_scalar_mul_div.out
Output: \verbinclude tut_arithmetic_scalar_mul_div.out
</td></tr></table>
@ -93,7 +93,7 @@ The transpose \f$ a^T \f$, conjugate \f$ \bar{a} \f$, and adjoint (i.e., conjuga
Example: \include tut_arithmetic_transpose_conjugate.cpp
</td>
<td>
Output: \include tut_arithmetic_transpose_conjugate.out
Output: \verbinclude tut_arithmetic_transpose_conjugate.out
</td></tr></table>
For real matrices, \c conjugate() is a no-operation, and so \c adjoint() is 100% equivalent to \c transpose().
@ -103,7 +103,7 @@ As for basic arithmetic operators, \c transpose() and \c adjoint() simply return
Example: \include tut_arithmetic_transpose_aliasing.cpp
</td>
<td>
Output: \include tut_arithmetic_transpose_aliasing.out
Output: \verbinclude tut_arithmetic_transpose_aliasing.out
</td></tr></table>
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.
@ -112,7 +112,7 @@ For \em in-place transposition, as for instance in <tt>a = a.transpose()</tt>, s
Example: \include tut_arithmetic_transpose_inplace.cpp
</td>
<td>
Output: \include tut_arithmetic_transpose_inplace.out
Output: \verbinclude tut_arithmetic_transpose_inplace.out
</td></tr></table>
There is also the \link MatrixBase::adjointInPlace() adjointInPlace()\endlink function for complex matrices.
@ -129,7 +129,7 @@ two operators:
Example: \include tut_arithmetic_matrix_mul.cpp
</td>
<td>
Output: \include tut_arithmetic_matrix_mul.out
Output: \verbinclude 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
@ -154,7 +154,7 @@ The above-discussed \c operator* cannot be used to compute dot and cross product
Example: \include tut_arithmetic_dot_cross.cpp
</td>
<td>
Output: \include tut_arithmetic_dot_cross.out
Output: \verbinclude 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.
@ -168,7 +168,7 @@ Eigen also provides some reduction operations to reduce a given matrix or vector
Example: \include tut_arithmetic_redux_basic.cpp
</td>
<td>
Output: \include tut_arithmetic_redux_basic.out
Output: \verbinclude tut_arithmetic_redux_basic.out
</td></tr></table>
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.
@ -179,7 +179,7 @@ There also exist variants of the \c minCoeff and \c maxCoeff functions returning
Example: \include tut_arithmetic_redux_minmax.cpp
</td>
<td>
Output: \include tut_arithmetic_redux_minmax.out
Output: \verbinclude tut_arithmetic_redux_minmax.out
</td></tr></table>

View File

@ -7,7 +7,7 @@ namespace Eigen {
\li \b Next: \ref TutorialBlockOperations
This tutorial aims to provide an overview and explanations on how to use
Eigen's \link ArrayBase Array \endlink class
Eigen's Array class.
\b Table \b of \b contents
- \ref TutorialArrayClassIntro
@ -15,6 +15,7 @@ Eigen's \link ArrayBase Array \endlink class
- \ref TutorialArrayClassAccess
- \ref TutorialArrayClassAddSub
- \ref TutorialArrayClassMult
- \ref TutorialArrayClassCwiseOther
- \ref TutorialArrayClassConvert
\section TutorialArrayClassIntro What is the Array class?
@ -27,17 +28,17 @@ such as adding a constant to every coefficient in the array or multiplying two a
\section TutorialArrayClassTypes Array types
Array is a class template taking the same template parameters as Matrix.
As with Matrix, the first 3 template parameters are mandatory:
As with Matrix, the first three template parameters are mandatory:
\code
Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>
\endcode
And the last 3 template parameters are optional. Since this is exactly the same as for Matrix,
we won't reexplain it and just refer to \ref TutorialMatrixClass "this page".
The last three template parameters are optional. Since this is exactly the same as for Matrix,
we won't explain it again here and just refer to \ref TutorialMatrixClass.
Eigen also provides typedefs for some common cases, in a way that is similar to the Matrix typedefs
but with some slight differences, as the word "array" is used for both 1-dimensional and 2-dimensional arrays.
We adopt that convention that typedefs of the form ArrayNt stand for 1-dimensional arrays, where N and t are
as in the Matrix typedefs explained on \ref TutorialMatrixClass "this page". For 2-dimensional arrays, we
the size and the scalar type, as in the Matrix typedefs explained on \ref TutorialMatrixClass "this page". For 2-dimensional arrays, we
use typedefs of the form ArrayNNt. Some examples are shown in the following table:
<table class="tutorial_code" align="center">
@ -71,69 +72,103 @@ use typedefs of the form ArrayNNt. Some examples are shown in the following tabl
\section TutorialArrayClassAccess Accessing values inside an Array
Write and read access to coefficients of an array expression is done in the same way as with matrix expressions.
For example:
\include Tutorial_ArrayClass_accessors.cpp
Output:
\verbinclude Tutorial_ArrayClass_accessors.out
The parenthesis operator is overloaded to provide write and read access to the coefficients of an array, just as with matrices.
Furthermore, the \c << operator can be used to initialize arrays (via the comma initializer) or to print them.
For more information about the comma initializer, refer to \ref TutorialAdvancedInitialization "this page".
<table class="tutorial_code"><tr><td>
Example: \include Tutorial_ArrayClass_accessors.cpp
</td>
<td>
Output: \verbinclude Tutorial_ArrayClass_accessors.out
</td></tr></table>
For more information about the comma initializer, see \ref TutorialAdvancedInitialization.
\section TutorialArrayClassAddSub Addition and substraction
\section TutorialArrayClassAddSub Addition and subtraction
Adding and subtracting two arrays is the same as for matrices.
The operation is valid if both arrays have the same size, and the addition or subtraction is done coefficient-wise.
Arrays also support expressions of the form <tt>array + scalar</tt> which add a scalar to each coefficient in the array.
This provides a functionality that is not directly available for Matrix objects.
<table class="tutorial_code"><tr><td>
Example: \include Tutorial_ArrayClass_addition.cpp
</td>
<td>
Output: \verbinclude Tutorial_ArrayClass_addition.out
</td></tr></table>
Adding and substracting two arrays has the same result as for Matrices.
This is valid as long as both arrays have the same sizes:
\include Tutorial_ArrayClass_addition.cpp
Output:
\verbinclude Tutorial_ArrayClass_addition.out
It is also allowed to add a scalar to each coefficient in an Array,
providing a functionality that was not available for Matrix objects:
\include Tutorial_ArrayClass_addition_scalar.cpp
Output:
\verbinclude Tutorial_ArrayClass_addition_scalar.out
\subsection TutorialArrayClassMult Array multiplication
\section TutorialArrayClassMult Array multiplication
First of all, of course you can multiply an array by a scalar, this works in the same way as matrices. Where arrays
are fundamentally different from matrices, is when you multiply two arrays together. While Matrices interprete
multiplication as matrix product, arrays interprete multiplication as coefficient-wise product. For example:
are fundamentally different from matrices, is when you multiply two together. Matrices interpret
multiplication as the matrix product and arrays interpret multiplication as the coefficient-wise product. Thus, two
arrays can be multiplied if they have the same size.
\include Tutorial_ArrayClass_mult.cpp
Output:
\verbinclude Tutorial_ArrayClass_mult.out
<table class="tutorial_code"><tr><td>
Example: \include Tutorial_ArrayClass_mult.cpp
</td>
<td>
Output: \verbinclude Tutorial_ArrayClass_mult.out
</td></tr></table>
\section TutorialArrayClassCwiseOther Other coefficient-wise operations
The Array class defined other coefficient-wise operations besides the addition, subtraction and multiplication
operators described about. For example, the \link ArrayBase::abs() .abs() \endlink method takes the absolute
value of each coefficient, while \link ArrayBase::sqrt() .sqrt() \endlink computes the square root of the
coefficients. If you have two arrays of the same size, you can call \link ArrayBase::min() .min() \endlink to
construct the array whose coefficients are the minimum of the corresponding coefficients of the two given
arrays. These operations are illustrated in the following example.
<table class="tutorial_code"><tr><td>
Example: \include Tutorial_ArrayClass_cwise_other.cpp
</td>
<td>
Output: \verbinclude Tutorial_ArrayClass_cwise_other.out
</td></tr></table>
More coefficient-wise operations can be found in the \ref QuickRefPage.
\section TutorialArrayClassConvert Converting between array and matrix expressions
It is possible to wrap a matrix expression as an array expression and conversely. This gives access to all operations
regardless of the choice of declaring objects as arrays or as matrices.
When should you use objects of the Matrix class and when should you use objects of the Array class? You cannot
apply Matrix operations on arrays, or Array operations on matrices. Thus, if you need to do linear algebraic
operations such as matrix multiplication, then you should use matrices; if you need to do coefficient-wise
operations, then you should use arrays. However, sometimes it is not that simple, but you need to use both
Matrix and Array operations. In that case, you need to convert a matrix to an array or reversely. This gives
access to all operations regardless of the choice of declaring objects as arrays or as matrices.
\link MatrixBase Matrix expressions \endlink have a \link MatrixBase::array() .array() \endlink method that
'converts' them into \link ArrayBase array expressions \endlink, so that coefficient-wise operations
\link MatrixBase Matrix expressions \endlink have an \link MatrixBase::array() .array() \endlink method that
'converts' them into \link ArrayBase array expressions\endlink, so that coefficient-wise operations
can be applied easily. Conversely, \link ArrayBase array expressions \endlink
have a \link ArrayBase::matrix() .matrix() \endlink method. As with all Eigen expression abstractions,
this doesn't have any runtime cost (provided that you let your compiler optimize).
Both \link MatrixBase::array() .array() \endlink and \link ArrayBase::matrix() .matrix() \endlink
can be used as rvalues and as lvalues.
Mixing matrices and arrays in an expression is forbidden with Eigen. However,
Mixing matrices and arrays in an expression is forbidden with Eigen. For instance, you cannot add a amtrix and
array directly; the operands of a \c + operator should either both be matrices or both be arrays. However,
it is easy to convert from one to the other with \link MatrixBase::array() .array() \endlink and
\link ArrayBase::matrix() .matrix() \endlink.
\link ArrayBase::matrix() .matrix()\endlink. The exception to this rule is the assignment operator: it is
allowed to assign a matrix expression to an array variable, or to assign an array expression to a matrix
variable.
On the other hand, assigning a matrix (resp. array) expression to an array (resp. matrix) expression is allowed.
The following example shows how to use array operations on a Matrix object by employing the
\link MatrixBase::array() .array() \endlink method. For example, the statement
<tt>result = m.array() * n.array()</tt> takes two matrices \c m and \c n, converts them both to an array, uses
* to multiply them coefficient-wise and assigns the result to the matrix variable \c result (this is legal
because Eigen allows assigning array expressions to matrix variables).
\subsection TutorialArrayClassInteropMatrix Matrix to array example
The following example shows how to use array operations on a Matrix object by employing
the \link MatrixBase::array() .array() \endlink method:
As a matter of fact, this usage case is so common that Eigen provides a \link MatrixBase::cwiseProduct()
.cwiseProduct() \endlink method for matrices to compute the coefficient-wise product. This is also shown in
the example program.
<table class="tutorial_code"><tr><td>
\include Tutorial_ArrayClass_interop_matrix.cpp
@ -143,21 +178,13 @@ Output:
\verbinclude Tutorial_ArrayClass_interop_matrix.out
</td></tr></table>
Similarly, if \c array1 and \c array2 are arrays, then the expression <tt>array1.matrix() * array2.matrix()</tt>
computes their matrix product.
\subsection TutorialArrayClassInteropArray Array to matrix example
The following example shows how to use matrix operations with an Array
object by employing the \link ArrayBase::matrix() .matrix() \endlink method:
<table class="tutorial_code"><tr><td>
\include Tutorial_ArrayClass_interop_array.cpp
</td>
<td>
Output:
\verbinclude Tutorial_ArrayClass_interop_array.out
</td></tr></table>
\subsection TutorialArrayClassInteropCombination Example with combinations of .array() and .matrix()
Here is a more advanced example:
Here is a more advanced example. The expression <tt>(m.array() + 4).matrix() * m</tt> adds 4 to every
coefficient in the matrix \c m and then computes the matrix product of the result with \c m. Similarly, the
expression <tt>(m.array() * n.array()).matrix() * m</tt> computes the coefficient-wise product of the matrices
\c m and \c n and then the matrix product of the result with \c m.
<table class="tutorial_code"><tr><td>
\include Tutorial_ArrayClass_interop.cpp

View File

@ -13,21 +13,22 @@ provided that you let your compiler optimize.
\b Table \b of \b contents
- \ref TutorialBlockOperationsUsing
- \ref TutorialBlockOperationsSyntax
- \ref TutorialBlockOperationsSyntaxColumnRows
- \ref TutorialBlockOperationsSyntaxCorners
- \ref TutorialBlockOperationsSyntaxColumnRows
- \ref TutorialBlockOperationsSyntaxCorners
- \ref TutorialBlockOperationsSyntaxVectors
\section TutorialBlockOperationsUsing Using block operations
The most general block operation in Eigen is called \link DenseBase::block() .block() \endlink.
This function returns a block of size <tt>(p,q)</tt> whose origin is at <tt>(i,j)</tt> by using
the following syntax:
This function returns a block of size <tt>(p,q)</tt> whose origin is at <tt>(i,j)</tt>.
There are two versions, whose syntax is as follows:
<table class="tutorial_code" align="center">
<tr><td align="center">\b Block \b operation</td>
<td align="center">Default \b version</td>
<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>
<tr><td>%Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>
<td>\code
matrix.block(i,j,p,q);\endcode </td>
<td>\code
@ -35,7 +36,15 @@ matrix.block<p,q>(i,j);\endcode </td>
</tr>
</table>
Therefore, if we want to print the values of a block inside a matrix we can simply write:
The default version is a method which takes four arguments. It can always be used. The optimized version
takes two template arguments (the size of the block) and two normal arguments (the position of the block).
It can only be used if the size of the block is known at compile time, but it may be faster than the
non-optimized version, especially if the size of the block is small. Both versions can be used on fixed-size
and dynamic-size matrices and arrays.
The following program uses the default and optimized versions to print the values of several blocks inside a
matrix.
<table class="tutorial_code"><tr><td>
\include Tutorial_BlockOperations_print_block.cpp
</td>
@ -44,10 +53,15 @@ Output:
\verbinclude Tutorial_BlockOperations_print_block.out
</td></tr></table>
In the above example the \link DenseBase::block() .block() \endlink function was employed
to read the values inside matrix \p m . However, blocks can also be used as lvalues, meaning that you can
assign to a block.
In the previous example the \link DenseBase::block() .block() \endlink function was employed
to read the values inside matrix \p m . Blocks can also be used to perform operations and
assignments within matrices or arrays of different size:
This is illustrated in the following example, which uses arrays instead of matrices. The coefficients of the
5-by-5 array \c n are first all set to 0.6, but then the 3-by-3 block in the middle is set to the values in
\c m . The penultimate line shows that blocks can be combined with matrices and arrays to create more complex
expressions. Blocks of an array are an array expression, and thus the multiplication here is coefficient-wise
multiplication.
<table class="tutorial_code"><tr><td>
\include Tutorial_BlockOperations_block_assignment.cpp
@ -57,55 +71,38 @@ Output:
\verbinclude Tutorial_BlockOperations_block_assignment.out
</td></tr></table>
The \link DenseBase::block() .block() \endlink method is used for general block operations, but there are
other methods for special cases. These are described in the rest of this page.
Blocks can also be combined with matrices and arrays to create more complex expressions:
\code
MatrixXf m(3,3), n(2,2);
MatrixXf p(3,3);
m.block(0,0,2,2) = m.block(0,0,2,2) * n + p.block(1,1,2,2);
\endcode
\section TutorialBlockOperationsSyntaxColumnRows Columns and rows
It is important to point out that \link DenseBase::block() .block() \endlink is the
general case for a block operation but there are many other useful block operations,
as described in the next section.
\section TutorialBlockOperationsSyntax Block operation syntax
The following tables show a summary of Eigen's block operations and how they are applied to
fixed- and dynamic-sized Eigen objects.
\subsection TutorialBlockOperationsSyntaxColumnRows Columns and rows
Other extremely useful block operations are \link DenseBase::col() .col() \endlink and
\link DenseBase::row() .row() \endlink which provide access to a
specific row or column. This is a special case in the sense that the syntax for fixed- and
dynamic-sized objects is exactly the same:
Individual columns and rows are special cases of blocks. Eigen provides methods to easily access them:
\link DenseBase::col() .col() \endlink and \link DenseBase::row() .row()\endlink. There is no syntax variant
for an optimized version.
<table class="tutorial_code" align="center">
<tr><td align="center">\b Block \b operation</td>
<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>i<sup>th</sup> row
\link DenseBase::row() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.row(i);\endcode </td>
matrix.row(i);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.row(i);\endcode </td>
matrix.row(i);\endcode </td>
</tr>
<tr><td>j<sup>th</sup> column
\link DenseBase::col() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.col(j);\endcode </td>
matrix.col(j);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.col(j);\endcode </td>
matrix.col(j);\endcode </td>
</tr>
</table>
A simple example demonstrating these feature follows:
The argument for \p col() and \p row() is the index of the column or row to be accessed, starting at
0. Therefore, \p col(0) will access the first column and \p col(1) the second one.
<table class="tutorial_code"><tr><td>
C++ code:
@ -113,94 +110,83 @@ C++ code:
</td>
<td>
Output:
\include Tutorial_BlockOperations_colrow.out
\verbinclude Tutorial_BlockOperations_colrow.out
</td></tr></table>
\b NOTE: the argument for \p col() and \p row() is the index of the column or row to be accessed,
starting at 0. Therefore, \p col(0) will access the first column and \p col(1) the second one.
\section TutorialBlockOperationsSyntaxCorners Corner-related operations
Eigen also provides special methods for blocks that are flushed against one of the corners or sides of a
matrix or array. For instance, \link DenseBase::topLeftCorner() .topLeftCorner() \endlink can be used to refer
to a block in the top-left corner of a matrix. Use <tt>matrix.topLeftCorner(p,q)</tt> to access the block
consisting of the coefficients <tt>matrix(i,j)</tt> with \c i &lt; \c p and \c j &lt; \c q. As an other
example, blocks consisting of whole rows flushed against the top side of the matrix can be accessed by
\link DenseBase::topRows() .topRows() \endlink.
The different possibilities are summarized in the following table:
\subsection TutorialBlockOperationsSyntaxCorners Corner-related operations
<table class="tutorial_code" align="center">
<tr><td align="center">\b Block \b operation</td>
<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>Top-left p by q block \link DenseBase::topLeftCorner() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.topLeftCorner(p,q);\endcode </td>
matrix.topLeftCorner(p,q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.topLeftCorner<p,q>();\endcode </td>
matrix.topLeftCorner<p,q>();\endcode </td>
</tr>
<tr><td>Bottom-left p by q block
\link DenseBase::bottomLeftCorner() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.bottomLeftCorner(p,q);\endcode </td>
matrix.bottomLeftCorner(p,q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.bottomLeftCorner<p,q>();\endcode </td>
matrix.bottomLeftCorner<p,q>();\endcode </td>
</tr>
<tr><td>Top-right p by q block
\link DenseBase::topRightCorner() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.topRightCorner(p,q);\endcode </td>
matrix.topRightCorner(p,q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.topRightCorner<p,q>();\endcode </td>
matrix.topRightCorner<p,q>();\endcode </td>
</tr>
<tr><td>Bottom-right p by q block
\link DenseBase::bottomRightCorner() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.bottomRightCorner(p,q);\endcode </td>
matrix.bottomRightCorner(p,q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.bottomRightCorner<p,q>();\endcode </td>
matrix.bottomRightCorner<p,q>();\endcode </td>
</tr>
<tr><td>Block containing the first q rows
<tr><td>%Block containing the first q rows
\link DenseBase::topRows() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.topRows(q);\endcode </td>
matrix.topRows(q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.topRows<q>();\endcode </td>
matrix.topRows<q>();\endcode </td>
</tr>
<tr><td>Block containing the last q rows
<tr><td>%Block containing the last q rows
\link DenseBase::bottomRows() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.bottomRows(q);\endcode </td>
matrix.bottomRows(q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.bottomRows<q>();\endcode </td>
matrix.bottomRows<q>();\endcode </td>
</tr>
<tr><td>Block containing the first p columns
<tr><td>%Block containing the first p columns
\link DenseBase::leftCols() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.leftCols(p);\endcode </td>
matrix.leftCols(p);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.leftCols<p>();\endcode </td>
matrix.leftCols<p>();\endcode </td>
</tr>
<tr><td>Block containing the last q columns
<tr><td>%Block containing the last q columns
\link DenseBase::rightCols() * \endlink</td>
<td>\code
MatrixXf m;
std::cout << m.rightCols(q);\endcode </td>
matrix.rightCols(q);\endcode </td>
<td>\code
Matrix3f m;
std::cout << m.rightCols<q>();\endcode </td>
matrix.rightCols<q>();\endcode </td>
</tr>
</table>
Here is a simple example showing the power of the operations presented above:
Here is a simple example illustrating the use of the operations presented above:
<table class="tutorial_code"><tr><td>
C++ code:
@ -208,49 +194,38 @@ C++ code:
</td>
<td>
Output:
\include Tutorial_BlockOperations_corner.out
\verbinclude Tutorial_BlockOperations_corner.out
</td></tr></table>
\section TutorialBlockOperationsSyntaxVectors Block operations for vectors
\subsection TutorialBlockOperationsSyntaxVectors Block operations for vectors
Eigen also provides a set of block operations designed specifically for vectors:
Eigen also provides a set of block operations designed specifically for vectors and one-dimensional arrays:
<table class="tutorial_code" align="center">
<tr><td align="center">\b Block \b operation</td>
<tr><td align="center">\b %Block \b operation</td>
<td align="center">Default version</td>
<td align="center">Optimized version when the<br>size is known at compile time</td></tr>
<tr><td>Block containing the first \p n elements
<tr><td>%Block containing the first \p n elements
\link DenseBase::head() * \endlink</td>
<td>\code
VectorXf v;
std::cout << v.head(n);\endcode </td>
vector.head(n);\endcode </td>
<td>\code
Vector3f v;
std::cout << v.head<n>();\endcode </td>
vector.head<n>();\endcode </td>
</tr>
<tr><td>Block containing the last \p n elements
<tr><td>%Block containing the last \p n elements
\link DenseBase::tail() * \endlink</td>
<td>\code
VectorXf v;
std::cout << v.tail(n);\endcode </td>
vector.tail(n);\endcode </td>
<td>\code
Vector3f m;
std::cout << v.tail<n>();\endcode </td>
vector.tail<n>();\endcode </td>
</tr>
<tr><td>Block containing \p n elements, starting at position \p i
<tr><td>%Block containing \p n elements, starting at position \p i
\link DenseBase::segment() * \endlink</td>
<td>\code
VectorXf v;
std::cout << v.segment(i,n);\endcode </td>
vector.segment(i,n);\endcode </td>
<td>\code
Vector3f m;
std::cout << v.segment<n>(i);\endcode </td>
vector.segment<n>(i);\endcode </td>
</tr>
</table>
@ -262,7 +237,7 @@ C++ code:
</td>
<td>
Output:
\include Tutorial_BlockOperations_vector.out
\verbinclude Tutorial_BlockOperations_vector.out
</td></tr></table>
\li \b Next: \ref TutorialAdvancedInitialization

View File

@ -30,7 +30,7 @@ which returns the addition of all the coefficients inside a given matrix or arra
Example: \include tut_arithmetic_redux_basic.cpp
</td>
<td>
Output: \include tut_arithmetic_redux_basic.out
Output: \verbinclude 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.

View File

@ -1217,12 +1217,14 @@ PREDEFINED = EIGEN_EMPTY_STRUCT \
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
EXPAND_AS_DEFINED = EIGEN_MAKE_SCALAR_OPS \
EIGEN_MAKE_TYPEDEFS \
EXPAND_AS_DEFINED = EIGEN_MAKE_TYPEDEFS \
EIGEN_MAKE_FIXED_TYPEDEFS \
EIGEN_MAKE_TYPEDEFS_ALL_SIZES \
EIGEN_MAKE_CWISE_BINARY_OP \
EIGEN_CWISE_UNOP_RETURN_TYPE \
EIGEN_CWISE_BINOP_RETURN_TYPE \
EIGEN_CWISE_PRODUCT_RETURN_TYPE \
EIGEN_CURRENT_STORAGE_BASE_CLASS \
_EIGEN_GENERIC_PUBLIC_INTERFACE
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then

View File

@ -8,17 +8,17 @@ int main()
{
ArrayXXf m(2,2);
//assign some values coefficient by coefficient
// 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;
m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);
//print values to standard output
// print values to standard output
cout << m << endl << endl;
// using the comma-initializer is also allowed
m << 1.0,2.0,
3.0,4.0;
//print values to standard output
// print values to standard output
cout << m << endl;
}

View File

@ -8,15 +8,16 @@ int main()
{
ArrayXXf a(3,3);
ArrayXXf b(3,3);
a << 1,2,3,
4,5,6,
7,8,9;
b << 1,2,3,
1,2,3,
1,2,3;
cout << "a + b = " << endl
<< a + b << endl;
// Adding two arrays
cout << "a + b = " << endl << a + b << endl << endl;
// Subtracting a scalar from an array
cout << "a - 2 = " << endl << a - 2 << endl;
}

View File

@ -1,17 +0,0 @@
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf a(3,3);
a << 1,2,3,
4,5,6,
7,8,9;
cout << "a + 2 = " << endl
<< a + 2 << endl;
}

View File

@ -0,0 +1,19 @@
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXf a = ArrayXf::Random(5);
a *= 2;
cout << "a =" << endl
<< a << endl;
cout << "a.abs() =" << endl
<< a.abs() << endl;
cout << "a.abs().sqrt() =" << endl
<< a.abs().sqrt() << endl;
cout << "a.min(a.abs().sqrt()) =" << endl
<< a.min(a.abs().sqrt()) << endl;
}

View File

@ -8,31 +8,15 @@ int main()
{
MatrixXf m(2,2);
MatrixXf n(2,2);
MatrixXf result(2,2);
//initialize matrices
m << 1,2,
3,4;
n << 5,6,
7,8;
// mix of array and matrix operations
// first coefficient-wise addition
// then the result is used with matrix multiplication
result = (m.array() + 4).matrix() * m;
cout << "-- Combination 1: --" << endl
<< result << endl << endl;
// mix of array and matrix operations
// first coefficient-wise multiplication
// then the result is used with matrix multiplication
cout << "-- Combination 1: --" << endl << result << endl << endl;
result = (m.array() * n.array()).matrix() * m;
cout << "-- Combination 2: --" << endl
<< result << endl << endl;
cout << "-- Combination 2: --" << endl << result << endl << endl;
}

View File

@ -1,34 +0,0 @@
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
using namespace std;
int main()
{
ArrayXXf m(2,2);
ArrayXXf n(2,2);
ArrayXXf result(2,2);
//initialize arrays
m << 1,2,
3,4;
n << 5,6,
7,8;
// --> array multiplication
result = m * n;
cout << "-- Array m*n: --" << endl
<< result << endl << endl;
// --> Matrix multiplication
result = m.matrix() * n.matrix();
cout << "-- Matrix m*n: --" << endl
<< result << endl << endl;
}

View File

@ -8,34 +8,19 @@ int main()
{
MatrixXf m(2,2);
MatrixXf n(2,2);
MatrixXf result(2,2);
//initialize matrices
m << 1,2,
3,4;
n << 5,6,
7,8;
// --> matrix multiplication
result = m * n;
cout << "-- Matrix m*n: --" << endl
<< result << endl << endl;
// --> coeff-wise multiplication
cout << "-- Matrix m*n: --" << endl << result << endl << endl;
result = m.array() * n.array();
cout << "-- Array m*n: --" << endl
<< result << endl << endl;
// ->> coeff-wise addition of a scalar
cout << "-- Array m*n: --" << endl << result << endl << endl;
result = m.cwiseProduct(n);
cout << "-- With cwiseProduct: --" << endl << result << endl << endl;
result = m.array() + 4;
cout << "-- Array m + 4: --" << endl
<< result << endl << endl;
cout << "-- Array m + 4: --" << endl << result << endl << endl;
}

View File

@ -8,13 +8,9 @@ int main()
{
ArrayXXf a(2,2);
ArrayXXf b(2,2);
a << 1,2,
3,4;
b << 5,6,
7,8;
cout << "a * b = " << endl
<< a * b << endl;
cout << "a * b = " << endl << a * b << endl;
}

View File

@ -6,26 +6,13 @@ using namespace Eigen;
int main()
{
MatrixXf m(3,3), n(2,2);
Array33f m;
m << 1,2,3,
4,5,6,
7,8,9;
// assignment through a block operation,
// block as rvalue
n = m.block(0,0,2,2);
//print n
Array<float,5,5> n = Array<float,5,5>::Constant(0.6);
n.block(1,1,3,3) = m;
cout << "n = " << endl << n << endl << endl;
n << 1,1,
1,1;
// block as lvalue
m.block(0,0,2,2) = n;
//print m
cout << "m = " << endl << m << endl;
Array33f res = n.block(0,0,3,3) * m;
cout << "res =" << endl << res << endl;
}

View File

@ -1,15 +1,14 @@
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
int main()
{
MatrixXf m(3,3);
Eigen::MatrixXf m(3,3);
m << 1,2,3,
4,5,6,
7,8,9;
std::cout << "2nd Row: "
<< m.row(1) << std::endl;
std::cout << "2nd Row: " << m.row(1) << std::endl;
m.col(0) += m.col(2);
std::cout << "m after adding third column to first:\n";
std::cout << m << std::endl;
}

View File

@ -2,26 +2,16 @@
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
MatrixXf m(4,4);
Eigen::Matrix4f m;
m << 1, 2, 3, 4,
5, 6, 7, 8,
9, 10,11,12,
13,14,15,16;
//print first two columns
cout << "-- leftCols(2) --" << endl
<< m.leftCols(2) << endl << endl;
//print last two rows
cout << "-- bottomRows(2) --" << endl
<< m.bottomRows(2) << endl << endl;
//print top-left 2x3 corner
cout << "-- topLeftCorner(2,3) --" << endl
<< m.topLeftCorner(2,3) << endl;
cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;
cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;
m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();
cout << "After assignment, m = " << endl << m << endl;
}

View File

@ -1,14 +1,18 @@
#include <Eigen/Dense>
#include <iostream>
using namespace Eigen;
int main()
{
MatrixXf m(3,3);
m << 1,2,3,
4,5,6,
7,8,9;
std::cout << m.block(0,0,2,2) << std::endl;
Eigen::MatrixXf m(4,4);
m << 1, 2, 3, 4,
5, 6, 7, 8,
9,10,11,12,
13,14,15,16;
std::cout << "Block in the middle" << std::endl;
std::cout << m.block<2,2>(1,1) << std::endl << std::endl;
for (int i = 1; i < 4; ++i)
{
std::cout << "Block of size " << i << std::endl;
std::cout << m.block(0,0,i,i) << std::endl << std::endl;
}
}

View File

@ -2,23 +2,13 @@
#include <iostream>
using namespace std;
using namespace Eigen;
int main()
{
VectorXf v(6);
Eigen::ArrayXf v(6);
v << 1, 2, 3, 4, 5, 6;
//print first three elements
cout << "-- head(3) --" << endl
<< v.head(3) << endl << endl;
//print last three elements
cout << "-- tail(3) --" << endl
<< v.tail(3) << endl << endl;
//print between 2nd and 5th elem. inclusive
cout << "-- segment(1,4) --" << endl
<< v.segment(1,4) << endl;
cout << "v.head(3) =" << endl << v.head(3) << endl << endl;
cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;
v.segment(1,4) *= 2;
cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;
}

View File

@ -15,5 +15,4 @@ int main()
v(0) = 4;
v(1) = v(0) - 1;
std::cout << "Here is the vector v:\n" << v << std::endl;
}