
About Indexing Functions


•

Indexing functions are used to index into an rtable (Array, Matrix, or Vector) to retrieve or store a value. They come in two types: builtin or userdefined (see below). An rtable can have zero or more indexing functions, each specified by name when the rtable is constructed. For more information on how to construct an rtable object with an indexing function, see the help pages for Array, Matrix, and Vector.

•

Whenever an attempt is made to reference or store a value in a location of an rtable that has indexing functions, the first indexing function of the rtable is called. The indexing function performs whatever manipulations it sees fit on the indices (e.g. sorting them for symmetric indexing), and then accesses the passed rtable by using the manipulated indices. If the passed rtable has any indexing functions, the first of these is invoked in the same manner as the current one.


When an attempt is made to reference or store a value in a location of an rtable that does not have any indexing functions, the rtable's storage function (as specified in the calling sequence when the rtable was constructed) is invoked to carry out the reference or storage operation.

•

A standard set of indexing functions is built into the Maple kernel (see below). In addition, you can add your own custom indexing function by defining a routine whose name starts with 'index/ ...' and passing the name to the appropriate constructor. An example is provided below.


The name of an indexing function is always of the form "index/indFn". When specifying indexing functions during the construction of an rtable, only the indFn part of the name is specified.



Responsibilities of an Indexing Function


•

When reading from an rtable, the indexing function is responsible for performing the appropriate index manipulation (for example, sorting for a symmetric Matrix), looking up the value by reindexing into the passed rtable, performing the appropriate manipulation of the result (for example, negation of a lowertriangle element of an antisymmetric Matrix), and returning the result.

•

When writing to an rtable, the indexing function must perform the appropriate index manipulation, and assign the value by reindexing into the passed rtable. Furthermore, it may need to make use of information about the rtable to know what must be assigned. For example, a symmetric Matrix with a rectangular storage must have both entries assigned.



Builtin Indexing Functions


•

Several indexing functions are built into Maple. For more information, see the corresponding help page.



User Indexing Functions


•

A user indexing function is a Maple procedure with name of the form `index/my_indexing_fn`.


If a user indexing function is included as a parameter passed to the Array constructor, or as the value of the shape parameter of a Matrix, Vector, or Array, the index/ part must be omitted (that is, Maple will add the index/ prefix, when accessing the Matrix or Vector).


A procedure which is to be used as an indexing function receives two or three arguments. The first is a list specifying the index at which the Matrix, Vector, or Array is being referenced. The second argument is the Matrix, Vector, or Array itself, with its first indexing function removed. For retrieval operations, no more arguments are specified. For storage operations, the third argument is a list of the value(s) to be stored in the location determined by the indexing function itself, given the first two arguments. It is the responsibility of the indexing function to remove the list wrapper. Since the first indexing function has been removed from the object being passed in, retrieval and storage are effected simply by indexing the Matrix, Vector, or Array at the (possibly new) index.


A typical user indexing function has the following form (with the obvious changes for Vector or Array indexing). If two arguments are provided, the data is retrieved from the specified location. If three arguments are provided, the given data replaces the data in the specified location.

>

`index/my_indexing_function` := proc( idx :: list( posint ), M::Matrix, val::list ); local idx1, init_val;
if nops(idx) <> 2 then
error "Matrix indexing requires exactly 2 indices";
end if;
idx1 := someFunctionOfIdx;
if nargs = 2 then
# retrieval
if someTestOnIdx1 then
# indexing function determines value, i.e.,
# location is not mutable
indexing_function_value;
else
# get value from storage
M[idx1];
end if;
else
# storage
if someTestOnIdx1 then
# indexing function determines value, i.e.,
# location is not mutable
if op( val ) <> indexing_function_value then
# invalid value
error "invalid assignment";
else
# be sure to do explicit write, but catch
# this if the storage fails, as storage
# for nonmutable locations need not be
# allocated
try
M[idx1] := op( val );
catch "unable to store":
# couldn't write, return value (as if
# the write succeeded)
op( val );
end try;
end if;
else
# general value
M[idx1] := op( val );
end if;
end if;
end proc;


The Matrix, Vector, or Array object M which is passed in to this routine is the Matrix, Vector, or Array on which the original index reference was requested, with its first indexing function removed.


Any number of user indexing functions can be provided, and they can be intermixed with the builtin indexing functions described in the previous section.



