Eigen and Std::Vector

Initialise Eigen::vector with std::vector

According to Eigen Doc, Vector is a typedef for Matrix, and the Matrix has a constructor with the following signature:

Matrix (const Scalar *data)

Constructs a fixed-sized matrix initialized with coefficients starting at data.

And vector reference defines the std::vector::data as:

std::vector::data

T* data();
const T* data() const;

Returns pointer to the underlying array serving as element storage.
The pointer is such that range [data(); data() + size()) is always a
valid range, even if the container is empty.

So, you could just pass the vector's data as a Vector3d constructor parameter:

Eigen::Vector3d v2(v1.data());

Also, as of Eigen 3.2.8, the constructor mentioned above defined as:

template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
inline Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>
::Matrix(const Scalar *data)
{
this->_set_noalias(Eigen::Map<const Matrix>(data));
}

As you can see, it also uses Eigen::Map, as noted by @ggael and @gongzhitaao.

Converting an Eigen::VectorXd to an std::vector double

You are using a constructor syntax for the std::vector vec although the vector was already declared. That doesn't work.

There are two efficient possibilities to copy the content of an Eigen::VectorXd into a std::vector<double>. You can either construct a new std::vector vec2, like this:

vector<double> vec2(firstEvector.data(), firstEvector.data() + firstEvector.size());

or use the previously declared vector vec and transfer the data from the Eigen::VectorXd by using Eigen::Map. But in that case the std::vector first needs to be resized:

vec.resize(firstEvector.size());
Map<VectorXd>(vec.data(), vec.size()) = firstEvector;

How to convert an std::vector to a matrix in Eigen?

How about trying to use the vectors data() method, which gives you access to the memory array used internally by the vector, like this:

    std::vector<float> test_vector = { 2,1,3 };
float* test_array = test_vector.data();
Eigen::MatrixXf test = Eigen::Map<Eigen::Matrix<float, 3, 1> >(test_array);

Or shorter:

    std::vector<float> test_vector = { 2,1,3 };
Eigen::MatrixXf test = Eigen::Map<Eigen::Matrix<float, 3, 1> >(test_vector.data());

Beware The asignment actually copies the data, therefore this is safe. However, you can also directly use the data of the vector like this

    std::vector<float> test_vector(3,2);
Eigen::Map<Eigen::Matrix<float, 3, 1> > dangerousVec (test_vector.data());

If vector goes out of scope the memory is deallocated and dangerousVec's data is dangeling.

Convert every column of an Eigen::Matrix to an std::vector?

I think the most elegant Solution would be to use Eigen::Map. In your case you would do it like this:

 Eigen::MatrixXf mat(3, 4);
mat << 1.1, 2, 3, 50,
2.2, 2, 3, 50,
3.1, 2, 3, 50;

std::vector<float> vec;
vec.resize(mat.rows());
for(int col=0; col<mat.cols(); col++){
Eigen::Map<Eigen::MatrixXf>(vec.data(), mat.rows(), 1 ) = mat.col(col); }

typecasting Eigen::VectorXd to std::vector

vector<int> vec(mat.data(), mat.data() + mat.rows() * mat.cols());

std::vector to Eigen::VectorXf

Your code seems correct. No need to initialize ev(N), though. You can just write

Eigen::VectorXf ev = Eigen::VectorXf::Map(&v[0], N);

Fill a std::vector from a row of an Eigen Array / Matrix

Figured it out. The problem is related to storage order, the way how Eigen lays out a two dimensional array in memory. There are two possible layouts: RowMajor and ColumnMajor. The default layout is ColumnMajor, which stores the 2D array elements column-wise.

Knowing this, the weird result I get makes sense. The .row(0).data() returns the pointer to the first element of the first row. The .row(0).size() is 4 and .row(0).data() + 4 takes the first 4 elements column-wise: [-1, 0, 0, 0]. Same argument for the second column which starts at (1, 0) element, and counting 4 elements column-wise leads to [0, 0, 0, 30.57].

There are two solutions:

  • Make the Array/Matrix layout row-major:
Array<double, 2, Dynamic, RowMajor> arr(2, 6);
arr << 1, 2, 3, 4
5, 6, 7, 8;

vector<double> row1_vec(arr.row(0).data(), arr.row(0).data() + arr.cols());

// row1_vec: 1, 2, 3, 4

  • or use Eigen's Map class:
Array2Xd arr(2, 4);
arr << 1, 2, 3, 4,
5, 6, 7, 8;

vector<double> row1_vec(arr.cols());
Map<RowVectorXd>(&row1_vec[0], 1, arr.cols()) = arr.row(0);

// row1_vec: 1, 2, 3, 4


Related Topics



Leave a reply



Submit