Congruence subgroup \(\Gamma_H(N)\)#

AUTHORS:

  • Jordi Quer

  • David Loeffler

class sage.modular.arithgroup.congroup_gammaH.GammaH_class(level, H, Hlist=None)#

Bases: CongruenceSubgroup

The congruence subgroup \(\Gamma_H(N)\) for some subgroup \(H \trianglelefteq (\ZZ / N\ZZ)^\times\), which is the subgroup of \(\SL_2(\ZZ)\) consisting of matrices of the form \(\begin{pmatrix} a & b \\ c & d \end{pmatrix}\) with \(N \mid c\) and \(a, d \in H\).

atkin_lehner_matrix(Q)#

Return the matrix of the Atkin–Lehner–Li operator \(W_Q\) associated to an exact divisor \(Q\) of \(N\), where \(N\) is the level of this group; that is, \(gcd(Q, N/Q) = 1\).

Note

We follow the conventions of [AL1978] here, so \(W_Q\) is given by the action of any matrix of the form \(\begin{pmatrix} Qx & y \\ Nz & Qw \end{pmatrix}\) where \(x,y,z,w\) are integers such that \(y = 1 \bmod Q\), \(x = 1 \bmod N/Q\), and \(det(W_Q) = Q\). For convenience, we actually always choose \(x = y = 1\).

INPUT:

  • Q (integer): an integer dividing \(N\), where \(N\) is the level of this group. If this divisor does not satisfy \(gcd(Q, N/Q) = 1\), it will be replaced by the unique integer with this property having the same prime factors as \(Q\).

EXAMPLES:

sage: Gamma1(994).atkin_lehner_matrix(71)
[  71    1]
[4970   71]
sage: Gamma1(996).atkin_lehner_matrix(2)
[   4    1]
[-996 -248]
sage: Gamma1(15).atkin_lehner_matrix(7)
Traceback (most recent call last):
...
ValueError: Q must divide the level
characters_mod_H(sign=None, galois_orbits=False)#

Return the characters of \((\ZZ / N\ZZ)^*\), of the specified sign, which are trivial on H.

INPUT:

  • sign (default: None): if not None, return only characters of the given sign

  • galois_orbits (default: False): if True, return only one character from each Galois orbit.

EXAMPLES:

sage: GammaH(5, [-1]).characters_mod_H()
[Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1,
 Dirichlet character modulo 5 of conductor 1 mapping 2 |--> 1]
sage: Gamma1(31).characters_mod_H(galois_orbits=True,sign=-1)
[Dirichlet character modulo 31 of conductor 31 mapping 3 |--> zeta30,
 Dirichlet character modulo 31 of conductor 31 mapping 3 |--> zeta30^3,
 Dirichlet character modulo 31 of conductor 31 mapping 3 |--> zeta30^5,
 Dirichlet character modulo 31 of conductor 31 mapping 3 |--> -1]
sage: GammaH(31, [-1]).characters_mod_H(sign=-1)
[]
coset_reps()#

Return a set of coset representatives for self \ SL2Z.

EXAMPLES:

sage: list(Gamma1(3).coset_reps())
[
[1 0]  [-1  0]  [ 0 -1]  [ 0  1]  [1 0]  [-1  0]  [ 0 -1]  [ 0  1]
[0 1], [ 0 -1], [ 1  0], [-1  0], [1 1], [-1 -1], [ 1  2], [-1 -2]
]
sage: len(list(Gamma1(31).coset_reps())) == 31**2 - 1
True
dimension_cusp_forms(k=2)#

Return the dimension of the space of weight k cusp forms for this group. For \(k \ge 2\), this is given by a standard formula in terms of k and various invariants of the group; see Diamond + Shurman, “A First Course in Modular Forms”, section 3.5 and 3.6. If k is not given, default to k = 2.

For dimensions of spaces of cusp forms with character for Gamma1, use the dimension_cusp_forms method of the Gamma1 class, or the standalone function dimension_cusp_forms().

For weight 1 cusp forms, there is no simple formula for the dimensions, so we first try to rule out nonzero cusp forms existing via Riemann-Roch, and if this fails, we trigger computation of the cusp form space using Schaeffer’s algorithm; this can be quite expensive in large levels.

