@@ -402,4 +402,157 @@ The following conventions hold for such a group <C>G</C>.
402402
403403</Section >
404404
405+ <!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
406+ <Section Label =" How to Write Code for Vector and Matrix Objects" >
407+ <Heading >How to Write Code for Vector and Matrix Objects</Heading >
408+
409+ Vector and matrix objects have a number of different representations in &GAP;
410+ which are optimised for different things;
411+ see the list <Ref Var =" ConstructingFiltersForMatrixGroupElements" /> for
412+ examples of available
413+ <Ref Attr =" ConstructingFilter" Label =" for a matrix object" /> values
414+ of matrix objects.
415+ Most &GAP; functions accepting vector or matrix objects as arguments
416+ do not depend on any particular representation for these objects.
417+ If the output of such a function involves vector and matrix objects,
418+ then these are expected to have the same representations as the inputs.
419+ For example, a function that computes the Kronecker product of two
420+ matrix objects <C >mat1</C >, <C >mat2</C > may take the two inputs,
421+ which must have the same
422+ <Ref Attr =" ConstructingFilter" Label =" for a matrix object" /> value,
423+ create a new matrix object which also lies in this filter,
424+ for example by calling <C >ZeroMatrix( m, n, mat1 )</C >,
425+ and then set the entries in this matrix.
426+
427+ <P />
428+
429+ Functions like
430+ <Ref Oper =" ZeroMatrix" Label =" for dimensions and matrix object" />,
431+ <Ref Oper =" IdentityMatrix" Label =" for dimension and matrix object" />,
432+ and <Ref Oper =" Matrix" Label =" for a list and a matrix object" />
433+ admit different kinds of inputs.
434+ <C >ZeroMatrix( R, m, n )</C > can be used, for example,
435+ if we want to leave the decision about the representation of the result
436+ to &GAP; .
437+ This might be useful if the result of <C >ZeroMatrix( R, m, n )</C > is
438+ the first matrix we create, and then later matrices are created
439+ relative to this matrix.
440+ If we already have a matrix object <C >M</C > and want <C >ZeroMatrix</C >
441+ to return a new matrix object that has the same representation as <C >M</C >,
442+ then <C >ZeroMatrix( R, m, n )</C > may not return a matrix with the expected
443+ representation.
444+ For example, even if we use the same <C >R</C > as before, &GAP; might decide
445+ to use a sparse representation for large enough <C >m</C > and <C >n</C >.
446+ It is possible to create a <C >ZeroMatrix</C > in the same representation
447+ as <C >M</C > by fully specifying this representation as follows
448+ <C >ZeroMatrix( ConstructingFilter( M ), BaseDomain( M ), m, n )</C >.
449+ It is also possible to produce the same result using the more convenient
450+ <C >ZeroMatrix( m, n, M )</C >.
451+
452+ <P />
453+
454+ This approach works also in many situation where the input involves
455+ the <Q >list of list</Q > matrices in the filter <Ref Filt =" IsMatrix" />.
456+ In practice, the question is often the other way round:
457+ one has old &GAP; code that was written for objects in <Ref Filt =" IsMatrix" />,
458+ and wants to rewrite it such that it works for general matrix objects also.
459+ In such cases, the following guidelines may be useful.
460+
461+ <List >
462+ <Item >
463+ Use <C >M[i, j]</C > not <C >M[i][j]</C >
464+ for accessing/assigning matrix entries.
465+ <P />
466+ <E >Reason:</E >
467+ <C >M[i][j]</C > means to fetch or even create <C >M[i]</C >
468+ and then take the <C >j</C >-th entry of it.
469+ </Item >
470+ <Item >
471+ Use <C >ExtractSubMatrix( M, rows, cols )</C > not <C >M{ rows }{ cols }</C >
472+ for accessing submatrices,
473+ similarly use <C >CopySubMatrix( src, dst, srows, drows, scols, dcols )</C >.
474+ <P />
475+ <E >Reason:</E >
476+ The <C >M{ rows }</C > syntax is supported only for
477+ row-list matrices, see <Ref Filt =" IsRowListMatrix" />.
478+ </Item >
479+ <Item >
480+ Use <C >ZeroVector( R, n )</C > not <C >[ 1 .. n ] * Zero( R )</C > for
481+ creating a zero vector over a given domain <C >R</C >.
482+ <P />
483+ <E >Reason:</E >
484+ The latter syntax creates an unnecessary new object <C >[ 1 .. n ]</C >,
485+ multiplies each of its entries with <C >Zero( R )</C >
486+ (not knowing that the result will be <C >Zero( R )</C > in each case),
487+ and creates not a vector object but a plain list of the results.
488+ </Item >
489+ <Item >
490+ Use <C >ZeroVector( n, M )</C > not <C >0 * M[1]</C > for a
491+ given matrix object <C >M</C > with <C >n</C > columns.
492+ <P />
493+ <E >Reason:</E >
494+ Calling <C >M[1]</C > may have to create an unnecessary new object
495+ <C >M[1]</C >.
496+ </Item >
497+ <Item >
498+ Use <Ref Attr =" BaseDomain" Label =" for a matrix object" />
499+ not <Ref Attr =" DefaultFieldOfMatrix" />.
500+ <P />
501+ <E >Reason:</E >
502+ This is just a conceptual issue, the results should in fact coincide.
503+ A matrix object <C >M</C > which is not a list of lists stores its
504+ <Ref Attr =" BaseDomain" Label =" for a matrix object" /> value.
505+ For convenience, <C >DefaultFieldOfMatrix( M )</C > is defined
506+ to return this value (although this need not be a field).
507+ On the other hand, a list of lists <C >M</C > in <Ref Filt =" IsMatrix" />
508+ does not store the two attribute values,
509+ <Ref Attr =" DefaultFieldOfMatrix" /> value is computed from the entries
510+ of <C >M</C >,
511+ and for convenience, <C >BaseDomain( M )</C > is defined to return the
512+ <Ref Attr =" DefaultFieldOfMatrix" /> value.
513+ </Item >
514+ <Item >
515+ Do not use the unary versions of
516+ <Ref Func =" ConvertToVectorRep" Label =" for a list (and a field)" />
517+ and <Ref Func =" ConvertToMatrixRep" Label =" for a list (and a field)" />.
518+ <P />
519+ <E >Reason:</E >
520+ For example, consider the two matrices <C >M1 = [ [ Z(4) ] ]</C > and
521+ <C >M2 = [ [ Z(4)^3 ] ]</C > over the field with four elements.
522+ The latter is in fact a matrix over the field with two elements,
523+ and <C >ConvertToMatrixRep( M2 )</C > turns it into a matrix in
524+ <Ref Filt =" IsGF2MatrixRep" />, whereas <C >ConvertToMatrixRep( M1 )</C >
525+ yields a matrix in <Ref Filt =" Is8BitMatrixRep" />.
526+ Thus computing products or sums of these matrices is more expensive
527+ than computations with two matrices in <Ref Filt =" Is8BitMatrixRep" />.
528+ </Item >
529+ <Item >
530+ Use <Ref Oper =" ImmutableMatrix" /> and the binary versions of
531+ <Ref Func =" ConvertToVectorRep" Label =" for a list (and a field)" />
532+ and <Ref Func =" ConvertToMatrixRep" Label =" for a list (and a field)" />
533+ only when creating initial objects
534+ which need not be compatible with given vectors or matrices.
535+ <P />
536+ <E >Reason:</E >
537+ The idea behind these functions is to choose a good representation
538+ for initial data (for example for some expensive MeatAxe computations,
539+ see Chapter <Ref Chap =" The MeatAxe" />).
540+ The results of computations with these data should then automatically
541+ be in the same representation.
542+ If not then the code in question has problems,
543+ and <Q >adjusting</Q > the representation of intermediate results by
544+ calling the abovementioned conversion functions just hides these problems.
545+ </Item >
546+ </List >
547+
548+ Conversely, do <E >not</E > use functions for vector and matrix objects
549+ when you want to create an object that shall be used just as a list.
550+ For example, use <C >ListWithIdenticalEntries( n, Zero( R ) )</C >
551+ not <C >Vector( R, n )</C > in this case.
552+ For creating a list with <C >n</C > entries, you can also first call
553+ <Ref Func =" EmptyPlist" /> for creating a big enough list,
554+ and then enter the values.
555+
556+ </Section >
557+
405558</Chapter >
0 commit comments