简介
本篇介绍Eigen中矩阵及二维数组的系数存储顺序–行优先及列优先,已经如何指定优先顺序。
行优先(row-majoe)、 列优先(column-majoe)
矩阵的系数条目组成了一个二维的结构,在内存内存储矩阵时,必须以某种结构来布局。Eigen内提供了2中布局方式: 行优先、列优先。
如有矩阵A,如下:
A
=
[
8
2
2
9
9
1
4
4
3
5
4
5
]
A = \begin{bmatrix} 8 & 2 & 2 & 9 \\ 9 & 1 & 4 & 4 \\ 3 & 5 & 4 & 5 \end{bmatrix}
A=⎣⎡893215244945⎦⎤
那么,以行优先存储时,其系数一行一行地,按照行顺序。其系数在内存中的顺序如此:
8 2 2 9 9 1 4 4 3 5 4 5
。
而以列优先的情况下,其系数的顺序则如此:
8 9 3 2 1 5 2 4 4 9 4 5
请看一下,并理解下面的示例,其使用PlainObjectBase::data()
的data()
函数,来得到矩阵保存于内存中的数据指针。
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;
执行的结果:
The matrix A:
8 2 2 9
9 1 4 4
3 5 4 5
In memory (column-major):
8 9 3 2 1 5 2 4 4 9 4 5
In memory (row-major):
8 2 2 9 9 1 4 4 3 5
Eigen中的存储方式
一个矩阵或一个二维数组可以通过指定的模板参数选项来设置矩阵和数组的存储模式/方式。就如矩阵类的说明所说,矩阵类模板有6个模板参数,其中三个是强制性的(标量,RowsAtCompileTime和ColsAtCompileTime),另外三是可选的(Options选项,MaxRowsAtCompileTime和MaxColsAtCompileTime)。如果选项参数设置为RowMajor,那么矩阵或数组存储采样行优先顺序;如果设置为ColMajor,然后存储在列为主的顺序。
这种机制就用于为程序指定的矩阵的存储顺序。如果没有指定存储顺序,那么就默认存储条目采样列优先column-major
。Eigen内定义的简化的typedef (Matrix3f ArrayXXd,等等)也是如此。
一个使用某种存储顺序的矩阵/数组可以使用赋值表达式,赋值给使用其他存储顺序矩阵/数组,如上面的示例的程序,在 Arowmajor初始化时,使用Acolmajor为其赋值。Eigen将自动重新排序所有的系数。更普遍的是,行和列为主的矩阵可以混合使用在一个表达式内。
选择哪种存储模式?
在程序中,选择哪种存储模式,这依赖于我们自己的程序。
- 如果你的程序还使用了其他的开发库,而不是只有Eigen。我们需要考虑相互之间的匹配的问题。这时,我们在程序中使用统一的存储顺序,程序会更容易、更快地开发。
- 如果算法要以行的方式操作,则程序采样行优先模式,会带来更好地性能。同样,采样列优先的模式,在需要访问列的时候更适合。
- Eigen缺省地采样列优先模式。自然地,大多数的开发和测试使用了列为主的矩阵。