Daniel said:
Kai-Uwe Bux said:
Daniel said:
Daniel T. wrote:
(a) does not talk about [][] versus (,).
So it is irrelevant to the discussion at hand.
That depends on how narrowly you define the topic of the discussion.
If you consider the veracity of the FAQ as the topic at hand, and if
you consider the rationales provided by the FAQ as claims of the
FAQ, then (a) is relevant as the FAQ creates the impression that
your life would be simpler without the proxy classes.
I think the implication of the FAQ is different. But this thread is more
about what the FAQ says, rather than what it implies. Is there anything
that it says that you disagree with?
a) Yes, e.g., the recommendation against [][].
b) Arguments for recommendations differ from truth preserving inferences in
important ways, e.g., a truth preserving inference cannot be invalidated by
additions to the set of hypotheses whereas a recommendation for a car based
upon the information that it has a really good transmission can be
invalidated by added information about the crapy engine and lousy seats.
The problem with the FAQ is not so much misinformation it may or may not
contain. But:
* The FAQ presents a highly selected and incomplete account of row and
column proxies.
* It only talks about the ease for the programmer of the matrix class not
about the ease for client code using the matrix class (which is where one
can see good reasons to have row and column proxies anyway).
Thus, the recommendation is ill-argued because the discussion leaves out
relevant information that can off-set the reasons put forth by the FAQ.
Why/how is [][] more "useful" syntacticly than (,)?
It's not---well: asside from generic algorithms templates that could
work with, e.g., double[m][n] as well as any matrix class offering
[][].
And the FAQ does make an exception for legacy code. To assert that *new
code* should use arrays of arrays is to deny FAQ 34.1.
I fail to see how this is only related to legacy code.
vector<vector<float> > is a perfect example of a 2D-array that offers
[][] but not (,). If you program generic matrix algorithms, why
would you want to exclude this data structure?
The construct in question is exactly what 13.11 argues against.
Although, I think that is a viable construct to use as a possible
implementation of a Matrix class, I wouldn't use it raw, nor advocate
its use. (Again, I accept that it may be used extensively in some legacy
code and in that case, one may be forced to support it
This is a simple misunderstanding. You seem to think, I was proposing
vector< vector< T > >
as an implementation for a matrix class. That is not the case. Reread what I
wrote and you will find that I was talking about genering algorithms.
Consider, for example:
#include <cstddef>
#include <cassert>
template < typename MatrixType >
struct MatrixValueType {
typedef typename MatrixType::value_type value;
};
template < typename MatrixType >
struct MatrixSizeType {
typedef typename MatrixType::size_type value;
};
template < typename MatrixType >
MatrixSizeType<MatrixType>::value
RowSize ( MatrixType const & M ) {
return ( M.row_size() );
}
template < typename MatrixType >
MatrixSizeType<MatrixType>::value
ColSize ( MatrixType const & M ) {
return ( M.col_size() );
}
template < typename MatrixType >
typename MatrixValueType<MatrixType>::value
trace_n ( MatrixType const & M,
typename MatrixSizeType<MatrixType>::type row_size,
typename MatrixSizeType<MatrixType>::type col_size ) {
assert( row_size == col_size );
typename MatrixValueType<MatrixType>::value result =
typename MatrixValueType<MatrixType>::value();
for ( typename MatrixSizeType<MatrixType>::value i = 0;
i < row_size;
++i ) {
result += M
; // should this be M(i,i) ?
}
return ( result );
}
This algorithm can be used with any matrix class that supports [][] and it
can be used with vector< vector< T >. All you need to add is partial
specializations for MatrixValueType and MatrixSizeType.
The FAQ does not address the issue of using [][] or (,) in algorithms like
the above (it never talks about the use of the matrix class in client
code!). Yet another shortcoming of the FAQ account on this issue.
Also note that this is not an issue of legacy code. This is an issue of
separating algorithms from containers. One question is whether (,) or [][]
is better suited to support such separation. Since native containers like
vector< vector< T > > already support [][] but not (,), a point can be made
that [][] might be a more natural choice for generic programming.
It isn't meant to cover a "good discussion of interface design for a
matrix class."
Well, that is part of the problem with these 3 FAQ items. Should it turn out
that row and column proxies are a good idea anyway, much of the rational
for why you should use (,) disappears.
IMO, the class would be better for it, but let's try to stick to what
the FAQ actually says rather than your impression (or mine) of what a
good matrix interface design should look like.
As explained above, the problem lies more with what the FAQ fails to tell.
IMO, yet another inappropriate design.
IMO, embedded proxies have no place in a full-fledged matrix class. I
believe that the design should be complete and minimal. Embedding
classes and function calls that could easily be written outside of the
Matrix proper (with no loss in performance or express-ability) makes for
a fat interface. If you care to go further down this road, we should
probably start a new thread though because it has nothing to do with
what the FAQ actually says.
Where in my posts did I say something about *embedded* proxies. The proxy
classes can be independent. In my own implementation they are part of the
expression template machinery used to cut down temporaries arising from
matrix expressions. It turns out that that is a natural place for the
proxies. Whether you have a row() method as part of the matrix class, or
just a Row( Matrix, Index ) freestanding function, is a minor issue.
Important is, that operators like + are generic: it should be possible to
add matrices with different storage layouts, etc. Thus, those are more or
less forced to be freestanding. Anyway, I agree that this is a digression.
The FAQ doesn't ask what a well designed, full-fledged matrix class
looks like. It only compares two methods of single element access.
Again: that narrow view is part of the problem since it means that the
recommendation is based upon incomplete information that leaves out
important aspects of the problem.
The main thrust of the FAQ is how to implement single element
access (How do I create a subscript operator for a Matrix class?),
what we learn is that performance wise, "the operator() approach
is never worse than, and sometimes better than, the [][]
approach." That is something that simply cannot be said the other
way around, at least not for all possible standards conforming
compilers.
The relevance of a statement about all possible (as opposed to all
actual) compilers when it comes to performance considerations is
highly doubtfull. What matters is whether people can be expected to
run into performance problems. The optimization techniques that
prevent this are well known and widely implemented.
IMO, the relevance of such micro-optimizations in general is highly
doubtful. I'm willing to completely drop the speed issue. The FAQs in
question make reference to "performance" in a few places but are all
sufficiently equivocal as to be pointless (not incorrect, just not worth
arguing about.) It was a blind ally I should have never gone down.
Agreed.
Best
Kai-Uwe