Skip to content

Commit

Permalink
Add MinimalNormalSubgroups and Socle for all nilpotent groups
Browse files Browse the repository at this point in the history
For (finite or infinite) nilpotent groups every normal subgroup intersects
the center nontrivially, thus minimal normal subgroups are central. As
every central subgroup is normal, minimal normal subgroups are cyclic of
prime order. Hence every minimal normal subgroup is in fact a minimal normal
subgroup of the socle, where socle is the Omega group of the Center for all
prime divisors.

Thus Socle method for finite nilpotent groups is rewritten for all nilpotent
groups (test file contains examples of pcp and fp groups) using
AbelianInvariants and IndependentGeneratorsOfGroup. Rank is increased
so that this method would trigger before the finite solvable method.
Trivial methods for elementary abelian and simple groups are added.

New method for MinimalNormalSubgroups goes over the Sylows of the Socle and
makes note of all minimal subgroups. Rank is increased to run this method
first.

Tests are added.
  • Loading branch information
hungaborhorvath committed Feb 10, 2016
1 parent 570594f commit 454c0d6
Show file tree
Hide file tree
Showing 3 changed files with 299 additions and 25 deletions.
162 changes: 137 additions & 25 deletions lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1626,43 +1626,87 @@ end );

#############################################################################
##
#M Socle( <G> ) . . . . . . . . . . . . . . . . for finite nilpotent groups
#M Socle( <G> ) . . . . . . . . . . . . . . . . . . . . . for simple groups
##
InstallMethod( Socle, "for finite nilpotent groups",
InstallMethod( Socle, "for simple groups",
[ IsGroup and IsSimpleGroup ], SUM_FLAGS, IdFunc );

#############################################################################
##
#M Socle( <G> ) . . . . . . . . . . . . . . . for elementary abelian groups
##
InstallMethod( Socle, "for elementary abelian groups",
[ IsGroup and IsElementaryAbelian ], SUM_FLAGS, IdFunc );

#############################################################################
##
#M Socle( <G> ) . . . . . . . . . . . . . . . . . . . . for nilpotent groups
##
InstallMethod( Socle, "for nilpotent groups",
[ IsGroup ],
RankFilter( IsGroup and CanComputeSize and IsFinite and
IsNilpotentGroup ) - RankFilter( IsGroup ),
RankFilter( IsGroup and IsNilpotentGroup and IsFinite )
- RankFilter( IsGroup ),
function(G)
local H, prodH;
local P, C, size, gen, abinv, indgen, i, p, q, soc;

if not CanComputeSize(G) or not IsFinite(G)
or not IsNilpotentGroup(G) then
# IsNilpotent check might error for fp-groups
if not IsAbelian(G) and not IsNilpotentGroup(G) then
TryNextMethod();
fi;

prodH := TrivialSubgroup(G);
# now socle is the product of Omega of the Sylow subgroups of the center
for H in SylowSystem(Center(G)) do
prodH := ClosureSubgroupNC(prodH, Omega(H, PrimePGroup(H)));
od;
# for finite groups the usual methods are faster
# for SylowSystem and Omega
if ( CanComputeSize(G) or HasIsFinite(G) ) and IsFinite(G) then
soc := TrivialSubgroup(G);
# now socle is the product of Omega of Sylow subgroups of the center
for P in SylowSystem(Center(G)) do
soc := ClosureSubgroupNC(soc, Omega(P, PrimePGroup(P)));
od;
else
# compute generators for the torsion Omega p-subgroups of the center
C := Center(G);
gen := [ ];
abinv := [ ];
indgen := [ ];
size := 1;
for i in [1..Length(AbelianInvariants(C))] do
q := AbelianInvariants(C)[i];
if q<>0 then
p := SmallestRootInt(q);
if not IsBound(gen[p]) then
gen[p] := [ IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p) ];
else
Add(gen[p], IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p));
fi;
size := size * p;
Add(abinv, p);
Add(indgen, IndependentGeneratorsOfAbelianGroup(C)[i]^(q/p));
fi;
od;
# Socle is the product of the torsion Omega p-groups of the center
soc := Subgroup(G, Concatenation(Compacted(gen)));
SetSize(soc, size);
SetAbelianInvariants(soc, abinv);
SetIndependentGeneratorsOfAbelianGroup(soc, indgen);
fi;

