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
Does Std::List::Remove Method Call Destructor of Each Removed Element
Error with Multiple Definitions of Function
How to Compile a Visual Studio Project from the Command-Line
/Usr/Lib/X86_64-Linux-Gnu/Libstdc++.So.6: Version Cxxabi_1.3.8' Not Found
When Is a C++ Destructor Called
Faster Bulk Inserts in SQLite3
Count Character Occurrences in a String in C++
C++11: How to Alias a Function
When Should I Use Raw Pointers Over Smart Pointers
Why Is It Undefined Behavior to Delete[] an Array of Derived Objects via a Base Pointer
Why Is It Ok to Return a 'Vector' from a Function
How to Check If an Object's Type Is a Particular Subclass in C++
What Are Top-Level Const Qualifiers
Why Does Cudamalloc() Use Pointer to Pointer
How to Parse Ini File with Boost
Seeking and Reading Large Files in a Linux C++ Application