Converti Eigen Matrix in C array

La libreria Eigen può mappare la memoria esistente in matrici Eigen.

float array[3]; Map(array, 3).fill(10); int data[4] = 1, 2, 3, 4; Matrix2i mat2x2(data); MatrixXi mat2x2 = Map(data); MatrixXi mat2x2 = Map(data, 2, 2); 

La mia domanda è, come possiamo ottenere l’array c (es. Float [] a) da una matrice eigen (ad esempio Matrix3f m)? Qual è il layout reale della matrice di eigen? I dati reali sono archiviati come nel normale array c?

È ansible utilizzare la funzione membro data () della class Eigen Matrix. Il layout di default è column-major, non row-major come array C multidimensionale (il layout può essere scelto quando si crea un object Matrix). Per le matrici sparse ovviamente la frase precedente non si applica.

Per convertire il tipo di dati normale in un tipo di matrice Eigen

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

Puoi creare una matrice doppia di dimensione nRows x nCols usando la funzionalità Mappa come questa:

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

Per convertire il tipo di matrice Eigen in tipo di dati normale

  MatrixXd resultEigen; // Eigen matrix with some result (non NULL!) double *resultC; // NULL pointer <-- WRONG INFO from the site. resultC must be preallocated! Map( resultC, resultEigen.rows(), resultEigen.cols() ) = resultEigen; 

In questo modo puoi entrare e uscire dalla matrice eigen. I crediti completi vanno a http://dovgalecs.com/blog/eigen-how-to-get-in-and-out-data-from-eigen-matrix/

È necessario utilizzare nuovamente la funzione Mappa. Si prega di vedere l’esempio qui: http://forum.kde.org/viewtopic.php?f=74&t=95457

Se la matrice è bidimensionale, è necessario prestare attenzione all’ordine di archiviazione. Per impostazione predefinita, Eigen memorizza le matrici nell’ordine delle colonne. Tuttavia, è necessario un ordine di riga maggiore per la conversione diretta di un array in una matrice Eigen. Se tali conversioni vengono eseguite frequentemente nel codice, potrebbe essere utile utilizzare un typedef corrispondente.

 using namespace Eigen; typedef Matrix RowMatrixXi; 

Con tale definizione si può ottenere una matrice Eigen da una matrice in modo semplice e compatto, preservando l’ordine dell’array originale.

Dall’array C a Eigen :: Matrix

 int nrow = 2, ncol = 3; int arr[nrow][ncol] = { {1 ,2, 3}, {4, 5, 6} }; Map eig(&arr[0][0], nrow, ncol); std::cout << "Eigen matrix:\n" << eig << std::endl; // Eigen matrix: // 1 2 3 // 4 5 6 

Nella direzione opposta, gli elementi di una matrice Eigen possono essere trasferiti direttamente a un array in stile C utilizzando Map .

Dall'array Eigen :: Matrix a C

 int arr2[nrow][ncol]; Map(&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 

Nota che in questo caso la matrice originale eig non ha bisogno di essere archiviata nel layout row-major. È sufficiente specificare l'ordine di riga principale in Map .

La soluzione con Map above segfaults quando provo (vedi commento sopra).

Invece, ecco una soluzione che funziona per me, copiando i dati in un vettore std :: da un Eigen :: Matrix. Pre-allocare lo spazio nel vettore per memorizzare il risultato della mappa / copia.

 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(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 vec(m.size()); Eigen::Map(vec.data(), m.rows(), m.cols()) = m; for (const auto& x : vec) cout << x << ", "; cout << "\n"; // Output: 3, 2.5, -1, 0 
 ComplexEigenSolver < MyMatrix > es; complex *eseig; es.compute(H); es.eigenvalues().transpose(); eseig=(complex *)es.eigenvalues().data();