将特征矩阵转换为 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:34:31  来源:igfitidea点击:

Convert Eigen Matrix to C array

c++arraysmatrixeigen

提问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 eigdoes 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();