Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor performance improvements, code cleanup and very local fixes #2733

Merged
merged 13 commits into from
Sep 9, 2018
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
3 changes: 1 addition & 2 deletions lib/autsr.gi
Original file line number Diff line number Diff line change
Expand Up @@ -620,8 +620,7 @@ local ff,r,d,ser,u,v,i,j,k,p,bd,e,gens,lhom,M,N,hom,Q,Mim,q,ocr,split,MPcgs,

# do we use induced radical automorphisms to help next step?
if Size(KernelOfMultiplicativeGeneralMapping(hom))>1 and
Size(A)>10^8 and (IsAbelian(r) or
Length(AbelianInvariants(r))<10)
Size(A)>10^8 and (IsAbelian(r) or AbelianRank(r)<10)
#(
## potentially large GL
#Size(GL(Length(MPcgs),RelativeOrders(MPcgs)[1]))>10^10 and
Expand Down
4 changes: 2 additions & 2 deletions lib/ctbl.gd
Original file line number Diff line number Diff line change
Expand Up @@ -4436,11 +4436,11 @@ DeclareGlobalFunction( "NormalSubgroupClasses" );
## Character( CharacterTable( S4 ), [ 3, 1, -1, 0, -1 ] ),
## Character( CharacterTable( S4 ), [ 1, 1, 1, 1, 1 ] ) ]
## gap> kernel:= KernelOfCharacter( irr[3] );
## Group([ (1,2)(3,4), (1,3)(2,4) ])
## Group([ (1,2)(3,4), (1,4)(2,3) ])
## gap> HasNormalSubgroupClassesInfo( tbl );
## true
## gap> NormalSubgroupClassesInfo( tbl );
## rec( nsg := [ Group([ (1,2)(3,4), (1,3)(2,4) ]) ],
## rec( nsg := [ Group([ (1,2)(3,4), (1,4)(2,3) ]) ],
## nsgclasses := [ [ 1, 3 ] ], nsgfactors := [ ] )
## gap> ClassPositionsOfNormalSubgroup( tbl, kernel );
## [ 1, 3 ]
Expand Down
15 changes: 12 additions & 3 deletions lib/ghomperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1964,6 +1964,13 @@ function( hom )

if IsEndoGeneralMapping( hom ) then

# cheap test for cycle structures
if Length(Set(List(MappingGeneratorsImages(hom),
x->List(x,CycleStructurePerm))))>1
then
return false;
fi;

# test in transitive case whether we can realize in S_n
# we do not yet compute the permutation here because we will still have to
# test first whether it is in fact an inner automorphism:
Expand Down Expand Up @@ -2106,9 +2113,11 @@ function( hom )
if rep<>fail then
pi:=List([1..Length(orb)],x->MappingPermListList(Permuted(orb[x],rep[x]),orb[x]));
rep:=Product(pi);
Assert(1,ForAll(genss,i->ImagesRepresentative(hom,i)=i^rep));
SetConjugatorOfConjugatorIsomorphism( hom, rep );
return true;
# must do final test, in case element maps to restricted perm
if ForAll(genss,i->ImagesRepresentative(hom,i)=i^rep) then
SetConjugatorOfConjugatorIsomorphism( hom, rep );
return true;
fi;
fi;

if ValueOption("cheap")=true then
Expand Down
2 changes: 2 additions & 0 deletions lib/gpprmsya.gi
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,8 @@ local G,max,dom,n,A,S,issn,p,i,j,m,k,powdec,pd,gps,v,invol,sel,mf,l,prim;
fi;
od;

Info(InfoPerformance,2,"Using Primitive Groups Library");

# type (f): Almost simple
if not PrimitiveGroupsAvailable(n) then
Error("tables missing");
Expand Down
15 changes: 12 additions & 3 deletions lib/grp.gd
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,9 @@ InstallTrueMethod( IsSimpleGroup, IsSporadicSimpleGroup );
DeclareProperty( "IsAlmostSimpleGroup", IsGroup );
InstallTrueMethod( IsGroup, IsAlmostSimpleGroup );

# a simple group is almost simple
InstallTrueMethod( IsAlmostSimpleGroup, IsSimpleGroup );


