C++ Eigen::Map 类问题

计算科学 C++ 本征
2021-12-23 22:31:31

此处的 Eigen::Map 文档 ( https://eigen.tuxfamily.org/dox/classEigen_1_1Map.html ) 提到以下内容:此类表示映射现有数据数组的矩阵或向量表达式。它可用于让 Eigen与非 Eigen 数据结构(例如普通 C 数组或来自其他库的结构)进行接口,而无需任何开销。

  • 没有任何开销是什么意思?这是否意味着如果我有一个Eigen::VectorXd并且我想将它映射到一个std::vector<double>或反之亦然,那么由于数据类型相同,我们可以为两个对象使用相同的内存位置?

为了对此进行测试,我运行了以下代码片段。

Eigen::VectorXd eigenVector (5);
eigenVector << 1, 1, 1, 1, 1;

std::vector<double> stdVector1 {eVector.data(), eVector.data() + eVector.size()};

std::vector<double> stdVector2 (5);
Eigen::VectorXd::Map(&stdVector2[0], eVector.size()) = eVector;

然后我打印了 eigenVector、stdVector1 和 stdVector2 的地址。他们都是不同的。

  • 上面最后一行的幕后究竟发生了什么?: Eigen::VectorXd::Map(&stdVector2[0], eVector.size()) = eVector;'=' 的存在是否会导致复制操作到另一个内存位置?还有另一种使用 Eigen::Map 的方法在这里会更有效吗?

  • 反过来的类似问题:将 a 映射std::vector<double>Eigen::VectorXd. 我为此使用了以下行 -Eigen::Map<Eigen::VectorXd> eVector2(&stdVector1[0], stdVector1.size());同样的故事,eVector2stdVector1.

  • 鉴于上述情况,Eigen::Map对于与原始数据类型的接口是否有用?对我来说,这相当于使用类似的东西std::transform

1个回答

我不会完全指望突出显示的声明。特征向量和标准向量肯定具有相同的连续内存布局。但是当然你需要一点开销,比如存储特征向量的大小。并且已经通过这个你将拥有不同的内存地址。

让我们详细考虑您的代码:

Eigen::VectorXd eigenVector (5);
eigenVector << 1, 1, 1, 1, 1;

std::vector<double> stdVector1 {eVector.data(), eVector.data() + eVector.size()};

在这里,您设置了一个新向量stdVector1并将 eigenVector 的内容复制到它。.data()成员不可能指向相同的内存地址

std::vector<double> stdVector2 (5);
Eigen::VectorXd::Map(&stdVector2[0], eVector.size()) = eVector;

在这里,您构建了一个向量,该向量stdVector2再次具有自己的内存范围以容纳五个双精度数。

通过Eigen::VectorXd::Map(&stdVector2[0], eVector.size())您构造一个临时 Map 对象并让其数据引用 stdVector2 的数据。但在下一步中,您可以使用赋值运算符重置对 eVector 数据的引用。值得注意的是,您不会更改 stdVector2 的任何参数。

总而言之,向量的所有内存位置都是不同的。