The GroupTheory package in 2019 contains more than sixty new or updated commands, new and enhanced databases of groups, and significant performance improvements.
>
with( GroupTheory ):
Computing Dessins D'enfants and Belyi maps
The new FindDessins command computes all dessins d'enfants corresponding to a specified branching pattern. A dessin also represents a Belyi map, and the DecomposeDessin command finds all decompositions of the corresponding Belyi map. These are both parametrized by certain triples of permutations, called 3-constellations, with cycle structure equal to the specified branching pattern.
Consider an example of degree with branching pattern [3$8], [2$12], [6$4].
FindDessins: Genus 1
FindDessins: 1 pairs before discarding conjugates
FindDessins: 1 dessins of degree 1/24 after .4e-2 seconds
FindDessins: 1 pairs before discarding conjugates
FindDessins: 1 dessins of degree 2/24 after .4e-2 seconds
FindDessins: 2 pairs before discarding conjugates
FindDessins: 1 dessins of degree 3/24 after .4e-2 seconds
FindDessins: 1 pairs before discarding conjugates
FindDessins: 1 dessins of degree 5/24 after .5e-2 seconds
FindDessins: 1 pairs before discarding conjugates
FindDessins: 1 dessins of degree 6/24 after .6e-2 seconds
FindDessins: 2 pairs before discarding conjugates
FindDessins: 3 pairs before discarding conjugates
FindDessins: 12 pairs before discarding conjugates
FindDessins: 3 pairs before discarding conjugates
FindDessins: 3 dessins of degree 12/24 after .15e-1 seconds
FindDessins: 4 pairs before discarding conjugates
FindDessins: 31 pairs before discarding conjugates
FindDessins: 2 pairs before discarding conjugates
FindDessins: 4 dessins of degree 18/24 after .46e-1 seconds
FindDessins: 4 pairs before discarding conjugates
FindDessins: 3 pairs before discarding conjugates
FindDessins: 3 dessins of degree 24/24 after .91e-1 seconds
In this case, FindDessins finds dessins.
>
nops( S );
>
d := S[ 2 ];
>
map( PermCycleType, d );
>
DecomposeDessin( d, 'L', 'gr' );
>
L[1];
>
gr;
By iterating over all possible cycle types of a given degree (in the example below, the degree is ), we can count all dessins d'enfants or, equivalently, Belyi maps up to equivalence.
>
infolevel[ 'FindDessins' ] := 0:
>
N := 6:
>
P := combinat:-partition( N ):
>
nops( P );
>
add( add( add( nops( FindDessins( i, j, k ) ), k = P ), j = P ), i = P );
New GroupTheory Package Commands
Many new commands have been added to the GroupTheory package in 2019. These include commands for recognizing groups with many interesting properties, new commands for constructing groups of various kinds, new commands to compute subgroups and subgroup series, as well as a suite of commands for recognizing numbers for which every group of a given order has one of a number of group-theoretic properties.
Frobenius Groups
Maple is now able to recognize finite Frobenius groups, either as abstract groups, or as permutation groups, and to compute Frobenius kernels and complements. Consult the linked help pages for more details. See also the section on the new database of small Frobenius groups below.
The IsFrobeniusGroup command determines whether a finite permutation group G is a Frobenius group, as an abstract group.
>
IsFrobeniusGroup( Symm( 3 ) ); # the smallest Frobenius group
>
IsFrobeniusGroup( DihedralGroup( 5 ) );
>
IsFrobeniusGroup( QuaternionGroup() );
The IsFrobeniusPermGroup command returns true if the permutation group G is Frobenius in its natural action.
>
IsFrobeniusPermGroup( SmallGroup( 6, 1 ) );
>
IsFrobeniusGroup( SmallGroup( 6, 1 ) );
If G is a Frobenius group, then the FrobeniusKernel( G ) command returns its Frobenius kernel. Likewise, the FrobeniusComplement( G ) command returns a representative Frobenius complement.
>
FrobeniusKernel( DihedralGroup( 5 ) );
>
FrobeniusComplement( DihedralGroup( 5 ) );
If a Frobenius group is not represented as a permutation group with Frobenius action, you can use the FrobeniusPermRep( G ) command to obtain a permutation group isomorphic to G for which the action is Frobenius.
>
P := FrobeniusPermRep( SmallGroup( 6, 1 ) );
>
IsFrobeniusPermGroup( P );
Hamiltonian Groups
Several new commands that allow you to work with finite Hamiltonian groups have been introduced in 2019.
Use the IsHamiltonian command to check whether a permutation group is Hamiltonian (that is, a non-Abelian group with every subgroup normal). The IsDedekind command allows you to determine whether a permutation group is a Dedekind group (either Abelian or Hamiltonian).
>
IsHamiltonian( QuaternionGroup() );
>
IsDedekind( DihedralGroup( 4 ) );
>
IsDedekind( ElementaryGroup( 3, 3 ) );
There are new constructors for Hamiltonian groups in this release. The HamiltonianGroup( n, k ) command returns the -th Hamiltonian group of order , where is a multiple of eight. (All Hamiltonian groups have order equal to a multiple of eight.) The NumHamiltonianGroups command returns the number of Hamiltonian groups of a given positive integral order.
>
NumHamiltonianGroups( 100 );
>
NumHamiltonianGroups( 200 );
>
G := HamiltonianGroup( 200, 2 ):
>
IsHamiltonian( G );
The AllHamiltonianGroups command returns an expression sequence of all the Hamiltonian groups of a given order.
>
AllHamiltonianGroups( 200 );
In addition, Hamiltonian groups in the database of small groups have been identified, allowing you to use the search term hamiltonian in the SearchSmallGroups command.
Subgroup Series
Every finite group has a composition series, a subnormal series with simple factors, and the CompositionSeries command returns a composition series for a finite permutation group.
Composition series are of type SubnormalSeries, but not (in general) of type NormalSeries.
>
type( cs, 'SubnormalSeries' );
>
type( cs, 'NormalSeries' );
>
[seq]( GroupOrder( H ), H = cs );
The CompositionLength command returns the number of composition factors.
>
CompositionLength( DihedralGroup( 10 ) );
For a prime number , the lower -central series of a finite group G can be computed by using the new LowerPCentralSeries( p, G ) command.
>
ser := LowerPCentralSeries( 2, DihedralGroup( 8 ) );
>
seq( GroupOrder( H ), H = ser );
To compute the lower Fitting series of a group use the LowerFittingSeries command. The FittingLength( G ) command returns the Fitting length of the soluble permutation group G.
>
ser := LowerFittingSeries( DihedralGroup( 10 ) );
>
seq( GroupOrder( H ), H = ser );
>
FittingLength( DihedralGroup( 10 ) );
>
FittingLength( DihedralGroup( 8 ) );
Use the new FrattiniSeries( G ) command to compute the Frattini series of a permutation group G.
>
fs := FrattiniSeries( Alt( 4 ) );
>
type( fs, 'NormalSeries' );
The FrattiniLength command computes the Frattini length of a permutation group; that is, the length of its Frattini series.
>
FrattiniLength( GL( 2, 3 ) );
A Sylow tower of a finite group is a normal series
for which the series quotients are isomorphic to the Sylow subgroups of , exactly one for each prime divisor of the order of . A sequence of primes is called a complexion of the Sylow tower if it contains all of the primes dividing the order of and if the tower quotients corresponding to the prime divisors of the order of appear in the order in which they appear in . A group may or may not have a Sylow tower, and may have a Sylow tower of one complexion, but not of another, but a group with a Sylow tower of any complexion is necessarily soluble.
The SylowTower( G ) command computes a Sylow tower (of some unspecified complexion) for a soluble permutation group G, if one exists.
>
st := SylowTower( Alt( 4 ) );
>
type( st, 'NormalSeries' );
The complexion for the computed Sylow tower can be retrieved by using the Complexion method.
>
Complexion( st );
The IsSylowTowerGroup( G ) command determines whether the group G has a Sylow tower.
>
IsSylowTowerGroup( Alt( 4 ) );
>
IsSylowTowerGroup( Symm( 4 ) );
A Sylow tower is called ordered if the primes corresponding to successive tower quotients occur in descending order of magnitude. The Sylow tower for the alternating group computed above is not ordered because the prime divisors and of the order of the group do not occur in descending order.
The OrderedSylowTower( G ) command computes an ordered Sylow tower for the soluble permutation group G if one exists.
In fact, the alternating group does not have an ordered Sylow tower.
>
OrderedSylowTower( Alt( 4 ) );
Error, group GroupTheory:-AlternatingGroup(4) has no ordered Sylow tower of complexion [3, 2]
However, every supersoluble group does have an ordered Sylow tower.
>
st := OrderedSylowTower( DihedralGroup( 15 ) );
Notice that the prime divisors in this example do occur in descending order.
>
Complexion( st );
Use the IsOrderedSylowTowerGroup( G ) command to determine whether the group G has an ordered Sylow tower.
>
IsOrderedSylowTowerGroup( Alt( 4 ) );
>
IsOrderedSylowTowerGroup( DihedralGroup( 15 ) );
More generally, the OrderedSylowTower command allows you to pre-specify any desired complexion, and computes a Sylow tower with the matching complexion, if possible.
Error, group GroupTheory:-DihedralGroup(15,form = "permgroup") has no ordered Sylow tower of complexion [3, 2, 5]
Remak Decompositions
The new DirectFactors command produces a Remak decomposition of a finite group. This is an expression sequence of directly indecomposable subgroups of the group such that the group is the direct product of the groups in the sequence.
A number of new commands have been introduced that allow you to test whether a finite group has various properties.
Some of these, such as the new commands IsHamiltonian, IsFrobeniusGroup and IsDirectlyIndecomposable, were described above.
Several more new commands are provided to test whether a finite group belongs to one of a number of other classes of soluble groups.
Use the IsMetacyclic command to determine whether a finite group is metacyclic, and the IsMetabelian command to decide whether a finite group is metabelian. For example, the alternating group of degree 4; is metabelian, but is not metacyclic.
>
IsMetacyclic( Alt( 4 ) );
>
IsMetabelian( Alt( 4 ) );
The new IsCyclicSylowGroup command determines whether a finite group has the property that all of its Sylow subgroups are cyclic. (These are most commonly referred to as Z-groups.)
>
IsCyclicSylowGroup( DihedralGroup( 5 ) );
Finite groups whose Sylow subgroups are all Abelian (often called A-groups) can be recognized by the new IsAbelianSylowGroup command.
>
IsAbelianSylowGroup( Alt( 4 ) );
Use the new IsAlmostSimple command to determine whether a group is almost simple.
>
IsAlmostSimple( Symm( 6 ) );
The new commands IsCNGroup, IsCAGroup and IsCCGroup are used to recognize groups based on properties of their centralizers. These commands detect, respectively, whether the centralizer of each non-trivial element of a finite group is nilpotent, Abelian or cyclic.
For example, the symmetric group of degree is the smallest non-nilpotent (CN)-group that is not a (CA)-group.
>
IsCNGroup( Symm( 4 ) );
>
IsCAGroup( Symm( 4 ) );
The IsHallPaigeGroup command determines whether a finite group has a complete mapping in the sense of Hall and Paige. (The Hall-Paige conjecture was recently settled.)
>
IsHallPaigeGroup( DihedralGroup( 5 ) );
>
IsHallPaigeGroup( DihedralGroup( 10 ) );
>
IsHallPaigeGroup( TitsGroup() );
The IsDihedral command determines whether a permutation group is isomorphic to a dihedral group (not necessarily of the same degree).
Other group properties implemented for permutation groups in this release include IsSupersoluble, IsLagrangian, IsGCLTGroup and IsStemGroup.
The IsSupersoluble( G ) command determines whether the group G is supersoluble; that is, whether all of its chief factors are cyclic of prime order.
>
IsSupersoluble( Alt( 4 ) );
>
IsSupersoluble( DihedralGroup( 7 ) );
Use the IsLagrangian( G ) command to determine whether the group G satisfies the converse of Lagrange's Theorem; that is, whether it has a subgroup of order for each divisor of its order.
>
IsLagrangian( Symm( 4 ) );
>
IsLagrangian( Alt( 4 ) );
The IsGCLTGroup( G ) command checks whether the group G is a GCLT-group.
>
IsGCLTGroup( Symm( 4 ) );
>
IsGCLTGroup( QuaternionGroup() );
To determine whether a group G is a stem group, use the new IsStemGroup( G ) command.
>
IsStemGroup( DihedralGroup( 4 ) );
>
IsStemGroup( CyclicGroup( 10 ) );
A finite group is said to have perfect order classes if the number of elements of each order is a divisor of the order of the group. The IsPerfectOrderClassesGroup command determines whether a group has perfect order classes.
>
IsPerfectOrderClassesGroup( Symm( 3 ) );
>
IsPerfectOrderClassesGroup( Symm( 4 ) );
New and Updated Group Constructors
The SmallGroup constructor can now construct groups of order , for arbitrary primes , and positive integers .
>
G := SmallGroup( 5^4, 3 ):
>
GroupOrder( G );
>
G := SmallGroup( 11^4, 11, 'form' = "fpgroup" );
>
GroupOrder( G );
Generalizing the DerivedSubgroup constructor, the new Commutator( A, B, G ) command computes the normal closure, in the group G, of the commutators , with in and in .
The AllAbelianGroups command returns the complete set of Abelian groups of a given order.
>
AllAbelianGroups( 4 );
Number Theoretic Commands
A selection of number-theoretic commands have been added that allow you to determine whether every group of a given order has a specific property. Here are several examples.
The IsCyclicNumber( n ) command returns true if, and only if, every group of order n is cyclic. This, of course, includes the primes, but also includes composite numbers. In this case, there is only one group of order .
>
IsCyclicNumber( 11 );
>
IsCyclicNumber( 15 );
>
NumGroups( 15 );
>
IsCyclicNumber( 6 );
>
NumGroups( 6 );
Positive integers for which every group of order is Abelian are recognized by the IsAbelianNumber( n ) command.
>
IsAbelianNumber( 4 );
>
andmap( IsAbelian, AllSmallGroups( 4 ) );
>
IsAbelianNumber( 6 );
>
andmap( IsAbelian, AllSmallGroups( 6 ) );
To determine whether every group of order is a nilpotent group, use the new IsNilpotentNumber( n ) command.
>
IsNilpotentNumber( 24 );
>
IsNilpotentNumber( 459 );
>
NumGroups( 459 );
>
andmap( IsNilpotent, AllSmallGroups( 459 ) );
Similarly, the IsSolubleNumber( n ) command determines whether every group of order n is soluble.
Since every supersoluble group has an ordered Sylow tower, every supersoluble number is an ordered Sylow tower number. Evidence for this is exhibited by this command:
But, the non-Abelian group of order is not supersoluble, yet it has an ordered Sylow tower. Therefore, is an ordered Sylow tower number, but not a supersoluble number.
>
IsOrderedSylowTowerNumber( 75 );
>
IsSupersolubleNumber( 75 );
The following additional number-theoretic commands are new in this release: IsIntegrableNumber, IsMetacyclicNumber, IsMetabelianNumber, IsLagrangianNumber, IsGCLTNumber.
Other New Commands
A number of other commands in the GroupTheory package have been added, or updated, in 2019.
The NumGroups command can compute the number of groups of order for more positive integers .
>
NumGroups( 837627012169834259 ); # returned FAIL in Maple 2018
The ElementPower command computes integral powers of elements of a finite group.
>
G := CayleyTableGroup( Symm( 3 ) );
>
g := RandomElement( G ):
>
ElementPower( g, 208374237432343274923743847385, G );
The IsTrivial and TrivialSubgroup commands are utilities for testing for a trivial subgroup, and constructing the trivial subgroup of a given group.
For permutation groups, the RandomInvolution command returns a randomly chosen element of order 2; in a group of even order.
>
g := RandomInvolution( Alt( 8 ) );
>
PermOrder( g );
The RandomPElement command selects an element of -power order from a permutation group at random, and the RandomPPrimeElement command chooses at random an element with order not divisible by a specified prime .
>
g := RandomPElement( 3, Alt( 11 ) );
>
ifactor( PermOrder( g ) );
>
evalb( g in Alt( 11 ) );
>
g := RandomPPrimeElement( 3, Alt( 11 ) );
>
ifactor( PermOrder( g ) );
>
evalb( g in Alt( 11 ) );
The new OrderClassProfile command computes the number of elements of each order in a finite group. A sorted list of element orders is returned by default, but you can request that the output be produced in the form of a MultiSet, or a list of pairs of the form [ order, multiplicity ] by using the appropriate option, as illustrated in the examples below.
The OrderClassPolynomial command provides an encoding of the order class data in the form of a polynomial expression in an indeterminate x, in which the coefficient of the term x^k is equal to the number of elements of order k.
>
OrderClassPolynomial( Alt( 4 ), 'x' );
New and Updated Group Databases
2019 includes a new database of Frobenius groups, as well as updates to the databases of small groups, transitive groups and perfect groups.
New Database of Frobenius Groups
2019 also introduces a new database of Frobenius groups.
To determine the number of Frobenius groups of a given order , use the command NumFrobeniusGroups( n ).
>
NumFrobeniusGroups( 6 );
>
NumFrobeniusGroups( 60 );
>
NumFrobeniusGroups( 100 );
To access a Frobenius group in the database, similar to the other group databases in Maple, use the command FrobeniusGroup( n, k ) to access the -th Frobenius group of order .
>
G := FrobeniusGroup( 100, 3 );
>
GroupOrder( FrobeniusKernel( G ) );
>
GroupOrder( FrobeniusComplement( G ) );
The AllFrobeniusGroups( n ) command returns a list of all the Frobenius groups of a given order .
>
L := AllFrobeniusGroups( 18 );
>
evalb( nops( L ) = NumFrobeniusGroups( 18 ) );
The IdentifyFrobeniusGroup command returns the ID of a Frobenius group that is present in the Frobenius groups database.
The Frobenius groups database is searchable by using the SearchFrobeniusGroups command. This is similar to SearchSmallGroups and SearchTransitiveGroups. Consult the help page SearchFrobeniusGroups for a complete list and description of the pre-computed properties that can be queried using this command.
>
SearchFrobeniusGroups( order < 50, 'cyclickernel', 'cycliccomplement' );
>
G := FrobeniusGroup( 42, 1 );
>
IsCyclic( FrobeniusKernel( G ) );
>
IsCyclic( FrobeniusComplement( G ) );
Let us construct one of the maximal subgroups of the exceptional group , as follows.
>
a, b := op( Generators( ExceptionalGroup( "Sz(8)" ) ) ):
To compute the Frobenius kernel and complement and determine their orders, proceed as follows.
>
K := FrobeniusKernel( G );
>
GroupOrder( K );
>
C := FrobeniusComplement( G );
>
GroupOrder( C );
>
IsMalnormal( C, G );
Subgroups of Frobenius complements whose order is the product of two primes are necessarily cyclic.
>
IsCyclic( C );
>
IdentifySmallGroup( C );
However, the natural action of this group is not Frobenius.
>
IsFrobeniusPermGroup( G );
To get an isomorphic Frobenius permutation group (via the action of G; on the cosets of the Frobenius complement), use the FrobeniusPermRep command.
>
P := FrobeniusPermRep( G );
>
IsFrobeniusPermGroup( P );
Of course, the Frobenius kernel and complement of are isomorphic to those of .
>
IdentifySmallGroup( FrobeniusComplement( P ) );
>
AreIsomorphic( FrobeniusKernel( P ), K );
To locate this group in the database of Frobenius groups, use the IdentifyFrobeniusGroup command.
>
IdentifyFrobeniusGroup( G );
Or, equivalently:
>
IdentifyFrobeniusGroup( P );
Finally, as discussed below, the Frobenius (permutation) groups in the database of transitive groups have been identified, and can be used as a search term there. As well, the Frobenius (abstract) groups in the Small Groups database have been identified.
Updated Database of Perfect Groups
The new SearchPerfectGroups command allows you to search the database of perfect group for groups satisfying various combinations of properties, including the order, center, socle, Fitting subgroup, class number and others. Consult the help page SearchPerfectGroups for a complete list of the supported properties.
Find the perfect groups with non-trivial center, whose order is less than .
>
L := [SearchPerfectGroups]( order < 1000, center > 1, 'form' = "fpgroup" );
>
map( GroupOrder, L );
>
map( IsPerfect, L );
>
map( GroupOrder @ Center @ PermutationGroup, L );
Find those perfect groups of order less than with center isomorphic to SmallGroup( 4, 2 ).
>
SearchPerfectGroups( order < 10000, center = [ 4, 2 ] ); # SmallGroup ID for center!
It is important to understand that the IDs returned by SearchPerfectGroups are the IDs of groups in the database of perfect groups, while the IDs used in queries such as the one above are IDs for the small groups database.
Updated Databases of Small Groups and Transitive Groups
Many new properties have been added to the databases of small groups and transitive groups. Here are a few examples:
>
SearchSmallGroups( order <= 32, compositionlength = 5, abelian );
>
SearchSmallGroups( hamiltonian, order = 100 .. 120 );
>
SearchSmallGroups( almostsimple );
The TransitiveGroups database now includes some abstract group-theoretic properties.
Which soluble, but non-Abelian transitive groups have degree less than ?
Arithmetic and other low-level operations for permutations have been completely re-written in compiled kernel code. In addition, the memory overhead of permutations has been considerably reduced.
For example, the following call to PermOrder took about 200 times longer in Maple 2018.
>
p := Perm( combinat:-randperm( 10^5 ) ):
>
PermOrder( p );
Timing details will of course vary from one machine to another, and depend also upon the random state of the Maple session. But, reproduced here are some representative calculations run in a fresh Maple 2018 session, on a particular 64-bit Linux workstation.
>
L := CodeTools:-Usage( [seq]( Perm( combinat:-randperm( 10^4 ) ), i = 1 .. 1000 ) ):
memory used=307.01MiB, alloc change=283.42MiB, cpu time=6.62s, real time=6.62s, gc time=108.00ma
>
CodeTools:-Usage( PermProduct( op( L ) ) ):
memory used=307.57MiB, alloc change=288.00MiB, cpu time=9.78s, real time=8.36s, gc time=1.75s
>
CodeTools:-Usage( map( PermOrder, L ) ):
memory used=2.54GiB, alloc change=96.00MiB, cpu time=52.62s, real time=40.96s, gc time=13.75s
>
CodeTools:-Usage( map( PermInverse, L ) ):
memory used=0.74GiB, alloc change=320.00MiB, cpu time=19.56s, real time=14.66s, gc time=5.71s
>
CodeTools:-Usage( map( PermCycleType, L ) ):
memory used=0.84MiB, alloc change=0 bytes, cpu time=152.00ms, real time=149.00ms, gc time=0ns
>
CodeTools:-Usage( map( PermPower, L, 3333 ) ):
memory used=4.53GiB, alloc change=2.22GiB, cpu time=3.78m, real time=2.17m, gc time=113.08s
And here are the same calculations run in a fresh 2019 session on the same machine. It is apparent that both time used and memory consumption have been considerably reduced.
>
L := CodeTools:-Usage( [seq]( Perm( combinat:-randperm( 10^4 ) ), i = 1 .. 1000 ) ):
memory used=77.16MiB, alloc change=59.42MiB, cpu time=1.10s, real time=1.10s, gc time=8.00ms
>
CodeTools:-Usage( PermProduct( op( L ) ) ):
memory used=77.85MiB, alloc change=0 bytes, cpu time=592.00ms, real time=587.00ms, gc time=24.00ms
>
CodeTools:-Usage( map( PermOrder, L ) ):
memory used=8.08MiB, alloc change=3.01MiB, cpu time=204.00ms, real time=203.00ms, gc time=0ns
>
CodeTools:-Usage( map( PermInverse, L ) ):
memory used=77.30MiB, alloc change=-1.00MiB, cpu time=568.00ms, real time=560.00ms, gc time=16.00ms
>
CodeTools:-Usage( map( PermCycleType, L ) ):
memory used=214.05KiB, alloc change=0 bytes, cpu time=124.00ms, real time=125.00ms, gc time=0ns
>
CodeTools:-Usage( map( PermPower, L, 3333 ) ):
memory used=77.81MiB, alloc change=0 bytes, cpu time=764.00ms, real time=752.00ms, gc time=36.00ms