Advanced Subscripting
The limitation of character string indexing is that the indices are static. For example, it is difficult to use character strings to subscript all entries from i through j, where i and j are C++ integer variables. For this situation, we must construct subscripting objects explicitly. Here is an example:
int i,j;
RWMathVec<double> v;
.
.
.
v(RWRange(i,j)) = 7; // all elements i through j
v(RWRange(i,j,2)) = 0; // every other element from i
// to j
The subscripts in this example are temporary objects of type
RWRange. In all, there are five types which may be used as subscripts:
Integers and character strings, discussed in the previous sections
Three subscript classes:
RWRange objects, which select a range of elements, as in the above example;
RWToEnd objects, which select all elements from a given element on;
RWSlice objects, which select a set of elements with a given length and start position.
All three subscripting classes optionally allow an increment between successive selected elements. In addition, the global object RWAll selects all elements. Any of the subscript types may be mixed in any statement, and all the types may be used for vectors, matrices, and three-dimensional and four-dimensional arrays. In each case, the object returned by the subscripting operation is a new view of the existing data.
Note that if you examine the vector, matrix, and array header files, you see that there are really only two types of subscripts used in the definitions of
operator(): int and
const RWSlice&. All the other subscript types are automatically converted to instances of
RWSlice by the compiler, either because they are already
RWSlice objects (
RWAll), because they are subclasses of
RWSlice (
RWRange and
RWToEnd), or because a conversion constructor exists (
char*). Since the subclasses
RWRange and
RWToEnd merely provide additional methods of constructing an
RWSlice, without adding data or redefining functions, you can safely construct an
RWSlice object from any subscript type without losing information. This can be useful in cases where you want to construct and use a subscript without knowing the precise type.
Here is an example showing how you can use subscripting to view planes of data in a 3-D array:
RWMathArray<double> A(10,10,10, rwUninitialized);
RWGenMat<double> xyplane = A(5,RWAll,RWAll);
RWGenMat<double> xzplane = A(RWAll,5,RWAll);
RWGenMat<double> yzplane = A(RWAll,RWAll,5);
Finally, here is how to create the three views used as the example in
Data and Views.
RWGenMat<double> A("3x3 [ 1 4 7 2 5 8 3 6 9 ]");
RWRange I(0,1);
RWGenMat<double> Atl = A(I,I);
RWMathVec<double> v = A(1,RWAll);