可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
The Eigen library can map existing memory into Eigen matrices.
float array[3]; Map(array, 3).fill(10); int data[4] = 1, 2, 3, 4; Matrix2i mat2x2(data); MatrixXi mat2x2 = Map(data); MatrixXi mat2x2 = Map(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?
回答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.
回答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( 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 ( 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/
回答3:
You need to use the Map function again. Please see the example here: http://forum.kde.org/viewtopic.php?f=74&t=95457
回答4:
The solution with Map above segfaults when I try it (see comment above).
Instead, here's a solution that works for me, copying the data into a std::vector from an Eigen::Matrix. I pre-allocate space in the vector to store the result of the Map/copy.
Eigen::MatrixXf m(2, 2); m(0, 0) = 3; m(1, 0) = 2.5; m(0, 1) = -1; m(1, 1) = 0; cout (p, m.rows(), m.cols()) = m; // Better code, which also copies into a std::vector: // Note that I initialize vec with the matrix size to begin with: std::vector vec(m.size()); Eigen::Map<:matrixxf>(vec.data(), m.rows(), m.cols()) = m; for (const auto& x : vec) cout
回答5:
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 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 eig(&arr[0][0], nrow, ncol); std::cout
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(&arr2[0][0], nrow, ncol) = eig; std::cout
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
.
回答6:
ComplexEigenSolver es; complex *eseig; es.compute(H); es.eigenvalues().transpose(); eseig=(complex *)es.eigenvalues().data();