Boost logo

Ublas :

Subject: Re: [ublas] size1 and size2
From: Jesse Perla (jesseperla_at_[hidden])
Date: 2009-09-14 09:47:18

On Mon, Sep 14, 2009 at 8:58 AM, Nasos Iliopoulos <nasos_i_at_[hidden]>wrote:

> Hello,
> > A.size1() ==> m if row_major OR n if column_major
> > A.size2() ==> n if row_major OR m if column_major
> I think this tries to bring together STL semantics and Mathematical
> semantics and should be avoided. I argue that it should be: size1()<=>nrows
> and size2()<=>ncols. After all an implementation like
> begin<tag::major>(MAT); can provide more elegant STL semantics if someone
> wants to use it.
> If you think that it is useful to have a major and minor size_..() member
> function I believe the one proposed by er is more apropriate, i.e.
> size_major, size_minor.
> For the record basic_column_major and basic_row_major functors already
> implement this functionality (members size_M and size_m) in functional.hpp.
> This implementation is a bit odd at first but it is there to avoid exposing
> matrix into layout_type.

My preference would be for whatever is consistent with GLAS and/or MTL. I
want to write generic code that could work with different libraries in case
I switch up. We also might want to check up with eigen.

However, I think that switching the meaning of size1 depending on storage
ordering is a bad idea. You want to write generic code that works for any
type of matrix expression, and not have to check storage ordering each
time. And fortran vs. C storage ordering doesn't even apply to all matrix

Last, I would love us to have something that makes conceptual sense for
higher order tensors as well. I write a lot of code that works with data
structures of different dimensions, and find dealing with different extent
sizes to be difficult. So I am sympathetic to:

   - Tensors have an order of dimensions. Consider the sizes of the matrix
   to be those dimensions in order for the 2nd order tensor.
   - So size1(), size2() make sense with this interpretation.
   - I don't see the problem with having an overload of "num_rows" and
   "num_columns" that forwards to size1 and size2 respectively, which I think
   is the GLAS interface. I also get messed up with rows vs. columns, but some
   people find this more intutive. I think that calling it "rows" and
   "columns" is a bad idea since it could conceptually be messed up with an
   interface that returns a row or column.... or future rows, columns interface
   that return a range of them.
   - Consider adding in size<1>(), size<2>(), which might be more consistent
   with higher order linear algebra. However, multi_array works by giving
   access to a container of its extents, so this interface wouldn't be
   consistent.... In that case, having an interface called "shape" that
   returns a vector of size_t is likely the most compatible (I believe it is
   how Blitz++ and multi_array work). Also, people are going to get messed up
   with size<0>() vs. size<1>() here since they may view it as a list of
   extents starting at 0, the normal way to count when you are allowed to pass
   in an index.

So to summarize my recommendation:
size1() == num_rows()
size2() == num_columns()

shape() gives array of the extents in a Container. Similar interface to
matlab, blitz++, multi_array.