Write topic page for storage orders.

This commit is contained in:
Jitse Niesen 2011-02-12 17:43:29 +00:00
parent 7015aa00a9
commit 9ac68e40a0
10 changed files with 125 additions and 24 deletions

View File

@ -181,9 +181,9 @@ class BandMatrixBase : public EigenBase<Derived>
* \param Supers Number of super diagonal
* \param Subs Number of sub diagonal
* \param _Options A combination of either \b RowMajor or \b ColMajor, and of \b SelfAdjoint
* The former controls storage order, and defaults to column-major. The latter controls
* whether the matrix represent a selfadjoint matrix in which case either Supers of Subs
* have to be null.
* The former controls \ref TopicStorageOrders "storage order", and defaults to
* column-major. The latter controls whether the matrix represents a selfadjoint
* matrix in which case either Supers of Subs have to be null.
*
* \sa class TridiagonalMatrix
*/

View File

@ -185,8 +185,8 @@ template<typename Derived> class DenseBase
/** \returns the outer size.
*
* \note For a vector, this returns just 1. For a matrix (non-vector), this is the major dimension
* with respect to the storage order, i.e., the number of columns for a column-major matrix,
* and the number of rows for a row-major matrix. */
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of columns for a
* column-major matrix, and the number of rows for a row-major matrix. */
Index outerSize() const
{
return IsVectorAtCompileTime ? 1
@ -196,8 +196,8 @@ template<typename Derived> class DenseBase
/** \returns the inner size.
*
* \note For a vector, this is just the size. For a matrix (non-vector), this is the minor dimension
* with respect to the storage order, i.e., the number of rows for a column-major matrix,
* and the number of columns for a row-major matrix. */
* with respect to the \ref TopicStorageOrders "storage order", i.e., the number of rows for a
* column-major matrix, and the number of columns for a row-major matrix. */
Index innerSize() const
{
return IsVectorAtCompileTime ? this->size()

View File

@ -44,7 +44,7 @@
* data is laid out contiguously in memory. You can however override this by explicitly specifying
* inner and outer strides.
*
* Here's an example of simply mapping a contiguous array as a column-major matrix:
* Here's an example of simply mapping a contiguous array as a \ref TopicStorageOrders "column-major" matrix:
* \include Map_simple.cpp
* Output: \verbinclude Map_simple.out
*
@ -74,7 +74,7 @@
*
* This class is the return type of Matrix::Map() but can also be used directly.
*
* \sa Matrix::Map()
* \sa Matrix::Map(), \ref TopicStorageOrders
*/
namespace internal {

View File

@ -45,7 +45,7 @@
* The remaining template parameters are optional -- in most cases you don't have to worry about them.
* \tparam _Options \anchor matrix_tparam_options A combination of either \b RowMajor or \b ColMajor, and of either
* \b AutoAlign or \b DontAlign.
* The former controls storage order, and defaults to column-major. The latter controls alignment, which is required
* The former controls \ref TopicStorageOrders "storage order", and defaults to column-major. The latter controls alignment, which is required
* for vectorization. It defaults to aligning matrices except for fixed sizes that aren't a multiple of the packet size.
* \tparam _MaxRows Maximum number of rows. Defaults to \a _Rows (\ref maxrows "note").
* \tparam _MaxCols Maximum number of columns. Defaults to \a _Cols (\ref maxrows "note").
@ -107,7 +107,8 @@
* are the dimensions of the original matrix, while _Rows and _Cols are Dynamic.</dd>
* </dl>
*
* \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy
* \see MatrixBase for the majority of the API methods for matrices, \ref TopicClassHierarchy,
* \ref TopicStorageOrders
*/
namespace internal {

View File

@ -51,7 +51,7 @@
* \include Map_general_stride.cpp
* Output: \verbinclude Map_general_stride.out
*
* \sa class InnerStride, class OuterStride
* \sa class InnerStride, class OuterStride, \ref TopicStorageOrders
*/
template<int _OuterStrideAtCompileTime, int _InnerStrideAtCompileTime>
class Stride

View File

@ -56,7 +56,8 @@ const int Infinity = -1;
* for a matrix, this means that the storage order is row-major.
* If this bit is not set, the storage order is column-major.
* For an expression, this determines the storage order of
* the matrix created by evaluation of that expression. */
* the matrix created by evaluation of that expression.
* \sa \ref TopicStorageOrders */
const unsigned int RowMajorBit = 0x1;
/** \ingroup flags

View File

@ -1,11 +0,0 @@
namespace Eigen {
/** \page TopicStorageOrders Storage orders
TODO: write this dox page!
Is linked from the tutorial on the Matrix class.
*/
}

91
doc/I15_StorageOrders.dox Normal file
View File

@ -0,0 +1,91 @@
namespace Eigen {
/** \page TopicStorageOrders Storage orders
There are two different storage orders for matrices and two-dimensional arrays: column-major and row-major.
This page explains these storage orders and how to specify which one should be used.
<b>Table of contents</b>
- \ref TopicStorageOrdersIntro
- \ref TopicStorageOrdersInEigen
- \ref TopicStorageOrdersWhich
\section TopicStorageOrdersIntro Column-major and row-major storage
The entries of a matrix form a two-dimensional grid. However, when the matrix is stored in memory, the entries
have to somehow be laid out linearly. There are two main ways to do this, by row and by column.
We say that a matrix is stored in \b row-major order if it is stored row by row. The entire first row is
stored first, followed by the entire second row, and so on. Consider for example the matrix
\f[
A = \begin{bmatrix}
8 & 2 & 2 & 9 \\
9 & 1 & 4 & 4 \\
3 & 5 & 4 & 5
\end{bmatrix}.
\f]
If this matrix is stored in row-major order, then the entries are laid out in memory as follows:
\code 8 2 2 9 9 1 4 4 3 5 4 5 \endcode
On the other hand, a matrix is stored in \b column-major order if it is stored column by column, starting with
the entire first column, followed by the entire second column, and so on. If the above matrix is stored in
column-major order, it is laid out as follows:
\code 8 9 3 2 1 5 2 4 4 9 4 5 \endcode
This example is illustrated by the following Eigen code. It uses the PlainObjectBase::data() function, which
returns a pointer to the memory location of the first entry of the matrix.
<table class="example">
<tr><th>Example</th><th>Output</th></tr>
<tr><td>
\include TopicStorageOrders_example.cpp
</td>
<td>
\verbinclude TopicStorageOrders_example.out
</td></tr></table>
\section TopicStorageOrdersInEigen Storage orders in Eigen
The storage order of a matrix or a two-dimensional array can be set by specifying the \c Options template
parameter for Matrix or Array. As \ref TutorialMatrixClass explains, the %Matrix class template has six
template parameters, of which three are compulsory (\c Scalar, \c RowsAtCompileTime and \c ColsAtCompileTime)
and three are optional (\c Options, \c MaxRowsAtCompileTime and \c MaxColsAtCompileTime). If the \c Options
parameter is set to \c RowMajor, then the matrix or array is stored in row-major order; if it is set to
\c ColMajor, then it is stored in column-major order. This mechanism is used in the above Eigen program to
specify the storage order.
If the storage order is not specified, then Eigen normally defaults to storing the entry in column-major
order. This is also the case if one of the convenience typedefs (\c Matrix3f, \c ArrayXXd, etc.) is
used. However, it is possible to change the default to row-major order by defining the
\c EIGEN_DEFAULT_TO_ROW_MAJOR \ref TopicPreprocessorDirectives "preprocessor directive".
Matrices and arrays using one storage order can be assigned to matrices and arrays using the other storage
order, as happens in the above program when \c Arowmajor is initialized using \c Acolmajor. Eigen will reorder
the entries automatically. More generally, row-major and column-major matrices can be mixed in an expression
as we want.
\section TopicStorageOrdersWhich Which storage order to choose?
So, which storage order should you use in your program? There is no simple answer to this question; it depends
on your application. Here are some points to keep in mind:
- Your users may expect you to use a specific storage order. Alternatively, you may use other libraries than
Eigen, and these other libraries may expect a certain storage order. In these cases it may be easiest and
fastest to use this storage order in your whole program.
- Algorithms that traverse a matrix row by row will go faster when the matrix is stored in row-major order
because of better data locality. Similarly, column-by-column traversal is faster for column-major
matrices. It may be worthwhile to experiment a bit to find out what is faster for your particular
application.
- The default in Eigen is column-major. Naturally, most of the development and testing of the Eigen library
is thus done with column-major matrices. This means that, even though we aim to support column-major and
row-major storage orders transparently, the Eigen library may well work best with column-major matrices.
*/
}

View File

@ -34,6 +34,7 @@ For a first contact with Eigen, the best place is to have a look at the \ref Get
- \ref TopicLinearAlgebraDecompositions
- \ref TopicCustomizingEigen
- \ref TopicPreprocessorDirectives
- \ref TopicStorageOrders
- \ref TopicInsideEigenExample
- \ref TopicWritingEfficientProductExpression
- \ref TopicClassHierarchy

View File

@ -0,0 +1,18 @@
Matrix<int, 3, 4, ColMajor> Acolmajor;
Acolmajor << 8, 2, 2, 9,
9, 1, 4, 4,
3, 5, 4, 5;
cout << "The matrix A:" << endl;
cout << Acolmajor << endl << endl;
cout << "In memory (column-major):" << endl;
for (int i = 0; i < Acolmajor.size(); i++)
cout << *(Acolmajor.data() + i) << " ";
cout << endl << endl;
Matrix<int, 3, 4, RowMajor> Arowmajor = Acolmajor;
cout << "In memory (row-major):" << endl;
for (int i = 0; i < Arowmajor.size(); i++)
cout << *(Arowmajor.data() + i) << " ";
cout << endl;