从 std::vector 创建 Eigen::Ref

Posted

技术标签:

【中文标题】从 std::vector 创建 Eigen::Ref【英文标题】:Create Eigen::Ref from std::vector 【发布时间】:2017-01-12 00:08:30 【问题描述】:

在例如之间复制数据很容易Eigen::VectorXdstd::vector<double>std::vector<Eigen::Vector3d>,例如

std::vector<Eigen::Vector3> vec1(10, 0,0,0);
Eigen::VectorXd vec2(30);
VectorXd::Map(&vec2[0], vec1.size()) = vec1;

(参见例如https://***.com/a/26094708/4069571 或https://***.com/a/21560121/4069571)

此外,可以从矩阵块/列/...创建Eigen::Ref&lt;VectorXd&gt;,例如

MatrixXd mat(10,10);
Eigen::Ref<VectorXd> vec = mat.col(0);

问题

是否可以在不首先复制数据的情况下从std::vector&lt;double&gt; 甚至std::vector&lt;Eigen::Vector3d&gt; 创建Eigen::Ref&lt;VectorXd&gt;

【问题讨论】:

根据文档,这应该是可能的:默认情况下, Ref 可以引用具有连续内存布局的浮点的任何密集向量表达式。 您可能必须Eigen::Map std::vector&lt;double&gt; 首先是Ref。我总是使用模板函数,Ref 用于非模板函数。所以没试过,但应该可以。参考文档链接:eigen.tuxfamily.org/dox///classEigen_1_1Ref.html 【参考方案1】:

我试过了,它实际上就像我在评论中描述的那样工作,首先映射然后将其包装为 Eigen::Ref 对象。此处通过 google 测试显示。

void processVector(Eigen::Ref<Eigen::VectorXd> refVec) 
  size_t size = refVec.size();
  ASSERT_TRUE(10 == size);
  std::cout << "Sum before change: " << refVec.sum(); // output is 50 = 10 * 5.0
  refVec(0) = 10.0; // for a sum of 55
  std::cout << "Sum after change: " << refVec.sum() << std::endl;


TEST(testEigenRef, onStdVector) 
  std::vector<double> v10(10, 5.0);
  Eigen::Map<Eigen::VectorXd> mPtr(&v10[0], 10);
  processVector(mPtr);
  // confirm that no copy is made and std::vector is changed as well
  std::cout << "Std vec[0]: " << v10[0] << std::endl; // output is 10.0

在第 2 次编辑后使其更加精细。现在我对Eigen::Ref 进行了谷歌单元测试(谢谢)。希望这会有所帮助。

【讨论】:

很清楚,感谢单元测试,谢谢。最后,我是在复制数据,因为我写的是Eigen::VectorXd x = Eigen::Map&lt;VectorXd&gt;(...) 而不是Eigen::Ref&lt;Eigen::VectorXd&gt; xEigen::Map&lt;Eigen::VectorXd&gt; x

以上是关于从 std::vector 创建 Eigen::Ref的主要内容,如果未能解决你的问题,请参考以下文章

从 std::vector 在 MEX C++ 中创建 MATLAB 数组

从 std::vector<std::vector<float>> 转换为 float**

将元素从 std::vector 复制到 std::stack c++

将数据从 std::vector 传递到 std::valarray 的最有效方法

为啥从 std::vector 中随机删除比 std::list 快?

从 Go 中迭代`std::vector<std::string>`?