# Cremona modular symbols#

class sage.libs.eclib.homspace.ModularSymbols[source]#

Bases: object

Class of Cremona Modular Symbols of given level and sign (and weight 2).

EXAMPLES:

sage: M = CremonaModularSymbols(225)
sage: type(M)
<class 'sage.libs.eclib.homspace.ModularSymbols'>

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(225))
>>> type(M)
<class 'sage.libs.eclib.homspace.ModularSymbols'>

dimension()[source]#

Return the dimension of this modular symbols space.

EXAMPLES:

sage: M = CremonaModularSymbols(1234, sign=1)
sage: M.dimension()
156

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(1234), sign=Integer(1))
>>> M.dimension()
156

hecke_matrix(p, dual=False, verbose=False)[source]#

Return the matrix of the p-th Hecke operator acting on this space of modular symbols.

The result of this command is not cached.

INPUT:

• p – a prime number

• dual – (default: False) whether to compute the Hecke

operator acting on the dual space, i.e., the transpose of the Hecke operator

• verbose – (default: False) print verbose output

OUTPUT:

(matrix) If p divides the level, the matrix of the Atkin-Lehner involution $$W_p$$ at p; otherwise the matrix of the Hecke operator $$T_p$$,

EXAMPLES:

sage: M = CremonaModularSymbols(37)
sage: t = M.hecke_matrix(2); t
5 x 5 Cremona matrix over Rational Field
sage: print(t.str())
[ 3  0  0  0  0]
[-1 -1  1  1  0]
[ 0  0 -1  0  1]
[-1  1  0 -1 -1]
[ 0  0  1  0 -1]
sage: t.charpoly().factor()
(x - 3) * x^2 * (x + 2)^2
sage: print(M.hecke_matrix(2, dual=True).str())
[ 3 -1  0 -1  0]
[ 0 -1  0  1  0]
[ 0  1 -1  0  1]
[ 0  1  0 -1  0]
[ 0  0  1 -1 -1]
sage: w = M.hecke_matrix(37); w
5 x 5 Cremona matrix over Rational Field
sage: w.charpoly().factor()
(x - 1)^2 * (x + 1)^3
sage: sw = w.sage_matrix_over_ZZ()
sage: st = t.sage_matrix_over_ZZ()
sage: sw^2 == sw.parent()(1)
True
sage: st*sw == sw*st
True

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(37))
>>> t = M.hecke_matrix(Integer(2)); t
5 x 5 Cremona matrix over Rational Field
>>> print(t.str())
[ 3  0  0  0  0]
[-1 -1  1  1  0]
[ 0  0 -1  0  1]
[-1  1  0 -1 -1]
[ 0  0  1  0 -1]
>>> t.charpoly().factor()
(x - 3) * x^2 * (x + 2)^2
>>> print(M.hecke_matrix(Integer(2), dual=True).str())
[ 3 -1  0 -1  0]
[ 0 -1  0  1  0]
[ 0  1 -1  0  1]
[ 0  1  0 -1  0]
[ 0  0  1 -1 -1]
>>> w = M.hecke_matrix(Integer(37)); w
5 x 5 Cremona matrix over Rational Field
>>> w.charpoly().factor()
(x - 1)^2 * (x + 1)^3
>>> sw = w.sage_matrix_over_ZZ()
>>> st = t.sage_matrix_over_ZZ()
>>> sw**Integer(2) == sw.parent()(Integer(1))
True
>>> st*sw == sw*st
True

is_cuspidal()[source]#

Return whether or not this space is cuspidal.

EXAMPLES:

sage: M = CremonaModularSymbols(1122); M.is_cuspidal()
0
sage: M = CremonaModularSymbols(1122, cuspidal=True); M.is_cuspidal()
1

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(1122)); M.is_cuspidal()
0
>>> M = CremonaModularSymbols(Integer(1122), cuspidal=True); M.is_cuspidal()
1

level()[source]#

Return the level of this modular symbols space.

EXAMPLES:

sage: M = CremonaModularSymbols(1234, sign=1)
sage: M.level()
1234

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(1234), sign=Integer(1))
>>> M.level()
1234

number_of_cusps()[source]#

Return the number of cusps for $$\Gamma_0(N)$$, where $$N$$ is the level.

EXAMPLES:

sage: M = CremonaModularSymbols(225)
sage: M.number_of_cusps()
24

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(225))
>>> M.number_of_cusps()
24

sign()[source]#

Return the sign of this Cremona modular symbols space. The sign is either 0, +1 or -1.

