La bibliothèque Eigen peut mapper la mémoire existante en matrices propres.
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 un tableau c (par exemple float [] a) à partir d'une matrice propre (par exemple Matrix3f m)? Quelle est la véritable disposition de la matrice propre? Les données réelles sont-elles stockées comme dans un tableau c normal?
Vous pouvez utiliser la fonction membre data () de la classe Eigen Matrix. La disposition par défaut est la colonne principale, pas la ligne principale comme un tableau C multidimensionnel (la disposition peut être choisie lors de la création d'un objet Matrix). Pour les matrices clairsemées, la phrase précédente ne s'applique évidemment pas.
Exemple:
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.
Pour convertir un type de données normal 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é Carte comme ceci:
MatrixXd eigenX = Map<MatrixXd>( X, nRows, nCols );
Pour convertir un type de matrice propre 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 la matrice propre. Les crédits complets vont à http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/
Vous devez réutiliser la fonction Carte. Veuillez voir l'exemple ici: http://forum.kde.org/viewtopic.php?f=74&t=95457
Si le tableau est bidimensionnel, il faut faire attention à l'ordre de stockage. Par défaut, Eigen stocke les matrices dans l'ordre des colonnes principales. Cependant, un ordre de 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 typedef
correspondant.
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 de manière simple et compacte, tout en préservant l'ordre du tableau d'origine.
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 opposé, les éléments d'une matrice propre peuvent être transférés directement vers un tableau de style C en utilisant Map
.
De Eigen :: Matrix à C array
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ée dans la disposition des lignes principales. Il suffit de spécifier l'ordre des lignes principales dans Map
.
La solution avec Map ci-dessus segfaults quand je l'essaye (voir le commentaire ci-dessus).
Au lieu de cela, voici une solution qui fonctionne pour moi, en copiant les données dans un vecteur std :: à partir d'une matrice Eigen ::. Je pré-alloue 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