1

It is easy to copy data between e.g. Eigen::VectorXd and std::vector<double> or std::vector<Eigen::Vector3d>, for example

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

(see e.g. https://stackoverflow.com/a/26094708/4069571 or https://stackoverflow.com/a/21560121/4069571)

Also, it is possible to create an Eigen::Ref<VectorXd> from a Matrix block/column/... for example like

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

The Question

Is it possible to create an Eigen::Ref<VectorXd> from a std::vector<double> or even std::vector<Eigen::Vector3d> without first copying the data?

Community
  • 1
  • 1
GPMueller
  • 2,881
  • 2
  • 27
  • 36
  • 1
    According to the documentation it should be possible: *By default, a Ref can reference any dense vector expression of float having a contiguous memory layout.* You may have to `Eigen::Map` the `std::vector` first and then wrap it up as `Ref`. I always use template functions and `Ref` is intended for non-template functions. So haven't tried, but should work. Link to ref doc: http://eigen.tuxfamily.org/dox///classEigen_1_1Ref.html – NameRakes Jan 12 '17 at 06:46

1 Answers1

4

I tried and it actually works as I describe in my comment by first mapping and then wrapping it as a Eigen::Ref object. Shown here through a google test.

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
}

Made it a bit more elaborate after the 2nd edit. Now I have my google unit test for Eigen::Ref (thank you). Hope this helps.

NameRakes
  • 463
  • 6
  • 12
  • Very clear, thanks to the unit tests, thank you. In the end, I was copying data because I wrote `Eigen::VectorXd x = Eigen::Map(...)` instead of `Eigen::Ref x` or `Eigen::Map x` – GPMueller Jan 13 '17 at 10:25