Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialise Eigen::vector with std::vector

Tags:

c++

eigen

People also ask

How do you initialize a vector in Eigen?

Eigen offers a comma initializer syntax which allows the user to easily set all the coefficients of a matrix, vector or array. Simply list the coefficients, starting at the top-left corner and moving from left to right and from the top to the bottom. The size of the object needs to be specified beforehand.


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.


Just to extend @ggael answer in case others didn't notice it:

From Quick Reference Guide: Mapping External Array:

float data[] = {1,2,3,4};
Map<Vector3f> v1(data);       // uses v1 as a Vector3f object
Map<ArrayXf>  v2(data,3);     // uses v2 as a ArrayXf object
Map<Array22f> m1(data);       // uses m1 as a Array22f object
Map<MatrixXf> m2(data,2,2);   // uses m2 as a MatrixXf object

The following one-liner should be more correct:

#include <Eigen/Dense>
#include <Eigen/Core>

std::vector<double> a = {1, 2, 3, 4};
Eigen::VectorXd b = Eigen::Map<Eigen::VectorXd, Eigen::Unaligned>(a.data(), a.size());

I found a better answer by this link:

https://forum.kde.org/viewtopic.php?f=74&t=94839

Basically first create a pointer to the std vector, and then pass the pointer and length to the constructor using Map.

This method works with dynamic Vector object in Eigen. While I tried using .data() function from std vector as the first answer suggest, it gives me an error: static assertion failed: YOU_CALLED_A_FIXED_SIZE_METHOD_ON_A_DYNAMIC_SIZE_MATRIX_OR_VECTOR

But using this method it works!

I just copy and paste the relevant code from the link here:

std::vector<double> v(4, 100.0);
double* ptr = &v[0];
Eigen::Map<Eigen::VectorXd> my_vect(ptr, 4);