2010-09-21 15 views
7

Estoy confundido sobre cómo funciona boost :: compressed_matrix. Supongamos que declaro la compressed_matrix como esto:aumentar los conceptos básicos de la matriz comprimida

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

Esto asigna espacio para 3 * 1000 elementos en una matriz de 1000x1000. Ahora, ¿cómo le doy las ubicaciones que son los elementos distintos de cero? ¿Cuándo y cómo se establecen los elementos distintos de cero? ¿Es cada vez que asigno un elemento en la matriz, p. B (4,4) = 4, ¿marcaría ese elemento como distinto de cero?

Realmente apreciaría si pudiera ayudarme a aprender esto usando un ejemplo si es posible. Alguna idea de la implementación interna sería genial. Quiero asegurarme de no escribir programas que son subóptimos por trabajo de adivinación.

gracias!

Respuesta

3

matriz de comprimido tiene un recipiente lineal subyacente (unbounded_array por defecto, pero se puede hacer que sea bounded_array o std::vector si lo desea), que contiene todos los elementos no nulos de la matriz, en la fila-mayor (por defecto) orden. Eso significa que cada vez que escriba un nuevo elemento distinto de cero en la matriz comprimida, es insertado en esa matriz subyacente. Si no está completando la matriz en orden (mayor fila), cada inserción será O (n). Cuando está cambiando un elemento existente distinto de cero, simplemente se cambia en el conjunto subyacente.

He aquí una sencilla prueba para ver cuál es la estructura subyacente parece:

#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

¿hay alguna ventaja de especificar el tercer argumento constructor - no de elementos distintos de cero? ¿Qué pasa si no lo especifico? – user236215

+2

Si comienza con 'unbounded_array' que es demasiado corto para contener todos sus no-ceros, crecerá automáticamente según sea necesario, causando asignaciones de memoria y muchas copias que suceden cada vez que se escribe un elemento distinto de cero en la matriz que excede la capacidad. Bueno, en la práctica, crece en pedazos, como 'std :: vector' en' push_back', por lo que no lo verá en cada escritura: experimento con el ejemplo anterior: hacer mi matriz comprimida (3, 3) y agrega no-ceros a cuatro elementos diferentes. – Cubbi

1

puede usar el operador (i,j) para crear un elemento distinto de cero implícitamente o usar la función de inserción de elementos para insertar el elemento de forma explícita.

El mejor lugar es en realidad mirar dentro de la ejecución:

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

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

Inserta el valor de t en el j-ésimo elemento de la i-ésima fila. Los elementos duplicados no están permitidos.


erase_element void (size_type i, size_type j)

Borra el valor en el j-ésimo elemento de la fila i-ésima.

+0

que la referencia de código fuente muy útil. Gracias – user236215

Cuestiones relacionadas