# Socle is central in G, set some properties and attributes accordingly
SetIsAbelian(prodH, true);
if not HasParent(prodH) then
SetParent(prodH, G);
SetCentralizerInParent(prodH, G);
SetIsNormalInParent(prodH, true);
elif CanComputeIsSubset(G, Parent(prodH))
and IsSubgroup(G, Parent(prodH)) then
SetCentralizerInParent(prodH, Parent(prodH));
SetIsNormalInParent(prodH, true);
elif CanComputeIsSubset(G, Parent(prodH))
and IsSubgroup(Parent(prodH), G) and IsNormal(Parent(prodH), G) then
SetIsAbelian(soc, true);
if not HasParent(soc) then
SetParent(soc, G);
SetCentralizerInParent(soc, G);
SetIsNormalInParent(soc, true);
elif CanComputeIsSubset(G, Parent(soc))
and IsSubgroup(G, Parent(soc)) then
SetCentralizerInParent(soc, Parent(soc));
SetIsNormalInParent(soc, true);
elif CanComputeIsSubset(G, Parent(soc))
and IsSubgroup(Parent(soc), G) and IsNormal(Parent(soc), G) then
# characteristic subgroup of a normal subgroup is normal
SetIsNormalInParent(prodH, true);
SetIsNormalInParent(soc, true);
fi;

return prodH;
return soc;
end);

#############################################################################
Expand Down Expand Up @@ -4323,6 +4367,74 @@ InstallMethod (MinimalNormalSubgroups,
end);


#############################################################################
##
#M MinimalNormalSubgroups( <G> )
##
InstallMethod( MinimalNormalSubgroups, "for simple groups",
[ IsGroup and IsSimpleGroup ], SUM_FLAGS,
function(G) return [ G ]; end);


#############################################################################
##
#M MinimalNormalSubgroups (<G>)
##
InstallMethod( MinimalNormalSubgroups, "for nilpotent groups",
[ IsGroup ], RankFilter( IsGroup and IsFinite and IsNilpotentGroup ) - RankFilter( IsGroup ),
function(G)
local soc, i, p, primes, gen, min, MinimalSubgroupsOfPGroupByGenerators;

# IsNilpotent check might error for fp-groups
if not IsAbelian(G) and not IsNilpotentGroup(G) then
TryNextMethod();
fi;

MinimalSubgroupsOfPGroupByGenerators := function(G, p, gen)
# G is the big group
# p is the prime p
# gens is the generators by which the p-group is given
local min, tuples, g, h, k;

min := [ ];
if Length(gen[p])=1 then
Add(min, Subgroup(G, gen[p]));
else
g := Remove(gen[p]);
for tuples in IteratorOfTuples([0..p-1], Length(gen[p])) do
h := g;
for i in [1..Length(tuples)] do
h := h*gen[p][i]^tuples[i];
od;
Add(min, Subgroup(G, [h]));
od;
Append(min, MinimalSubgroupsOfPGroupByGenerators(G, p, gen));
fi;

return min;
end;

soc := Socle(G);
primes := [ ];
gen := [ ];
min := [ ];
for i in [1..Length(AbelianInvariants(soc))] do
p := AbelianInvariants(soc)[i];
AddSet(primes, p);
if not IsBound(gen[p]) then
gen[p] := [ IndependentGeneratorsOfAbelianGroup(soc)[i] ];
else
Add(gen[p], IndependentGeneratorsOfAbelianGroup(soc)[i]);
fi;
od;

for p in primes do
Append(min, MinimalSubgroupsOfPGroupByGenerators(G, p, gen));
od;
return min;
end);


