Skip to content

Commit aa52ee2

Browse files
authored
Add RandomMatrix, RandomInvertibleMatrix; and fix a problem with a new feature for matrix groups (#6232)
- add a description of the cache `FULLGLNICOCACHE` in the code; it is used only by `NicomorphismFFMatGroupOnFullSpace` - change the keys of `FULLGLNICOCACHE`: take the field of the matrix entries into account (not only its size), take the `ConstructingFilter` of the matrices into account - in `NicomorphismFFMatGroupOnFullSpace`, deal with special cases of matrices in `IsBlockMatrixRep` (which have no `ConstructingFilter`) and in `Is8BitMatrixRep` in the situation that the group itself lives over `GF(2)` - in order to admit the action of `IsMatrixObj` matrices on vectors supported by GAP's `Enumerator`s of vector spaces, add a `\^` method that `Unpack`s the matrix object (Eventually we want to avoid this overhead, but then we need `Enumerator`s consisting of vector objects corresponding to the matrix objects.) - add `Matrix` calls in the function that computes preimages under an action homomorphism with `Source` a matrix group, in order to support matrix group elements of prescribed kinds of `IsMatrixObj`. - add tests for the new supported situations (most of the changes were actually forced by already available tests) * add `\in` methods for matrix object and (`GL` or `SL`) * avoid some `Unpack` hacks - introduce `NormedRowVectors_internal( F, base )`, and `AsListOfFreeLeftModule_internal( F, base, zero )`, in order to admit `IsVectorObj`s in `base` without supporting the whole vector space machinery for these objects - introduce `ExternalSet( G )` for matrix groups `G`, meaning the natural `G`-set (an undocumented method for permutation groups `G` was already available) - change `NicomorphismFFMatGroupOnFullSpace` such that we can act with the `IsMatrixObj` matrices on their `IsVectorObj` vectors, without unpacking the matrices - support `IsMatrixObj` matrices in the `Random` methods for GL and SL * adjust also `IsProjectiveActionHomomorphism` methods * add `RandomMatrix`, `RandomInvertibleMatrix` and fix the `RankMat` method for `IsPlistMatrixRep`
1 parent 7889216 commit aa52ee2

17 files changed

Lines changed: 823 additions & 112 deletions

doc/ref/matrix.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,9 @@ see&nbsp;<Ref Sect="Mutability and Copyability"/>.
341341
<Heading>Random Matrices</Heading>
342342

343343
<#Include Label="RandomMat">
344+
<#Include Label="RandomMatrix">
344345
<#Include Label="RandomInvertibleMat">
346+
<#Include Label="RandomInvertibleMatrix">
345347
<#Include Label="RandomUnimodularMat">
346348

347349
</Section>

grp/classic.gd

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ BindGlobal( "SymplecticGroup", function ( arg )
836836
rep:= filt;
837837
filt:= IsMatrixGroup;
838838
else
839-
rep:= fail;
839+
rep:= ValueOption( "ConstructingFilter" );
840840
fi;
841841
if DescribesInvariantBilinearForm( Last( arg ) ) then
842842
form:= Remove( arg );

lib/grpffmat.gi

Lines changed: 129 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,46 +124,95 @@ end );
124124

125125
#############################################################################
126126
##
127-
#M NiceMonomorphism( <ffe-mat-grp> )
127+
## the natural G-set of a matrix group consists of the vectors of the
128+
## natural module
129+
##
130+
InstallOtherMethod( ExternalSet,
131+
[ IsFFEMatrixGroup and IsFinite ],
132+
function( G )
133+
local basis, zero;
134+
135+
basis:= RowsOfMatrix( One( G ) );
136+
zero:= Zero( basis[1] );
137+
return ExternalSet( G, AsListOfFreeLeftModule_internal(
138+
FieldOfMatrixGroup( G ), basis, zero ) );
139+
end );
140+
141+
#############################################################################
142+
##
143+
#V FULLGLNICOCACHE
144+
##
145+
## 'NicomorphismFFMatGroupOnFullSpace' uses a cache of length up to 5,
146+
## as follows.
147+
##
148+
## - If the argument is a matrix group that fits to an entry of this
149+
## cache, in the sense that dimension, field of definition,
150+
## and 'ConstructingFilter' of the matrices in the group are the same as
151+
## for the cached value, the stored mapping is returned.
152+
## - If a new mapping has to be constructed, the first cached entry is
153+
## dropped and the new mapping gets added to the cache.
128154
##
129155
MakeThreadLocal("FULLGLNICOCACHE"); # avoid recreating same homom. repeatedly
130-
FULLGLNICOCACHE:=[];
131-
InstallGlobalFunction( NicomorphismFFMatGroupOnFullSpace, function( grp )
132-
local field, dim, V, xset, nice;
156+
BindGlobal( "FULLGLNICOCACHE", [] );
133157

134-
field := FieldOfMatrixGroup( grp );
135-
dim := DimensionOfMatrixGroup( grp );
158+
159+
#############################################################################
160+
##
161+
#M NiceMonomorphism( <ffe-mat-grp> )
162+
##
163+
InstallGlobalFunction( NicomorphismFFMatGroupOnFullSpace, function( grp )
164+
local rep, filt, q, dim, field, xset, nice;
165+
166+
rep:= Representative( grp );
167+
field:= FieldOfMatrixGroup( grp );
168+
q:= Size( field );
169+
if IsBlockMatrixRep( rep ) then
170+
# There is no support for these matrices acting on vectors.
171+
filt:= IsPlistRep;
172+
elif q = 2 and Is8BitMatrixRep( rep ) then
173+
# We cannot keep both 'field' and 'Is8BitMatrixRep',
174+
# the latter does not admit matrices over GF(2).
175+
filt:= IsGF2MatrixRep;
176+
#TODO: How can we get rid of these hacks?
177+
else
178+
filt:= ConstructingFilter( rep );
179+
fi;
180+
dim:= DimensionOfMatrixGroup( grp );
136181

137182
#check cache
138-
V:=Size(field);
139-
nice:=First(FULLGLNICOCACHE,x->x[1]=V and x[2]=dim);
140-
if nice<>fail then return nice[3];fi;
183+
nice:= First( FULLGLNICOCACHE,
184+
x -> x[1] = field and x[2] = dim and x[3] = filt );
185+
186+
if nice<>fail then return nice[4];fi;
141187

142188
if not (HasIsNaturalGL(grp) and IsNaturalGL(grp)) then
143-
grp:=GL(dim,field); # enforce map on full GL
189+
# enforce map on full GL
190+
grp:= GL( dim, field : ConstructingFilter:= filt );
144191
fi;
145-
V := field ^ dim;
146-
xset := ExternalSet( grp, V );
147-
192+
xset := ExternalSet( grp );
148193

149194
# STILL: reverse the base to get point sorting compatible with lexicographic
150195
# vector arrangement
151-
SetBaseOfGroup( xset, One( grp ));
196+
if IsList( One( grp ) ) then
197+
SetBaseOfGroup( xset, One( grp ));
198+
else
199+
SetBaseOfGroup( xset, RowsOfMatrix( One( grp ) ) );
200+
fi;
152201
nice := ActionHomomorphism( xset,"surjective" );
153202
SetIsInjective( nice, true );
154203
if not HasNiceMonomorphism(grp) then
155204
SetNiceMonomorphism(grp,nice);
156205
fi;
157206
# because we act on the full space we are canonical.
158207
SetIsCanonicalNiceMonomorphism(nice,true);
159-
if Size(V)>10^5 then
208+
if q^dim > 10^5 then
160209
# store only one big one and have it get thrown out quickly
161-
FULLGLNICOCACHE[1]:=[Size(field),dim,nice];
210+
FULLGLNICOCACHE[1]:= [ field, dim, filt, nice ];
162211
else
163212
if Length(FULLGLNICOCACHE)>4 then
164-
FULLGLNICOCACHE:=FULLGLNICOCACHE{[2..5]};
213+
Remove( FULLGLNICOCACHE, 1 );
165214
fi;
166-
Add(FULLGLNICOCACHE,[Size(field),dim,nice]);
215+
Add( FULLGLNICOCACHE, [ field, dim, filt, nice ] );
167216
fi;
168217

169218
return nice;
@@ -190,8 +239,7 @@ local tt;
190239
# if the permutation image would be too large, compute the orbit.
191240
TryNextMethod();
192241
fi;
193-
return NicomorphismFFMatGroupOnFullSpace( GL( DimensionOfMatrixGroup( grp ),
194-
Size( FieldOfMatrixGroup( Parent(grp) ) ) ) );
242+
return NicomorphismFFMatGroupOnFullSpace( grp );
195243
end );
196244

197245
#############################################################################
@@ -256,6 +304,25 @@ InstallMethod( \in, "general linear group", IsElmsColls,
256304
and Length( mat ) = RankMat( mat );
257305
end );
258306

307+
InstallMethod( \in, "general linear group", IsElmsColls,
308+
[ IsMatrixObj, IsFFEMatrixGroup and IsFinite and IsNaturalGL ], 0,
309+
function( mat, G )
310+
local n, F;
311+
n:= NumberRows( mat );
312+
F:= FieldOfMatrixGroup( G );
313+
return n = NumberColumns( mat )
314+
and n = DimensionOfMatrixGroup( G )
315+
and n = RankMat( mat )
316+
#TODO:
317+
# Currently we cannot force the rule that all matrices in a matrix
318+
# group consisting of matrix objects have the same 'BaseDomain',
319+
# and that this common 'BaseDomain' is equal to the 'FieldOfMatrixGroup'
320+
# of the group.
321+
# Eventually we want 'true' only if 'F = BaseDomain( mat )' holds.
322+
and ( IsSubset( F, BaseDomain( mat ) ) or
323+
ForAll( Unpack( mat ), row -> IsSubset( F, row ) ) );
324+
end );
325+
259326
InstallMethod( \in, "special linear group", IsElmsColls,
260327
[ IsMatrix, IsFFEMatrixGroup and IsFinite and IsNaturalSL ], 0,
261328
function( mat, G )
@@ -266,6 +333,19 @@ InstallMethod( \in, "special linear group", IsElmsColls,
266333
and DeterminantMat(mat)=One(FieldOfMatrixGroup( G ));
267334
end );
268335

336+
InstallMethod( \in, "special linear group", IsElmsColls,
337+
[ IsMatrixObj, IsFFEMatrixGroup and IsFinite and IsNaturalSL ], 0,
338+
function( mat, G )
339+
local n, F;
340+
n:= NumberRows( mat );
341+
F:= FieldOfMatrixGroup( G );
342+
return n = NumberColumns( mat )
343+
and n = DimensionOfMatrixGroup( G )
344+
and ( IsSubset( F, BaseDomain( mat ) ) or
345+
ForAll( Unpack( mat ), row -> IsSubset( F, row ) ) )
346+
and DeterminantMat( mat ) = One( F );
347+
end );
348+
269349

270350
#############################################################################
271351
##
@@ -508,10 +588,23 @@ InstallMethodWithRandomSource( Random,
508588
"for a random source and natural GL",
509589
[ IsRandomSource, IsFFEMatrixGroup and IsFinite and IsNaturalGL ],
510590
function(rs, G)
511-
local m;
512-
m := RandomInvertibleMat( rs, DimensionOfMatrixGroup( G ),
513-
FieldOfMatrixGroup( G ) );
514-
return ImmutableMatrix(FieldOfMatrixGroup(G), m, true);
591+
local d, F, m;
592+
593+
d:= DimensionOfMatrixGroup( G );
594+
F:= FieldOfMatrixGroup( G );
595+
m:= Representative( G );
596+
if IsMatrix( m ) then
597+
m:= RandomInvertibleMat( rs, d, F );
598+
m:= ImmutableMatrix(F, m, true);
599+
else
600+
m:= ZeroMatrix( d, d, m );
601+
repeat
602+
Randomize( rs, m );
603+
until RankMat( m ) = d;
604+
MakeImmutable( m );
605+
fi;
606+
607+
return m;
515608
end);
516609

517610

@@ -527,11 +620,18 @@ InstallMethodWithRandomSource( Random,
527620
"for a random source and natural SL",
528621
[ IsRandomSource, IsFFEMatrixGroup and IsFinite and IsNaturalSL ],
529622
function(rs, G)
530-
local m;
531-
m:= RandomInvertibleMat( rs, DimensionOfMatrixGroup( G ),
532-
FieldOfMatrixGroup( G ) );
533-
MultVector(m[1], DeterminantMat(m)^-1);
534-
return ImmutableMatrix(FieldOfMatrixGroup(G), m, true);
623+
local d, m;
624+
625+
# We assume that all elements in the group have the same
626+
# 'BaseDomain' value, hence we may take any 'Representative'.
627+
# see the section "Groups Consisting of Matrix Objects"
628+
# in the Reference Manual.
629+
d:= DimensionOfMatrixGroup( G );
630+
m:= RandomInvertibleMatrix( rs, d, Representative( G ) );
631+
MultMatrixRow( m, 1, DeterminantMatrix( m )^-1 );
632+
MakeImmutable( m );
633+
634+
return m;
535635
end);
536636

537637
#############################################################################

lib/matobjplist.gi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1218,7 +1218,13 @@ InstallMethod( InverseSameMutability,
12181218

12191219
InstallMethod( RankMat,
12201220
[ "IsPlistMatrixRep" ],
1221-
M -> RankMat( List( M![ROWSPOS], x -> x![ELSPOS] ) ) );
1221+
function( M )
1222+
M:= M![ROWSPOS];
1223+
if Length( M ) = 0 then
1224+
return 0;
1225+
fi;
1226+
return RankMat( List( M, x -> x![ELSPOS] ) );
1227+
end );
12221228

12231229
InstallMethodWithRandomSource( Randomize,
12241230
"for a random source and a mutable plist matrix",

0 commit comments

Comments
 (0)