72 votes

Convertir la matrice propre en tableau C

En Eigen permet de transformer une mémoire existante en 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 la suivante : comment obtenir un tableau c (par exemple float[] a) à partir d'une matrice propre (par exemple Matrix3f m) ? Quelle est la disposition réelle de la matrice propre ? Les données réelles sont-elles stockées comme dans un tableau c normal ?

1 votes

Ce ne sont pas des types de données standard. Est-ce que "Eigen" est le nom de la bibliothèque, ou une référence aux fondements mathématiques ? Dans ce dernier cas, de quelle bibliothèque proviennent les types ? De plus, le C n'a pas de modèles de types. Puisque les matrices sont bidimensionnelles, que voulez-vous exactement dans le tableau ordinaire ? Une ligne ou une colonne particulière, ou la matrice entière remodelée à une dimension ?

0 votes

@outis Eigen fait référence à un bibliothèque .

0 votes

@ChristianRau : c'est possible, mais je veux être absolument sûr que c'est bien à cela que Lil fait référence.

74voto

janneb Points 17303

Vous pouvez utiliser le données() fonction membre de la classe des matrices propres. La disposition par défaut est de type colonne-major, et non pas ligne-major comme pour un tableau C multidimensionnel (la disposition 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.

Ejemplo:

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.

4 votes

@Pedro77 Pour une future personne : Eigen::Matrix<float, -1, 3, Eigen::RowMajor> vertices_;

0 votes

C'est bizarre, mais la fonction membre data() est non documentée pour une raison quelconque. Je regarde ici : eigen.tuxfamily.org/

0 votes

@enigmaticPhysicist : eigen.tuxfamily.org/dox/

23voto

user1574779 Points 41

Pour convertir le type de données normales en type de matrice propre

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

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

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

Pour convertir le type de matrice propre en type de données normales

  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 la matrice propre. Tous les crédits vont à http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/

8voto

RHertel Points 8139

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 de rangée majeure est nécessaire pour la conversion directe d'un tableau en une matrice Eigen. Si de telles conversions sont effectuées fréquemment dans le code, il peut être utile d'utiliser un ordre de stockage 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.

Du tableau 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

Dans le sens inverse, les éléments d'une matrice propre peuvent être transférés directement dans un tableau de style C en utilisant Map .

De Eigen::Matrix à un tableau 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 

Notez que dans ce cas, la matrice originale eig n'a pas besoin d'être stocké dans une structure à rangée majeure. Il suffit de spécifier l'ordre des rangées dans le fichier Map .

3voto

Prashanth Points 21

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

0voto

eraoul Points 396

La solution avec la carte ci-dessus se bloque lorsque je l'essaie (voir le commentaire ci-dessus).

A la place, voici une solution qui fonctionne pour moi, copier les données dans un std::vector à partir d'une Eigen::Matrix. Je pré-alloue de l'espace dans le vecteur pour stocker le résultat de la Map/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 votes

Je veux juste signaler ici qu'il est prévu que le code commenté présente des erreurs. Map n'alloue pas de mémoire, donc vous essayez de copier des données dans un fichier nullptr essentiellement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X