Skip to content

Commit

Permalink
Trac #29977: Make modular doctests ready for random seeds
Browse files Browse the repository at this point in the history
This ticket makes
{{{
sage -t --long --random-seed=n src/sage/modular/
}}}
pass for different values `n` than just `0`.

URL: https://trac.sagemath.org/29977
Reported by: gh-kliem
Ticket author(s): Jonathan Kliem
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager committed Jul 23, 2021
2 parents 36ccebe + a890c4d commit ec795bf
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 68 deletions.
43 changes: 28 additions & 15 deletions src/sage/modular/arithgroup/arithgroup_perm.py
Original file line number Diff line number Diff line change
Expand Up @@ -2049,8 +2049,14 @@ def _spanning_tree_kulkarni(self, root=0, on_right=True):
s3,s3
s3,s3,s2
sage: gens
[(0, 1, 's2'), (3, 3, 's3')]
sage: edges = G.coset_graph().edges(); edges
[(0, 1, 's2'), (0, 1, 's3'), (1, 0, 's2'), (1, 2, 's3'), (2, 0, 's3'), (2, 3, 's2'), (3, 2, 's2'), (3, 3, 's3')]
sage: len(gens)
2
sage: (3, 3, 's3') in gens
True
sage: any(e in gens for e in edges[:5])
True
"""
from sage.graphs.digraph import DiGraph
from sage.misc.prandom import randint
Expand Down Expand Up @@ -2178,8 +2184,14 @@ def _spanning_tree_verrill(self, root=0, on_right=True):
****
sage: wreps
['', 's', 'll', 'l']
sage: gens
[(2, 0, 'l'), (1, 1, 'l'), (2, 3, 's')]
sage: len(gens)
3
sage: (1, 1, 'l') in gens
True
sage: (2, 3, 's') in gens or (3, 2, 's') in gens
True
sage: (2, 0, 'l') in gens
True
.. TODO::
Expand Down Expand Up @@ -2279,12 +2291,10 @@ def todd_coxeter_s2_s3(self):
sage: g1,g2 = gens
sage: g1 in G and g2 in G
True
sage: g1
[-1 0]
[ 1 -1]
sage: g2
[-1 3]
[-1 2]
sage: Matrix(2, 2, [-1, 3, -1, 2]) in gens
True
sage: Matrix(2, 2, [-1, 0, 1, -1]) in gens or Matrix(2, 2, [1, 0, 1, 1]) in gens
True
sage: S2 = SL2Z([0,-1,1,0])
sage: S3 = SL2Z([0,1,-1,1])
sage: reps[0] == SL2Z([1,0,0,1])
Expand Down Expand Up @@ -2323,11 +2333,14 @@ def todd_coxeter_l_s2(self):
[1 0] [ 0 -1] [1 2] [1 1]
[0 1], [ 1 0], [0 1], [0 1]
]
sage: gens
[
[1 3] [ 1 0] [ 2 -3]
[0 1], [-1 1], [ 1 -1]
]
sage: len(gens)
3
sage: Matrix(2, 2, [1, 3, 0, 1]) in gens
True
sage: Matrix(2, 2, [1, 0, -1, 1]) in gens
True
sage: Matrix(2, 2, [1, -3, 1, -2]) in gens or Matrix(2, 2, [2, -3, 1, -1]) in gens
True
sage: l
[3, 1, 0, 2]
sage: s
Expand Down
23 changes: 14 additions & 9 deletions src/sage/modular/arithgroup/congroup_sl2z.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,18 +194,23 @@ def random_element(self, bound=100, *args, **kwds):
EXAMPLES::
sage: SL2Z.random_element()
[60 13]
[83 18]
sage: SL2Z.random_element(5)
[-1 3]
[ 1 -4]
sage: s = SL2Z.random_element()
sage: s.parent() is SL2Z
True
sage: all(a in range(-99, 100) for a in list(s))
True
sage: S = set()
sage: while len(S) < 180:
....: s = SL2Z.random_element(5)
....: assert all(a in range(-4, 5) for a in list(s))
....: assert s.parent() is SL2Z
....: assert s in SL2Z
....: S.add(s)
Passes extra positional or keyword arguments through::
sage: SL2Z.random_element(5, distribution='1/n')
[ 1 -4]
[ 0 1]
sage: SL2Z.random_element(5, distribution='1/n').parent() is SL2Z
True
"""
if bound <= 1:
raise ValueError("bound must be greater than 1")
Expand Down
35 changes: 29 additions & 6 deletions src/sage/modular/dirichlet.py
Original file line number Diff line number Diff line change
Expand Up @@ -3143,12 +3143,35 @@ def random_element(self):
EXAMPLES::
sage: DirichletGroup(37).random_element()
Dirichlet character modulo 37 of conductor 37 mapping 2 |--> zeta36^4
sage: DirichletGroup(20).random_element()
Dirichlet character modulo 20 of conductor 4 mapping 11 |--> -1, 17 |--> 1
sage: DirichletGroup(60).random_element()
Dirichlet character modulo 60 of conductor 3 mapping 31 |--> 1, 41 |--> -1, 37 |--> 1
sage: D = DirichletGroup(37)
sage: g = D.random_element()
sage: g.parent() is D
True
sage: g**36
Dirichlet character modulo 37 of conductor 1 mapping 2 |--> 1
sage: S = set(D.random_element().conductor() for _ in range(100))
sage: while S != {1, 37}:
....: S.add(D.random_element().conductor())
sage: D = DirichletGroup(20)
sage: g = D.random_element()
sage: g.parent() is D
True
sage: g**4
Dirichlet character modulo 20 of conductor 1 mapping 11 |--> 1, 17 |--> 1
sage: S = set(D.random_element().conductor() for _ in range(100))
sage: while S != {1, 4, 5, 20}:
....: S.add(D.random_element().conductor())
sage: D = DirichletGroup(60)
sage: g = D.random_element()
sage: g.parent() is D
True
sage: g**4
Dirichlet character modulo 60 of conductor 1 mapping 31 |--> 1, 41 |--> 1, 37 |--> 1
sage: S = set(D.random_element().conductor() for _ in range(100))
sage: while S != {1, 3, 4, 5, 12, 15, 20, 60}:
....: S.add(D.random_element().conductor())
"""
e = self(1)
for i in range(self.ngens()):
Expand Down
8 changes: 6 additions & 2 deletions src/sage/modular/hecke/algebra.py
Original file line number Diff line number Diff line change
Expand Up @@ -410,8 +410,12 @@ def basis(self):
[0 2])
sage: M = ModularSymbols(Gamma0(22), sign=1)
sage: [B[0,0] for B in M.hecke_algebra().basis()]
[-955, -994, -706, -490, -1070]
sage: H = M.hecke_algebra()
sage: B = H.basis()
sage: len(B)
5
sage: all(b in H for b in B)
True
sage: [B[0, 0] for B in M.anemic_hecke_algebra().basis()]
Traceback (most recent call last):
...
Expand Down
36 changes: 18 additions & 18 deletions src/sage/modular/local_comp/local_comp.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ def LocalComponent(f, p, twist_factor=None):
Character of Q_7*, of level 0, mapping 7 |--> 1
sage: Pi.species()
'Supercuspidal'
sage: set(Pi.characters())
{Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> -d, 7 |--> 1,
Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> d, 7 |--> 1}
sage: sorted(Pi.characters(), key=str)
[Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> -d, 7 |--> 1,
Character of unramified extension Q_7(s)* (s^2 + 6*s + 3 = 0), of level 1, mapping s |--> d, 7 |--> 1]
"""
p = ZZ(p)
if not p.is_prime():
Expand Down Expand Up @@ -634,9 +634,9 @@ def characters(self):
sage: f = Newform('50a')
sage: Pi = LocalComponent(f, 5)
sage: chars = Pi.characters(); set(chars)
{Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -d - 1, 5 |--> 1,
Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> d, 5 |--> 1}
sage: chars = Pi.characters(); sorted(chars, key=str)
[Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -d - 1, 5 |--> 1,
Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> d, 5 |--> 1]
sage: chars[0].base_ring()
Number Field in d with defining polynomial x^2 + x + 1
Expand All @@ -650,9 +650,9 @@ def characters(self):
sage: f = Newforms(GammaH(25, [6]), 3, names='j')[0]; f
q + j0*q^2 + 1/3*j0^3*q^3 - 1/3*j0^2*q^4 + O(q^6)
sage: Pi = LocalComponent(f, 5)
sage: set(Pi.characters())
{Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> 1/3*j0^2*d - 1/3*j0^3, 5 |--> 5,
Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -1/3*j0^2*d, 5 |--> 5}
sage: sorted(Pi.characters(), key=str)
[Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> -1/3*j0^2*d, 5 |--> 5,
Character of unramified extension Q_5(s)* (s^2 + 4*s + 2 = 0), of level 1, mapping s |--> 1/3*j0^2*d - 1/3*j0^3, 5 |--> 5]
sage: Pi.characters()[0].base_ring()
Number Field in d with defining polynomial x^2 - j0*x + 1/3*j0^2 over its base field
Expand All @@ -667,9 +667,9 @@ def characters(self):
sage: f = Newform('81a', names='j'); f
q + j0*q^2 + q^4 - j0*q^5 + O(q^6)
sage: set(LocalComponent(f, 3).characters()) # long time (12s on sage.math, 2012)
{Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> -2*d + j0, 4 |--> 1, 3*s + 1 |--> -j0*d + 1, 3 |--> 1,
Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> 2*d - j0, 4 |--> 1, 3*s + 1 |--> j0*d - 2, 3 |--> 1}
sage: sorted(LocalComponent(f, 3).characters(), key=str) # long time (12s on sage.math, 2012)
[Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> -2*d + j0, 4 |--> 1, 3*s + 1 |--> -j0*d + 1, 3 |--> 1,
Character of unramified extension Q_3(s)* (s^2 + 2*s + 2 = 0), of level 2, mapping -2*s |--> 2*d - j0, 4 |--> 1, 3*s + 1 |--> j0*d - 2, 3 |--> 1]
Some ramified examples::
Expand Down Expand Up @@ -699,9 +699,9 @@ def characters(self):
Character of unramified extension Q_2(s)* (s^2 + s + 1 = 0), of level 3, mapping s |--> 1, 2*s + 1 |--> 1/2*a0, 4*s + 1 |--> 1, -1 |--> 1, 2 |--> 1,
Character of unramified extension Q_2(s)* (s^2 + s + 1 = 0), of level 3, mapping s |--> 1, 2*s + 1 |--> 1/2*a0, 4*s + 1 |--> -1, -1 |--> 1, 2 |--> 1
]
sage: set(Newform('243a',names='a').local_component(3).characters()) # long time
{Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> -d - 1, 4 |--> 1, 3*s + 1 |--> -d - 1, s |--> 1,
Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> d, 4 |--> 1, 3*s + 1 |--> d, s |--> 1}
sage: sorted(Newform('243a',names='a').local_component(3).characters(), key=str) # long time
[Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> -d - 1, 4 |--> 1, 3*s + 1 |--> -d - 1, s |--> 1,
Character of ramified extension Q_3(s)* (s^2 - 6 = 0), of level 4, mapping -2*s - 1 |--> d, 4 |--> 1, 3*s + 1 |--> d, s |--> 1]
"""
T = self.type_space()
p = self.prime()
Expand Down Expand Up @@ -779,7 +779,7 @@ def characters(self):
flag = G._reduce_Qp(1, x)
except ValueError:
flag = None
if flag is not None:
if flag is not None:
verbose("skipping x=%s as congruent to %s mod p" % (x, flag))
continue

Expand Down Expand Up @@ -1021,8 +1021,8 @@ def _repr_(self):
def characters(self):
r"""
Return the pair of characters (either of `\QQ_p^*` or of some quadratic
extension) corresponding to this representation.
extension) corresponding to this representation.
EXAMPLES::
sage: f = [f for f in Newforms(63, 4, names='a') if f[2] == 1][0]
Expand Down
9 changes: 7 additions & 2 deletions src/sage/modular/local_comp/type_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,8 +370,13 @@ def minimal_twist(self):
sage: f = Newforms(256,names='a')[0]
sage: T = TypeSpace(f,2)
sage: g = T.minimal_twist(); g
q - a*q^3 + O(q^6)
sage: g = T.minimal_twist()
sage: g[0:3]
[0, 1, 0]
sage: str(g[3]) in ('a', '-a', '-1/2*a', '1/2*a')
True
sage: g[4:]
[]
sage: g.level()
64
"""
Expand Down
11 changes: 6 additions & 5 deletions src/sage/modular/modform/numerical.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,10 @@ def _eigenvectors(self):
sage: n = numerical_eigenforms(61, eps=2.0)
sage: evectors = n._eigenvectors()
sage: evalues = diagonal_matrix(CDF, [-283.0, 142.0, 108.522012456])
sage: diff = n._hecke_matrix*evectors - evectors*evalues
sage: sum([abs(diff[i,j]) for i in range(5) for j in range(3)]) < 1.0e-9
sage: evalues = [(matrix((n._hecke_matrix*evectors).column(i))/matrix(evectors.column(i)))[0, 0]
....: for i in range(evectors.ncols())]
sage: diff = n._hecke_matrix*evectors - evectors*diagonal_matrix(evalues)
sage: sum(abs(a) for a in diff.list()) < 1.0e-9
True
"""
verbose('Finding eigenvector basis')
Expand Down Expand Up @@ -443,7 +444,7 @@ def systems_of_eigenvalues(self, bound):
EXAMPLES::
sage: numerical_eigenforms(61).systems_of_eigenvalues(10) # rel tol 6e-14
sage: numerical_eigenforms(61).systems_of_eigenvalues(10) # rel tol 1e-12
[
[-1.4811943040920152, 0.8060634335253695, 3.1563251746586642, 0.6751308705666477],
[-1.0, -2.0000000000000027, -3.000000000000003, 1.0000000000000044],
Expand All @@ -470,7 +471,7 @@ def systems_of_abs(self, bound):
EXAMPLES::
sage: numerical_eigenforms(61).systems_of_abs(10) # rel tol 6e-14
sage: numerical_eigenforms(61).systems_of_abs(10) # rel tol 1e-12
[
[0.3111078174659775, 2.903211925911551, 2.525427560843529, 3.214319743377552],
[1.0, 2.0000000000000027, 3.000000000000003, 1.0000000000000044],
Expand Down
38 changes: 27 additions & 11 deletions src/sage/modular/overconvergent/hecke_series.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,8 +266,14 @@ def random_solution(B,K):
EXAMPLES::
sage: from sage.modular.overconvergent.hecke_series import random_solution
sage: random_solution(5,10)
[1, 1, 1, 1, 0]
sage: s = random_solution(5,10)
sage: sum(s[i]*(i+1) for i in range(5))
10
sage: S = set()
sage: while len(S) != 30:
....: s = random_solution(5,10)
....: assert sum(s[i]*(i+1) for i in range(5)) == 10
....: S.add(tuple(s))
"""
a = []
for i in range(B,1,-1):
Expand Down Expand Up @@ -703,15 +709,25 @@ def higher_level_UpGj(p, N, klist, m, modformsring, bound, extra_data=False):
EXAMPLES::
sage: from sage.modular.overconvergent.hecke_series import higher_level_UpGj
sage: higher_level_UpGj(5,3,[4],2,true,6)
[
[ 1 0 0 0 0 0]
[ 0 1 0 0 0 0]
[ 0 7 0 0 0 0]
[ 0 5 10 20 0 0]
[ 0 7 20 0 20 0]
[ 0 1 24 0 20 0]
]
sage: A = Matrix([
....: [1, 0, 0, 0, 0, 0],
....: [0, 1, 0, 0, 0, 0],
....: [0, 7, 0, 0, 0, 0],
....: [0, 5, 10, 20, 0, 0],
....: [0, 7, 20, 0, 20, 0],
....: [0, 1, 24, 0, 20, 0]])
sage: B = Matrix([
....: [1, 0, 0, 0, 0, 0],
....: [0, 1, 0, 0, 0, 0],
....: [0, 7, 0, 0, 0, 0],
....: [0, 19, 0, 20, 0, 0],
....: [0, 7, 20, 0, 20, 0],
....: [0, 1, 24, 0, 20, 0]])
sage: C = higher_level_UpGj(5,3,[4],2,true,6)
sage: len(C)
1
sage: C[0] in (A, B)
True
sage: len(higher_level_UpGj(5,3,[4],2,true,6,extra_data=True))
4
"""
Expand Down

0 comments on commit ec795bf

Please sign in to comment.