Eigen(v4前版本)中MatrixXi转VectorXi的无循环实现方法
问题描述
现有一个Eigen的MatrixXi矩阵,示例如下:
[0, 1, 2] [0, 2, 3] [4, 7, 6] [4, 6, 5] [0, 4, 5] [0, 5, 1] [1, 5, 6]
通过以下代码截取矩阵的部分行:
MatrixXi MR = F.middleRows(first, last);
其中first和last可按需设置。现在需要将截取到的n行转换为列向量VectorXi,格式示例如下:
[0, 1, 2, 0, 2, 3]
要求尽量不使用循环。尝试了以下代码但触发断言错误:
VectorXi VRT(MR.rows() * MR.cols()); VRT.tail(MR.rows() * MR.cols()) = MR.array();
错误信息:
Assertion failed: (rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize.")
由于使用的是Eigen v4之前的版本,无法使用reshape函数,请问该如何实现?
解决方案
在Eigen v4之前的版本中,可通过**内存映射(Map)**直接将矩阵数据转换为列向量,无需循环,且能避免断言错误。
核心实现代码
// 利用Map直接复用MR的内存,转换为列向量 VectorXi VRT = Eigen::Map<VectorXi>(MR.data(), MR.rows() * MR.cols());
细节说明
- 存储顺序适配:Eigen默认矩阵为列优先存储,上述代码会按列遍历矩阵元素生成列向量。若你的矩阵是行优先存储(创建时指定
RowMajor),需先转置矩阵再映射:VectorXi VRT = Eigen::Map<VectorXi>(MR.transpose().data(), MR.rows() * MR.cols()); - 原代码错误原因:
MR.array()返回的数组表达式维度与VRT.tail(...)不匹配,Eigen不允许维度不兼容的赋值操作,因此触发断言错误。 - 拷贝控制:上述代码是直接映射原内存,若需要独立的向量副本,可在末尾添加
.eval():VectorXi VRT = Eigen::Map<VectorXi>(MR.data(), MR.rows() * MR.cols()).eval();
内容的提问来源于stack exchange,提问作者Kabu
相关产品推荐
相关产品推荐

