Skip to content
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
4 changes: 4 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ This file describes changes in the smallgrp package.
# 1.6dev

- Require GAP 4.12
- `NumberSmallGroups` now accepts a list of orders and the selection
criteria of `AllSmallGroups`, as in `NumberSmallGroups(96, IsAbelian)`.
It counts by listing the ids, so it costs what `IdsOfAllSmallGroups`
costs (issue #68)
- Selection by `IsAbelian`, `IsNilpotentGroup`, `IsSupersolvableGroup`,
`IsSolvableGroup`, `RankPGroup` and `PClassPGroup` now avoids
constructing the groups for most orders which had no precomputed data,
Expand Down
24 changes: 22 additions & 2 deletions gap/small.gd
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,10 @@ DeclareGlobalFunction( "SelectSmallGroups" );
## <P/>
## <Ref Func="SmallGroupsInformation"/> reports which criteria are indexed
## for a given order.
## <P/>
## <Ref Func="IdsOfAllSmallGroups"/> returns the ids of these groups instead
## of the groups themselves, and <Ref Func="NumberSmallGroups"/> just their
## number.
## <Example><![CDATA[
## gap> AllSmallGroups( 6 );
## [ <pc group of size 6 with 2 generators>,
Expand Down Expand Up @@ -790,11 +794,12 @@ DeclareSynonym( "IdsOfAllGroups", IdsOfAllSmallGroups );
#############################################################################
##
#F NumberSmallGroups( <order> )
#F NumberSmallGroups( <arg> )
##
## <#GAPDoc Label="NumberSmallGroups">
## <ManSection>
## <Func Name="NumberSmallGroups" Arg='order'/>
## <Func Name="NrSmallGroups" Arg='order'/>
## <Func Name="NumberSmallGroups" Arg='order[, func1, val1, ...]'/>
## <Func Name="NrSmallGroups" Arg='order[, func1, val1, ...]'/>
##
## <Description>
## returns the number of groups of order <A>order</A>.
Expand All @@ -806,6 +811,21 @@ DeclareSynonym( "IdsOfAllGroups", IdsOfAllSmallGroups );
## gap> NumberSmallGroups( 4096 );
## Error, the library of groups of size 4096 is not available
## ]]></Example>
## <P/>
## The function also accepts the arguments of
## <Ref Func="AllSmallGroups"/> and counts the groups that function would
## return.
## <Example><![CDATA[
## gap> NumberSmallGroups( [ 1 .. 100 ] );
## 1048
## gap> NumberSmallGroups( 96, IsAbelian );
## 7
## ]]></Example>
## <P/>
## Orders alone are answered from the numbers of groups. Otherwise the
## cost is that of <Ref Func="IdsOfAllSmallGroups"/>: the indexed criteria
## are applied first, whatever order the criteria are given in, and only
## the groups a remaining criterion must be tested on are constructed.
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand Down
53 changes: 45 additions & 8 deletions gap/small.gi
Original file line number Diff line number Diff line change
Expand Up @@ -638,16 +638,12 @@ end );

