Boost logo

Ublas :

Subject: Re: [ublas] fixed_vector and fixed_storage.
From: Nasos Iliopoulos (nasos_i_at_[hidden])
Date: 2009-09-09 10:47:05

Answering to myself just to keep a record on the list:

I think i solved the problem I had by defining a new traits class:

template<typename T>
struct prefered_temporary_type {typedef T temporary_storage_type;};

template<typename T, std::size_t N>

struct prefered_temporary_type< fixed_array<T, N> > { typedef bounded_array<T,N> temporary_storage_type; };
this mechanism chooses self_type for all the arrays and is specialised for the fixed_array to choose bounded_array. There also needs to be a modification in the vector class, which although works (passes all the unit test) I am not sure if there are any implications especially with sparse vectors:

- typedef self_type vector_temporary_type;
+ typedef vector<T, typename prefered_temporary_type<A>::temporary_storage_type> vector_temporary_type;
If somebody has any suggestions or comments let me know!

Nasos Iliopoulos

From: nasos_i_at_[hidden]
To: ublas_at_[hidden]
Date: Tue, 8 Sep 2009 18:21:33 -0400
Subject: [ublas] fixed_vector and fixed_storage.

Hello all.

I am trying to implement a fixed_array / fixed_vector couple and have come across a difficulty. My fixed_array class is pretty similar to the bounded_array class, but with the size_t size_ member thrown away and with the necessary changes in functions returning or requiring this variable. While most things work well in the unit tests, the difficulty arises when assigning to a projection, i.e.:

ublas::fixed_vector<double, 3> v1, v2;project (v1, ublas::range(0,1)) = project (v2, ublas::range(0,1));

Tracing back the function calls I get the following flow:

1. basic_range (size_type start, size_type stop) (constructor of the second ublas::range)2. vector_range (vector_type &data, const range_type &r) (constructor of the second ublas::range) - requests v2.size()
3. basic_range (size_type start, size_type stop) (constructor of the first ublas::range)
4. vector_range (vector_type &data, const range_type &r) (constructor of the first ublas::range) - requests v1.size()

5. vector_range &operator = (const vector_range &vr)
6. vector (const vector_expression<AE> &ae) (implicit vector construction from a vector_range)7. fixed_array (size_type size)8. vector_assign (V &v, const vector_expression<E> &e, dense_proxy_tag)9. indexing_vector_assign (V &v, const vector_expression<E> &e)10. size_type size (BOOST_UBLAS_SAME (v.size (), e ().size ()));

and in line 10 is where the BOOST CHECK fails. What happens is that v.size() (which is temporary of a fixed_vector<double, 3>) has of course a size of 3, while e().size() has a size of 1 (as been the range(0,1).
In order to come over this error I changed my fixed_vector typedefs to instead of using self_type as the
vector_temporary_type, to use a bounded_vector<T, N>, which does the trick (since bounded_vector is not actually fixed and can be resized to be of the same size as the vector_range).

Although in this case the same problem arises when creating a vector with storage container the fixed_array (i.e. vector<double, fixed_array<double, 3> > ), where the vector_temporary_type is not so easy to change.

So my questions are:
A. Is there an elegant way to alter the vector_temporary type in ublas::vector given only the storage type?
B. Would it be a mess to change (10.) BOOST_UBLAS_SAME to something like BOOST_UBLAS_LESS?
C. Is there any other workaround through the traits mechanism I am not aware of?

And finally are the developers interested in a fixed_array / fixed_vector, if it gets to work? I think it will provide some nice ground for metaprograms and a few other convenience tricks that can come handy.

Thanks in advance
Nasos Iliopoulos

Windows Live: Keep your friends up to date with what you do online. Find out more.
Get back to school stuff for them and cashback for you.