0
$\begingroup$

The Eigen::Map documentation here (https://eigen.tuxfamily.org/dox/classEigen_1_1Map.html) mentions the following: This class represents a matrix or vector expression mapping an existing array of data. It can be used to let Eigen interface without any overhead with non-Eigen data structures, such as plain C arrays or structures from other libraries.

  • What does without any overhead mean? Does this mean that if I have an Eigen::VectorXd and I want to map it to a std::vector<double> or vice versa, then since the data type is the same, we can use the same memory location for both objects?

In order to test this, I ran the following code snippet.

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;

Then I printed the addresses of eigenVector, stdVector1 and stdVector2. All of them are different.

  • What is exactly going on behind the scenes with the last line above? : Eigen::VectorXd::Map(&stdVector2[0], eVector.size()) = eVector; Is the presence of an '=' leading to a copy operation to another memory location? Is there another way to use Eigen::Map that would be more efficient here?

  • Similar question for the other way round: Mapping a std::vector<double> to Eigen::VectorXd. I used the following line for this - Eigen::Map<Eigen::VectorXd> eVector2(&stdVector1[0], stdVector1.size()); Same story here, eVector2 is a different memory location than stdVector1.

  • Given the above, is Eigen::Map even useful for interfacing with raw data types? To me, it is equivalent to using something like std::transform instead.

$\endgroup$
0
0
$\begingroup$

I would not count exactly on the highlighted statement. The Eigen and std-vectors sure have the same contigouus memory layout. But of course you need a little overhead, such as storing the size of the Eigen vector. And already by this you''ll have different memory addresses.

Let's consider your code in detail:

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

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

Here, you set up a new vector stdVector1 and copy the content of the eigenVector to it. There is no way that the .data() members could point to the same memory address-.

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

Here you construct a vector stdVector2 which again has an own memory range to hold five doubles.

By Eigen::VectorXd::Map(&stdVector2[0], eVector.size()) you construct a temporary Map-object and let its data refer to the data of stdVector2. But in the next step, with the assignment operator, you reset the reference to the data of eVector. Notably, you do not change any parameter of stdVector2.

Summarizing, all memory locations of your vector are different.

$\endgroup$
5
  • $\begingroup$ Thanks for your answer. You bring up a good point, I was looking at the memory address of the Eigen::vector and std::vector objects and not the data() locations. I checked again and compared the data() locations eigenVector.data(), stdVector1.data() and stdVector2.data() and all of them are different memory addresses as well. $\endgroup$
    – commonys
    Apr 17 at 18:51
  • $\begingroup$ Curiously though, from my second last bullet point in the original post, eVector2.data() and stdVector1.data() are referring to the same memory location. So for the use case of mapping a std::vector to an Eigen::Vector, it looks like Eigen::Map is doing what I would expect and not making another copy of the data. Why does it not work the other way round? It could be because Eigen::Map supports efficient mapping to eigen types only and not from eigen types to something else. $\endgroup$
    – commonys
    Apr 17 at 18:56
  • $\begingroup$ The only other thing I can think of is, my question about if there is any other way to do the example 1 mapping in my post without the assignment operator? $\endgroup$
    – commonys
    Apr 17 at 19:00
  • $\begingroup$ I added a more detailed analysis of your code, have a look. $\endgroup$
    – davidhigh
    Apr 17 at 21:48
  • $\begingroup$ Thanks! That answers my questions. To close the remaining open question I had, I also found this - forum.kde.org/viewtopic.php?f=74&t=102900#p225539. For avoiding a copy operation to the std::vector, it is best to first allocate a std::vector memory block, then use Eigen::Map and perform operations using Eigen, which get reflected in the originally assigned memory block. I can't find much documentation about this online, I might add it as an update to my original question in case someone else finds it useful. $\endgroup$
    – commonys
    Apr 17 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.