#############################################################################
##
Expand Down Expand Up @@ -858,6 +861,10 @@ InstallTrueMethod( IsPolycyclicGroup,
##
DeclareAttribute( "AbelianInvariants", IsGroup );

# minimal number of generators for abelianization. Used internally to check
# whether it is worth to attempt to reduce generator number
DeclareAttribute( "AbelianRank", IsGroup );
Copy link
Member

Choose a reason for hiding this comment

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

[Question] would it be useful to document this attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My concern was that this could lead to confusion as AbelianInvariants will (in general) return a longer list by separating different primes, while this attribute gives the minimal generator number of $G/G'$.


#############################################################################
##
#A IsInfiniteAbelianizationGroup( <G> )
Expand Down Expand Up @@ -1221,7 +1228,9 @@ DeclareAttribute("TryMaximalSubgroupClassReps",IsGroup,"mutable");
# utility function in maximal subgroups code
DeclareGlobalFunction("TryMaxSubgroupTainter");
DeclareGlobalFunction("DoMaxesTF");
DeclareGlobalFunction("MaxesAlmostSimple");

# make this an operation to allow for overloading and TryNextMethod();
DeclareOperation("MaxesAlmostSimple",[IsGroup]);

#############################################################################
##
Expand Down Expand Up @@ -1868,8 +1877,8 @@ DeclareAttribute( "MinimalNormalSubgroups", IsGroup );
## returns a list of all normal subgroups of <A>G</A>.
## <Example><![CDATA[
## gap> g:=SymmetricGroup(4);;NormalSubgroups(g);
## [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,2)
## (3,4) ]), Group(()) ]
## [ Sym( [ 1 .. 4 ] ), Alt( [ 1 .. 4 ] ), Group([ (1,4)(2,3), (1,3)
## (2,4) ]), Group(()) ]
## ]]></Example>
## <P/>
## The algorithm for the computation of normal subgroups is described in
Expand Down
12 changes: 12 additions & 0 deletions lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,18 @@ InstallMethod( AbelianInvariants,
return inv;
end );

InstallMethod( AbelianRank ,"generic method for groups", [ IsGroup ],0,
function(G)
local a,r;
a:=AbelianInvariants(G);
r:=Number(a,IsZero);
a:=Filtered(a,x->not IsZero(x));
if Length(a)=0 then return r; fi;
a:=List(Set(a,SmallestRootInt),p->Number(a,x->x mod p=0));
return r+Maximum(a);
end);


#############################################################################
##
#M IsInfiniteAbelianizationGroup( <G> )
Expand Down
22 changes: 22 additions & 0 deletions lib/grpffmat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -125,14 +125,26 @@ end );
##
#M NiceMonomorphism( <ffe-mat-grp> )
##
MakeThreadLocal("FULLGLNICOCACHE"); # avoid recreating same homom. repeatedly
FULLGLNICOCACHE:=[];
InstallGlobalFunction( NicomorphismFFMatGroupOnFullSpace, function( grp )
local field, dim, V, xset, nice;

field := FieldOfMatrixGroup( grp );
dim := DimensionOfMatrixGroup( grp );

#check cache
V:=Size(field);
nice:=First(FULLGLNICOCACHE,x->x[1]=V and x[2]=dim);
if nice<>fail then return nice[3];fi;

if not (HasIsNaturalGL(grp) and IsNaturalGL(grp)) then
grp:=GL(dim,field); # enforce map on full GL
fi;
V := field ^ dim;
xset := ExternalSet( grp, V );


# STILL: reverse the base to get point sorting compatible with lexicographic
# vector arrangement
SetBaseOfGroup( xset, One( grp ));
Expand All @@ -144,6 +156,16 @@ InstallGlobalFunction( NicomorphismFFMatGroupOnFullSpace, function( grp )
SetFilterObj(nice,IsNiceMonomorphism);
# because we act on the full space we are canonical.
SetIsCanonicalNiceMonomorphism(nice,true);
if Size(V)>10^5 then
# store only one big one and have it get thrown out quickly
FULLGLNICOCACHE[1]:=[Size(field),dim,nice];
else
if Length(FULLGLNICOCACHE)>4 then
FULLGLNICOCACHE:=FULLGLNICOCACHE{[2..5]};
fi;
Add(FULLGLNICOCACHE,[Size(field),dim,nice]);
fi;

return nice;
end );

Expand Down
7 changes: 7 additions & 0 deletions lib/grpfp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,13 @@ InstallOtherMethod( Length,
[ IsElementOfFpGroup and IsPackedElementDefaultRep ],0,
x->Length(UnderlyingElement(x)));

InstallOtherMethod(Subword,"for an element of an f.p. group (default repres.)",true,
[ IsElementOfFpGroup and IsPackedElementDefaultRep, IsInt, IsInt ],0,
function(word,a,b)
return ElementOfFpGroup(FamilyObj(word),Subword(UnderlyingElement(word),a,b));
end);


#############################################################################
##
#M InverseOp( <elm> ) . . . . . . . . . . . . . . for element of f.p. group
Expand Down
2 changes: 2 additions & 0 deletions lib/grplatt.gd
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,8 @@ DeclareGlobalFunction("TomDataSubgroupsAlmostSimple");
## returned. If also a function <A>dosub</A> is given, maximal subgroups
## are only attempted if this function returns true (this is separated for
## performance reasons).
## In the example below, the result would be the same with leaving out the
## fourth function, but calculation this way is slightly faster.
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand Down
25 changes: 18 additions & 7 deletions lib/grplatt.gi
Original file line number Diff line number Diff line change
Expand Up @@ -2122,14 +2122,25 @@ local G, # group
Info(InfoLattice,2,"Search involution");

# find involution in M/T
cnt:=0;
repeat
repeat
inv:=Random(M);
until (Order(inv) mod 2 =0) and not inv in T;
o:=First([2..Order(inv)],i->inv^i in T);
until (o mod 2 =0);
Info(InfoLattice,2,"Element of order ",o);
inv:=inv^(o/2); # this is an involution in the factor
repeat
repeat
inv:=Random(M);
until (Order(inv) mod 2 =0) and not inv in T;
o:=First([2..Order(inv)],i->inv^i in T);
until (o mod 2 =0);
Info(InfoLattice,2,"Element of order ",o);
inv:=inv^(o/2); # this is an involution in the factor

cnt:=cnt+1;
# in permgroups try to pick an involution that does not move all
# points. This can make the core of C to be computed quicker.
until not (IsPermGroup(M) and cnt<10
and Length(MovedPoints(inv))=Length(MovedPoints(M)));



Assert(1,inv^2 in T and not inv in T);

S:=Normalizer(G,T); # stabilize first component
Expand Down
7 changes: 7 additions & 0 deletions lib/grpnice.gi
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,13 @@ end);
AttributeMethodByNiceMonomorphism( Size,
[ IsGroup ] );

