As I've understood from Eigen::Map
official tutorial and documentation, this utilities is provided in order to wrap some raw data with a Eigen
structure, without copying the actual underlying data. From the tutorial:
Occasionally you may have a pre-defined array of numbers that you want to use within Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an Eigen type. Fortunately, this is very easy with the Map class.
I've prepared the following very simple code, in which I'm wrapping an Eigen::VectorX
around a C++ buffer of 4 float elements:
#include <iostream>
#include <Eigen/Dense>
int main()
{
const int size = 4;
float my_array[size]{ 1.0, 2.0, 3.0, 4.0 };
printf("Original array: ");
for (int i = 0; i < size; i++) printf("%.1f, ", my_array[i]);
printf("\n");
Eigen::ArrayXf eigen_array = Eigen::ArrayXf::Map(&my_array[0], 4, 1);
printf("Eigen Array: ");
for (int i = 0; i < size; i++) printf("%.1f, ",eigen_array(i));
printf("\n");
printf("Original array address: %0x\n", &my_array[0]);
printf("Eigen array data address: %0xn\n", eigen_array.data());
my_array[1] = 10.0;
printf("Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: %.1f\n", eigen_array(1));
eigen_array(2) = 20.0;
printf("Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: %.1f\n", my_array[2]);
return 0;
}
Built with MSVC 19, Eigen 3.4.90, I get this result, that clearly shows how the array is copied in the new Eigen instance (NOTE: exactly the same happens if I replace ArrayXf
with VectorXf
, in Debug and Release mode):
Original array: 1.0, 2.0, 3.0, 4.0,
Eigen Array: 1.0, 2.0, 3.0, 4.0,
Original array address: 31cff628
Eigen array data address: b27c4df0n
Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: 2.0
Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: 3.0
Am I missing something? Did I misinterpreted the documentation in some way? Or this is a bug? (I want to think that the problem is on my side, first).
Eigen::ArrayXf::Map
works correctly. It does not copy the array. The issue in your code is the conversion to Eigen::ArrayXf
that copies the array.
There is no copy when you use the right type. Let the compier figure it out:
auto eigen_array = Eigen::ArrayXf::Map(&my_array[0], 4, 1);
Produces expected output:
Original array: 1.0, 2.0, 3.0, 4.0,
Eigen Array: 1.0, 2.0, 3.0, 4.0,
Original array address: d9a99c70
Eigen array data address: d9a99c70n
Modified Original array at index 1 (new value = 10.0). Eigen value at index 1: 10.0
Modified Eigen array at index 2 (new value = 20.0). Original array value at index 2: 20.0
(the stray n
is from your code, the pointers have identical value)