Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions doc/ref/matobj.xml
Original file line number Diff line number Diff line change
Expand Up @@ -402,4 +402,157 @@ The following conventions hold for such a group <C>G</C>.

</Section>

<!-- %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -->
<Section Label="How to Write Code for Vector and Matrix Objects">
<Heading>How to Write Code for Vector and Matrix Objects</Heading>

Vector and matrix objects have a number of different representations in &GAP;
which are optimised for different things;
see the list <Ref Var="ConstructingFiltersForMatrixGroupElements"/> for
examples of available
<Ref Attr="ConstructingFilter" Label="for a matrix object"/> values
of matrix objects.
Most &GAP; 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 <C>mat1</C>, <C>mat2</C> may take the two inputs,
which must have the same
<Ref Attr="ConstructingFilter" Label="for a matrix object"/> value,
create a new matrix object which also lies in this filter,
for example by calling <C>ZeroMatrix( m, n, mat1 )</C>,
and then set the entries in this matrix.

<P/>

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

<P/>

This approach works also in many situation where the input involves
the <Q>list of list</Q> matrices in the filter <Ref Filt="IsMatrix"/>.
In practice, the question is often the other way round:
one has old &GAP; code that was written for objects in <Ref Filt="IsMatrix"/>,
and wants to rewrite it such that it works for general matrix objects also.
In such cases, the following guidelines may be useful.

<List>
<Item>
Use <C>M[i, j]</C> not <C>M[i][j]</C>
for accessing/assigning matrix entries.
Comment thread
james-d-mitchell marked this conversation as resolved.
<P/>
<E>Reason:</E>
<C>M[i][j]</C> means to fetch or even create <C>M[i]</C>
and then take the <C>j</C>-th entry of it.
</Item>
<Item>
Use <C>ExtractSubMatrix( M, rows, cols )</C> not <C>M{ rows }{ cols }</C>
for accessing submatrices,
similarly use <C>CopySubMatrix( src, dst, srows, drows, scols, dcols )</C>.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again presumably better because the intermediate object M{rows} is not created?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That, and also the {...} syntax may not be available at all (it can only be supported in general for row-list matrices).

Perhaps there should be a general pattern: terse "rule" to follow (just what to do), optionally followed by an explanation; perhaps in a visually distinct style: new paragraph, and then a key phrase ("The reason for this is/are"; or just "Background:" or "Motivation:", possibly in italics or so)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps also ExtractSubVector and CopySubVector should be mentioned?

<P/>
<E>Reason:</E>
The <C>M{ rows }</C> syntax is supported only for
row-list matrices, see <Ref Filt="IsRowListMatrix"/>.
</Item>
<Item>
Use <C>ZeroVector( R, n )</C> not <C>[ 1 .. n ] * Zero( R )</C> for
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe expand it?

Suggested change
Use <C>ZeroVector( R, n )</C> not <C>[ 1 .. n ] * Zero( R )</C> for
Use <C>ZeroVector( R, n )</C> not <C>[ 1 .. n ] * Zero( R )</C> or
<C>ListWithIdenticalEntries( n, Zero( R ) )</C> or similar constructs for

creating a zero vector over a given domain <C>R</C>.
<P/>
<E>Reason:</E>
The latter syntax creates an unnecessary new object <C>[ 1 .. n ]</C>,
multiplies each of its entries with <C>Zero( R )</C>
(not knowing that the result will be <C>Zero( R )</C> in each case),
and creates not a vector object but a plain list of the results.
</Item>
<Item>
Use <C>ZeroVector( n, M )</C> not <C>0 * M[1]</C> for a
given matrix object <C>M</C> with <C>n</C> columns.
<P/>
<E>Reason:</E>
Calling <C>M[1]</C> may have to create an unnecessary new object
<C>M[1]</C>.
</Item>
<Item>
Use <Ref Attr="BaseDomain" Label="for a matrix object"/>
not <Ref Attr="DefaultFieldOfMatrix"/>.
<P/>
<E>Reason:</E>
This is just a conceptual issue, the results should in fact coincide.
A matrix object <C>M</C> which is not a list of lists stores its
<Ref Attr="BaseDomain" Label="for a matrix object"/> value.
For convenience, <C>DefaultFieldOfMatrix( M )</C> is defined
to return this value (although this need not be a field).
On the other hand, a list of lists <C>M</C> in <Ref Filt="IsMatrix"/>
does not store the two attribute values,
<Ref Attr="DefaultFieldOfMatrix"/> value is computed from the entries
of <C>M</C>,
and for convenience, <C>BaseDomain( M )</C> is defined to return the
<Ref Attr="DefaultFieldOfMatrix"/> value.
</Item>
<Item>
Do not use the unary versions of
<Ref Func="ConvertToVectorRep" Label="for a list (and a field)"/>
and <Ref Func="ConvertToMatrixRep" Label="for a list (and a field)"/>.
<P/>
<E>Reason:</E>
For example, consider the two matrices <C>M1 = [ [ Z(4) ] ]</C> and
<C>M2 = [ [ Z(4)^3 ] ]</C> over the field with four elements.
The latter is in fact a matrix over the field with two elements,
and <C>ConvertToMatrixRep( M2 )</C> turns it into a matrix in
<Ref Filt="IsGF2MatrixRep"/>, whereas <C>ConvertToMatrixRep( M1 )</C>
yields a matrix in <Ref Filt="Is8BitMatrixRep"/>.
Thus computing products or sums of these matrices is more expensive
than computations with two matrices in <Ref Filt="Is8BitMatrixRep"/>.
</Item>
<Item>
Use <Ref Oper="ImmutableMatrix"/> and the binary versions of
<Ref Func="ConvertToVectorRep" Label="for a list (and a field)"/>
and <Ref Func="ConvertToMatrixRep" Label="for a list (and a field)"/>
only when creating initial objects
which need not be compatible with given vectors or matrices.
<P/>
<E>Reason:</E>
The idea behind these functions is to choose a good representation
for initial data (for example for some expensive MeatAxe computations,
see Chapter <Ref Chap="The MeatAxe"/>).
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 <Q>adjusting</Q> the representation of intermediate results by
calling the abovementioned conversion functions just hides these problems.
</Item>
</List>

Conversely, do <E>not</E> 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 <C>ListWithIdenticalEntries( n, Zero( R ) )</C>
not <C>Vector( R, n )</C> in this case.
For creating a list with <C>n</C> entries, you can also first call
<Ref Func="EmptyPlist"/> for creating a big enough list,
and then enter the values.

</Section>

</Chapter>
Loading