-
Notifications
You must be signed in to change notification settings - Fork 175
Description
The following code is a rewriting of the original DirectFactorsOfGroup code as
- to only check direct factors from a given list. This is supposed to enhance speed because after a direct factor is obtained, one does not need to recompute normal subgroups of the factor, but rather pull them from the list;
- it checks trivial intersection of two normal subgroups by checking if a (generator of a) minimal normal subgroup (again, given by a list) is in both normal subgroups. Again, this should be significantly faster if MinimalNormalSubgroups are computed at the beginning, compared to always intersecting the two normal subgroups.
However, testing shows that on a 96-element group it gives only two direct factors, rather than the correct three, if_CRISP_is_used. Without CRISP it gives the correct result.
The code:
DeclareOperation( "IsTrivialNormalIntersectionInList",[IsList, IsGroup, IsGroup]);
DeclareGlobalFunction( "DirectFactorsOfGroupFromList", [IsGroup, IsList, IsList]);
#############################################################################
##
#M IsTrivialNormalIntersectionInList( , , ) . . . . generic method
##
InstallMethod( IsTrivialNormalIntersectionInList,
"if minimal normal subgroups are computed",
[ IsList, IsGroup, IsGroup ],
function( L, U, V )
local gs;
gs:= List(L, N -> GeneratorsOfGroup(N)[1]);
return ForAll(gs, g -> not g in U or not g in V);
end);
InstallGlobalFunction( DirectFactorsOfGroupFromList,
function ( G, NList, MinList )
local gs, Ns, MinNs, NNs, MinNNs, facts, sizes, i, j, s1, s2;
if not IsFinite(G) then TryNextMethod(); fi;
Ns := ShallowCopy(NList);
MinNs := ShallowCopy(MinList);
gs := GeneratorsOfGroup(Socle(G));
Ns := Filtered(Ns, N -> not IsSubset(N, gs));
sizes := List(Ns,Size);
SortParallel(sizes,Ns);
for s1 in Difference(Set(sizes),[Size(G),1]) do
i := PositionSet(sizes,s1);
s2 := Size(G)/s1;
if s1 <= s2 then
repeat
if s2 > s1 then
j := PositionSet(sizes,s2);
if j = fail then break; fi;
else
j := i + 1;
fi;
while j <= Size(sizes) and sizes[j] = s2 do
if IsTrivialNormalIntersectionInList(MinList,Ns[i],Ns[j]) then
# Ns[i] is the smallest direct factor, hence direct irreducible
# we keep from Ns only the subgroups of Ns[j] having size min. s1
NNs := Filtered(Ns, N -> Size(N) >= s1 and s2 mod Size(N) = 0
and IsSubset(Ns[j], N));
MinNNs := Filtered(MinNs, N -> s2 mod Size(N) = 0
and IsSubset(Ns[j], N));
return Union([ Ns[i] ], DirectFactorsOfGroupFromList(Ns[j],
NNs, MinNNs));
fi;
j := j + 1;
od;
i := i + 1;
until i>=Size(sizes) or sizes[i] <> s1;
fi;
od;
return [ G ];
end );
With CRISP I have only two direct factors.
┌───────┐ GAP v4.7.8-469-g23ff54d of 2015-10-30 17:11:41 (CET)
│ GAP │ http://www.gap-system.org
└───────┘ Architecture: x86_64-pc-linux-gnu-gcc-default64
Libs used: gmp, readline
Loading the library and packages ...
Components: trans 1.0, prim 2.1, small* 1.0, id* 1.0
Packages: CRISP 1.3.9, GAPDoc 1.5.1
Try '?help' for help. See also '?copyright' and '?authors'
gap> Read("Df.g");
gap> G := Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ]);
Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)
(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ])
gap> DirectFactorsOfGroupFromList(G, NormalSubgroups(G), MinimalNormalSubgroups(G));
[ "permutation group of size 48 with 5 generators", Group([ (3,4)(20,21) ]) ]
The problem with CRISP does not always happen, but if I rerun it, then about every second time it appears. Without CRISP the result is always 3 direct factors, that are isomorphic, but not always the same three:
┌───────┐ GAP v4.7.8-469-g23ff54d of 2015-10-30 17:11:26 (CET)
│ GAP │ http://www.gap-system.org
└───────┘ Architecture: x86_64-pc-linux-gnu-gcc-default64
Libs used: gmp, readline
Loading the library and packages ...
Components: trans 1.0, prim 2.1, small* 1.0, id* 1.0
Packages: GAPDoc 1.5.1
Try '?help' for help. See also '?copyright' and '?authors'
gap> Read("Df.g");
gap> G := Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ]);
Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)
(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ])
gap> DirectFactorsOfGroupFromList(G, NormalSubgroups(G), MinimalNormalSubgroups(G));
[ "permutation group of size 24 with 4 generators", Group([ (3,4)(20,21) ]),
Group([ (3,4)(10,11) ]) ]
gap> G := Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ]);
Group([ (6,7)(8,9)(10,11)(12,13)(14,15)(16,17)(18,19)(20,21)(22,23)
(24,25), (3,4)(6,8)(13,15)(16,18)(23,25), (8,9)(12,13)(16,17)(20,21)(24,25) ])
gap> DirectFactorsOfGroupFromList(G, NormalSubgroups(G), MinimalNormalSubgroups(G));
[ Group([ (8,9)(10,11)(12,13)(16,17)(24,25), (7,9,8)(12,13,14)(16,19,17)
(22,24,25), (6,7)(8,9)(12,13)(14,15)(16,17)(18,19)(22,23)(24,25) ]),
Group([ (3,4)(20,21) ]), Group([ (3,4)(10,11) ]) ]
Burkhard observed in issue #160 that if one sets the assertion level to 1, a CRISP routine detects an inconsistency: a modulo pcgs returns wrong exponents, e.g., at the break caused by the assertion, enter
ExponentsOfPcElement (gpcgs, gpcgs[1]);
which will return [0,0] instead of [1,0].
Could someone please diagnose this? The above code would be crucial for a new DirectFactorsOfGroup code, but currently I cannot test it properly. Thank you.
Edit: apparently "permutation group of size 24 with 4 generators" and "permutation group of size 48 with 5 generators" are not visible if I put them between smaller and bigger signs as they appear in GAP output. I put them inside apostrophes.