Skip to content

Commit

Permalink
Import CopyToVectorRep(NC) from HPC-GAP
Browse files Browse the repository at this point in the history
... as a stop-gap measure so we can make progress on the MatrixObj API
without compromising HPC-GAP.

Resolves #1643
  • Loading branch information
fingolfin authored and wilfwilson committed Apr 14, 2021
1 parent 179c9d7 commit 5de1900
Show file tree
Hide file tree
Showing 2 changed files with 203 additions and 29 deletions.
58 changes: 29 additions & 29 deletions hpcgap/lib/vecmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1395,41 +1395,41 @@ InstallGlobalFunction(CopyToVectorRep,function( v, q )
local vc, common, field, res;

# Handle fast, certain cases where there is no work. Microseconds count here

if Length(v) = 0 then
return v;
fi;
fi;

if IsGF2VectorRep(v) and q=2 then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;

if Is8BitVectorRep(v) then
if q = Q_VEC8BIT(v) then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;
fi;

# Ask the kernel to check the list for us.
# We have to do this, even in an NC version because the list might contain
# elements of large finite fields.
# Calling IS_VECFFE may force a full inspection of the list.

if not IS_VECFFE(v) then
# TODO: no need of the next 'if' block in the NC-version
if IsFFECollection(v) then
# Now we might have some elements in a large field representation
# or possibly a totally bad list. We will examine the shallow copy
# of v to avoid side effects when CopyToVectorRep modifies v and
# then returns fail
# or possibly a totally bad list. We will examine the shallow copy
# of v to avoid side effects when CopyToVectorRep modifies v and
# then returns fail
vc := ShallowCopy(v);
common := FFECONWAY.WriteOverSmallestCommonField(vc);
#
Expand All @@ -1453,7 +1453,7 @@ InstallGlobalFunction(CopyToVectorRep,function( v, q )
common := COMMON_FIELD_VECFFE(v);
vc := v;
fi;

if q = 2 then
Assert(2, ForAll(vc, elm -> elm in GF(2)));
if common > 2 and common mod 2 = 0 then
Expand All @@ -1466,7 +1466,7 @@ InstallGlobalFunction(CopyToVectorRep,function( v, q )
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
elif q <= 256 then
if common <> q then
if common <> q then
Assert(2, ForAll(vc, elm -> elm in GF(q)));
if IsPlistRep(vc) and GcdInt(common,q) > 1 then
common := SMALLEST_FIELD_VECFFE(vc);
Expand All @@ -1478,7 +1478,7 @@ InstallGlobalFunction(CopyToVectorRep,function( v, q )
res := COPY_VEC8BIT(vc,q);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
else
else
return fail; # vector cannot be written over GF(q)
fi;
end);
Expand All @@ -1489,36 +1489,36 @@ end);
#F CopyToVectorRepNC( <v>, <q> )
##
## This is the NC-version of CopyToVectorRep. It is forbidden to call it
## unless v is a plain list or a row vector, q<=256 is a valid size of a
## finite field, and all elements of v lie in this field.
## unless v is a plain list or a row vector, q<=256 is a valid size of a
## finite field, and all elements of v lie in this field.
##
InstallGlobalFunction(CopyToVectorRepNC,function( v, q )
local common, field, res;

# Handle fast, certain cases where there is no work. Microseconds count here

if Length(v) = 0 then
return v;
fi;

if IsGF2VectorRep(v) and q=2 then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;

if Is8BitVectorRep(v) then
if q = Q_VEC8BIT(v) then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;
fi;

# Calling COMMON_FIELD_VECFFE may force a full inspection of the list.
common := COMMON_FIELD_VECFFE(v);
if common = fail then
Expand All @@ -1527,35 +1527,35 @@ InstallGlobalFunction(CopyToVectorRepNC,function( v, q )
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,").\n",
"You may try to use CopyToVectorRep instead\n");
fi;

fi;

if q = 2 then
Assert(2, ForAll(v, elm -> elm in GF(2)));
if common > 2 and common mod 2 = 0 then
common := SMALLEST_FIELD_VECFFE(v);
fi;
if common <> 2 then
Error("ConvertToVectorRepNC: Vector cannot be written over GF(2)");
Error("CopyToVectorRepNC: Vector cannot be written over GF(2)");
fi;
res := COPY_GF2VEC(v);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
elif q <= 256 then
if common <> q then
if common <> q then
Assert(2, ForAll(v, elm -> elm in GF(q)));
if IsPlistRep(v) and GcdInt(common,q) > 1 then
common := SMALLEST_FIELD_VECFFE(v);
fi;
if common ^ LogInt(q, common) <> q then
Error("ConvertToVectorRepNC: Vector cannot be written over GF(",q,")");
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,")");
fi;
fi;
res :=COPY_VEC8BIT(v,q);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
else
Error("ConvertToVectorRepNC: Vector cannot be written over GF(",q,")");
else
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,")");
fi;
end);