EXAMPLES:

sage: M = CremonaModularSymbols(1122, sign=1); M
Cremona Modular Symbols space of dimension 224 for Gamma_0(1122) of weight 2 with sign 1
sage: M.sign()
1
sage: M = CremonaModularSymbols(1122); M
Cremona Modular Symbols space of dimension 433 for Gamma_0(1122) of weight 2 with sign 0
sage: M.sign()
0
sage: M = CremonaModularSymbols(1122, sign=-1); M
Cremona Modular Symbols space of dimension 209 for Gamma_0(1122) of weight 2 with sign -1
sage: M.sign()
-1

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(1122), sign=Integer(1)); M
Cremona Modular Symbols space of dimension 224 for Gamma_0(1122) of weight 2 with sign 1
>>> M.sign()
1
>>> M = CremonaModularSymbols(Integer(1122)); M
Cremona Modular Symbols space of dimension 433 for Gamma_0(1122) of weight 2 with sign 0
>>> M.sign()
0
>>> M = CremonaModularSymbols(Integer(1122), sign=-Integer(1)); M
Cremona Modular Symbols space of dimension 209 for Gamma_0(1122) of weight 2 with sign -1
>>> M.sign()
-1

sparse_hecke_matrix(p, dual=False, verbose=False, base_ring='ZZ')[source]#

Return the matrix of the p-th Hecke operator acting on this space of modular symbols as a sparse Sage matrix over base_ring. This is more memory-efficient than creating a Cremona matrix and then applying sage_matrix_over_ZZ with sparse=True.

The result of this command is not cached.

INPUT:

• p – a prime number

• dual – (default: False) whether to compute the Hecke

operator acting on the dual space, i.e., the transpose of the Hecke operator

• verbose – (default: False) print verbose output

OUTPUT:

(matrix) If p divides the level, the matrix of the Atkin-Lehner involution $$W_p$$ at p; otherwise the matrix of the Hecke operator $$T_p$$,

EXAMPLES:

sage: M = CremonaModularSymbols(37)
sage: t = M.sparse_hecke_matrix(2); type(t)
<class 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'>
sage: print(t)
[ 3  0  0  0  0]
[-1 -1  1  1  0]
[ 0  0 -1  0  1]
[-1  1  0 -1 -1]
[ 0  0  1  0 -1]
sage: M = CremonaModularSymbols(5001)
sage: T = M.sparse_hecke_matrix(2)
sage: U = M.hecke_matrix(2).sage_matrix_over_ZZ(sparse=True)
sage: print(T == U)
True
sage: T = M.sparse_hecke_matrix(2, dual=True)
sage: print(T == U.transpose())
True
sage: T = M.sparse_hecke_matrix(2, base_ring=GF(7))
sage: print(T == U.change_ring(GF(7)))
True

>>> from sage.all import *
>>> M = CremonaModularSymbols(Integer(37))
>>> t = M.sparse_hecke_matrix(Integer(2)); type(t)
<class 'sage.matrix.matrix_integer_sparse.Matrix_integer_sparse'>
>>> print(t)
[ 3  0  0  0  0]
[-1 -1  1  1  0]
[ 0  0 -1  0  1]
[-1  1  0 -1 -1]
[ 0  0  1  0 -1]
>>> M = CremonaModularSymbols(Integer(5001))
>>> T = M.sparse_hecke_matrix(Integer(2))
>>> U = M.hecke_matrix(Integer(2)).sage_matrix_over_ZZ(sparse=True)
>>> print(T == U)
True
>>> T = M.sparse_hecke_matrix(Integer(2), dual=True)
>>> print(T == U.transpose())
True
>>> T = M.sparse_hecke_matrix(Integer(2), base_ring=GF(Integer(7)))
>>> print(T == U.change_ring(GF(Integer(7))))
True


This concerns an issue reported on Issue #21303:

sage: C = CremonaModularSymbols(45, cuspidal=True,sign=-1)
sage: T2a = C.hecke_matrix(2).sage_matrix_over_ZZ()
sage: T2b = C.sparse_hecke_matrix(2)
sage: print(T2a == T2b)
True

>>> from sage.all import *
>>> C = CremonaModularSymbols(Integer(45), cuspidal=True,sign=-Integer(1))
>>> T2a = C.hecke_matrix(Integer(2)).sage_matrix_over_ZZ()
>>> T2b = C.sparse_hecke_matrix(Integer(2))
>>> print(T2a == T2b)
True