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
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ This file describes changes in the GAP package 'polycyclic'.
- Allow a finite group fallback for `RepresentativeAction` and `IsConjugate` for
subgroups
- Optimise `NormalIntersection`
- Avoid needlessly large powers when norming and sifting elements at a depth
of finite relative order; this also changes which power `NormedPcpElement`
returns
- Make more use of `NC` versions of functions, and avoid the use of generic `PreImage`
and `Image` dispatchers to improve speed and memory usage
- Implement a method for sorting pcp-subgroups, which prevents hangs when creating
Expand Down
7 changes: 5 additions & 2 deletions doc/defins.xml
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,11 @@ its relative index. For each pcp-element <M>g</M> there exists an integer
<ManSection>
<Func Name="NormingExponent" Arg="g"/>
<Description>
returns an integer <M>e</M>, either positive or <M>-1</M>, such that the pcp-element
<A>g</A> raised to the power of <M>e</M> is normed.
returns an integer <M>e</M> such that the pcp-element <A>g</A> raised to the

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.

This changes documented results: NormingExponent can now be negative at finite depths, and NormedPcpElement, Ngs, Igs return different elements. E.g. G := PcGroupToPcpGroup(CyclicGroup(IsPcGroup, 25));; NormingExponent(G.1^2); gives 3 on master, -2 here; NormedPcpElement(G.1^2) gives g1*g2 vs g1*g2^4. #174 had a CHANGES.md entry for this; please carry it over. Optionally state the range here: in (-r/2, r/2] for relative order r > 0, ±1 for r = 0.

power of <M>e</M> is normed.
For non-trivial <A>g</A> with factor order <M>r</M>, we have
<M>-r/2 &lt; e \leq r/2</M> if <M>r &gt; 0</M>, and
<M>e \in \{-1,1\}</M> if <M>r = 0</M>.
</Description>
</ManSection>

Expand Down
15 changes: 13 additions & 2 deletions gap/basic/pcpelms.gi
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,17 @@ function( g )
return o;
end );

#############################################################################
##
#F SmallestResidue( q, r ) . . . . . . . q mod r in (-r/2, r/2], q if r = 0
##
BindGlobal( "SmallestResidue", function( q, r )
if r = 0 then return q; fi;
q := q mod r;
if 2*q > r then q := q - r; fi;
return q;
end );

#############################################################################
##
#F NormingExponent( g ) . . . . . . . . .returns f such that g^f is normed
Expand All @@ -234,10 +245,10 @@ BindGlobal( "NormingExponent", function( g )
elif r = 0 then
return 1;
elif IsPrime( r ) then
return l^-1 mod r;
return SmallestResidue( l^-1, r );
else
e := Gcdex( r, l ); # = RelativeIndex
return e.coeff2 mod r; # l * c2 = e mod r
return SmallestResidue( e.coeff2, r ); # l * c2 = e mod r
fi;
end );

Expand Down
8 changes: 5 additions & 3 deletions gap/basic/pcppara.gi
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,11 @@ end );
## Apply GcdPcp( g, h ), and apply the same operations on i and j.
##
BindGlobal( "GcdPcpPara", function(g, h, i, j)
local x, y, a, b, q, r, t, z, w, u;
local x, y, a, b, q, r, t, z, w, u, rel;

x := g;
y := h;
rel := FactorOrder(g);

a := LeadingExponent(x);
b := LeadingExponent(y);
Expand All @@ -52,6 +53,8 @@ BindGlobal( "GcdPcpPara", function(g, h, i, j)

while b <> 0 do
q := QuoInt(a, b);
r := a - q * b;
q := SmallestResidue(q, rel);

t := x * y ^ -q;
x := y;
Expand All @@ -61,7 +64,6 @@ BindGlobal( "GcdPcpPara", function(g, h, i, j)
z := w;
w := u;

r := a - q * b;
a := b;
b := r;
od;
Expand Down Expand Up @@ -183,7 +185,7 @@ function( pcs, gens, ppcs, pgens )
b := LeadingExponent(h);
if a > 0 and b > 0 and a mod b = 0 then
# GcdPcpPara would leave h and hh unchanged.
q := a/b;
q := SmallestResidue(a/b, rels[d]);
g := g * h^-q;
gg := gg * hh^-q;
else
Expand Down
12 changes: 7 additions & 5 deletions gap/basic/pcppcps.gi
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,15 @@ IGSValFun := IGSValFun4;
##
## For two non-trivial PcpElements g and h with the same depth, apply the
## Euclidean algorithm to the leading exponents, and do the same operations
## on the elements themselves.
## on the elements themselves. At a depth of finite relative order the
## quotients are taken modulo that order.
##
BindGlobal( "GcdPcp", function(g, h)
local x, y, a, b, q, r, t;
local x, y, a, b, q, r, t, rel;

x := g;
y := h;
rel := FactorOrder(g);

a := LeadingExponent(x);
b := LeadingExponent(y);
Expand All @@ -123,12 +125,12 @@ BindGlobal( "GcdPcp", function(g, h)

while b <> 0 do
q := QuoInt(a, b);
r := a - q * b;

t := x * y ^ -q;
t := x * y ^ -SmallestResidue(q, rel);
x := y;
y := t;

r := a - q * b;
a := b;
b := r;
od;
Expand Down Expand Up @@ -190,7 +192,7 @@ InstallGlobalFunction(AddToIgs, function(igs, gens)
b := LeadingExponent(h);
if a > 0 and b > 0 and a mod b = 0 then
# GcdPcp would leave h unchanged.
g := g * h^(-a/b);
g := g * h^-SmallestResidue(a/b, rels[d]);
else
pair := GcdPcp(g, h);
h := pair[1];
Expand Down
Loading