#############################################################################
##
#M StructureDescription( <G> )
##
AttributeMethodByNiceMonomorphism( StructureDescription,
[ IsGroup ] );


#############################################################################
##
Expand Down
24 changes: 17 additions & 7 deletions lib/grppcext.gi
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,7 @@ end);
InstallGlobalFunction( CompatiblePairs, function( arg )
local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1,
K2, f, tmp, Ggens, pcgs, l, idx, u, tup,Dos,elmlist,preimlist,pows,
baspt,newimgs,i,j,basicact;
baspt,newimgs,i,j,basicact,neu;

# catch arguments
G := arg[1];
Expand Down Expand Up @@ -694,24 +694,34 @@ local G, M, Mgrp, oper, A, B, D, translate, gens, genimgs, triso, K, K1,
tmp:=List(genimgs,x->x[1]);
preimlist:=List(tmp,x->[x,List(Ggens,y->PreImagesRepresentative(x,y))]);

# ensure wa also account for action
# ensure we also account for action
u:=Group(tup);
elmlist:=AsSSortedList(u);
tmp:=GeneratorsOfGroup(u);
tmp:=SmallGeneratingSet(u);
i:=1;
while elmlist<>fail and i<=Length(tmp) do
for j in genimgs do
if elmlist<>fail and not tmp[i]^j[2] in elmlist then
u:=ClosureGroup(u,tmp[i]^j[2]);
j:=1;
while j<=Length(genimgs) do
neu:=tmp[i]^genimgs[j][2];
if elmlist<>fail and not neu in elmlist then
u:=ClosureGroup(u,neu);
if Size(u)>50000 then
# catch cases of too many elements.
elmlist:=fail;
f:=basicact;
j:=Length(genimgs)+1;
else
elmlist:=AsSSortedList(u);
tmp:=GeneratorsOfGroup(u);
if Length(SmallGeneratingSet(u))<Length(tmp) then
tmp:=SmallGeneratingSet(u);
i:=0;
j:=Length(genimgs)+1; # force loop reset
else
tmp:=Concatenation(tmp,[neu]);
fi;
fi;
fi;
j:=j+1;
od;
i:=i+1;
od;
Expand Down
14 changes: 12 additions & 2 deletions lib/grppclat.gd
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,18 @@ DeclareGlobalFunction(
## It returns a list of representatives up to <A>G</A>-conjugacy.
## <P/>
## The optional argument <A>opt</A> is a record, which may
## be used to put restrictions on the subgroups computed. The following record
## components of <A>opt</A> are recognized and have the following effects:
## be used to suggest restrictions on the subgroups computed.
## The following record
## components of <A>opt</A> are recognized and have the following effects.
## Note that all of the following
## restrictions to subgroups with particular properties are
## only used to speed up the calculation, but the result might still contain
## subgroups (that had to be computed in any case) that do not satisfy the
## properties. If this is not desired, the calculation must be followed by an
## explicit test for the desired properties (which is not done by default, as
## it would be a general slowdown).
## The function guarantees that representatives of all subgroups that
## satisfy the properties are found, i.e. there can be only false positives.
## <List>
## <Mark><C>actions</C></Mark>
## <Item>
Expand Down
2 changes: 1 addition & 1 deletion lib/grppclat.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ InstallMethod(CharacteristicSubgroups,"solvable, automorphisms",true,
[IsGroup and IsSolvableGroup],0,
function(G)
local A,s;
if Length(AbelianInvariants(G))<5 then
if AbelianRank(G)<5 then
TryNextMethod();
fi;
A:=AutomorphismGroup(G);
Expand Down
47 changes: 26 additions & 21 deletions lib/grpperm.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1519,7 +1519,7 @@ end );
##
#M Socle( <G> ) . . . . . . . . . . . socle of primitive permutation group
##
InstallMethod( Socle,"for permgrp", true, [ IsPermGroup ], 0,
InstallMethod( Socle,"test primitive", true, [ IsPermGroup ], 0,
function( G )
local Omega, deg, shortcut, coll, d, m, c, ds, L, z, ord,
p, i;
Expand All @@ -1539,25 +1539,27 @@ InstallMethod( Socle,"for permgrp", true, [ IsPermGroup ], 0,
deg := Length( Omega );
if deg >= 6103515625 then
TryNextMethod();
elif deg < 12960000 then
shortcut := true;
if deg >= 3125 then
coll := Collected( Factors(Integers, deg ) );
d := Gcd( List( coll, c -> c[ 2 ] ) );
if d mod 5 = 0 then
m := 1;
for c in coll do
m := m * c[ 1 ] ^ ( c[ 2 ] / d );
od;
if m >= 5 then
shortcut := false;
fi;
fi;
fi;
if shortcut then
ds := DerivedSeriesOfGroup( G );
return ds[ Length( ds ) ];
fi;
# the normal closure actually seems to be faster than derived series, so
Copy link
Member

Choose a reason for hiding this comment

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

[Maybe] Remove the code instead of commenting it out, and describe in the comment that formerly there was some code here which was removed because of some reasons.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think I have run or analyzed enough examples to state categorically that the old (now commented out) code is clearly useless. Someone (well, myself) might stumble on this place again when looking at an inefficiency, and it might turn out that under certain circumstances the now commented-out code is in fact better. If it is immediately removed, it is hard to recover it from git.

# this is not really a shortcut
#elif deg < 12960000 then
# shortcut := true;
# if deg >= 3125 then
# coll := Collected( Factors( deg ) );
# d := Gcd( List( coll, c -> c[ 2 ] ) );
# if d mod 5 = 0 then
# m := 1;
# for c in coll do
# m := m * c[ 1 ] ^ ( c[ 2 ] / d );
# od;
# if m >= 5 then
# shortcut := false;
# fi;
# fi;
# fi;
# if shortcut then
# ds := DerivedSeriesOfGroup( G );
# return ds[ Length( ds ) ];
# fi;
fi;

coll := Collected( Factors(Integers, Size( G ) ) );
Expand All @@ -1577,7 +1579,10 @@ InstallMethod( Socle,"for permgrp", true, [ IsPermGroup ], 0,
until ord mod p = 0;
z := z ^ ( ord / p );
until Index( G, Centralizer( G, z ) ) mod p <> 0;
L := NormalClosure( G, SubgroupNC( G, [ z ] ) );

# immediately add conjugate as this will be needed anyhow and seems to
# speed up the closure process
L := NormalClosure( G, SubgroupNC( G, [ z,z^Random(G) ] ) );
if deg >= 78125 then
ds := DerivedSeriesOfGroup( L );
L := ds[ Length( ds ) ];
Expand Down
Loading