Convertir matrice Eigen en tableau C

Propres la bibliothèque peut cartographier la mémoire existante dans des matrices 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);

ma question Est, Comment Pouvons-nous obtenir c array (e.g. float[] A) à partir de la matrice propre (e.g. Matrix3f m)? Qu'elle est la véritable disposition des propres de la matrice? Les données réelles sont-elles stockées comme dans le tableau c normal?

38
demandé sur outis 2011-12-09 12:53:35

6 réponses

vous pouvez utiliser la fonction membre data() de la classe matrice Eigen. La mise en page par défaut est colonne-majeure, pas Ligne-majeure comme un tableau c multidimensionnel (la mise en page peut être choisie lors de la création d'un objet Matrix). Pour les matrices Éparses, La phrase précédente ne s'applique évidemment pas.

43
répondu janneb 2011-12-09 09:59:19

pour convertir le type de données normal en type de matrice propre

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

vous pouvez créer une double matrice de taille nRows x nCols en utilisant la fonctionnalité Map comme ceci:

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

pour convertir le type de matrice eigen en type de données normal

  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;

de cette façon, vous pouvez entrer et sortir de eigen matrix. Tous les crédits vont à http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/

12
répondu GPrathap 2017-04-02 00:53:00

vous devez utiliser la fonction Map à nouveau. Veuillez voir l'exemple ici: http://forum.kde.org/viewtopic.php?f=74&t=95457

3
répondu Prashanth 2012-06-19 11:52:20

si le tableau est bidimensionnel, il faut faire attention à l'ordre de stockage. Par défaut, Eigen stocke les matrices dans l'ordre colonne-majeur. Cependant, un ordre ligne-majeure est nécessaire pour la conversion directe d'un tableau en une matrice propre. Si de telles conversions sont effectuées fréquemment dans le code, il peut être utile d'utiliser un correspondant typedef.

using namespace Eigen;
typedef Matrix<int, Dynamic, Dynamic, RowMajor> RowMatrixXi;

avec une telle définition on peut obtenir une matrice propre à partir d'un tableau d'une manière simple et compacte, tout en préservant l'ordre du tableau original.

à Partir de C tableau de 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

dans la direction opposée, les éléments d'une matrice propre peuvent être transférés directement dans un tableau de style C en utilisant Map.

à Partir de Eigen::Matrice de C tableau

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 

Notez que dans ce cas la matrice d'origine eig n'a pas besoin d'être stocké dans la ligne-mise en page principale. Il suffit de spécifier la ligne ordre majeur dans Map.

3
répondu RHertel 2018-02-08 05:54:58

La solution avec la Carte ci-dessus de segmentation quand je l'ai essayer (voir le commentaire ci-dessus).

au lieu de cela, Voici une solution qui fonctionne pour moi, copier les données dans un vecteur std::à partir d'une matrice Eigen::. Je pré-affecte de l'espace dans le vecteur pour stocker le résultat de la carte/copie.

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
1
répondu eraoul 2018-01-11 07:43:23
ComplexEigenSolver < MyMatrix > es;
complex<double> *eseig;
es.compute(H);
es.eigenvalues().transpose();
eseig=(complex<double> *)es.eigenvalues().data();
-2
répondu user3097951 2013-12-13 03:50:04