diff --git a/doc/ref/matobj.xml b/doc/ref/matobj.xml index 8ed8908e47..2818815902 100644 --- a/doc/ref/matobj.xml +++ b/doc/ref/matobj.xml @@ -402,4 +402,157 @@ The following conventions hold for such a group G. + +
+How to Write Code for Vector and Matrix Objects + +Vector and matrix objects have a number of different representations in ⪆ +which are optimised for different things; +see the list for +examples of available + values +of matrix objects. +Most ⪆ functions accepting vector or matrix objects as arguments +do not depend on any particular representation for these objects. +If the output of such a function involves vector and matrix objects, +then these are expected to have the same representations as the inputs. +For example, a function that computes the Kronecker product of two +matrix objects mat1, mat2 may take the two inputs, +which must have the same + value, +create a new matrix object which also lies in this filter, +for example by calling ZeroMatrix( m, n, mat1 ), +and then set the entries in this matrix. + +

+ +Functions like +, +, +and +admit different kinds of inputs. +ZeroMatrix( R, m, n ) can be used, for example, +if we want to leave the decision about the representation of the result +to ⪆. +This might be useful if the result of ZeroMatrix( R, m, n ) is +the first matrix we create, and then later matrices are created +relative to this matrix. +If we already have a matrix object M and want ZeroMatrix +to return a new matrix object that has the same representation as M, +then ZeroMatrix( R, m, n ) may not return a matrix with the expected +representation. +For example, even if we use the same R as before, ⪆ might decide +to use a sparse representation for large enough m and n. +It is possible to create a ZeroMatrix in the same representation +as M by fully specifying this representation as follows +ZeroMatrix( ConstructingFilter( M ), BaseDomain( M ), m, n ). +It is also possible to produce the same result using the more convenient +ZeroMatrix( m, n, M ). + +

+ +This approach works also in many situation where the input involves +the list of list matrices in the filter . +In practice, the question is often the other way round: +one has old ⪆ code that was written for objects in , +and wants to rewrite it such that it works for general matrix objects also. +In such cases, the following guidelines may be useful. + + + + Use M[i, j] not M[i][j] + for accessing/assigning matrix entries. +

+ Reason: + M[i][j] means to fetch or even create M[i] + and then take the j-th entry of it. + + + Use ExtractSubMatrix( M, rows, cols ) not M{ rows }{ cols } + for accessing submatrices, + similarly use CopySubMatrix( src, dst, srows, drows, scols, dcols ). +

+ Reason: + The M{ rows } syntax is supported only for + row-list matrices, see . + + + Use ZeroVector( R, n ) not [ 1 .. n ] * Zero( R ) for + creating a zero vector over a given domain R. +

+ Reason: + The latter syntax creates an unnecessary new object [ 1 .. n ], + multiplies each of its entries with Zero( R ) + (not knowing that the result will be Zero( R ) in each case), + and creates not a vector object but a plain list of the results. + + + Use ZeroVector( n, M ) not 0 * M[1] for a + given matrix object M with n columns. +

+ Reason: + Calling M[1] may have to create an unnecessary new object + M[1]. + + + Use + not . +

+ Reason: + This is just a conceptual issue, the results should in fact coincide. + A matrix object M which is not a list of lists stores its + value. + For convenience, DefaultFieldOfMatrix( M ) is defined + to return this value (although this need not be a field). + On the other hand, a list of lists M in + does not store the two attribute values, + value is computed from the entries + of M, + and for convenience, BaseDomain( M ) is defined to return the + value. + + + Do not use the unary versions of + + and . +

+ Reason: + For example, consider the two matrices M1 = [ [ Z(4) ] ] and + M2 = [ [ Z(4)^3 ] ] over the field with four elements. + The latter is in fact a matrix over the field with two elements, + and ConvertToMatrixRep( M2 ) turns it into a matrix in + , whereas ConvertToMatrixRep( M1 ) + yields a matrix in . + Thus computing products or sums of these matrices is more expensive + than computations with two matrices in . + + + Use and the binary versions of + + and + only when creating initial objects + which need not be compatible with given vectors or matrices. +

+ Reason: + The idea behind these functions is to choose a good representation + for initial data (for example for some expensive MeatAxe computations, + see Chapter ). + The results of computations with these data should then automatically + be in the same representation. + If not then the code in question has problems, + and adjusting the representation of intermediate results by + calling the abovementioned conversion functions just hides these problems. + + + +Conversely, do not use functions for vector and matrix objects +when you want to create an object that shall be used just as a list. +For example, use ListWithIdenticalEntries( n, Zero( R ) ) +not Vector( R, n ) in this case. +For creating a list with n entries, you can also first call + for creating a big enough list, +and then enter the values. + +

+