2014-11-03 37 views
5

Attualmente sto provando a convertire qualche codice Python in C++. Un problema "piccolo" sta cambiando le dimensioni di una matrice. È possibile rimodellare una matrice in C++ simile alla funzione Python reshape?Come rimodellare una matrice?

Ad esempio, in Python posso facilmente creare un array con numpy e rimodellare facilmente le dimensioni.

a = np.array([[1,2,3],[4,5,6]]) 
>>> a.reshape(3,2) 
array([[1, 2], 
     [3, 4], 
     [5, 6]]) 

Come ho potuto farlo in C++? Forse questa è una domanda semplice ma sono completamente incapace di farlo. Ho visto questo all'interno della libreria OpenCV con la classe Mathere, tuttavia sta dimostrando di essere faticosamente difficile da funzionare correttamente con MinGW, per non parlare di un'aggiunta molto grande per una singola funzione. Sarebbe l'ideale se ciò fosse possibile con le funzioni di "base".

+0

Questa è in realtà una domanda molto complessa. In NumPy è facile perché gli array NumPy tengono traccia dei loro passi e della loro forma; [questo articolo] (http://arxiv.org/pdf/1102.1523) descrive la struttura e può fornire ispirazione anche per i programmi C++. –

risposta

4

quanto riguarda la memoria è disposto contiguo (ad esempio matrici C strisciamento), è possibile reinterpretare il tipo con differenti indici:

int array[2][3] = { { 1, 2, 3 }, 
         { 4, 5, 6 } 
        }; 

// Reinterpret the array with different indices 
int(*array_pointer)[3][2] = reinterpret_cast<int(*)[3][2]>(array); 

for (int x = 0; x < 3; ++x) { 
    for (int y = 0; y < 2; ++y) 
     std::cout << (*array_pointer)[x][y] << " "; 
    std::cout << std::endl; 
} 
// Output: 
// 1 2 
// 3 4 
// 5 6 

Example

Quanto sopra

è solo un esempio per mostrare che il problema si riduce in realtà a come è strutturata la memoria nella classe matrix.

Nel caso in cui la classe utilizzi uno std::vector<int> internamente con indici lineari, è sufficiente reinterpretare tali indici in base ai propri schemi di accesso.

+1

Questo è esattamente quello che stavo cercando. Grazie! – cdeterman

0

Dipende dalla classe della matrice che si sta utilizzando. Se si scrive il proprio: ci sono due comuni tecniche di implementazione: una std::vector<double>, con calcoli di indice per trovare il piatto indice di e un std::vector<std::vector<double>>, con una classe invariante che tutti i membri del vettore esterno deve avere la stessa misura. Se si utilizza il primo, rimodellare è facile, a partire da in quanto la dimensione totale non cambia (ed è difficile immaginare che cosa significherebbe altrimenti). Se si utilizza il secondo, la modifica di richiede probabilmente la creazione di una copia con una nuova forma.

0

Non esiste una libreria di matrici standard in C++, quindi si è da soli quando si tratta di matrici. Un modo per memorizzare i dati di una matrice è in un array semplice. Dovrai quindi eseguire l'aritmetica della riga e della colonna quando accederai a singole righe e colonne. Nel tuo caso la risagoma viene quindi gratuitamente sostituendo semplicemente le dimensioni di righe e colonne.

Se si desidera una libreria matrix, provare: GLM.

3

Ecco un esempio utilizzando boost::ublas:

#include <iostream> 
#include <boost/numeric/ublas/matrix.hpp> 

//... 

using namespace boost::numeric::ublas; 

matrix<double> a(2, 3); 
a(0, 0) = 1; 
a(0, 1) = 2; 
a(0, 2) = 3; 
a(1, 0) = 4; 
a(1, 1) = 5; 
a(1, 2) = 6; 
matrix<double> r(3, 2, a.data()); 

for (int i = 0;i < 3;++i) 
{ 
    for (int j = 0;j < 2;++j) 
    std::cout << r(i, j) << ", "; 
    std::cout << std::endl; 
} 

1, 2,

3, 4,

5, 6,

1

Un leggero, facile -to-use La libreria algebra lineare C++ è Armadillo e fornisce la funzionalità reshape.

#include <armadillo> 
using namespace arma; 
int main() 
{ 
    // C++11 
    // mat a = { { 1, 2, 3 }, 
    // { 4, 5, 6 } }; 

    // C++98 
    mat a; 
    a << 1 << 2 << 3 << endr 
     << 2 << 4 << 6 << endr; 

    a.reshape(3, 2); 
    a.print(); 

    return 0; 
} 

Nota: io suggerirei di non fare using namespace arma; e invece fare arma::mat e arma::endr, ecc ho fatto l'esempio solo per chiarezza.

Problemi correlati