xref: /aosp_15_r20/external/eigen/doc/StorageOrders.dox (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
1*bf2c3715SXin Linamespace Eigen {
2*bf2c3715SXin Li
3*bf2c3715SXin Li/** \eigenManualPage TopicStorageOrders Storage orders
4*bf2c3715SXin Li
5*bf2c3715SXin LiThere are two different storage orders for matrices and two-dimensional arrays: column-major and row-major.
6*bf2c3715SXin LiThis page explains these storage orders and how to specify which one should be used.
7*bf2c3715SXin Li
8*bf2c3715SXin Li\eigenAutoToc
9*bf2c3715SXin Li
10*bf2c3715SXin Li
11*bf2c3715SXin Li\section TopicStorageOrdersIntro Column-major and row-major storage
12*bf2c3715SXin Li
13*bf2c3715SXin LiThe entries of a matrix form a two-dimensional grid. However, when the matrix is stored in memory, the entries
14*bf2c3715SXin Lihave to somehow be laid out linearly. There are two main ways to do this, by row and by column.
15*bf2c3715SXin Li
16*bf2c3715SXin LiWe say that a matrix is stored in \b row-major order if it is stored row by row. The entire first row is
17*bf2c3715SXin Listored first, followed by the entire second row, and so on. Consider for example the matrix
18*bf2c3715SXin Li
19*bf2c3715SXin Li\f[
20*bf2c3715SXin LiA = \begin{bmatrix}
21*bf2c3715SXin Li8 & 2 & 2 & 9 \\
22*bf2c3715SXin Li9 & 1 & 4 & 4 \\
23*bf2c3715SXin Li3 & 5 & 4 & 5
24*bf2c3715SXin Li\end{bmatrix}.
25*bf2c3715SXin Li\f]
26*bf2c3715SXin Li
27*bf2c3715SXin LiIf this matrix is stored in row-major order, then the entries are laid out in memory as follows:
28*bf2c3715SXin Li
29*bf2c3715SXin Li\code 8 2 2 9 9 1 4 4 3 5 4 5 \endcode
30*bf2c3715SXin Li
31*bf2c3715SXin LiOn the other hand, a matrix is stored in \b column-major order if it is stored column by column, starting with
32*bf2c3715SXin Lithe entire first column, followed by the entire second column, and so on. If the above matrix is stored in
33*bf2c3715SXin Licolumn-major order, it is laid out as follows:
34*bf2c3715SXin Li
35*bf2c3715SXin Li\code 8 9 3 2 1 5 2 4 4 9 4 5 \endcode
36*bf2c3715SXin Li
37*bf2c3715SXin LiThis example is illustrated by the following Eigen code. It uses the PlainObjectBase::data() function, which
38*bf2c3715SXin Lireturns a pointer to the memory location of the first entry of the matrix.
39*bf2c3715SXin Li
40*bf2c3715SXin Li<table class="example">
41*bf2c3715SXin Li<tr><th>Example</th><th>Output</th></tr>
42*bf2c3715SXin Li<tr><td>
43*bf2c3715SXin Li\include TopicStorageOrders_example.cpp
44*bf2c3715SXin Li</td>
45*bf2c3715SXin Li<td>
46*bf2c3715SXin Li\verbinclude TopicStorageOrders_example.out
47*bf2c3715SXin Li</td></tr></table>
48*bf2c3715SXin Li
49*bf2c3715SXin Li
50*bf2c3715SXin Li\section TopicStorageOrdersInEigen Storage orders in Eigen
51*bf2c3715SXin Li
52*bf2c3715SXin LiThe storage order of a matrix or a two-dimensional array can be set by specifying the \c Options template
53*bf2c3715SXin Liparameter for Matrix or Array. As \ref TutorialMatrixClass explains, the %Matrix class template has six
54*bf2c3715SXin Litemplate parameters, of which three are compulsory (\c Scalar, \c RowsAtCompileTime and \c ColsAtCompileTime)
55*bf2c3715SXin Liand three are optional (\c Options, \c MaxRowsAtCompileTime and \c MaxColsAtCompileTime). If the \c Options
56*bf2c3715SXin Liparameter is set to \c RowMajor, then the matrix or array is stored in row-major order; if it is set to
57*bf2c3715SXin Li\c ColMajor, then it is stored in column-major order. This mechanism is used in the above Eigen program to
58*bf2c3715SXin Lispecify the storage order.
59*bf2c3715SXin Li
60*bf2c3715SXin LiIf the storage order is not specified, then Eigen defaults to storing the entry in column-major. This is also
61*bf2c3715SXin Lithe case if one of the convenience typedefs (\c Matrix3f, \c ArrayXXd, etc.) is used.
62*bf2c3715SXin Li
63*bf2c3715SXin LiMatrices and arrays using one storage order can be assigned to matrices and arrays using the other storage
64*bf2c3715SXin Liorder, as happens in the above program when \c Arowmajor is initialized using \c Acolmajor. Eigen will reorder
65*bf2c3715SXin Lithe entries automatically. More generally, row-major and column-major matrices can be mixed in an expression
66*bf2c3715SXin Lias we want.
67*bf2c3715SXin Li
68*bf2c3715SXin Li
69*bf2c3715SXin Li\section TopicStorageOrdersWhich Which storage order to choose?
70*bf2c3715SXin Li
71*bf2c3715SXin LiSo, which storage order should you use in your program? There is no simple answer to this question; it depends
72*bf2c3715SXin Lion your application. Here are some points to keep in mind:
73*bf2c3715SXin Li
74*bf2c3715SXin Li  - Your users may expect you to use a specific storage order. Alternatively, you may use other libraries than
75*bf2c3715SXin Li    Eigen, and these other libraries may expect a certain storage order. In these cases it may be easiest and
76*bf2c3715SXin Li    fastest to use this storage order in your whole program.
77*bf2c3715SXin Li  - Algorithms that traverse a matrix row by row will go faster when the matrix is stored in row-major order
78*bf2c3715SXin Li    because of better data locality. Similarly, column-by-column traversal is faster for column-major
79*bf2c3715SXin Li    matrices. It may be worthwhile to experiment a bit to find out what is faster for your particular
80*bf2c3715SXin Li    application.
81*bf2c3715SXin Li  - The default in Eigen is column-major. Naturally, most of the development and testing of the Eigen library
82*bf2c3715SXin Li    is thus done with column-major matrices. This means that, even though we aim to support column-major and
83*bf2c3715SXin Li    row-major storage orders transparently, the Eigen library may well work best with column-major matrices.
84*bf2c3715SXin Li
85*bf2c3715SXin Li*/
86*bf2c3715SXin Li}
87