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