Skip to content
Merged
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
77 changes: 70 additions & 7 deletions lib/randiso.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,63 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
## <Func Name="CodePcgs" Arg='pcgs'/>
##
## <Description>
## returns the code corresponding to <A>pcgs</A>.
## returns the non-negative integer code corresponding to the finite pcgs
## <A>pcgs</A>, which must be in <Ref Prop="IsPrimeOrdersPcgs"/>.
## The code stores the relative orders of <A>pcgs</A> and
## the right hand sides of the nontrivial power and commutator relations
## of the pc presentation defined by <A>pcgs</A>. This integer encoding of
## pc groups underlies the group construction method described in
## <Cite Key="BescheEick98"/>.
## <P/>
## More precisely, let
## <M>g_1,\ldots,g_l</M> be the entries of <A>pcgs</A>, and let
## <M>r_1,\ldots,r_l</M> be their relative orders. If <M>l=0</M>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In [BescheEick98], it is assumed that the relative orders of the pcgs are prime integers.
Not every pcgs in GAP has this property, there is a GAP function IsPrimeOrdersPcgs for checking it.

If one admits non-prime relative orders then one cannot read off the relative orders from the order of a given p-group. Thus this assumption should be mentioned in the documentation. Perhaps CodePcgs should check the relative orders, and signal an error if not all of them are prime integers.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Adding that check would certainly be a good idea (but of course this goes beyond the scope of this PR, i.e., is not a blocker).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Such a check has now been added by Thomas in PR #6451

## the code is <M>0</M>. Otherwise put

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

In fact, the code is 0 for any elementary abelian p-group.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@ThomasBreuer By the way, is there a reason why the group order is not encoded in this code as well?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I do not know why the code was defined like this.
One reason to leave out the group order could be that whenever one stores many groups of the same order (which is not unlikely for p-groups), including the group order in each code would be redundant.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, that seems like a good reason.

## <M>m = \max_i r_i - 1</M>. If the relative orders are not all equal,
## the first <M>l</M> base <M>m</M> digits are
## <M>r_1-2,\ldots,r_l-2</M>, so the relative order part is
## <M>\sum_{i=1}^l (r_i-2)m^{l-i}</M>. If the relative orders are all
## equal, this part is omitted; on decoding the relative orders are then
## read from the factorisation of the supplied group order.
## <P/>
## After the relative order part comes a bit mask of length
## <M>l(l+1)/2-1</M>. The bits, from least significant to most
## significant, correspond first to the power relations
## <M>g_1^{r_1},\ldots,g_{l-1}^{r_{l-1}}</M>, and then to the
## commutators <M>[g_j,g_i]</M> for
## <M>1 \leq i &lt; j \leq l</M>, ordered by increasing <M>i</M> and, for
## fixed <M>i</M>, increasing <M>j</M>. A bit is <M>1</M> exactly when
## the corresponding right hand side is nontrivial. The final power
## relation <M>g_l^{r_l}=1</M> is not stored separately.
## <P/>
## The nontrivial right hand sides, in the same order as their set bits,
## are stored as base <M>|G|</M> digits, where <M>G</M> is the group
## generated by <A>pcgs</A>. If
## <M>x = g_1^{e_1} \cdots g_l^{e_l}</M>, with
## <M>0 \leq e_i &lt; r_i</M>, then the digit for <M>x</M> is
## <M>\sum_{i=1}^l e_i\prod_{k=i+1}^l r_k</M>. Equivalently, this is
## the zero-based position of <M>x</M> in the canonical list
## <M>g_1^{e_1}\cdots g_l^{e_l}</M>, ordered according to the
## lexicographic order of the tuples <M>e_1,\dots,e_l</M>.
## <P/>
## Thus if <M>b</M> is <M>m^l</M> when the relative order part is present
## and <M>1</M> otherwise, if <M>u</M> is the bit mask, and if
## <M>a_1,\ldots,a_t</M> are the digits for the nontrivial right hand
## sides, then the complete code is
## <M>A + b(u + 2^{l(l+1)/2-1}(a_1 + |G|a_2 + \cdots +
## |G|^{t-1}a_t))</M>, where <M>A</M> is the relative order part, or
## <M>0</M> if that part is omitted.
## <Example><![CDATA[
## gap> G := CyclicGroup(512);;
## gap> G := CyclicGroup(8);;
## gap> p := Pcgs( G );;
## gap> CodePcgs( p );
## 162895587718739690298008513020159
## 323
## ]]></Example>
## In this example the relative orders are <M>[2,2,2]</M>, so there is
## no relative order part. The nontrivial power tails are <M>g_2</M>
## and <M>g_3</M>, with digits <M>2</M> and <M>1</M> in the canonical
## list. Hence the code is
## <M>1 + 2 + 2^5(2 + 8\cdot 1) = 323</M>.
## </Description>
## </ManSection>
## <#/GAPDoc>
Expand All @@ -43,11 +93,15 @@ DeclareGlobalFunction( "CodePcgs" );
## <Func Name="CodePcGroup" Arg='G'/>
##
## <Description>
## returns the code for a pcgs of <A>G</A>.
## returns the code for the pcgs returned by <C>Pcgs</C> for <A>G</A>.
## The encoding is the one described for <Ref Func="CodePcgs"/>.
## <Example><![CDATA[
## gap> G := DihedralGroup(512);;
## gap> CodePcGroup( G );
## 2940208627577393070560341803949986912431725641726
## gap> G := CyclicGroup(8);;
## gap> code := CodePcGroup( G );
## 323
## gap> H := PcGroupCode( code, Size( G ) );;
## gap> IsCyclic( H ) and Size( H ) = Size( G );
## true
## ]]></Example>
## </Description>
## </ManSection>
Expand All @@ -69,6 +123,15 @@ DeclareGlobalFunction( "CodePcGroup" );
## otherwise anything may happen.
## Valid codes are usually obtained by one of the functions
## <Ref Func="CodePcgs"/> or <Ref Func="CodePcGroup"/>.
## The inverse construction uses the integer format described for
## <Ref Func="CodePcgs"/>. The length of the pcgs, and in the case where
## all relative orders are equal also the relative orders themselves, are
## recovered from the prime factorisation of <A>size</A>.
## <P/>
## The same integer format is also used by Magma's
## <C>SmallGroupEncoding</C> and <C>SmallGroupDecoding</C>, and by
## OSCAR's <C>encode</C> for pc groups and
## <C>pc_group( order, code )</C>.
## <Example><![CDATA[
## gap> G := SmallGroup( 24, 12 );;
## gap> p := Pcgs( G );;
Expand Down
Loading