You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ Eigen数组如何高效访问多个指定索引元素并返回向量

问题原因

你当前使用的test(inds.row(0), inds.row(1))写法,会返回行索引集与列索引集做笛卡尔积生成的子矩阵——行索引中的每个值会和列索引的所有值配对取元素,因此你会得到3×3的结果矩阵,只有对角线位置是你需要的「第k个行索引配对第k个列索引」的目标元素。先生成完整子矩阵再调用diagonal()提取的方案会产生大量冗余计算,内存和计算效率都很低。

高效实现方法

Eigen默认采用列优先存储规则,二维位置(row, col)对应的线性索引计算公式为 row + col * test.rows()。你可以先将成对的行列索引转换为线性索引向量,直接通过线性索引提取目标元素,全程不会生成多余的临时子矩阵,没有冗余计算。

对应实现代码如下:

Eigen::ArrayXXi test;
test.resize(5,5);
test.setRandom();
Eigen::Matrix<int, 2, 3> inds;
inds<<0, 2, 3, 2, 3, 1;

// 转换线性索引后直接提取目标元素
Eigen::ArrayXi res = test(
    (inds.row(0).array() + inds.row(1).array() * test.rows()).matrix()
);

std::cout<<"test: \n"<<test <<std::endl;
std::cout<<"inds: \n"<<inds <<std::endl;
std::cout<<"res: \n"<<res <<std::endl;

运行后res就是长度为3的一维数组,元素依次对应test(0,2)、test(2,3)、test(3,1),和你之前取对角线得到的结果完全一致。

如果索引长度是动态变化的,也可以用循环写法预计算线性索引,开启O2优化后和上面的向量化写法效率没有区别:

Eigen::VectorXi lin_idx(inds.cols());
for (int i = 0; i < inds.cols(); ++i) {
    lin_idx(i) = inds(0, i) + inds(1, i) * test.rows();
}
auto res = test(lin_idx);
注意事项
  • 如果你的矩阵/数组手动设置为行优先存储,线性索引计算公式需要替换为 col + row * test.cols()
  • 该方法对所有Eigen二维稠密存储类型(Array、Matrix的不同数值类型、不同大小版本)都生效
  • 提取得到的结果是连续内存的向量结构,不需要额外拷贝即可直接使用

内容的提问来源于stack exchange,提问作者raincold23

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 14:57:23