<Chapter Label=
"CongruenceSubgroups">
<Heading>Construction of congruence subgroups</Heading>
<Index Key=
"IsCongruenceSubgroup"><C>IsCongruenceSubgroup</C></Index>
The package &Congruence; provides functions to construct several
types of canonical congruence subgroups in <M>SL_2(&ZZ;)</M>, and also
intersections of a finite number of such subgroups. They will return
a matrix group in the category <C>IsCongruenceSubgroup</C>,
which is defined as a subcategory of <C>IsMatrixGroup</C>, and
which will have a distinguishing property determining whether it is
a congruence subgroup of one of the canonical types, or an intersection
of such congruence subgroups (if it can not be reduced to one of the
canonical congruence subgroups).
To start to work with the package, you need first to load it as follows:
<Log><![
CDATA[
gap> LoadPackage(
"congruence");
-----------------------------------------------------------------------------
Loading Congruence 1.2.7 (Congruence subgroups of SL(2,Integers))
by Ann Dooms (
http://homepages.vub.ac.be/~andooms),
Eric Jespers (
http://homepages.vub.ac.be/~efjesper),
Olexandr Konovalov (
https://olexandr-konovalov.github.io/), and
Helena Verrill (
http://www.math.lsu.edu/~verrill).
maintained by:
Ann Dooms (
http://homepages.vub.ac.be/~andooms),
Olexandr Konovalov (
https://olexandr-konovalov.github.io/), and
Helena Verrill (
http://www.math.lsu.edu/~verrill).
Homepage:
https://gap-packages.github.io/congruence
Report issues at
https://github.com/gap-packages/congruence/issues
-----------------------------------------------------------------------------
true
]]></Log>
<Section Label=
"CongConstr">
<Heading>Construction of congruence subgroups</Heading>
<ManSection>
<Oper Name=
"PrincipalCongruenceSubgroup"
Arg=
"N"
Comm=
"" />
<Description>
Returns the principal congruence subgroup <M>\Gamma(N)</M> of level <A>N</A>
in <M>SL_2(&ZZ;)</M>.<P/>
This subgroup consists of
all matrices of the form
<Alt Only=
"LaTeX">
<![
CDATA[
\[
\left(
\begin{array}{rr}
1+N a & N b \\
N c & 1+N d
\end{array}
\right)
\]
]]>
</Alt>
<Alt Only=
"Text,HTML"><Verb><![
CDATA[
[1+N*a N*b]
[ N*c 1+N*d]
]]></Verb></Alt>
where <M>a</M>,<M>b</M>,<M>c</M>,<M>d</M> are integers.
The returned group will have the property
<Ref Prop=
"IsPrincipalCongruenceSubgroup" />.
</Description>
</ManSection>
<Example><![
CDATA[
gap> G_8:=PrincipalCongruenceSubgroup(8);
<principal congruence subgroup of level 8 in SL_2(Z)>
gap> IsGroup(G_8);
true
gap> IsMatrixGroup(G_8);
true
gap> DimensionOfMatrixGroup(G_8);
2
gap> MultiplicativeNeutralElement(G_8);
[ [ 1, 0 ], [ 0, 1 ] ]
gap> One(G);
[ [ 1, 0 ], [ 0, 1 ] ]
gap> [[1,2],[3,4]] in G_8;
false
gap> [[1,8],[8,65]] in G_8;
true
gap> SL_2:=SL(2,Integers);
SL(2,Integers)
gap> IsSubgroup(SL_2,G_8);
true
]]></Example>
<ManSection>
<Oper Name=
"CongruenceSubgroupGamma0"
Arg=
"N"
Comm=
"" />
<Description>
Returns the congruence subgroup <M>\Gamma_0(N)</M>
of level <A>N</A> in <M>SL_2(&ZZ;)</M>.<P/>
This subgroup consists of
all matrices of the form
<Alt Only=
"LaTeX">
<![
CDATA[
\[
\left(
\begin{array}{rr}
a & b \\
N c & d
\end{array}
\right)
\]
]]>
</Alt>
<Alt Only=
"Text,HTML"><Verb><![
CDATA[
[a b]
[N*c d]
]]></Verb></Alt>
where <M>a</M>,<M>b</M>,<M>c</M>,<M>d</M> are integers.
The returned group will have the property
<Ref Prop=
"IsCongruenceSubgroupGamma0" />.
</Description>
</ManSection>
<Example><![
CDATA[
gap> G0_4:=CongruenceSubgroupGamma0(4);
<congruence subgroup CongruenceSubgroupGamma_0(4) in SL_2(Z)>
]]></Example>
<ManSection>
<Oper Name=
"CongruenceSubgroupGammaUpper0"
Arg=
"N"
Comm=
"" />
<Description>
Returns the congruence subgroup <M>\Gamma^0(N)</M>
of level <A>N</A> in <M>SL_2(&ZZ;)</M>.<P/>
This subgroup consists of
all matrices of the form
<Alt Only=
"LaTeX">
<![
CDATA[
\[
\left(
\begin{array}{rr}
a & N b \\
c & d
\end{array}
\right)
\]
]]>
</Alt>
<Alt Only=
"Text,HTML"><Verb><![
CDATA[
[a N*b]
[c d]
]]></Verb></Alt>
where <M>a</M>,<M>b</M>,<M>c</M>,<M>d</M> are integers.
The returned group will have the property
<Ref Prop=
"IsCongruenceSubgroupGammaUpper0" />.
</Description>
</ManSection>
<Example><![
CDATA[
gap> GU0_2:=CongruenceSubgroupGammaUpper0(2);
<congruence subgroup CongruenceSubgroupGamma^0(2) in SL_2(Z)>
]]></Example>
<ManSection>
<Oper Name=
"CongruenceSubgroupGamma1"
Arg=
"N"
Comm=
"" />
<Description>
Returns the congruence subgroup <M>\Gamma_1(N)</M>
of level <A>N</A> in <M>SL_2(&ZZ;)</M>.<P/>
This subgroup consists of
all matrices of the form
<Alt Only=
"LaTeX">
<![
CDATA[
\[
\left(
\begin{array}{rr}
1+N a & b \\
N c & 1+N d
\end{array}
\right)
\]
]]>
</Alt>
<Alt Only=
"Text,HTML"><Verb><![
CDATA[
[1+N*a b]
[ N*c 1+N*d]
]]></Verb></Alt>
where <M>a</M>,<M>b</M>,<M>c</M>,<M>d</M> are integers.
The returned group will have the property
<Ref Prop=
"IsCongruenceSubgroupGamma1" />.
</Description>
</ManSection>
<Example><![
CDATA[
gap> G1_6:=CongruenceSubgroupGamma1(6);
<congruence subgroup CongruenceSubgroupGamma_1(6) in SL_2(Z)>
]]></Example>
<ManSection>
<Oper Name=
"CongruenceSubgroupGammaUpper1"
Arg=
"N"
Comm=
"" />
<Description>
Returns the congruence subgroup <M>\Gamma^1(N)</M>
of level <A>N</A> in <M>SL_2(&ZZ;)</M>.<P/>
This subgroup consists of
all matrices of the form
<Alt Only=
"LaTeX">
<![
CDATA[
\[
\left(
\begin{array}{rr}
1+N a & N b \\
c & 1+N d
\end{array}
\right)
\]
]]>
</Alt>
<Alt Only=
"Text,HTML"><Verb><![
CDATA[
[1+N*a N*b]
[ c 1+N*d]
]]></Verb></Alt>
where <M>a</M>,<M>b</M>,<M>c</M>,<M>d</M> are integers.
The returned group will have the property
<Ref Prop=
"IsCongruenceSubgroupGammaUpper1" />.
</Description>
</ManSection>
<Example><![
CDATA[
gap> GU1_4:=CongruenceSubgroupGammaUpper1(4);
<congruence subgroup CongruenceSubgroupGamma^1(4) in SL_2(Z)>
]]></Example>
<ManSection>
<Func Name=
"IntersectionOfCongruenceSubgroups"
Arg=
"G1, G2, ..., GN" />
<Func Name=
"Intersection"
Arg=
"G1, G2, ..., GN" />
<Description>
Returns the intersection of its arguments, which can be
congruence subgroups or their intersections, constructed
with the same function. It is not necessary for the user
to use <C>IntersectionOfCongruenceSubgroups</C>, since
it will be called automatically from <C>Intersection</C>.<P/>
The returned group will have the property
<Ref Prop=
"IsIntersectionOfCongruenceSubgroups" />.<P/>
The list of congruence subgroups that form the intersection
can be obtained using <Ref Attr=
"DefiningCongruenceSubgroups"/>.
Note, that when the intersection appears to be one of the
canonical congruence subgroups, the package will recognize
this and will return a canonical subgroup of the
appropriate
type.
</Description>
</ManSection>
<Example><![
CDATA[
gap> I:=IntersectionOfCongruenceSubgroups(G0_4,GU1_4);
<principal congruence subgroup of level 4 in SL_2(Z)>
gap> J:=IntersectionOfCongruenceSubgroups(G0_4,G1_6);
<intersection of congruence subgroups of resulting level 12 in SL_2(Z)>
]]></Example>
</Section>
<!-- ********************************************************* -->
<Section Label=
"CongProperties">
<Heading>Properties of congruence subgroups</Heading>
A congruence subgroup constructed by one of the five above listed functions
will have certain properties determining its
type. These properties will be
used for method selection by &Congruence; algorithms. Note that they do not
provide an actual test whether a certain matrix group is a congruence subgroup
or not.
<ManSection>
<Prop Name=
"IsPrincipalCongruenceSubgroup"
Arg=
"G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if <A>G</A> was
constructed by <Ref Func=
"PrincipalCongruenceSubgroup" />
(or reduced to one as a result of an intersection) and
returns <K>false</K> otherwise.
</Description>
</ManSection>
<Example><![
CDATA[
gap> IsPrincipalCongruenceSubgroup(G_8);
true
gap> IsPrincipalCongruenceSubgroup(G0_4);
false
gap> IsPrincipalCongruenceSubgroup(I);
true
]]></Example>
<ManSection>
<Prop Name=
"IsCongruenceSubgroupGamma0"
Arg=
"G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> was constructed by <Ref Func=
"CongruenceSubgroupGamma0" /> (or reduced to one as a result o
f an intersection)
and returns <K>false</K> otherwise.
</Description>
</ManSection>
<ManSection>
<Prop Name="IsCongruenceSubgroupGammaUpper0"
Arg="G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> was constructed by <Ref Func="CongruenceSubgroupGammaUpper0" /> (or reduced to one as a result of an intersection)
and returns <K>false</K> otherwise.
</Description>
</ManSection>
<ManSection>
<Prop Name="IsCongruenceSubgroupGamma1"
Arg="G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> was constructed by <Ref Func="CongruenceSubgroupGamma1" /> (or reduced to one as a result of an intersection)
and returns <K>false</K> otherwise.
</Description>
</ManSection>
<ManSection>
<Prop Name="IsCongruenceSubgroupGammaUpper1"
Arg="G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> was constructed by <Ref Func="CongruenceSubgroupGammaUpper1" /> (or reduced to one as a result of an intersection)
and returns <K>false</K> otherwise.
</Description>
</ManSection>
<ManSection>
<Prop Name="IsIntersectionOfCongruenceSubgroups"
Arg="G"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> was constructed by
<Ref Func="IntersectionOfCongruenceSubgroups"/> and
without being one of the canonical congruence
subgroups, otherwise it returns <K>false</K>.
</Description>
</ManSection>
<Example><![CDATA[
gap> IsIntersectionOfCongruenceSubgroups(I);
false
gap> IsIntersectionOfCongruenceSubgroups(J);
true
]]></Example>
</Section>
<!-- ********************************************************* -->
<Section Label="CongAttributes">
<Heading>Attributes of congruence subgroups</Heading>
The next three attributes store key properties of congruence subgroups.
<ManSection>
<Attr Name="LevelOfCongruenceSubgroup"
Arg="G"/>
<Description>
Stores the level of the congruence subgroup <A>G</A>. The (arithmetic) level of a congruence subgroup G is the smallest positive
number N such that G contains the principal congruence subgroup of level N.
</Description>
</ManSection>
<Example><![CDATA[
gap> LevelOfCongruenceSubgroup(G_8);
8
gap> LevelOfCongruenceSubgroup(G1_6);
6
gap> LevelOfCongruenceSubgroup(I);
4
gap> LevelOfCongruenceSubgroup(J);
12
]]></Example>
<ManSection>
<Attr Name="IndexInSL2Z"
Arg="G"/>
<Description>
Stores the index of the congruence subgroup <A>G</A> in <M>SL_2(&ZZ;)</M>.
</Description>
</ManSection>
<Example><![CDATA[
gap> IndexInSL2Z(G_8);
384
gap> G_2:=PrincipalCongruenceSubgroup(2);
<principal congruence subgroup of level 2 in SL_2(Z)>
gap> IndexInSL2Z(G_2);
12
gap> IndexInSL2Z(GU1_4);
12
]]></Example>
<ManSection>
<Attr Name="DefiningCongruenceSubgroups"
Arg="G" />
<Returns>
list of congruence subgroups
</Returns>
<Description>
For an intersection of congruence subgroups, returns
the list of congruence subgroups forming this intersection.
For a canonical congruence subgroup returns a list of length
one containing that subgroup.
</Description>
</ManSection>
<Example><![CDATA[
gap> DefiningCongruenceSubgroups(J);
[ <congruence subgroup CongruenceSubgroupGamma_0(4) in SL_2(Z)>,
<congruence subgroup CongruenceSubgroupGamma_1(6) in SL_2(Z)> ]
gap> P:=PrincipalCongruenceSubgroup(6);
<principal congruence subgroup of level 6 in SL_2(Z)>
gap> Q:=PrincipalCongruenceSubgroup(10);
<principal congruence subgroup of level 10 in SL_2(Z)>
gap> G:=IntersectionOfCongruenceSubgroups(Q,P);
<principal congruence subgroup of level 30 in SL_2(Z)>
gap> DefiningCongruenceSubgroups(G);
[ <principal congruence subgroup of level 30 in SL_2(Z)> ]
]]></Example>
</Section>
<!-- ********************************************************* -->
<Section Label="CongMethods">
<Heading>Operations for congruence subgroups</Heading>
&Congruence; installs several special methods for operations already
available in &GAP;.
<ManSection>
<Oper Name="Random"
Label="one and two argument versions"
Arg="G"/>
<Oper Name="Random"
Arg="G m"/>
<Description>
For a congruence subgroup <A>G</A> in the category
<C>IsCongruenceSubgroup</C>, returns random element.
In the two-argument form, the second parameter will
control the absolute value of randomly selected
entries of the matrix.
</Description>
</ManSection>
<Example><![CDATA[
gap> Random(G_2) in G_2;
true
gap> Random(G_8,2) in G_8;
true
]]></Example>
<ManSection>
<Oper Name="\in"
Arg="m G"/>
<Description>
It is easy to implement the membership test for
congruence subgroups and their intersections.
</Description>
</ManSection>
<Example><![CDATA[
gap> \in([ [ 21, 10 ], [ 2, 1 ] ],G_2);
true
gap> \in([ [ 21, 10 ], [ 2, 1 ] ],G_8);
false
]]></Example>
<ManSection>
<Oper Name="CanEasilyCompareCongruenceSubgroups"
Arg="G H"/>
<Description>
For congruence subgroups <A>G,H</A> in the category
<C>IsCongruenceSubgroup</C>, returns <K>true</K> if
<A>G</A> and <A>H</A> are of the same type listed in
<Ref Func="PrincipalCongruenceSubgroup" /> -->
<Ref Func="CongruenceSubgroupGammaUpper1" />
and have the same
<Ref Func="LevelOfCongruenceSubgroup"/> or if <A>G</A> and <A>H</A>
are of the type <Ref Func="IntersectionOfCongruenceSubgroups"/> and
the groups from
<Ref Func="DefiningCongruenceSubgroups"/> are in one
to one correspondence, otherwise it returns <K>false</K>.
</Description>
</ManSection>
<Example><![CDATA[
gap> CanEasilyCompareCongruenceSubgroups(G_8,I);
false
]]></Example>
<ManSection>
<Oper Name="IsSubset"
Arg="G H"/>
<Description>
&Congruence; provides methods for <C>IsSubset</C>
for congruence subgroups. <C>IsSubset</C> returns <K>true</K>
if <A>H</A> is a subset of <A>G</A>. These methods make it possible
to use <C>IsSubgroup</C> operation for congruence subgroups.
</Description>
</ManSection>
<Example><![CDATA[
gap> IsSubset(G_2,G_8);
true
gap> IsSubset(G_8,G_2);
false
gap> f:=[PrincipalCongruenceSubgroup,CongruenceSubgroupGamma1,CongruenceSubgroupGammaUpper1,CongruenceSubgroupGamma0,CongruenceSubgroupGammaUpper0];;
gap> g1:=List(f, t -> t(2));;
gap> g2:=List(f, t -> t(4));;
gap> for g in g2 do
> Print( List( g1, x -> IsSubgroup(x,g) ), "\n");
> od;
[ true, true, true, true, true ]
[ false, true, false, true, false ]
[ false, false, true, false, true ]
[ false, false, false, true, false ]
[ false, false, false, false, true ]
]]></Example>
<ManSection>
<Oper Name="Index"
Arg="G H"/>
<Description>
If a congruence subgroup <A>H</A> is a subgroup of a congruence
subgroup <A>G</A>, we can easily compute the index of <A>H</A> in
<A>G</A>, since we know the index of both subgroups in <M>SL_2(&ZZ;)</M>.
</Description>
</ManSection>
<Example><![CDATA[
gap> Index(G_2,G_8);
32
]]></Example>
</Section>
</Chapter>