Expand Down
174 changes: 174 additions & 0 deletions lib/vecmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1379,6 +1379,180 @@ InstallGlobalFunction(ConvertToVectorRepNC,function( arg )
fi;
end);


#############################################################################
##
#F CopyToVectorRep( <v>, <q> )
##
InstallGlobalFunction(CopyToVectorRep,function( v, q )
local vc, common, field, res;

# Handle fast, certain cases where there is no work. Microseconds count here

if Length(v) = 0 then
return v;
fi;

if IsGF2VectorRep(v) and q=2 then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;

if Is8BitVectorRep(v) then
if q = Q_VEC8BIT(v) then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;

# Ask the kernel to check the list for us.
# We have to do this, even in an NC version because the list might contain
# elements of large finite fields.
# Calling IS_VECFFE may force a full inspection of the list.

if not IS_VECFFE(v) then
# TODO: no need of the next 'if' block in the NC-version
if IsFFECollection(v) then
# Now we might have some elements in a large field representation
# or possibly a totally bad list. We will examine the shallow copy
# of v to avoid side effects when CopyToVectorRep modifies v and
# then returns fail
vc := ShallowCopy(v);
common := FFECONWAY.WriteOverSmallestCommonField(vc);
#
# FFECONWAY.WriteOverSmallestCommonField returns an integer or fail.
# When it resturns an integer, it may modify individual entries of vc
#
if common = fail or common > 256 then
#
# vector needs a field > 256, so can't be compressed
# or vector contains non-ffes or no common characteristic
#
return fail; # v cannot be written over GF(q)
fi;
if not IsMutable(v) then
MakeImmutable(vc);
fi;
else
return fail; # v cannot be written over GF(q)
fi;
else
common := COMMON_FIELD_VECFFE(v);
vc := v;
fi;

if q = 2 then
Assert(2, ForAll(vc, elm -> elm in GF(2)));
if common > 2 and common mod 2 = 0 then
common := SMALLEST_FIELD_VECFFE(vc);
fi;
if common <> 2 then
Error("CopyToVectorRep: Vector cannot be written over GF(2)");
fi;
res := COPY_GF2VEC(vc);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
elif q <= 256 then
if common <> q then
Assert(2, ForAll(vc, elm -> elm in GF(q)));
if IsPlistRep(vc) and GcdInt(common,q) > 1 then
common := SMALLEST_FIELD_VECFFE(vc);
fi;
if common ^ LogInt(q, common) <> q then
Error("CopyToVectorRep: Vector cannot be written over GF(",q,")");
fi;
fi;
res := COPY_VEC8BIT(vc,q);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
else
return fail; # vector cannot be written over GF(q)
fi;
end);


#############################################################################
##
#F CopyToVectorRepNC( <v>, <q> )
##
## This is the NC-version of CopyToVectorRep. It is forbidden to call it
## unless v is a plain list or a row vector, q<=256 is a valid size of a
## finite field, and all elements of v lie in this field.
##
InstallGlobalFunction(CopyToVectorRepNC,function( v, q )
local common, field, res;

# Handle fast, certain cases where there is no work. Microseconds count here

if Length(v) = 0 then
return v;
fi;

if IsGF2VectorRep(v) and q=2 then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;

if Is8BitVectorRep(v) then
if q = Q_VEC8BIT(v) then
if IsMutable(v) then
return(ShallowCopy(v));
else
return v;
fi;
fi;
fi;

# Calling COMMON_FIELD_VECFFE may force a full inspection of the list.
common := COMMON_FIELD_VECFFE(v);
if common = fail then
common := SMALLEST_FIELD_VECFFE(v);
if common = fail then
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,").\n",
"You may try to use CopyToVectorRep instead\n");
fi;

fi;

if q = 2 then
Assert(2, ForAll(v, elm -> elm in GF(2)));
if common > 2 and common mod 2 = 0 then
common := SMALLEST_FIELD_VECFFE(v);
fi;
if common <> 2 then
Error("CopyToVectorRepNC: Vector cannot be written over GF(2)");
fi;
res := COPY_GF2VEC(v);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
elif q <= 256 then
if common <> q then
Assert(2, ForAll(v, elm -> elm in GF(q)));
if IsPlistRep(v) and GcdInt(common,q) > 1 then
common := SMALLEST_FIELD_VECFFE(v);
fi;
if common ^ LogInt(q, common) <> q then
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,")");
fi;
fi;
res :=COPY_VEC8BIT(v,q);
if not IsMutable(v) then MakeImmutable(res); fi;
return res;
else
Error("CopyToVectorRepNC: Vector cannot be written over GF(",q,")");
fi;
end);


#############################################################################
##
#F ImmutableMatrix( <field>, <matrix> [,<change>] )
Expand Down

0 comments on commit 5de1900

Please sign in to comment.