EXAMPLES:

sage: GammaH(31, [23]).dimension_cusp_forms(10)
69
sage: GammaH(31, [7]).dimension_cusp_forms(1)
1
dimension_new_cusp_forms(k=2, p=0)#

Return the dimension of the space of new (or \(p\)-new) weight \(k\) cusp forms for this congruence subgroup.

INPUT:

  • k - an integer (default: 2), the weight. Not fully implemented for k = 1.

  • p - integer (default: 0); if nonzero, compute the \(p\)-new subspace.

OUTPUT: Integer

EXAMPLES:

sage: GammaH(33,[2]).dimension_new_cusp_forms()
3
sage: Gamma1(4*25).dimension_new_cusp_forms(2, p=5)
225
sage: Gamma1(33).dimension_new_cusp_forms(2)
19
sage: Gamma1(33).dimension_new_cusp_forms(2,p=11)
21
divisor_subgroups()#

Given this congruence subgroup \(\Gamma_H(N)\), return all subgroups \(\Gamma_G(M)\) for \(M\) a divisor of \(N\) and such that \(G\) is equal to the image of \(H\) modulo \(M\).

EXAMPLES:

sage: G = GammaH(33,[2]); G
Congruence Subgroup Gamma_H(33) with H generated by [2]
sage: G._list_of_elements_in_H()
[1, 2, 4, 8, 16, 17, 25, 29, 31, 32]
sage: G.divisor_subgroups()
[Modular Group SL(2,Z),
 Congruence Subgroup Gamma0(3),
 Congruence Subgroup Gamma0(11),
 Congruence Subgroup Gamma_H(33) with H generated by [2]]
extend(M)#

Return the subgroup of \(\Gamma_0(M)\), for \(M\) a multiple of \(N\), obtained by taking the preimage of this group under the reduction map; in other words, the intersection of this group with \(\Gamma_0(M)\).

EXAMPLES:

sage: G = GammaH(33, [2])
sage: G.extend(99)
Congruence Subgroup Gamma_H(99) with H generated by [2, 17, 68]
sage: G.extend(11)
Traceback (most recent call last):
...
ValueError: M (=11) must be a multiple of the level (33) of self
gamma0_coset_reps()#

Return a set of coset representatives for self \ Gamma0(N), where N is the level of self.

EXAMPLES:

sage: GammaH(108, [1,-1]).gamma0_coset_reps()
[
[1 0]  [-43  -2]  [ 31   2]  [-49  -5]  [ 25   3]  [-19  -3]
[0 1], [108   5], [108   7], [108  11], [108  13], [108  17],

[-17  -3]  [ 47  10]  [ 13   3]  [ 41  11]  [  7   2]  [-37 -12]
[108  19], [108  23], [108  25], [108  29], [108  31], [108  35],

[-35 -12]  [ 29  11]  [ -5  -2]  [ 23  10]  [-11  -5]  [ 53  26]
[108  37], [108  41], [108  43], [108  47], [108  49], [108  53]
]
generators(algorithm='farey')#

Return generators for this congruence subgroup. The result is cached.

INPUT:

  • algorithm (string): either farey (default) or todd-coxeter.

If algorithm is set to "farey", then the generators will be calculated using Farey symbols, which will always return a minimal generating set. See farey_symbol for more information.

If algorithm is set to "todd-coxeter", a simpler algorithm based on Todd-Coxeter enumeration will be used. This tends to return far larger sets of generators.

EXAMPLES:

sage: GammaH(7, [2]).generators()
[
[1 1]  [ 2 -1]  [ 4 -3]
[0 1], [ 7 -3], [ 7 -5]
]
sage: GammaH(7, [2]).generators(algorithm="todd-coxeter")
[
[1 1]  [-13   4]  [ 15   4]  [-3 -1]  [ 1 -1]  [1 0]  [1 1]  [-3 -1]
[0 1], [ 42 -13], [-49 -13], [ 7  2], [ 0  1], [7 1], [0 1], [ 7  2],

[-13   4]  [-5 -1]  [-5 -2]  [-10   3]  [ 1  0]  [ 2 -1]  [1 0]
[ 42 -13], [21  4], [28 11], [ 63 -19], [-7  1], [ 7 -3], [7 1],

[-3 -1]  [ 15  -4]  [ 2 -1]  [-5  1]  [  8  -3]  [11  5]  [-13  -4]
[ 7  2], [ 49 -13], [ 7 -3], [14 -3], [-21   8], [35 16], [-42 -13]
]
image_mod_n()#

