Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2004-07-12 14:29:12


Matthias Schabel <boost_at_[hidden]> writes:

>> Maybe so, but I wouldn't start there. The way any particular class
>> template is defined should be one of the last concerns in the design
>> of any generic framework. It's all about concepts and algorithms.
>
> I agree in principle; on the other hand, it is often quite difficult
> to tease out appropriately
> complete and orthogonal concepts until one has had significant
> experience in practice
> with the problem domain - that requires an actual working
> implementation against which
> concepts can be tested.
>
>> If by that you mean driving towards something based on the STL
>> (reversible) container requirements in tables 65 and 66, then I
>> strongly disagree. Those are bloated concepts and little or no
>> generic code has been written to take advantage of them.
>
> I'm not familiar with tables 65 and 66; I just think that the
> interface should support as much of the existing standard for
> one-dimensional containers as possible as there is existing code
> which would presumably work with little modification if that is
> done.

I doubt it. My claim is that very little code is truly written to
the standard container requirements. It's well known that the
standard containers are not usually substitutable for one-another
(Scott Meyers has written extensively on the subject).

>> That's potentially rather inefficient with all those .end()
>> invocations. Anyway, I don't think low-level iteration over elements
>> should be required by the concepts to be exposed as the primary
>> begin() and end() iterators of a matrix, but through some kind of
>> indirection. Since I am predisposed to using a free-function
>> interface:
>>
>> std::for_each(begin(elements(mat)), end(elements(mat)), _1 = _1*_1);
>
> I'm curious - what's the rationale for preferring
> begin(elements(mat)) to mat.begin() ? While the syntax you describe
> looks fine to me, I think it's also important to remember that many
> numericists for whom this sort of library would be interesting are
> not interested in advanced coding techniques, per se

Do you find built-in arrays to be advanced? You can't call member
functions on those, so you need to use non-members in generic code if
you want to operate on them.

> , and will likely be put off by the need to learn lambda
> expressions,

There's nothing in what I was describing that requires lambda
expressions; using std::for_each drastically simplifies the code and
probably makes it much more efficient due to built-in loop unrolling.
Here; I'll write it with a for loop if it makes you happy...

   for(iterator<Matrix>::type i = begin(elements(mat)
        , finish = end(elements(mat));
       i != finish; ++i)
   {
        *i = *i * *i;
   }

Ugly.

>>> of arbitrary indices with no need to reorder the underlying storage
>>> (that is mat.transpose(0,1) causes all subsequent calls to mat(i,j) to
>>> provide the transposed element without moving the elements
>>> themselves).
>>
>> I'm not sure that's a nice property, since it means that the
>> traversal order of the matrix is not a compile-time property.
>
> This is actually precisely the kind of issue that I'm hoping to
> side-step by allowing flexible implementation - I imagine different
> requirements will call for different concepts to be supported. In
> some applications having static traversal order may not be as
> important as being able to dynamically reconfigure array access,
> whereas in others it may be critical. However, for another large
> class of algorithms it may well be irrelevant and, for those
> applications, it should be an unspecified implementation detail.

I'm not convinced that being able to specify the transposition at
runtime is a significant advantage over something like:

    transpose<0,1>(mat)

which can preseve full compile-time information. Having one
interface is simpler than having two.

>> Your matrix implementation might be very nice, but from my point of
>> view, using any specific implementation as the basis of a new linear
>> algebra library design is starting from the wrong end of things... so
>> for me, at least, looking at it in detail would be premature.
>
> I understand your point here and agree that algorithms should only
> require that their arguments support the relevant concepts. I'm not
> arguing that my particular implementation should be considered as
> the basis for a new MTL, just that it would be hugely beneficial if
> a new linear algebra library was based on a well considered and
> reasonably mature multidimensional array interface/concept set.

Of course I think whatever I'm going to do will be well-considered ;-)

> I think that it is critically important to decouple the 2D array
> aspects of a linear algebra library from the actual linear algebra
> aspects

I don't understand how or why. It's a linear algebra library; why
should it be decoupled from linear algebra?

> - there are many algorithms which one might want to apply to a
> matrix which have nothing to do with linear algebra. It would be
> very nice to see Boost put forth at least the start of a solution to
> the ongoing problem of proliferating array and matrix libraries.

I'm not sure why that's a problem, but I think that solving it is
probably outside the scope of my work.

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk