将特征矩阵转换为 C 数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8443102/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert Eigen Matrix to C array
提问by lil
The Eigenlibrary 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?
我的问题是,我们如何从特征矩阵(例如 Matrix3f m)中获得 c 数组(例如 float[] a)?特征矩阵的真实布局是什么?真实数据是否存储在普通的 c 数组中?
回答by janneb
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.
您可以使用Eigen Matrix 类的data()成员函数。默认布局是列优先,而不是行优先作为多维 C 数组(可以在创建 Matrix 对象时选择布局)。对于稀疏矩阵,前面的句子显然不适用。
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.
回答by GPrathap
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:
您可以使用 Map 功能创建一个 nRows x nCols 大小的双矩阵,如下所示:
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/
通过这种方式,您可以进出特征矩阵。全部学分转到http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/
回答by Prashanth
You need to use the Map function again. Please see the example here: http://forum.kde.org/viewtopic.php?f=74&t=95457
您需要再次使用 Map 功能。请看这里的例子:http: //forum.kde.org/viewtopic.php?f=74&t=95457
回答by RHertel
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
.
如果数组是二维的,则需要注意存储顺序。默认情况下,Eigen 按列主序存储矩阵。但是,将数组直接转换为特征矩阵需要行主序。如果在代码中频繁执行此类转换,则使用相应的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
从 C 数组到 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
.
在相反的方向上,可以使用 将特征矩阵的元素直接转换为 C 样式数组Map
。
From Eigen::Matrix to C array
从 Eigen::Matrix 到 C 数组
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
.
请注意,在这种情况下,原始矩阵eig
不需要存储在行优先布局中。在 中指定行优先顺序就足够了Map
。
回答by eraoul
The solution with Map above segfaults when I try it (see comment above).
当我尝试时,Map 上面有段错误的解决方案(见上面的评论)。
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::Matrix 复制到 std::vector 中。我在向量中预先分配空间来存储 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 << m << "\n";
// Output:
// 3 -1
// 2.5 0
// Segfaults with this code:
//
// float* p = nullptr;
// Eigen::Map<Eigen::MatrixXf>(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<float> vec(m.size());
Eigen::Map<Eigen::MatrixXf>(vec.data(), m.rows(), m.cols()) = m;
for (const auto& x : vec)
cout << x << ", ";
cout << "\n";
// Output: 3, 2.5, -1, 0
回答by user3097951
ComplexEigenSolver < MyMatrix > es;
complex<double> *eseig;
es.compute(H);
es.eigenvalues().transpose();
eseig=(complex<double> *)es.eigenvalues().data();