Return the image of this group in \(SL(2, \ZZ / N\ZZ)\).

EXAMPLES:

sage: Gamma0(3).image_mod_n()
Matrix group over Ring of integers modulo 3 with 2 generators (
[2 0]  [1 1]
[0 2], [0 1]
)
index()#

Return the index of self in SL2Z.

EXAMPLES:

sage: [G.index() for G in Gamma0(40).gamma_h_subgroups()]  # optional - gap_package_polycyclic
[72, 144, 144, 144, 144, 288, 288, 288, 288, 144, 288, 288, 576, 576, 144, 288, 288, 576, 576, 144, 288, 288, 576, 576, 288, 576, 1152]
is_even()#

Return True precisely if this subgroup contains the matrix -1.

EXAMPLES:

sage: GammaH(10, [3]).is_even()
True
sage: GammaH(14, [1]).is_even()
False
is_subgroup(other)#

Return True if self is a subgroup of right, and False otherwise.

EXAMPLES:

sage: GammaH(24,[7]).is_subgroup(SL2Z)
True
sage: GammaH(24,[7]).is_subgroup(Gamma0(8))
True
sage: GammaH(24, []).is_subgroup(GammaH(24, [7]))
True
sage: GammaH(24, []).is_subgroup(Gamma1(24))
True
sage: GammaH(24, [17]).is_subgroup(GammaH(24, [7]))
False
sage: GammaH(1371, [169]).is_subgroup(GammaH(457, [169]))
True
ncusps()#

Return the number of orbits of cusps (regular or otherwise) for this subgroup.

EXAMPLES:

sage: GammaH(33,[2]).ncusps()
8
sage: GammaH(32079, [21676]).ncusps()
28800

AUTHORS:

  • Jordi Quer

nirregcusps()#

Return the number of irregular cusps for this subgroup.

EXAMPLES:

sage: GammaH(3212, [2045, 2773]).nirregcusps()
720
nregcusps()#

Return the number of orbits of regular cusps for this subgroup. A cusp is regular if we may find a parabolic element generating the stabiliser of that cusp whose eigenvalues are both +1 rather than -1. If G contains -1, all cusps are regular.

EXAMPLES:

sage: GammaH(20, [17]).nregcusps()
4
sage: GammaH(20, [17]).nirregcusps()
2
sage: GammaH(3212, [2045, 2773]).nregcusps()
1440
sage: GammaH(3212, [2045, 2773]).nirregcusps()
720

AUTHOR:

  • Jordi Quer

nu2()#

Return the number of orbits of elliptic points of order 2 for this group.

EXAMPLES:

sage: [H.nu2() for n in [1..10] for H in Gamma0(n).gamma_h_subgroups()]  # optional - gap_package_polycyclic
[1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0]
sage: GammaH(33,[2]).nu2()
0
sage: GammaH(5,[2]).nu2()
2

AUTHORS:

  • Jordi Quer

nu3()#

Return the number of orbits of elliptic points of order 3 for this group.

EXAMPLES:

