Convert Eigen Matrix to C array
You can use the data() member function of the Eigen Matrix class. The layout by default is column-major, not row-major as a multidimensional C array (the layout can be chosen when creating a Matrix object). For sparse matrices the preceding sentence obviously doesn't apply.
Example:
ArrayXf v = ArrayXf::LinSpaced(11, 0.f, 10.f);
// vc is the corresponding C array. Here's how you can use it yourself:
float *vc = v.data();
cout << vc[3] << endl; // 3.0
// Or you can give it to some C api call that takes a C array:
some_c_api_call(vc, v.size());
// Be careful not to use this pointer after v goes out of scope! If
// you still need the data after this point, you must copy vc. This can
// be done using in the usual C manner, or with Eigen's Map<> class.
How to Convert Eigen Matrix to C/C++ Array
If you want to compute the matrix root of a matrix passed as C-style array and handle the result like a C-style array, you can either store the result into a MatrixXf
and use the data()
member of that matrix:
Eigen::MatrixXf matrix_root = Eigen::MatrixXf::Map( array_C_input , 3, 3).sqrt();
float* array_C_output = matrix_root.data();
Alternatively, if you already have memory allocated for the result, you can map the output to that:
void foo(float* output_array, float const* input_array) {
Eigen::MatrixXf::Map( output_array , 3, 3) =
Eigen::MatrixXf::Map( input_array , 3, 3).sqrt();
}
Note that Matrix::sqrt
computes the matrix-root, i.e., if S = A.sqrt()
, then S*S == M
. If you want an element-wise root, you need to use
Eigen::ArrayXXf::Map( input_array , 3, 3).sqrt()
convert eigen matrix into std::vectorstd::array form
You can map the memory of a std::vector<std::array<double,3>>
to a writable Eigen type using Eigen::Map
, e.g.,
// typedef for brevity, if you need this more often:
typedef Eigen::Matrix<double, 4, 3, Eigen::RowMajor> Mat43dR;
std::vector<std::array<double,3>> raw_data;
raw_data.resize(4); // allocate memory for 4x3 entries
// Copy A to raw_data:
Mat43dR::Map(raw_data[0].data() ) = A;
You can also read from raw_data
using Eigen::Map
, of course. And there are some alternative ways to work with Eigen::Map
: https://eigen.tuxfamily.org/dox/group__TutorialMapClass.html
Addendum: If you don't know the size of A
at compile-time, you can work with Dynamic
sizes like so:
typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatXXdR;
std::vector<std::array<double,3>> raw_data; // the `3` must still be known at compile-time
assert(A.cols()==3);
raw_data.resize(A.rows()); // allocate memory for Nx3 entries
// Copy A to raw_data:
MatXXdR::Map(raw_data[0].data(), A.rows(), A.cols() ) = A;
Copy an Eigen vector to a C array?
Since you did not clarify, I'm speculating three possible errors you could have made:
Either your
mesh
is actually aVectorXd
, but then it will always have exactly one column, but potentially multiple rows, i.e., you need to write:Eigen::VectorXd::Map(r, mesh.rows()) = mesh;
Or your
mesh
is aRowVectorXd
(i.e., having one row and multiple columns). Then you need to write:Eigen::RowVectorXd::Map(r, mesh.cols()) = mesh;
If
mesh
actually is a matrix, you need to decide how to map it to linear memory (i.e. row-major or column-major). This is also possible withMap
:Eigen::MatrixXd::Map(r, mesh.rows(), mesh.cols()) = mesh;
Map a Eigen Matrix to an C array
It's not the type of the matrix m
that matters, but the type used in the Map
template. You have to change the type used in the Map
template to be row major.
Eigen::Map<Matrix<double,2,5,RowMajor> >(p,2,5) = m;
What is the performance efficient way to convert Eigen's Matrix to c array so that I can use gsl
I have worked with Eigen before...
Usually, for simple access to the internal array data, like mentioned by user janneb in this thread, you just want to invoke data():
Vector3d v;
// Operations to add values to the vector.
double *c_ptr = v.data();
If you wish to iterate the individual values to perform some operation, you want to iterate every line (.row(index)) and column (.col(index)), depending on the matrix order that you want to lay down in the destination vector.
In your specific example, you need only iterate the rows:
Matrix<double,3,1> --> c_array []
You would want to call .col(0). Should similar needs arise, the specific documentation is always helpful!
So you would end up with something like (assuming you wish to use a three-line single-column matrix):
Vector3d v;
// Operations to add values to the vector.
for (int i=0; i<v.rows(); ++i)
c_array[i] = v(i,0);
Hope that helped.
mapping c++ array to Eigen Matrix
You misunderstand what a Eigen::Map
is. The map wraps an existing memory block and allows you to use Eigens functionality on that block. With a Eigen::Map
Eigen does handle any of the memory allocations. This allow you to manipulate the data in objects from other libraries without copying back and forth. As mentioned in the comments, if you allocate the result
array as double result[36];
the program should run fine.
How to create a row-major C array from an Eigen matrix with run-time dimensions?
You were very close:
typedef Matrix<double,Dynamic,Dynamic,RowMajor> RowMajMat;
RowMajMat::Map(destination, evector.rows(), evector.cols()) = evector;
Here, RowMajMat::Map
is a static method returning a Map<RowMajMat>
, so you can also write Map<RowMajMat>(destination, evector.rows(), evector.cols())
.
Converting Eigen matrix to unsigned char *
Here is a solution that works for me, inspired by @Nico Schertler 's comment. I do the cast within a for loop. However I had to use an array first and then give the adress of the first element to my unsigned char *
.
In the future I should consider trying std::transform
as is advised in the link from @Nico Schertler .
Note that I did not cast the Eigen array to unsigned char directly, because my real application is using a big array. When I tried it, I got an error linked to memory issues.
Here is my solution:
unsigned char gray_UC_tmp[size];
for (int i=0; i<9;++i){
gray_UC_tmp[i] = static_cast<unsigned char> (gray_array[i]);
}
gray_UC = gray_UC_tmp;
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); }
Related Topics
Printing Double Without Losing Precision
Boost-Python How to Pass a C++ Class Instance to a Python Class
C++ Local Variable Destruction Order
Do Stl Iterators Guarantee Validity After Collection Was Changed
Install Gcc on Linux with No Root Privilege
What Does the Vertical Pipe ( | ) Mean in C++
Visual Studio 2010 & 2008 Can't Handle Source Files with Identical Names in Different Folders
Boost::Property_Tree Xml Pretty Printing
Project Error: Unknown Module(S) in Qt: Webkitwidgets
How to Get Current CPU and Ram Usage in C++