Skip to content

Should multiplying a MatrixObj with a list work? Always? Never? Current state: sometimes, at random #6635

Open

Description

@fingolfin

Yesterday @GalaxyCo asked me how to multiply MatrixObj objects with lists of coefficients. This quickly turned into "should this work"? Maybe one should require using a "compatible" VectorObj

This raised the question how to even get such a VectorObj (which lead to issue #6634).

But also it lead to experiments which uncovered a lot of irregularities. Sometimes it fails:

gap> F:=GF(2);;
gap> m:=Matrix(IsGenericMatrixRep, F,  IdentityMat(3, F));;
gap> v:=[1,2,3]*One(F);;
gap> m*v;
Error, no method found! For debugging hints type ?Recovery from NoMethodFound

But it weirdly works if v is a compressed vector (maybe because those are VectorObj, even if they are not declared as "compatible" here):

gap> ConvertToVectorRep(v);
2
gap> v;
<a GF2 vector of length 3>
gap> m*v;
<a GF2 vector of length 3>

As a hack workearound I inserted this:

InstallOtherMethod( Vector,
    [ IsList and IsFFECollection, IsList and IsFFECollection ],
    { v, example } -> v );

which makes both work. Before you complain too much about it, please consider that this is already in the library:

# The following method is used for example
# in code dealing with elements of 'AlgebraicExtension's.
# (Note that we want to return a vector with the same mutability status
# as the given vector, and we need not copy it if it is mutable.)
InstallOtherMethod( Vector,
    [ IsList and IsCyclotomicCollection, IsList and IsCyclotomicCollection ],
    { v, example } -> v );

Anyway what about characteristic 0? Well, it already works for integers:

gap> F:=Integers;;
gap> m:=Matrix(IsGenericMatrixRep, F,  IdentityMat(3, F));;
gap> v:=[1,2,3]*One(F);;
gap> m*v;
[ 1, 2, 3 ]

However, it still fails for e.g. rationals:

gap> F:=Rationals;;
gap> m:=Matrix(IsGenericMatrixRep, F,  IdentityMat(3, F));;
gap> v:=[1,2,3]*One(F);;
gap> m*v;
Error, <M> and <v> are not compatible

My guess is that this is because GAP "guesses" the basedomain for the vector as Integers (TODO: we really should improve the error message there to give out this information).

Indeed, we can confirm my theory:

gap> m*(v/2);
[ 1/2, 1, 3/2 ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions