Skip to content
Merged
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ This file describes changes in the orb package.
5.x.y (2026-MM-DD)
- Once again allow using this package without its kernel extension
(this was accidentally broken in version 4.9.1)
- Add hash functions for non-compressed finite-field vectors and matrices

5.0.1 (2025-06-20)
- Various janitorial changes
Expand Down
42 changes: 30 additions & 12 deletions doc/hash.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,7 @@ Oper="ChooseHashFunction"/>.
<Returns> a record </Returns>
<Description>
This method is for compressed vectors over the field <C>GF(2)</C> of
two elements. Note that there is no hash function for non-compressed
vectors over <C>GF(2)</C> because those objects cannot efficiently
be recognised from their type.
two elements.
<P/>
Note that you can only use the resulting hash functions for vectors
of the same length.
Expand All @@ -103,9 +101,7 @@ of the same length.
<Returns> a record </Returns>
<Description>
This method is for compressed vectors over a finite field with up
to <M>256</M> elements. Note that there is no hash function for
non-compressed such vectors because those objects cannot efficiently be
recognised from their type.
to <M>256</M> elements.
<P/>
Note that you can only use the resulting hash functions for vectors
of the same length.
Expand All @@ -117,9 +113,7 @@ of the same length.
<Returns> a record </Returns>
<Description>
This method is for compressed matrices over the field <C>GF(2)</C> of
two elements. Note that there is no hash function for non-compressed
matrices over <C>GF(2)</C> because those objects cannot efficiently
be recognised from their type.
two elements.
<P/>
Note that you can only use the resulting hash functions for matrices
of the same size.
Expand All @@ -131,9 +125,33 @@ of the same size.
<Returns> a record </Returns>
<Description>
This method is for compressed matrices over a finite field with up
to <M>256</M> elements. Note that there is no hash function for
non-compressed such vectors because those objects cannot efficiently be
recognised from their type.
to <M>256</M> elements.
<P/>
Note that you can only use the resulting hash functions for matrices
of the same size.
</Description>
</ManSection>

<ManSection>
<Meth Name="ChooseHashFunction" Arg="ob, len" Label="ffevec"/>
<Returns> a record </Returns>
<Description>
This method is for non-compressed vectors of finite field elements.
It uses the smallest field containing all entries of the vector, so
equal vectors involving entries from subfields get the same hash.
<P/>
Note that you can only use the resulting hash functions for vectors
of the same length.
</Description>
</ManSection>

<ManSection>
<Meth Name="ChooseHashFunction" Arg="ob, len" Label="ffemat"/>
<Returns> a record </Returns>
<Description>
This method is for non-compressed matrices of finite field elements.
It hashes the rows using the method for non-compressed vectors of
finite field elements.
<P/>
Note that you can only use the resulting hash functions for matrices
of the same size.
Expand Down
1 change: 1 addition & 0 deletions gap/hash.gd
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ DeclareGlobalFunction( "ORB_HashFunctionForShortGF2Vectors" );
DeclareGlobalFunction( "ORB_HashFunctionForShort8BitVectors" );
DeclareGlobalFunction( "ORB_HashFunctionForGF2Vectors" );
DeclareGlobalFunction( "ORB_HashFunctionFor8BitVectors" );
DeclareGlobalFunction( "ORB_HashFunctionForFFEVectors" );
DeclareGlobalFunction( "ORB_HashFunctionForCompressedMats" );
DeclareGlobalFunction( "ORB_HashFunctionForIntegers" );
DeclareGlobalFunction( "ORB_HashFunctionForMemory" );
Expand Down
55 changes: 42 additions & 13 deletions gap/hash.gi
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,20 @@ function(v,data)
return HashKeyBag(v,101,3*GAPInfo.BytesPerVariable,data[2]) mod data[1] + 1;
end );

InstallGlobalFunction( ORB_HashFunctionForFFEVectors,
function(v,data)
local f,x;
if not IsRowVector(v) or not IsFFECollection(v) then
return fail;
fi;
f := BaseDomain(v);
x := NumberFFVector(v, Size(f));
if x = fail then
return fail;
fi;
return x mod data[1] + 1;
end );