#############################################################################
##
#F NumberSmallGroups(<size>)
#F SMALL_GROUPS_NUMBER( <size> )
##
## returns the number of groups of the order <size>.
InstallGlobalFunction( NumberSmallGroups, function( size )
SMALL_GROUPS_NUMBER := function( size )
local inforec;

if not IsPosInt( size ) then
Error( "usage: NumberSmallGroups( order )" );
fi;
if size = 1024 then
if size = 1024 then
return 49487367289;
fi;

Expand All @@ -656,10 +652,51 @@ InstallGlobalFunction( NumberSmallGroups, function( size )
Error( "the library of groups of size ", size, " is not available" );
fi;

if IsBound( inforec.number ) then
if IsBound( inforec.number ) then
return inforec.number;
fi;
return NUMBER_SMALL_GROUPS_FUNCS[ inforec.func ]( size, inforec ).number;
end;

#############################################################################
##
#F NumberSmallGroups(<size>)
#F NumberSmallGroups(<arg>)
##
## returns the number of the groups 'AllSmallGroups' would return for <arg>.
InstallGlobalFunction( NumberSmallGroups, function( arg )
local argl, sizes;

# the classical form, just an order
if Length( arg ) = 1 and IsPosInt( arg[ 1 ] ) then
return SMALL_GROUPS_NUMBER( arg[ 1 ] );
fi;

# 'Size' may precede the orders
argl := arg;
if Length( argl ) > 0 and argl[ 1 ] = Size then
argl := argl{ [ 2 .. Length( argl ) ] };
fi;

# without a criterion the numbers of the orders just add up. A single
# list argument is the orders; a second one would be group numbers and
# is left to 'SelectSmallGroups'.
sizes := fail;
if Length( argl ) = 1 and IsList( argl[ 1 ] ) then
sizes := argl[ 1 ];
elif Length( argl ) > 0 and ForAll( argl, IsPosInt ) then
sizes := argl;
fi;
if sizes <> fail and ForAll( sizes, IsPosInt ) then
return Sum( sizes, SMALL_GROUPS_NUMBER );
fi;

if Length( arg ) <= 1 then
Error( "usage: NumberSmallGroups( order )" );
fi;

# so far counting the groups is not cheaper than listing their ids
return Length( SelectSmallGroups( arg, true, true ) );
end );

#############################################################################
Expand Down
52 changes: 52 additions & 0 deletions tst/small.tst
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,18 @@ gap> IdGroup(G);
################################################################################
# NumberSmallGroups GlobalFunction
################################################################################
gap> NumberSmallGroups();
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups(fail);
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups(0);
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups(Size);
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups("abc");
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups([ 1, fail ]);
Error, usage: NumberSmallGroups( order )
gap> NumberSmallGroups(19);
1
gap> NumberSmallGroups(1024);
Expand All @@ -121,6 +129,50 @@ gap> NumberSmallGroups(5^6);
gap> NumberSmallGroups(5*7*9*11*13);
22

# orders alone need no group at all
gap> NumberSmallGroups([]);
0
gap> NumberSmallGroups([ 1 .. 100 ]);
1048
gap> NumberSmallGroups(Size, [ 1 .. 100 ]);
1048
gap> NumberSmallGroups(60, 1024);
49487367302
gap> NumberSmallGroups(Size, [ 1000, 3996 ]);
Error, the library of groups of size 3996 is not available

# with selection criteria
gap> NumberSmallGroups(96, IsAbelian);
7
gap> NumberSmallGroups(96, IsAbelian, false);
224
gap> NrSmallGroups(96, IsAbelian) + NrSmallGroups(96, IsAbelian, false)
> = NrSmallGroups(96);
true
gap> NumberSmallGroups(Size, [ 1 .. 100 ], IsSolvableGroup, false);
1
gap> NumberSmallGroups(Size, 60, IsSupersolvableGroup, true);
11
gap> ForAll([ 1 .. 100 ], n -> NumberSmallGroups(n, IsNilpotentGroup)
> = Length(IdsOfAllSmallGroups(n, IsNilpotentGroup)));
true

# the indexed criteria come first, whatever order they are given in
gap> NumberSmallGroups(512, IsAbelian, true, Exponent, 2);
1
gap> NumberSmallGroups(512, Exponent, 2, IsAbelian, true);
1

# a list of group numbers may narrow down the selection
gap> NumberSmallGroups(60, [ 1 .. 10 ]);
10
gap> NumberSmallGroups(60, [ 1 .. 10 ], IsNilpotentGroup);
1

# selection criteria need the library, even where the number does not
gap> NumberSmallGroups(1024, IsAbelian);
Error, AllSmallGroups / OneSmallGroup: groups of order 1024 not available

################################################################################
# SelectSmallGroups GlobalFunction (called by AllSmallGroups or OneSmallGroup)
################################################################################
Expand Down