
Matthias Schabel <boost@schabel-family.org> 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