2012-08-17 21 views
6

Desidero mappare una matrice di doppia a una struttura MatrixXd esistente. Finora sono riuscito a mappare la matrice Eigen a un array semplice, ma non riesco a trovare il modo di farlo indietro.Mappatura della matrice su una matrice Eigen esistente

void foo(MatrixXd matrix, int n){ 

double arrayd = new double[n*n]; 
// map the input matrix to an array 
Map<MatrixXd>(arrayd, n, n) = matrix; 

    //do something with the array 
      ....... 
// map array back to the existing matrix 

} 
+1

Che cos'è questa funzione Mappa <>? Puoi mostrarlo? –

+0

Questo è tutto quello che so http://eigen.tuxfamily.org/dox/TutorialMapClass.html – Manolete

risposta

13

Non sono sicuro di quello che vuoi, ma proverò a spiegare.

Stai mixando double e float nel codice (un MatrixXf è una matrice in cui ogni voce è un float). Per il momento suppongo che questo sia stato involontario e che tu voglia usare il doppio dappertutto; vedi sotto per se questa era davvero la tua intenzione.

L'istruzione Map<MatrixXd>(arrayd, n, n) = matrix copia le voci di matrix in arrayd. E 'equivalente al ciclo

for (int i = 0; i < n; ++i) 
    for (int j = 0; j < n; ++j) 
     arrayd[i + j*n] = matrix(i, j); 

Per copiare le voci di arrayd in matrix, si dovrebbe utilizzare l'assegnazione inversa: matrix = Map<MatrixXd>(arrayd, n, n).

Tuttavia, di solito la seguente tecnica è più utile:

void foo(MatrixXd matrix, int n) { 
    double* arrayd = matrix.data(); 
    // do something with the array 
} 

punti Ora arrayd alle voci nella matrice e si può elaborarlo come qualsiasi matrice C++. I dati sono condivisi tra matrix e arrayd, quindi non è necessario copiare nulla alla fine. Per inciso, non è necessario passare n alla funzione foo(), perché è memorizzata nella matrice; usa matrix.rows() e matrix.cols() per interrogare il suo valore.

Se si desidera copiare un MatrixXf in una matrice di doppi, è necessario includere il cast esplicitamente. La sintassi in Eigen per questo è: Map<MatrixXd>(arrayd, n, n) = matrix.cast<double>().

+0

scusa per la confusione con float e double. Ora aggiornato! – Manolete

+0

Questa è un'ottima spiegazione. Cosa succede se i dati completamente nuovi vengono copiati in arrayd? Anche questi dati saranno condivisi in matrice? L'idea è di inviare arrayd ad una GPU, fare calcoli e tornare alla CPU avere i dati in un MatrixXd – Manolete

+0

@Manolete Sì, che dovrebbe funzionare –

8

Non è necessario eseguire alcuna operazione di retromarcia.

Quando si utilizza Eigen :: Map si sta mappando un array raw in una classe Eigen. Ciò significa che ora è possibile leggere o scrivere utilizzando le funzioni Eighen.

Se si modifica l'array mappato, le modifiche sono già presenti. Puoi semplicemente accedere alla matrice originale.

float buffer[16]; //a raw array of float 

//let's map the array using an Eigen matrix 
Eigen::Map<Eigen::Matrix4f> eigenMatrix(buffer); 

//do something on the matrix 
eigenMatrix = Eigen::Matrix4f::Identity(); 


//now buffer will contain the following values 
//buffer = [1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1]