Boost logo

Ublas :

Subject: Re: [ublas] Matrix in Preallocatd Chunk of Memory, Slices?
From: Gunter Winkler (guwi17_at_[hidden])
Date: 2009-02-05 15:27:54

Jonas Huckestein schrieb:
> Hello there,
> I just started using ublas (a great library, congratulations!) and
> have a couple of questions :)
> i have preallocated a matrix field of doubles like
> double* array = new double[r][r];
> Now I want to use that field of memory in an incremental algorithm,
> which starts with a small 1x1 matrix which will grow but never exceed
> rxr. is something like the following possible:
> matrix<double> m (1,1, array); // I made this up :)
there are two array adapters available (see storage.hpp).

    // Array adaptor with normal deep copy semantics of elements
    class array_adaptor;

    // Array adaptor with shallow (reference) copy semantics of elements.
    // shared_array is used to maintain reference counts.
    // This class breaks the normal copy semantics for a storage
container and is very dangerous!
    class shallow_array_adaptor;

However ublas containers rely on their own memory management, thus it is
not recommended to use a preallocated matrix. If you know the maximum
sizes of your matrix, then you can use bounded_matrix which takes the
maximum rows/columns as template arguments.
> // then in each step of the algorithm
> while(...) {
> if( increase_dimension ) {
> m.resize(i+1, i+1); // resize, without allocating or moving memory
> }
> m = something*m // do stuff
> }
> In fact, I do not know how the data of a dense matrix is stored. Is it
> stored like a two-dimensional array? Or perhaps as an array
> double[rows*cols].
The latter: all containers (except c_matrix) store their data in a
linear array.
> Is it possible to use slices instead? Do slices have a large
> performance overhead? Could/Should I do the following:
> matrix<double> m(r,r); // allocate huge matrix
> // then in each step of the algorithm
> while(...) {
> if( increase_dimension ) {
> dim ++;
> }
> subslice(m,0,1,dim,0,1,dim) = something*subslice(m,0,1,dim,0,1,dim)
> // does this work? is it fast?
> }

Yes this is a valid approach. You can even use the free function
project(matrix, range_or_slice, range_or_slice) to get reference to the
corresponding matrix elements. Ublas in usually creates only proxy
classes. If you want to copy values then you have to assign the proxy
(range, slice) to a vector/matrix.

> Can I copy a matrix into a matric_slice, thus copying the elements of
> the matrix into the slice, like follows?
> subslice(m,0,1,dim,m,0,1,dim) = some other matrix;
yes - if the dimensions matche.
> What is the fastest way to copy a column of a sparse matrix in
> compressed row_major format into the column of a dense matrix in
> column major format?
This is quite difficult to answer. I think the fastest way is to use
axpy_prod with a unit_vector to select the column. I'd suggest to avoid
accessing data orthogonal to the storage direction (especially for
sparse types...)