将Eigen Matrix转换为C数组

时间:2011-12-09 08:53:36

标签: c++ arrays matrix eigen

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);

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

7 个答案:

答案 0 :(得分:49)

您可以使用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.

答案 1 :(得分:14)

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

  double *X; // non-NULL pointer to some data

您可以使用以下地图功能创建nRows x nCols尺寸双矩阵:

  MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );

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

  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;

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

答案 2 :(得分:3)

您需要再次使用Map功能。请看这里的例子: http://forum.kde.org/viewtopic.php?f=74&t=95457

答案 3 :(得分:3)

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

可能会有所帮助
using namespace Eigen;
typedef Matrix<int, Dynamic, Dynamic, RowMajor> RowMatrixXi;

通过这样的定义,可以以简单紧凑的方式从数组中获得特征矩阵,同时保留原始数组的顺序。

从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

在相反方向,可以使用Map将特征矩阵的元素直接传递到C风格的数组。

从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 

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

答案 4 :(得分:1)

当我尝试使用Map上面的segfaults解决方案时(请参阅上面的评论)。

相反,这是一个适合我的解决方案,将数据复制到来自Eigen :: Matrix的std :: vector中。我在向量中预先分配空间来存储Map / copy的结果。

{
  "links": {
    "self": "http://localhost:3000/api/clients/1/campaigns"
  },
  "data": [
    {
      "type": "campaigns",
      "relationships": {
        "client": {
          "links": {
            "related": "http://localhost:3000/api/campaigns/1/client"
          }
        }
      },
      "id": "1",
      "attributes": {
        "enddate": "2019-01-01T00:00:00.000Z",
        "name": "test",
        "startdate": null
      },
      "links": {
        "self": "http://localhost:3000/api/campaigns/1"
      }
    }
  ]
}

答案 5 :(得分:0)

我试过了:在(0,0)传递元素的地址并向前迭代。

for dictionary in Data:
    del dictionary['predictionValues']

这是输出:001011111101000010110100 数据似乎主要存储在行中

答案 6 :(得分:-2)

ComplexEigenSolver < MyMatrix > es;
complex<double> *eseig;
es.compute(H);
es.eigenvalues().transpose();
eseig=(complex<double> *)es.eigenvalues().data();