inline
doubleSubVector doubleSubMatrix::operator [] (Offset i) {
return doubleSubVector(handle(), offset() + (Stride)i*stride2(),
stride1());
}
inline
doubleSubScalar doubleSubVector::operator [] (Offset j) {
return doubleSubScalar(handle(), offset() + (Stride)j*stride());
}
.
.
.
#include<svmt.h>
int
main () {
const
Length m = 6;
const
Length n = 7;
doubleMatrix A(m, n);
for (Offset i = 0; i < m; i++) {
for (Offset j = 0; j < n; j++) {
A[i][j] = 10*i + j;
}
}
cout << "A =\n" << setw(2, 7) << A;
return 0;
}
produces the following output:
A =
0 1 2 3 4 5 6
10 11 12 13 14 15 16
20 21 22 23 24 25 26
30 31 32 33 34 35 36
40 41 42 43 44 45 46
50 51 52 53 54 55 56
My GNU C++ compiler, g++, optimizes away the inline operators and constuctors.
If you compare the result with doubleSubMatrix::operator () (Offset, Offset),
I'm pretty sure you won't find any significant difference in performance.
If you really think that multiplications are a problem, you could write:
doubleHandle& h = (doubleHandle&)A.handle();
Offset o_i = A.offset();
for (Offset i = 0; i < m; i++) {
Offset o_j = o_i;
for (Offset j = 0; j < n; j++) {
h.put(o_j, (double)(10*i + j));
o_j += A.stride1();
}
o_i += A.stride2();
}
and just bump the offset along without any multiplication at all.
Of course, if you know that the underlying representation for the 1D array
is an ordinary 1D C array, you should be able to obtain a pointer
to the beginning of that array:
doubleHandle& h = (doubleHandle&)A.handle();
double* p_i = (double*)h + A.offset();
for (Offset i = 0; i < m; i++) {
double* p_j = p_i;
for (Offset j = 0; j < n; j++) {
*p_j = (double)(10*i + j);
p_j += A.stride1();
}
p_i += A.stride2();
}
If (double*)h is 0, it means that either A.handle() is empty
or A.handle() references a 1D array that cannot be treated
as an ordinary 1D C array for some reason.
Indexing really isn't very important to the portable application programmer.
It is everything to the library developer.
The library standard is probably deficient if the application programmer
is frequently forced to loop through the individual elements of an array.
I can understand why application programmers might want to peek
at the underlying representation (of the 1D array in this case)
sometimes and muck about with it in order to improve performance
but they shouldn't expect their applications to be portable if they do.
It doesn't make any sense to insist upon a particular representation.
It doesn't make applications more portable
it only prevents developers from delivering the best possible library.
The purpose of the standard is to specify an interface which permits
a division of labor between application programmers and library developers.
Some people want to be both application programmers and library developers.
This is fine. But they should try to remember that they might look silly
if they try to wear both hats at the same time. Bob Tisdale