Shapes and Storage Modes for Matrices and Vectors

Each of the builtin shapes has an associated storage scheme, which is used if no storage value is provided in the Matrix or Vector constructor. The storage parameter in the Matrix and Vector constructors specify how physical memory is allocated for holding the entries of the constructed Matrix or Vector.


Shape



The shape parameter must be either a Maple name (possibly indexed) or else a list of (possibly indexed) Maple names (see the list below for the builtin shapes).


If no storage parameter is given, then the storage mode is deduced from the last component of the shape. For example, the storage method used for shape = [triangular[upper], band[0, 2] ] will be to store by diagonals (and hence store only the three non0 diagonals), whereas shape = [band[0, 2], triangular[upper] ] will store the entire upper triangle (by columns, unless the order parameter specifies C_order).


Note: A symmetric band Matrix should be created with shape = symmetric, storage = band[0, b] or shape = symmetric, storage = band[b, 0]. That is, the band property should be given as the storage, rather than as part of the shape. If the band property is given as part of the shape, then it must agree with the storage, as shape = [symmetric, band[0, b]], storage = band[0, b] or shape = [symmetric, band[b, b]], storage = band[b, b], not as shape = [symmetric, band[b, b]], storage = band[0, b]. The latter specification will lose the off diagonal information from the initializer (because of the way that Matrices are initialized). If the storage parameter is not specified, it will default to agreeing with the shape, as described above.


For Vectors, the shapes (builtin indexing functions) are:


For Matrices, the shapes (builtin indexing functions) are:


Note: For each of the shapes following, and including, diagonal in the above list, the resulting Matrix is constructed according to the following view: The initializer effectively causes a Matrix with no (i.e., rectangular) shape to be built, and then the shape is "imposed", as a mask, on the result. For example, if A is a 2 x 2 Matrix, then the calling sequence Matrix( A, shape=triangular[lower]), results in a 2 x 2 lower triangular Matrix, which has the same entries as A except for the [1, 2] entry, which is 0. Similarly, Matrix( [[A], [A, A]], shape=triangular[lower], scan=triangular[lower] ) builds a lower triangular Matrix, with the pieces of the diagonal blocks which "stuck out" above the diagonal being set to 0. For the shapes in the symmetric family, the entries in the upper triangle are used to construct the result. (Note that if the initializer is an array, or a list containing arrays, the array indices are implicitly shifted to be 1based for this operation  or any other Matrix construction or modification operation.)


For completeness, a shape value of rectangular can be given when constructing a Matrix or Vector. All occurrences of rectangular in the shape parameter are removed when the Matrix or Vector is constructed, so that specifying shape = rectangular is identical to shape = [].



Storage



The storage value can be any one of

rectangular

triangular[upper]

triangular[lower]

triangular[upper, strict]

triangular[lower, strict]

Hessenberg[upper]

Hessenberg[lower]

band[b1, b2]

band[b]

diagonal

empty

sparse

sparse[upper]

sparse[lower]





The sparse[upper] and sparse[lower] storage values can be used to efficiently store sparse Matrices which have symmetry (symmetric, hermitian, etc).


Maple combines the storage and (in the case of Matrices) order values into the storage mode for the Matrix or Vector. The storage mode and the shape combine to form the access method. The shape parameter tells Maple (together with the scan method, if necessary) how much storage to allocate (in units determined by the datatype parameter of the Matrix or Vector constructor). The access method tells Maple how to retrieve values, and how to store values. In particular, the access method provides the following information:


* Whether a Matrix is stored as sparse, Fortran order (column major), C order (row major) and/or other special format.


* Whether or which of the entries are determinable from the access method itself.


If the datatype parameter is provided:


* Storage is allocated in units of corresponding size.


* If datatype is a floatingpoint or hardware type, data is converted to this type before storing. This conversion is done by the storage function (which is implicitly called by the last indexing function). Data of the correct type is not modified in any way (e.g., floatingpoint numbers are not rounded to Digits precision).


* Data to be stored in the Matrix or Vector must be of the specified type (after conversion to floatingpoint or hardware numeric type, if necessary).


* Values returned from the storage function are of this type.


1. In general, the specified storage mode for a Matrix or Vector must provide storage for each location in the Matrix or Vector for which a value cannot be obtained directly from the shape. For example, if there is no shape associated with a Matrix, it will generally be an error to provide any storage parameter value other than rectangular or sparse; if storage = triangular[upper] were given, for instance, the resulting Matrix would have mutable locations (the lower triangle) for which no storage is provided. Attempting to access such an entry results in an error.


2. A nonzero value returned from the storage function is guaranteed to be of the correct type. However, if a user indexing function returns a value without invoking the storage function, no type conversion is implied (i.e., it is the responsibility of the user indexing function to return an object of the correct type). A zero value returned from the storage function cannot be guaranteed to be of the correct type, because such values are returned from positions not corresponding to physical memory positions (i.e., values outside of the actual storage allocated) and 0 may not, in fact, be recognized by the datatype type.


The last indexing function for a Matrix or Vector calls the storage function for that Matrix or Vector to perform the actual storage or retrieval operation requested (this is done simply by referencing the appropriate element of the Matrix or Vector, just as if the storage function were another indexing function).


