将Eigen Matrix转换为C数组

lil*_*lil 54 c++ arrays matrix eigen

本征库可以映射现有存储器到本征矩阵.

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);
Run Code Online (Sandbox Code Playgroud)

我的问题是,如何从特征矩阵(例如Matrix3f m)得到c数组(例如float [] a)?什么是特征矩阵的真实布局?真实数据是否存储在普通c数组中?

jan*_*neb 55

您可以使用Eigen Matrix类的data()成员函数.默认情况下,布局是column-major,而不是row-major作为多维C数组(可以在创建Matrix对象时选择布局).对于稀疏矩阵,前一句明显不适用.

例:

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.
Run Code Online (Sandbox Code Playgroud)

  • @Pedro77 对于未来的某人:`Eigen::Matrix&lt;float, -1, 3, Eigen::RowMajor&gt; vertices_;` (3认同)
  • 旁注,如果矩阵是通过延迟求值计算的,例如 `Eigen::Matrix&lt;float,2,2&gt;::Random()`,则必须首先调用 `.eval()` 以使矩阵具有可用“数据”功能。例如 `auto x = Eigen::Matrix&lt;float,2,2&gt;::Random().eval(); 自动 data_ptr = x.data();` (2认同)

GPr*_*hap 15

将普通数据类型转换为特征矩阵类型

  double *X; // non-NULL pointer to some data
Run Code Online (Sandbox Code Playgroud)

您可以使用Map功能创建nRows x nCols size double矩阵,如下所示:

  MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
Run Code Online (Sandbox Code Playgroud)

将特征矩阵类型转换为普通数据类型

  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;
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以从特征矩阵进出.完整学分归http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/

  • 第二部分毫无意义.Eigen :: Map如何神奇地采用NULL指针(resultC)并将数据复制到它?实际上,我尝试了上面的代码,带有一个2x2样本矩阵和Map segfaults,正如您所期望的那样. (3认同)
  • 只需使用不正确的信息从网站ctrl + c ctrl + v!这不起作用.有人可以请更正这个答案吗?同样在这里@eraoul (2认同)

RHe*_*tel 7

如果数组是二维的,则需要注意存储顺序。默认情况下,Eigen 按列主序存储矩阵。但是,将数组直接转换为特征矩阵需要行主序。如果在代码中频繁执行此类转换,则使用相应的typedef.

using namespace Eigen;
typedef Matrix<int, Dynamic, Dynamic, RowMajor> RowMatrixXi;
Run Code Online (Sandbox Code Playgroud)

有了这样的定义,我们可以以一种简单而紧凑的方式从数组中获得一个特征矩阵,同时保留原始数组的顺序。

从 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
Run Code Online (Sandbox Code Playgroud)

在相反的方向上,可以使用 将特征矩阵的元素直接转换为 C 样式数组Map

从 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 
Run Code Online (Sandbox Code Playgroud)

请注意,在这种情况下,原始矩阵eig不需要存储在行优先布局中。在 中指定行优先顺序就足够了Map