2010-09-21 21 views
7

Sono confuso su come funziona boost :: compressed_matrix. Supponiamo Dichiaro il compressed_matrix simili:boost basi di base compresse

boost::numeric::ublas::compressed_matrix<double> T(1000, 1000, 3*1000); 

Questo alloca spazio per 3 * 1000 elementi in una matrice 1000x1000. Ora come faccio a dargli le posizioni che sono gli elementi diversi da zero? Quando e come vengono impostati gli elementi diversi da zero? È ogni volta che assegno un elemento nella matrice, ad es. B (4,4) = 4, contrassegna quell'elemento come non-zero?

Sarei davvero grato se potessi aiutarmi a imparare questo utilizzando un esempio se possibile. Qualche visione dell'implementazione interna sarebbe grandiosa. Voglio assicurarmi che non scriva programmi che non sono ottimali per il lavoro di congettura.

grazie!

risposta

3

matrice compressa ha un contenitore lineare sottostante (unbounded_array di default, ma si può rendere bounded_array o std::vector se si desidera), che contiene tutti gli elementi non nulli della matrice, in row-major (di default) ordine. Ciò significa che ogni volta che si scrive un nuovo elemento diverso da zero nella matrice compressa, è inserito nell'array sottostante. Se non si sta riempiendo l'ordine matrice (riga principale), ogni inserimento sarà O (n). Quando si modifica un elemento non zero esistente, viene semplicemente modificato nell'array sottostante.

Ecco un semplice test per vedere che cosa la struttura sottostante si presenta come:

#include <boost/numeric/ublas/matrix_sparse.hpp> 
#include <boost/numeric/ublas/storage.hpp> 
namespace ublas = boost::numeric::ublas; 
void show_array(const ublas::unbounded_array<double>& a) 
{ 
    for(size_t i=0; i<a.size(); ++i) 
      std::cout << a[i] << ' '; 
    std::cout << '\n'; 
} 
int main() 
{ 
    ublas::compressed_matrix<double> m (10, 10, 3 * 10); 
    m(0, 5) = 1; // underlying array is {1, 0, 0, 0, ...} 
    show_array(m.value_data()); 
    m(0, 6) = 2; // underlying array is {1, 2, 0, 0, ...} 
    show_array(m.value_data()); 
    m(0, 4) = 3; // underlying array is {3, 1, 2, 0, ...} 
    show_array(m.value_data()); 
    m(0, 4) = 7; // underlying array is {7, 1, 2, 0, ...} 
    show_array(m.value_data()); 
} 
+1

c'è qualche vantaggio nel specificare il terzo argomento del costruttore - no degli elementi diversi da zero? Cosa succede se non lo specifichi? – user236215

+2

Se inizi con 'unbounded_array' che è troppo corto per contenere tutti i tuoi non-zero, crescerà automaticamente se necessario, causando allocazioni di memoria e molte copie che si verificano ogni volta che un elemento diverso da zero viene scritto nella matrice che supera la capacità. Beh, in pratica, cresce in blocchi, come 'std :: vector' fa su' push_back', quindi non lo vedremo su ogni scrittura: esperimento con l'esempio precedente: crea la mia matrice compressa (3, 3), e aggiungi non zero a quattro elementi diversi. – Cubbi

1

è possibile utilizzare l'operatore (i,j) per creare implicitamente un elemento diverso da zero o utilizzare la funzione insert_element per inserire l'elemento in modo esplicito.

Posto migliore è in realtà guardare dentro implementazione:

http://www.tena-sda.org/doc/5.2.2/boost/d2/db7/matrix__sparse_8hpp-source.html#l02761

true_reference insert_element (size_type i, size_type j, t const_reference)

inserisce il valore t al j-esimo elemento di l'i-esima fila. Gli elementi duplicati non sono ammessi.


erase_element vuoto (size_type i, j size_type)

Cancella il valore al j-esimo elemento della riga i-esima.

+0

che il codice sorgente di riferimento molto utile. grazie – user236215

Problemi correlati