为何Eigen无简便方法正确将二维double数组转为Matrix3d?
问题原因与解决方法
首先明确两个核心前提:
- C++标准二维数组(如
double a[3][3])在内存中是行优先连续存储的,你的数组a在内存里的顺序为:1,2,3,4,5,6,7,8,9。 - Eigen的
Matrix3d默认采用列优先存储,即矩阵元素按列依次存入内存。
转置结果的成因
你使用的Map<Matrix3d, RowMajor>(a[0])这类写法中,第二个模板参数RowMajor是告诉Eigen:被映射的源内存是行优先排列的,但目标类型Matrix3d本身是列优先存储的。当你将Map对象赋值给Matrix3d时,Eigen会自动将行优先的源数据转换为列优先的存储格式,最终得到转置后的矩阵。
ColMajor是Map的默认参数,此时Eigen会把源内存当作列优先解析,但你的数组实际是行优先,自然也会得到转置结果;DontAlign仅控制内存对齐规则,和存储顺序无关,因此无法改变结果。
正确的转换方法
要得到和原数组行列一致的Eigen矩阵,有三种简便方式:
方式1:映射为行优先矩阵类型
直接将Map的目标类型指定为行优先矩阵,再赋值给Matrix3d,Eigen会自动处理存储格式转换并保持行列正确:
Matrix3d b = Map<Matrix<double, 3, 3, RowMajor>>(a[0]);
方式2:映射后转置
若不想指定行优先矩阵类型,可先按列优先映射,再通过转置得到正确结果:
Matrix3d b = Map<Matrix3d>(a[0]).transpose();
方式3:C++11+直接初始化
如果使用C++11或更高版本,可直接用初始化列表构造矩阵,无需依赖数组:
Matrix3d b{{1,2,3}, {4,5,6}, {7,8,9}};
补充说明
Eigen默认采用列优先存储,是为了兼容BLAS等主流线性代数库的存储规范,从而获得更好的性能表现。只要明确存储顺序的差异,就能通过简单操作满足工程师/数学家对矩阵行列的直观预期。
内容的提问来源于stack exchange,提问作者Thomas Kirven
相关产品推荐
相关产品推荐

