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

Add method for Socle for finite nilpotent groups #402

Merged
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
40 changes: 40 additions & 0 deletions lib/grp.gi
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,46 @@ function( G )
return comp;
end );

#############################################################################
##
#M Socle( <G> ) . . . . . . . . . . . . . . . . for finite nilpotent groups
##
InstallMethod( Socle, "for finite nilpotent groups",
[ IsGroup ],
RankFilter( IsGroup and CanComputeSize and IsFinite and
IsNilpotentGroup ) - RankFilter( IsGroup ),
function(G)
local H, prodH;

if not CanComputeSize(G) or not IsFinite(G)
or not IsNilpotentGroup(G) then
TryNextMethod();
fi;
Copy link
Member

Choose a reason for hiding this comment

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

Won't this usually end up computing the size of the group? That in turn may not terminate. Perhaps have a CanComputeSize check first, perhaps as part of the filter?

An easy way to trigger a problem:

F:=FreeGroup(2);; G:=F/[F.1^2,F.2^2]; Socle(G);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right, it should also check first for CanComputeSize first.

Do you want a tst file on Socle, as well? At least for testing the nilpotent case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I have added CanComputeSize and a tst file. Checks are running now.


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;
Copy link
Member

Choose a reason for hiding this comment

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

You created prodH as a subgroup of G here, so I am pretty sure (but have not verified) that G is always the parent of prodH here -- so you could simplify the code a lot.

Moreover, I don't think it's worth it setting this information for the intermediate groups prodH which you are throwing away in the next loop operation anyway. It should be enough to set this information for the final value of prodH only, i.e. outside the loop. Or am I missing something?

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 am not entirely sure, but I think in one of my examples prodH did not have a parent...

However, in any case the parent might not be G, e.g. if G is a FittingGroup of some bigger group, then prodH would inherit the parent of G (see examples from #398).

I set these filters for the internal groups so that GAP would know about them. It might be a waste of memory, or the user might use these groups later on for something else. I can move it outside of the loop if that is preferred.

Copy link
Member

Choose a reason for hiding this comment

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

Right, I see your point regarding parents, I forgot that G could already have another parent. Drats.

Copy link
Contributor

Choose a reason for hiding this comment

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

On Dec 14, 2015, at 11:03 AM, Max Horn notifications@github.com wrote:

In lib/grp.gi:

  • now socle is product of Omega of the center of its Sylow subgroups

  • for H in SylowSystem(G) do
  •  p := PrimePGroup(H);
    
  •  prodH := ClosureSubgroupNC(prodH, Omega(Center(H), p));
    
  •  # prodH 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 IsSubgroup(G, Parent(prodH)) then
    
  •    SetCentralizerInParent(prodH, Parent(prodH));
    
  •    SetIsNormalInParent(prodH, true);
    
  •  fi;
    
  • od;

You created prodH as a subgroup of G here, so I am pretty sure (but have not verified) that G is always the parent of prodH here

I would not want to bet on this. There even is no guarantee that Subgroup(G,l) always returns an object whose parent is set to be G (it might instead be a parent of G. Also code such asClosure’ might try to be clever and realize the closure is already a known group and then return this group (with a stored, different, parent).

When Parent’ was created it had been intended to serve a similar role as the group of the FamilyPcgs, but it turns out that with subgroups of subgroups it was not possible to formulate a consistent policy on howParent’ should be set.

Moreover, I don't think it's worth it setting this information for the intermediate groups prodH which you are throwing away in the next loop operation anyway. It should be enough to set this information for the final value of prodH only, i.e. outside the loop. Or am I missing something?


Reply to this email directly or view it on GitHub.

Copy link
Member

Choose a reason for hiding this comment

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

@hulpke You are of course right about parent (and I was utterly wrong). @hungaborhorvath already convinced me about that :)


# 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
# characteristic subgroup of a normal subgroup is normal
SetIsNormalInParent(prodH, true);
fi;

return prodH;
end);

#############################################################################
##
Expand Down
36 changes: 36 additions & 0 deletions tst/testinstall/opers/Socle.tst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
gap> START_TEST("socle.tst");
gap> Socle(DihedralGroup(8));
Group([ f3 ])
gap> D := Group((1,3),(1,2,3,4));
Group([ (1,3), (1,2,3,4) ])
gap> Socle(D);
Group([ (1,3)(2,4) ])
gap> Socle(DirectProduct(D, D, D));
Group([ (1,3)(2,4), (5,7)(6,8), (9,11)(10,12) ])
gap> Socle(QuaternionGroup(8));
Group([ y2 ])
gap> Socle(SymmetricGroup(4));
Group([ (1,4)(2,3), (1,2)(3,4) ])
gap> Socle(SymmetricGroup(5));
Alt( [ 1 .. 5 ] )
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) ])
gap> k := 5;; P := SylowSubgroup(SymmetricGroup(4*k), 2);; A := Group((4*k+1, 4*k+2, 4*k+3));; G := ClosureGroup(P, A);
<permutation group with 19 generators>
gap> Socle(G);
Group([ (21,22,23), (1,2)(3,4)(5,6)(7,8)(9,10)(11,12)(13,14)(15,16), (17,18)
(19,20) ])
gap> A := DihedralGroup(16);;
gap> B := SmallGroup(27, 3);;
gap> C := SmallGroup(125, 4);;
gap> D := DirectProduct(A, B, C, SmallGroup(1536, 2));;
gap> GeneratorsOfGroup(Socle(D));
[ f4, f7, f10, f16, f17, f18, f19, f20 ]
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) ]);
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) ])
gap> STOP_TEST("socle", 10000);