InstallMethod( ChooseHashFunction, "failure method",
[IsObject,IsInt],
function(p,hashlen)
Expand All @@ -540,7 +554,7 @@ InstallMethod( ChooseHashFunction, "failure method",
# Now the choosing methods for compressed vectors:

InstallMethod( ChooseHashFunction, "for compressed gf2 vectors",
[IsGF2VectorRep and IsList,IsInt],
[IsRowVector and IsFFECollection and IsGF2VectorRep,IsInt],
function(p,hashlen)
local bytelen;
bytelen := QuoInt(Length(p),8);
Expand All @@ -557,7 +571,7 @@ InstallMethod( ChooseHashFunction, "for compressed gf2 vectors",
end );

InstallMethod( ChooseHashFunction, "for compressed 8bit vectors",
[Is8BitVectorRep and IsList,IsInt],
[IsRowVector and IsFFECollection and Is8BitVectorRep,IsInt],
function(p,hashlen)
local bytelen,i,q,qq;
q := Q_VEC8BIT(p);
Expand Down Expand Up @@ -595,7 +609,7 @@ function(x,data)
end );

InstallMethod( ChooseHashFunction, "for compressed gf2 matrices",
[IsGF2MatrixRep and IsList,IsInt],
[IsMatrix and IsFFECollColl and IsGF2MatrixRep and IsList,IsInt],
function(p,hashlen)
local data;
data := [hashlen,ChooseHashFunction(p[1],hashlen),
Expand All @@ -605,7 +619,7 @@ InstallMethod( ChooseHashFunction, "for compressed gf2 matrices",
end );

InstallMethod( ChooseHashFunction, "for compressed 8bit matrices",
[Is8BitMatrixRep and IsList,IsInt],
[IsMatrix and IsFFECollColl and Is8BitMatrixRep and IsList,IsInt],
function(p,hashlen)
local data,q;
q := Q_VEC8BIT(p[1]);
Expand Down Expand Up @@ -782,17 +796,32 @@ InstallMethod( ChooseHashFunction, "for lists of matrices",
end );

InstallMethod( ChooseHashFunction,
"for finite field vectors over big finite fields",
[IsList, IsInt],
"for finite field vectors",
[IsRowVector and IsFFECollection, IsInt],
function( l, hashlen )
local f,q;
if NestingDepthA(l) = 1 and Length(l) > 0 and IsFFE(l[1]) then
f := Field(l);
q := Size(f);
return rec( func := ORB_HashFunctionForShort8BitVectors,
data := [hashlen,q] );
if IsGF2VectorRep(l) or Is8BitVectorRep(l) then
TryNextMethod();
fi;
TryNextMethod();
return rec( func := ORB_HashFunctionForFFEVectors,
data := [hashlen] );
end );

InstallMethod( ChooseHashFunction,
"for finite field matrices",
[IsMatrix and IsFFECollColl, IsInt],
function( m, hashlen )
local r;
if Length(m) = 0 then
r := rec( func := ORB_HashFunctionForFFEVectors,
data := [hashlen] );
else
r := ChooseHashFunction( m[1], hashlen );
if r = fail then
return fail;
fi;
fi;
return rec( func := ORB_HashFunctionForMatList,
data := [101,hashlen,r] );
end );

if IsBound(HASH_FUNC_FOR_PPERM) then
Expand Down
27 changes: 27 additions & 0 deletions tst/bugfix.tst
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,32 @@ gap> hf.func(w, hf.data);
gap> hf.func(v, hf.data);
446

# verify plain finite field vectors and matrices can be hashed using the
# minimal field generated by their entries
gap> v := [Z(2)^0, 0*Z(2), Z(4)];;
gap> w := [Z(2^2)^0, 0*Z(2), Z(4)];;
gap> v = w;
true
gap> hf := ChooseHashFunction(v, 1009);;
gap> IsRecord(hf);
true
gap> hf.func(v, hf.data) = hf.func(w, hf.data);
true
gap> m := IdentityMat(2, GF(1024));;
gap> n := IdentityMat(2, GF(2));;
gap> m = n;
true
gap> hf := ChooseHashFunction(m, 1009);;
gap> IsRecord(hf);
true
gap> hf.func(m, hf.data) = hf.func(n, hf.data);
true
gap> m := [[Z(3)^0, 0*Z(3)], [0*Z(3), Z(3)^0]];;
gap> hf := ChooseHashFunction(m, 1009);;
gap> IsRecord(hf);
true
gap> IsInt(hf.func(m, hf.data));
true

#
gap> STOP_TEST("Orb package: bugfix.tst", 0);