Convert Eigen Matrix to C array
Solution 1
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.
Solution 2
To convert normal data type to eigen matrix type
double *X; // non-NULL pointer to some data
You can create an nRows x nCols size double matrix using the Map functionality like this:
MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
To convert eigen matrix type into normal data type
MatrixXd resultEigen; // Eigen matrix with some result (non NULL!)
double *resultC; // NULL pointer <-- WRONG INFO from the site. resultC must be preallocated!
Map<MatrixXd>( resultC, resultEigen.rows(), resultEigen.cols() ) = resultEigen;
In this way you can get in and out from eigen matrix. Full credits goes to http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/
Solution 3
If the array is two-dimensional, one needs to pay attention to the storage order. By default, Eigen stores matrices in column-major order. However, a row-major order is needed for the direct conversion of an array into an Eigen matrix. If such conversions are performed frequently in the code, it might be helpful to use a corresponding typedef
.
using namespace Eigen;
typedef Matrix<int, Dynamic, Dynamic, RowMajor> RowMatrixXi;
With such a definition one can obtain an Eigen matrix from an array in a simple and compact way, while preserving the order of the original array.
From C array to Eigen::Matrix
int nrow = 2, ncol = 3;
int arr[nrow][ncol] = { {1 ,2, 3}, {4, 5, 6} };
Map<RowMatrixXi> eig(&arr[0][0], nrow, ncol);
std::cout << "Eigen matrix:\n" << eig << std::endl;
// Eigen matrix:
// 1 2 3
// 4 5 6
In the opposite direction, the elements of an Eigen matrix can be transferred directly to a C-style array by using Map
.
From Eigen::Matrix to C array
int arr2[nrow][ncol];
Map<RowMatrixXi>(&arr2[0][0], nrow, ncol) = eig;
std::cout << "C array:\n";
for (int i = 0; i < nrow; ++i) {
for (int j = 0; j < ncol; ++j) {
std::cout << arr2[i][j] << " ";
}
std::cout << "\n";
}
// C array:
// 1 2 3
// 4 5 6
Note that in this case the original matrix eig
does not need to be stored in row-major layout. It is sufficient to specify the row-major order in Map
.
Solution 4
You need to use the Map function again. Please see the example here: http://forum.kde.org/viewtopic.php?f=74&t=95457
lil
Updated on July 08, 2022Comments
-
lil almost 2 years
The Eigen library can map existing memory into Eigen matrices.
float array[3]; Map<Vector3f>(array, 3).fill(10); int data[4] = 1, 2, 3, 4; Matrix2i mat2x2(data); MatrixXi mat2x2 = Map<Matrix2i>(data); MatrixXi mat2x2 = Map<MatrixXi>(data, 2, 2);
My question is, how can we get c array (e.g. float[] a) from eigen matrix (e.g. Matrix3f m)? What it the real layout of eigen matrix? Is the real data stored as in normal c array?
-
eraoul over 7 yearsThe second part makes no sense. How can Eigen::Map magically take a NULL pointer (resultC) and copy data to it?? Indeed, I tried the code above with a sample 2x2 matrix and the Map segfaults, as you'd expect.
-
Pedro77 about 7 yearsJust ctrl+c ctrl+v from the site using incorrect information! This does not work. Someone can please correct this answer? Same here @eraoul
-
RHertel over 6 years@eraoul The first part doesn't make sense either. This answer produces wrong results because it does not account for the different storage order in Eigen and C
-
Calle Bergström over 5 years@Pedro77 For future someone:
Eigen::Matrix<float, -1, 3, Eigen::RowMajor> vertices_;
-
enigmaticPhysicist over 5 yearsIt's weird, but the data() member function is undocumented for some reason. I'm looking here: eigen.tuxfamily.org/…
-
janneb over 5 years@enigmaticPhysicist: eigen.tuxfamily.org/dox/…
-
enigmaticPhysicist over 5 yearsOh, there it is. Thanks, @janneb.
-
rayryeng almost 4 yearsWhat does computing the eigenvalues and eigenvectors have to do with this question?
-
niosus about 3 yearsI just want to point out here that this is expected that the commented out code segfaults.
Map
does not allocate memory, so you're trying to copy data into anullptr
essentially. -
Jamie almost 2 yearswhy is this not possible for the following type of data
fftw_complex *mat = (fftw_complex*) fftw_malloc((((n)*(n)))* sizeof(fftw_complex));
??