sage: [H.nu3() for n in [1..10] for H in Gamma0(n).gamma_h_subgroups()]  # optional - gap_package_polycyclic
[1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
sage: GammaH(33,[2]).nu3()
0
sage: GammaH(7,[2]).nu3()
2

AUTHORS:

  • Jordi Quer

reduce_cusp(c)#

Compute a minimal representative for the given cusp c. Returns a cusp c’ which is equivalent to the given cusp, and is in lowest terms with minimal positive denominator, and minimal positive numerator for that denominator.

Two cusps \(u_1/v_1\) and \(u_2/v_2\) are equivalent modulo \(\Gamma_H(N)\) if and only if

\[v_1 = h v_2 \bmod N\quad \text{and}\quad u_1 = h^{-1} u_2 \bmod {\rm gcd}(v_1,N)\]

or

\[v_1 = -h v_2 \bmod N\quad \text{and}\quad u_1 = -h^{-1} u_2 \bmod {\rm gcd}(v_1,N)\]

for some \(h \in H\).

EXAMPLES:

sage: GammaH(6,[5]).reduce_cusp(5/3)
1/3
sage: GammaH(12,[5]).reduce_cusp(Cusp(8,9))
1/3
sage: GammaH(12,[5]).reduce_cusp(5/12)
Infinity
sage: GammaH(12,[]).reduce_cusp(Cusp(5,12))
5/12
sage: GammaH(21,[5]).reduce_cusp(Cusp(-9/14))
1/7
sage: Gamma1(5).reduce_cusp(oo)
Infinity
sage: Gamma1(5).reduce_cusp(0)
0
restrict(M)#

Return the subgroup of \(\Gamma_0(M)\), for \(M\) a divisor of \(N\), obtained by taking the image of this group under reduction modulo \(N\).

EXAMPLES:

sage: G = GammaH(33,[2])
sage: G.restrict(11)
Congruence Subgroup Gamma0(11)
sage: G.restrict(1)
Modular Group SL(2,Z)
sage: G.restrict(15)
Traceback (most recent call last):
...
ValueError: M (=15) must be a divisor of the level (33) of self
to_even_subgroup()#

Return the smallest even subgroup of \(SL(2, \ZZ)\) containing self.

EXAMPLES:

sage: GammaH(11, [4]).to_even_subgroup()
Congruence Subgroup Gamma0(11)
sage: Gamma1(11).to_even_subgroup()
Congruence Subgroup Gamma_H(11) with H generated by [10]
sage.modular.arithgroup.congroup_gammaH.GammaH_constructor(level, H)#

Return the congruence subgroup \(\Gamma_H(N)\), which is the subgroup of \(SL_2(\ZZ)\) consisting of matrices of the form \(\begin{pmatrix} a & b \\ c & d \end{pmatrix}\) with \(N | c\) and \(a, d \in H\), for \(H\) a specified subgroup of \((\ZZ/N\ZZ)^\times\).

INPUT:

  • level – an integer

  • H – either 0, 1, or a list
    • If H is a list, return \(\Gamma_H(N)\), where \(H\) is the subgroup of \((\ZZ/N\ZZ)^*\) generated by the elements of the list.

    • If H = 0, returns \(\Gamma_0(N)\).

    • If H = 1, returns \(\Gamma_1(N)\).

EXAMPLES:

sage: GammaH(11,0) # indirect doctest
Congruence Subgroup Gamma0(11)
sage: GammaH(11,1)
Congruence Subgroup Gamma1(11)
sage: GammaH(11,[10])
Congruence Subgroup Gamma_H(11) with H generated by [10]
sage: GammaH(11,[10,1])
Congruence Subgroup Gamma_H(11) with H generated by [10]
sage: GammaH(14,[10])
Traceback (most recent call last):
...
ArithmeticError: The generators [10] must be units modulo 14
sage.modular.arithgroup.congroup_gammaH.is_GammaH(x)#

Return True if x is a congruence subgroup of type GammaH.

EXAMPLES:

sage: from sage.modular.arithgroup.all import is_GammaH
sage: is_GammaH(GammaH(13, [2]))
True
sage: is_GammaH(Gamma0(6))
True
sage: is_GammaH(Gamma1(6))
True
sage: is_GammaH(sage.modular.arithgroup.congroup_generic.CongruenceSubgroup(5))
False
sage.modular.arithgroup.congroup_gammaH.mumu(N)#

Return 0 if any cube divides \(N\). Otherwise return \((-2)^v\) where \(v\) is the number of primes that exactly divide \(N\).

This is similar to the Möbius function.

INPUT:

  • N – an integer at least 1

OUTPUT: Integer

EXAMPLES:

sage: from sage.modular.arithgroup.congroup_gammaH import mumu
sage: mumu(27)
0
sage: mumu(6*25)
4
sage: mumu(7*9*25)
-2
sage: mumu(9*25)
1