#############################################################################
##
#M SmallGeneratingSet(<G>)
Expand Down
126 changes: 126 additions & 0 deletions tst/testinstall/opers/MinimalNormalSubgroups.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
gap> START_TEST("Socle.tst");
gap> MinimalNormalSubgroups(Group(()));
[ ]
gap> G := Group(());; NormalSubgroups(G);; MinimalNormalSubgroups(G);
[ ]
gap> D := DihedralGroup(8);;
gap> MinimalNormalSubgroups(D) = [ Center(D) ];
true
gap> List(MinimalNormalSubgroups(D), IdGroup);
[ [ 2, 1 ] ]
gap> D := DihedralGroup(IsFpGroup, 8);;
gap> MinimalNormalSubgroups(D) = [ Center(D) ];
true
gap> List(MinimalNormalSubgroups(D), IdGroup);
[ [ 2, 1 ] ]
gap> D := DihedralGroup(IsPcpGroup, 8);;
gap> MinimalNormalSubgroups(D) = [ Center(D) ];
true
gap> List(MinimalNormalSubgroups(D), IdGroup);
[ [ 2, 1 ] ]
gap> D := Group((1,3),(1,2,3,4));;
gap> MinimalNormalSubgroups(D) = [ Center(D) ];
true
gap> List(MinimalNormalSubgroups(D), IdGroup);
[ [ 2, 1 ] ]
gap> DDD := DirectProduct(D, D, D);;
gap> List(MinimalNormalSubgroups(DDD), IdGroup);
[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ] ]
gap> Q := QuaternionGroup(8);;
gap> MinimalNormalSubgroups(Q) = [ Center(Q) ];
true
gap> List(MinimalNormalSubgroups(Q), IdGroup);
[ [ 2, 1 ] ]
gap> MinimalNormalSubgroups(SymmetricGroup(4)) = [ Group((1,2)(3,4),(1,3)(2,4)) ];
true
gap> List(MinimalNormalSubgroups(SymmetricGroup(5)), IdGroup);
[ [ 60, 5 ] ]
gap> List(MinimalNormalSubgroups(AlternatingGroup(5)), IdGroup);
[ [ 60, 5 ] ]
gap> G := Group((1,2),(3,4),(5,6),(7,8));;
gap> IsElementaryAbelian(G);
true
gap> Size(MinimalNormalSubgroups(G));
15
gap> MinimalNormalSubgroups(PrimitiveGroup(8,3)) = [ Group([ (1,7)(2,8)(3,5)(4,6), (1,3)(2,4)(5,7)(6,8), (1,2)(3,4)(5,6)(7,8) ]) ];
true
gap> k := 5;; P := SylowSubgroup(SymmetricGroup(4*k), 2);; A := Group((4*k+1, 4*k+2, 4*k+3));; G := ClosureGroup(P, A);;
gap> Set(MinimalNormalSubgroups(G)) = Set([ Group([ (1,2)(3,4)(5,6)(7,8)(9,10)(11,12)(13,14)(15,16) ]), Group([ (17,18)(19,20) ]), Group([ (1,2)(3,4)(5,6)(7,8)(9,10)(11,12)(13,14)(15,16)(17,18)(19,20) ]), Group([ (21,22,23) ]) ]);
true
gap> A := DihedralGroup(16);;
gap> B := SmallGroup(27, 3);;
gap> C := SmallGroup(125, 4);;
gap> D := DirectProduct(A, B, C, SmallGroup(1536, 2));;
gap> List(MinimalNormalSubgroups(D), IdGroup);
[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ],
[ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ],
[ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ],
[ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 2, 1 ],
[ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 3, 1 ], [ 3, 1 ], [ 3, 1 ], [ 3, 1 ],
[ 5, 1 ] ]
gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,12)(7,11), (3,5)(4,6,10,8,12)(9,11), (1,3,11,9,5)(4,6,10,8,12) ]);;
gap> MinimalNormalSubgroups(G) = Set([ Group([ (6,12)(8,10), (2,10)(4,12), (2,12)(6,10) ]), Group([ (5,11)(7,9), (3,9)(7,11), (1,9,5,11,7) ]) ]);
true
gap> F := AbelianPcpGroup([0,0,0]);;
gap> G := F / Subgroup(F, [(F.1*F.2)^180, (F.1*F.2^5)^168]);;
gap> MinimalNormalSubgroups(G);
[ Pcp-group with orders [ 2 ], Pcp-group with orders [ 2 ],
Pcp-group with orders [ 2 ], Pcp-group with orders [ 3 ],
Pcp-group with orders [ 3 ], Pcp-group with orders [ 3 ],
Pcp-group with orders [ 3 ], Pcp-group with orders [ 5 ],
Pcp-group with orders [ 7 ] ]
gap> F := FreeGroup("x", "y", "z");;
gap> x := F.1;; y := F.2;; z := F.3;;
gap> F := FreeGroup("x", "y", "z");;
gap> x := F.1;; y := F.2;; z := F.3;;
gap> G := F/[x^(-1)*y^(-1)*x*y, x^(-1)*z^(-1)*x*z, z^(-1)*y^(-1)*z*y, (x*y)^180, (x*y^5)^168];;
gap> Size(MinimalNormalSubgroups(G));
9
gap> MinimalNormalSubgroups(HeisenbergPcpGroup(3));
[ ]
gap> for G in AllGroups(60) do NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); od;
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 60, 5 ] ]
[ [ 3, 1 ], [ 5, 1 ] ]
[ [ 3, 1 ], [ 5, 1 ] ]
[ [ 3, 1 ], [ 5, 1 ] ]
[ [ 4, 2 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 3, 1 ], [ 5, 1 ] ]
gap> G := SmallGroup(120,5);; List(MinimalNormalSubgroups(G), IdGroup);
[ [ 2, 1 ] ]
gap> G := SmallGroup(120,34);; List(MinimalNormalSubgroups(G), IdGroup);
[ [ 60, 5 ] ]
gap> G := SmallGroup(120,35);; List(MinimalNormalSubgroups(G), IdGroup);
[ [ 2, 1 ], [ 60, 5 ] ]
gap> for G in AllGroups(240) do if not IsSolvable(G) then NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); fi; od;
[ [ 2, 1 ] ]
[ [ 2, 1 ] ]
[ [ 2, 1 ], [ 60, 5 ] ]
[ [ 2, 1 ], [ 60, 5 ] ]
[ [ 2, 1 ] ]
[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ] ]
[ [ 2, 1 ], [ 60, 5 ] ]
[ [ 2, 1 ], [ 2, 1 ], [ 2, 1 ], [ 60, 5 ] ]
gap> for G in AllGroups(360) do if not IsSolvable(G) then NormalSubgroups(G);; Print(List(MinimalNormalSubgroups(G), IdGroup), "\n"); fi; od;
[ [ 2, 1 ], [ 3, 1 ] ]
[ [ 360, 118 ] ]
[ [ 3, 1 ], [ 60, 5 ] ]
[ [ 3, 1 ], [ 60, 5 ] ]
[ [ 3, 1 ], [ 60, 5 ] ]
[ [ 2, 1 ], [ 3, 1 ], [ 60, 5 ] ]
gap> G := AbelianGroup([2, 3, 4, 5, 6, 7, 8, 9, 10]);;
gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size));
[ [ 2, 31 ], [ 3, 13 ], [ 5, 6 ], [ 7, 1 ] ]
gap> G := ElementaryAbelianGroup(2^10);;
gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size));
[ [ 2, 1023 ] ]
gap> G := ElementaryAbelianGroup(7^4);;
gap> Collected(List(Set(MinimalNormalSubgroups(G)), Size));
[ [ 7, 400 ] ]
gap> STOP_TEST("Socle.tst", 10000);
36 changes: 36 additions & 0 deletions tst/testinstall/opers/Socle.tst
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
gap> START_TEST("Socle.tst");
gap> Socle(Group(()));
Group(())
gap> D := DihedralGroup(8);;
gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup)));
true
gap> IdGroup(Socle(D));
[ 2, 1 ]
gap> Socle(D) = Center(D);
true
gap> D := DihedralGroup(IsFpGroup, 8);;
gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup)));
true
gap> IdGroup(Socle(D));
[ 2, 1 ]
gap> Socle(D) = Center(D);
true
gap> D := DihedralGroup(IsPcpGroup, 8);;
gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup)));
true
gap> IdGroup(Socle(D));
[ 2, 1 ]
gap> Socle(D) = Center(D);
true
gap> D := Group((1,3),(1,2,3,4));;
gap> Socle(D) = ClosureSubgroup(TrivialSubgroup(D), Union(Set(MinimalNormalSubgroups(D), GeneratorsOfGroup)));
true
Expand All @@ -31,6 +47,13 @@ gap> Socle(SymmetricGroup(4)) = Group((1,2)(3,4),(1,3)(2,4));
true
gap> IdGroup(Socle(SymmetricGroup(5)));
[ 60, 5 ]
gap> IdGroup(Socle(AlternatingGroup(5)));
[ 60, 5 ]
gap> G := Group((1,2),(3,4),(5,6),(7,8));;
gap> IsElementaryAbelian(G);
true
gap> Socle(G)=G;
true
gap> Socle(PrimitiveGroup(8,3)) = Group([ (1,7)(2,8)(3,5)(4,6), (1,3)(2,4)(5,7)(6,8), (1,2)(3,4)(5,6)(7,8) ]);
true
gap> k := 5;; P := SylowSubgroup(SymmetricGroup(4*k), 2);; A := Group((4*k+1, 4*k+2, 4*k+3));; G := ClosureGroup(P, A);;
Expand All @@ -44,8 +67,21 @@ gap> IdGroup(Socle(D));
[ 1440, 5958 ]
gap> Socle(D) = Center(D);
true
gap> Socle(FittingSubgroup(SymmetricGroup(4)));
Group([ (1,4)(2,3), (1,3)(2,4) ])
gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,12)
> (7,11), (3,5)(4,6,10,8,12)(9,11), (1,3,11,9,5)(4,6,10,8,12) ]);;
gap> Socle(G) = Group([ (3,7)(5,9), (5,11)(7,9), (1,5,3)(7,11,9), (2,8,10)(4,6,12), (4,6)(10,12) ]);
true
gap> F := AbelianPcpGroup([0,0,0]);;
gap> G := F / Subgroup(F, [(F.1*F.2)^180, (F.1*F.2^5)^168]);;
gap> Socle(G);
Pcp-group with orders [ 6, 210 ]
gap> F := FreeGroup("x", "y", "z");;
gap> x := F.1;; y := F.2;; z := F.3;;
gap> G := F/[x^(-1)*y^(-1)*x*y, x^(-1)*z^(-1)*x*z, z^(-1)*y^(-1)*z*y, (x*y)^180, (x*y^5)^168];;
gap> Size(Socle(G));
1260
gap> Socle(HeisenbergPcpGroup(3));
Pcp-group with orders [ ]
gap> STOP_TEST("Socle.tst", 10000);

0 comments on commit 454c0d6

Please sign in to comment.