Boost logo

Ublas :

From: Gunter Winkler (guwi17_at_[hidden])
Date: 2007-06-14 07:14:59

Am Mittwoch, 13. Juni 2007 19:22 schrieb Vardan Akopian:
> > I guess getting a vector-view onto a matrix is not possible in
> > uBLAS.
> Getting a vector-view onto a dense matrix is possible in uBLAS,
> although admittedly a bit awkward:
> matrix<double> mat(10, 20);
> // ...
> size_t data_size =;
> shallow_array_adaptor<double> shared(data_size,;
> vector<double, shallow_array_adaptor<double> > vec(data_size,
> shared);
> This approach allows to have any kind of "reshaping" operations (a la
> Matlab reshape), without copying the data.
> Note, that this requires BOOST_UBLAS_SHALLOW_ARRAY_ADAPTOR to be
> defined.

However, this adaptor must be used with care. It is especially important
to use noalias() on every operation.

vector<double, shallow_array_adaptor<double> > v(n, shared1);
matrix A; vector b;

v = prod(A,b);

this computes a temporary t = prod(A,b); of the same type as v which
however owns its storage. Then it calls v1.assign_temporary(t) which
swaps the data of v and t. Thus now v owns its storage and t is

v.assign( prod(A,b) ); and noalias( v ) = prod(A,b);
work as expected because there is no temporary involved.

Much more dangerous is the modification of the original owner. Imagine
you call

mat = prod(A, B)

after creation of vec. Then mat swaps its data array with the temporary
vector. Then the temporary is destroyed but vec still has a pointer
into that memory. That's way we used boost::shared_array to do the
reference counting. The worst effect is, however, that vec does not
change although mat changes!

again: the .assign and noalias() version works as expected.

The next surprise is what happens on contruction:

vector<double, shallow_array_adaptor<double> > v2(v);
vector<double, shallow_array_adaptor<double> > v3;
v3 = v;

Both versions result in a copy of v which owns its storage. Thus they
are essentially usual ublas vectors. Is this what you expect of a
shallow array?

To summarize:

The use of shallow_array_adaptor does not guarantee a permanent relation
of the original array and the created vector unless one avoids
operations that use a temporary.