2

E.g., if I have an Eigen::MatrixXd of size 10 columns and 3 rows, how can I alias that to a std::vector of 10 elements of Eigen::Vector3d? when I say alias I mean using the same memory block without copying.

I know that I can do the reversed mapping by something like:

std::vector<Vector3d> v(10);
...
Map<Matrix<double,3,Dynamic> >  m(v.data().data(), 3, 10);

but reversely, if I have an Eigen::Matrix, I tried to convert it to a vector of Eigen::vector but the following code line failed compilation

Eigen::Matrix2Xd points;
...
std::vector<Eigen::Vector2d> v_points(points.data()
    Eigen::aligned_allocator<Eigen::vector2d>(points_data()))
shelper
  • 10,053
  • 8
  • 41
  • 67
  • Possible duplicate of [std::vector to Eigen::MatrixXd Eigen](https://stackoverflow.com/questions/49813340/stdvectoreigenvector3d-to-eigenmatrixxd-eigen) – chtz Feb 15 '19 at 14:37
  • 1
    no it is not, i want the reversed conversion – shelper Feb 15 '19 at 18:23

1 Answers1

4

This is possible using a custom allocator as described there: Is it possible to initialize std::vector over already allocated memory?

To this end, you'll have to reinterpret it as a Vector3d*:

Vector3d* buf = reinterpret_cast<Vector3d*>(mat.data());

and then pass it to your custom allocator:

std::vector<Vector3d, PreAllocator<Vector3d>> my_vec(10, PreAllocator<Vector3d>(buf, 10));

Another option would be to wrap it within some views alike std::vector, e.g. gsl::span:

gsl::span<Vector3d> view(buf,mat.cols());

In both cases, the mat object must stay alive throughout the lifetime of the std::vector or span.

For completeness, you can also deeply copy it within a std::vector:

std::vector<Vector3d> v(10);
Matrix<double,3,Dynamic>::Map(v.data().data(),3,10) = mat;
shelper
  • 10,053
  • 8
  • 41
  • 67
ggael
  • 28,425
  • 2
  • 65
  • 71
  • So you mean `Matrix::Map(vec.data().data()) = mat;` deep copies the data in `mat` to `vec`? I read about the documentation of `Map` and seems it does not copy the memory, I am confused here where the deep copy happens... – shelper Feb 14 '19 at 15:53
  • The `Map` object only stores a pointer to `vec`'s buffer and the deep copy happens in `operator= `. – ggael Feb 14 '19 at 17:24
  • So, I saw this question here with some interesting answer https://stackoverflow.com/questions/21917529/is-it-possible-to-initialize-stdvector-over-already-allocated-memory , would it be possible to implement something like this for Eigen::Matrix using a customized allocator? – shelper Feb 14 '19 at 17:48
  • I did not thought about using a custom allocator for that, but yes that's definitely possible, just pass `mat.data()` to your custom allocator! – ggael Feb 15 '19 at 10:02
  • @ggael Still could not figure out, can you be more specific? or if you can edit the answer, i will update my question first – shelper Feb 15 '19 at 15:38
  • Have you noticed that I edited my answer to include the relevant code snippets, with `PreAllocator` coming from the other answer. – ggael Feb 15 '19 at 23:09
  • yep, i edited it because i believe there is a typo. also, You sure i can directly use the PreAllocator class from the post directly? i tried, and there seems to be compilation error... – shelper Feb 17 '19 at 14:32