Convert Eigen Matrix to C Array

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 a VectorXd, 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 a RowVectorXd (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 with Map:

    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::transformas 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



Leave a reply



Submit