From bcc2c19e52f9c9c4c56e271028cd73feaca48450 Mon Sep 17 00:00:00 2001
From: Peter Bruin
Date: Tue, 25 Feb 2020 07:56:56 +0100
Subject: [PATCH] Trac 29246: improve handling of easy cases in lift_to_sl2z()
---
.../modular/arithgroup/congroup_gamma1.py | 8 ++--
.../modular/arithgroup/congroup_gammaH.py | 31 +++++++-------
src/sage/modular/cusps.py | 4 +-
src/sage/modular/local_comp/liftings.py | 2 +-
src/sage/modular/modsym/boundary.py | 4 +-
src/sage/modular/modsym/manin_symbol.pyx | 12 ++++--
src/sage/modular/modsym/p1list.pyx | 41 ++++++++++++-------
7 files changed, 58 insertions(+), 44 deletions(-)
diff --git a/src/sage/modular/arithgroup/congroup_gamma1.py b/src/sage/modular/arithgroup/congroup_gamma1.py
index cb023cf4532..fbaa065f005 100644
--- a/src/sage/modular/arithgroup/congroup_gamma1.py
+++ b/src/sage/modular/arithgroup/congroup_gamma1.py
@@ -215,11 +215,11 @@ def generators(self, algorithm="farey"):
]
sage: Gamma1(3).generators(algorithm="todd-coxeter")
[
- [1 1] [-20 9] [ 4 1] [-5 -2] [ 1 -1] [1 0] [1 1] [-5 2]
- [0 1], [ 51 -23], [-9 -2], [ 3 1], [ 0 1], [3 1], [0 1], [12 -5],
+ [1 1] [-2 1] [1 1] [ 1 -1] [1 0] [1 1] [-5 2] [ 1 0]
+ [0 1], [-3 1], [0 1], [ 0 1], [3 1], [0 1], [12 -5], [-3 1],
- [ 1 0] [ 4 -1] [ -5 3] [ 1 -1] [ 7 -3] [ 4 -1] [ -5 3]
- [-3 1], [ 9 -2], [-12 7], [ 3 -2], [12 -5], [ 9 -2], [-12 7]
+ [ 1 -1] [ 1 -1] [ 4 -1] [ -5 3]
+ [ 3 -2], [ 3 -2], [ 9 -2], [-12 7]
]
"""
if algorithm=="farey":
diff --git a/src/sage/modular/arithgroup/congroup_gammaH.py b/src/sage/modular/arithgroup/congroup_gammaH.py
index aa91f91db92..896ee61d5e5 100644
--- a/src/sage/modular/arithgroup/congroup_gammaH.py
+++ b/src/sage/modular/arithgroup/congroup_gammaH.py
@@ -470,17 +470,14 @@ def generators(self, algorithm="farey"):
]
sage: GammaH(7, [2]).generators(algorithm="todd-coxeter")
[
- [1 1] [-90 29] [ 15 4] [-10 -3] [ 1 -1] [1 0] [1 1] [-3 -1]
- [0 1], [301 -97], [-49 -13], [ 7 2], [ 0 1], [7 1], [0 1], [ 7 2],
+ [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] [ 9 -1] [-20 7]
- [ 42 -13], [21 4], [28 11], [ 63 -19], [-7 1], [28 -3], [-63 22],
+ [-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],
- [1 0] [-3 -1] [ 15 -4] [ 2 -1] [ 22 -7] [-5 1] [ 8 -3]
- [7 1], [ 7 2], [ 49 -13], [ 7 -3], [ 63 -20], [14 -3], [-21 8],
-
- [11 5] [-13 -4]
- [35 16], [-42 -13]
+ [-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]
]
"""
if algorithm=="farey":
@@ -969,14 +966,14 @@ def gamma0_coset_reps(self):
sage: GammaH(108, [1,-1]).gamma0_coset_reps()
[
- [1 0] [-43 -45] [ 31 33] [-49 -54] [ 25 28] [-19 -22]
- [0 1], [108 113], [108 115], [108 119], [108 121], [108 125],
+ [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 -20] [ 47 57] [ 13 16] [ 41 52] [ 7 9] [-37 -49]
- [108 127], [108 131], [108 133], [108 137], [108 139], [108 143],
+ [-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 -47] [ 29 40] [ -5 -7] [ 23 33] [-11 -16] [ 53 79]
- [108 145], [108 149], [108 151], [108 155], [108 157], [108 161]
+ [-35 -12] [ 29 11] [ -5 -2] [ 23 10] [-11 -5] [ 53 26]
+ [108 37], [108 41], [108 43], [108 47], [108 49], [108 53]
]
"""
from .all import SL2Z
@@ -991,8 +988,8 @@ def coset_reps(self):
sage: list(Gamma1(3).coset_reps())
[
- [1 0] [-1 -2] [ 0 -1] [-2 1] [1 0] [-3 -2] [ 0 -1] [-2 -3]
- [0 1], [ 3 5], [ 1 0], [ 5 -3], [1 1], [ 8 5], [ 1 2], [ 5 7]
+ [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
diff --git a/src/sage/modular/cusps.py b/src/sage/modular/cusps.py
index 47c3f8286d8..ea5a2861de6 100644
--- a/src/sage/modular/cusps.py
+++ b/src/sage/modular/cusps.py
@@ -751,7 +751,7 @@ def is_gamma_h_equiv(self, other, G):
sage: G = GammaH(25,[6]) ; M = G.modular_symbols() ; M
Modular Symbols space of dimension 11 for Congruence Subgroup Gamma_H(25) with H generated by [6] of weight 2 with sign 0 and over Rational Field
sage: M.cusps()
- [33/100, 1/3, 31/125, 1/4, 1/15, -7/15, 7/15, 4/15, 1/20, 3/20, 7/20, 9/20]
+ [8/25, 1/3, 6/25, 1/4, 1/15, -7/15, 7/15, 4/15, 1/20, 3/20, 7/20, 9/20]
sage: len(M.cusps())
12
@@ -896,7 +896,7 @@ def galois_action(self, t, N):
sage: Cusp(oo).galois_action(3, 50)
Infinity
sage: c=Cusp(0).galois_action(3, 50); c
- 50/67
+ 50/17
sage: Gamma0(50).reduce_cusp(c)
0
diff --git a/src/sage/modular/local_comp/liftings.py b/src/sage/modular/local_comp/liftings.py
index 5d7be71f16e..91bfd2448d3 100644
--- a/src/sage/modular/local_comp/liftings.py
+++ b/src/sage/modular/local_comp/liftings.py
@@ -171,7 +171,7 @@ def lift_ramified(g, p, u, n):
sage: from sage.modular.local_comp.liftings import lift_ramified
sage: lift_ramified([2,2,3,2], 3, 1, 1)
- [5, 8, 3, 5]
+ [-1, -1, 3, 2]
sage: lift_ramified([8,2,12,2], 3, 2, 23)
[323, 110, -133584, -45493]
sage: type(lift_ramified([8,2,12,2], 3, 2, 23)[0])
diff --git a/src/sage/modular/modsym/boundary.py b/src/sage/modular/modsym/boundary.py
index 55f3b46a823..80fa4da4289 100644
--- a/src/sage/modular/modsym/boundary.py
+++ b/src/sage/modular/modsym/boundary.py
@@ -508,9 +508,9 @@ def _coerce_in_manin_symbol(self, x):
sage: M = ModularSymbols(Gamma1(5), 4) ; B = M.boundary_space()
sage: [ B(x) for x in M.basis() ]
- [-[2/5], -[-1/5], -[1/3], -[-1/4], -[-1/4], -[-1/4]]
+ [-[2/5], -[Infinity], -[1/3], -[-1/4], -[-1/4], -[-1/4]]
sage: [ B._coerce_in_manin_symbol(x) for x in M.manin_symbols_basis() ]
- [-[2/5], -[-1/5], -[1/3], -[-1/4], -[-1/4], -[-1/4]]
+ [-[2/5], -[Infinity], -[1/3], -[-1/4], -[-1/4], -[-1/4]]
"""
i = x.i
alpha, beta = x.endpoints(self.level())
diff --git a/src/sage/modular/modsym/manin_symbol.pyx b/src/sage/modular/modsym/manin_symbol.pyx
index 99b913816d7..0a4944b4ad8 100644
--- a/src/sage/modular/modsym/manin_symbol.pyx
+++ b/src/sage/modular/modsym/manin_symbol.pyx
@@ -343,6 +343,14 @@ cdef class ManinSymbol(Element):
return [ZZ.one(), ZZ.zero(), ZZ.zero(), ZZ.one()]
c = Integer(self.u)
d = Integer(self.v)
+
+ if c == 0:
+ if d == 1:
+ return [ZZ.one(), ZZ.zero(), ZZ.zero(), ZZ.one()]
+ if d == N - 1:
+ return [Integer(-1), ZZ.zero(), ZZ.zero(), Integer(-1)]
+ c = Integer(N)
+
g, z1, z2 = c.xgcd(d)
# We're lucky: z1*c + z2*d = 1.
@@ -350,10 +358,6 @@ cdef class ManinSymbol(Element):
return [z2, -z1, c, d]
# Have to try harder.
- if c == 0:
- c += N
- if d == 0:
- d += N
m = c
# compute prime-to-d part of m.
diff --git a/src/sage/modular/modsym/p1list.pyx b/src/sage/modular/modsym/p1list.pyx
index 841b920f68e..263a8236bb3 100644
--- a/src/sage/modular/modsym/p1list.pyx
+++ b/src/sage/modular/modsym/p1list.pyx
@@ -1216,8 +1216,16 @@ def lift_to_sl2z_int(int c, int d, int N):
"""
cdef int z1, z2, g, m
- if c == 0 and d == 0:
- raise AttributeError("Element (%s, %s) not in P1." % (c,d))
+ if N == 1:
+ return [1, 0, 0, 1]
+
+ if c == 0:
+ if d == 1:
+ return [1, 0, 0, 1]
+ if d == N - 1:
+ return [-1, 0, 0, -1]
+ c = N
+
g = arith_int.c_xgcd_int(c, d, &z1, &z2)
# We're lucky: z1*c + z2*d = 1.
@@ -1225,11 +1233,7 @@ def lift_to_sl2z_int(int c, int d, int N):
return [z2, -z1, c, d]
# Have to try harder.
- if c == 0:
- c = c + N;
- if d == 0:
- d = d + N;
- m = c;
+ m = c
# compute prime-to-d part of m.
while True:
@@ -1283,8 +1287,16 @@ def lift_to_sl2z_llong(llong c, llong d, int N):
"""
cdef llong z1, z2, g, m
- if c == 0 and d == 0:
- raise AttributeError("Element (%s, %s) not in P1." % (c,d))
+ if N == 1:
+ return [1, 0, 0, 1]
+
+ if c == 0:
+ if d == 1:
+ return [1, 0, 0, 1]
+ if d == N - 1:
+ return [-1, 0, 0, -1]
+ c = N
+
g = arith_llong.c_xgcd_longlong(c, d, &z1, &z2)
# We're lucky: z1*c + z2*d = 1.
@@ -1292,11 +1304,7 @@ def lift_to_sl2z_llong(llong c, llong d, int N):
return [z2, -z1, c, d]
# Have to try harder.
- if c == 0:
- c = c + N;
- if d == 0:
- d = d + N;
- m = c;
+ m = c
# compute prime-to-d part of m.
while True:
@@ -1351,6 +1359,11 @@ def lift_to_sl2z(c, d, N):
Traceback (most recent call last):
...
NotImplementedError: N too large
+
+ TESTS::
+
+ sage: lift_to_sl2z(0, 0, 1)
+ [1, 0, 0, 1]
"""
if N <= 46340:
return lift_to_sl2z_int(c,d,N)