Markus,
I was browsing the mail archives yesterday and I came across those posts. I think that the fixed vector class will have some problems with projections as discussed here:
http://lists.boost.org/MailArchives/ublas/2009/09/3678.php
A fairly satisfying solutions for that design can be found here:
http://lists.boost.org/MailArchives/ublas/2009/09/3682.php
I also believe that the derivation from the container classes will not have this inelegant style (defining some new traits used by only one container type to get the projections working).
> Sharing of common code is important for maintainability and other obvious
> reasons, it should be a high priority goal.
That's true and when you browse uBlas sources you can be easily confused by the amount of repetitive code.
> best place to perform vector arithmetic. Can you sketch the inheritance
> hierarchy you have in mind?
At first I would suggest something like:
vector_container->dense_container->vector
vector_container->dense_container->fixed_vector
vector_container->dense_container->c_vector
vector_container->dense_container->bounded_vector
dense_container can implement most of the interface. Sparse containers can have similar hierarchy.
Because though of the large uBlas codebase, I started comparing interfaces and implementations of uBlas classes. I find many commonalities, but I don't know if we can gather them into a few types (most likely we can).
Look for example at operator +=. The same implementation is repeated many times and it can certainly (along with other member functions) be abstracted: (I hope the following does not appear very dense on the mailing list):
Category 1:
---------------
hermitian_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
vector_of_vector& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
c_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
mapped_vector_of_mapped_vector& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
symmetric_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
triangular_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
generalized_vector_of_vector& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae); return assign_temporary (temporary); }
Category 2:
----------------
compressed_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae, capacity_); return assign_temporary (temporary); }
coordinate_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae, capacity_); return assign_temporary (temporary); }
Category 3:
---------------
banded_matrix& operator += (const matrix_expression<AE> &ae) { self_type temporary (*this + ae, lower_, upper_); return assign_temporary (temporary); }
Furthermore we must consider the implications of uBlas' polymorphic design (static with crtp and Barton-Nackman) rather than through virtual functions, which I believe must be retained to enforce some performance goodies.
Best,
Nasos
> To: ublas@lists.boost.org
> From: grabner@icg.tugraz.at
> Date: Fri, 6 Aug 2010 01:54:24 +0200
> Subject: Re: [ublas] fixed size vector in boost::numeric::ublas?
>
> Nasos Iliopoulos wrote:
>
> >
> > Markus,
> >
> > Please find attached some basic tests I did on the fixed types. It seems
> > that everything works as expected :).
> Thanks! I can confirm that they work with gcc-4.5.
>
> > I did not run the ublas unittests
> > though to see whether the changes affect other components. (I don't find
> > any reason why it should).
> I'll have a look at it when we agreed on the design.
>
> > I am divided between the desire to see the fixed_vector and matrix in
> > uBlas and scalability and maintenance concerns.
> >
> > 1. Putting the fixed types as they are into uBlas:
> > Pros:
> > a Does not seem to change the matrix functionality
> > b Will give time to people to play before the next release.
> > c Does not constitute a major change in the container types.
> > Cons:
> > d There are maybe some things we are missing and will badly affect other
> > uBlas components.
> The current fixed_vector proposal is more or less a bounded_vector (with an
> additional lower bound which is identical to the upper bound), so it should
> be as complete as the bounded_vector.
>
> > e We introduce an ill-conditioned design by having a
> > resize function in a fixed container classes (I think Karl is right here,
> > although I am not as absolute about the matter).
> This is true for the current definition of the vector concept. Is it
> acceptable to modify the concept such that the resize method checks the
> requested size against a valid range (which is a single integer in the fixed
> case) and throws if it is outside? Then the method is still there, but its
> semantic is compatible with the fixed vector and matrix types as suggested
> by you below.
>
> > 2. Investigating other options like sub-classing the vector_container and
> > matrix_container classes: Pros:
> > a Certainly does not affect the current state of uBlas at all.
> > b There is no vector_container concept in uBlas concepts, we are probably
> > free to define it (i.e. without the resize function)
> > c Because the fixed
> > type do not need an uBlas storagearray, we don't need to satisfy its
> > requirements either (we get away with the sizing constructor).
> > d Its
> > development may be a simple refinement of Markus' fixed containers
> > implementation
> > Cons:
> > e Will probably need a redefinition of many things
> > (like iterators for fixed types).
> > f We don't know whether containers are
> > totally compatible with the rest of uBlas (they should be though,
> > otherwise some things should change in uBlas).
> > g Its development may take
> > much more time than what it looks at a first glance.
> >
> > Concerning 1.e.:
> > We will indeed be ok with having the resize function just check for size
> > compatibility. I would argue though to at least put a warning directive,
> > so that we give the developers the time to update their design in case we
> > decide to get rid of the resize. In such a case I think I would personally
> > feel fairly comfortable going with the current Markus' design.
> >
> > Concering 2d and 2g:
> > We will need to investigate option 2 because it may solve all the
> > problems, especially if it doesn't require extended implementations.
> It will solve 1e, but not Jesse's requirement of having the resize() method
> even for fixed size types.
>
> > Concerning 2e
> > Furthermore we should keep in mind that we might introduce most of the
> > functionality of vector into vector_container (similarly for matrix), as
> > fixed and dynamic vectors can share a lot.
> Sharing of common code is important for maintainability and other obvious
> reasons, it should be a high priority goal. The current implementation of
> the c_vector has its own iterators etc., which could probably be replaced by
> common code.
>
> As far as I understand the ublas design, vector_container is mainly used as
> a "connector" between a vector and a vector expression, it may not be the
> best place to perform vector arithmetic. Can you sketch the inheritance
> hierarchy you have in mind?
>
> Kind regards,
> Markus
>
>
> --
> Markus Grabner
> Institute for Computer Graphics and Vision
> Graz University of Technology, Inffeldgasse 16a/II, 8010 Graz, Austria
> WWW: http://www.icg.tugraz.at/Members/grabner
>
> _______________________________________________
> ublas mailing list
> ublas@lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/ublas
> Sent to: nasos_i@hotmail.com