Creation of modular symbols spaces#
EXAMPLES: We create a space and output its category.
sage: C = HeckeModules(RationalField()); C
Category of Hecke modules over Rational Field
sage: M = ModularSymbols(11)
sage: M.category()
Category of Hecke modules over Rational Field
sage: M in C
True
>>> from sage.all import *
>>> C = HeckeModules(RationalField()); C
Category of Hecke modules over Rational Field
>>> M = ModularSymbols(Integer(11))
>>> M.category()
Category of Hecke modules over Rational Field
>>> M in C
True
We create a space compute the charpoly, then compute the same but over a bigger field. In each case we also decompose the space using \(T_2\).
sage: M = ModularSymbols(23,2, base_ring=QQ)
sage: M.T(2).charpoly('x').factor()
(x - 3) * (x^2 + x - 1)^2
sage: M.decomposition(2)
[
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Rational Field,
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Rational Field
]
>>> from sage.all import *
>>> M = ModularSymbols(Integer(23),Integer(2), base_ring=QQ)
>>> M.T(Integer(2)).charpoly('x').factor()
(x - 3) * (x^2 + x - 1)^2
>>> M.decomposition(Integer(2))
[
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Rational Field,
Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Rational Field
]
sage: # needs sage.rings.number_field
sage: M = ModularSymbols(23,2, base_ring=QuadraticField(5, 'sqrt5'))
sage: M.T(2).charpoly('x').factor()
(x - 3) * (x - 1/2*sqrt5 + 1/2)^2 * (x + 1/2*sqrt5 + 1/2)^2
sage: M.decomposition(2)
[
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?,
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?,
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?
]
>>> from sage.all import *
>>> # needs sage.rings.number_field
>>> M = ModularSymbols(Integer(23),Integer(2), base_ring=QuadraticField(Integer(5), 'sqrt5'))
>>> M.T(Integer(2)).charpoly('x').factor()
(x - 3) * (x - 1/2*sqrt5 + 1/2)^2 * (x + 1/2*sqrt5 + 1/2)^2
>>> M.decomposition(Integer(2))
[
Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?,
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?,
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5
for Gamma_0(23) of weight 2 with sign 0 over Number Field in sqrt5
with defining polynomial x^2 - 5 with sqrt5 = 2.236067977499790?
]
We compute some Hecke operators and do a consistency check:
sage: m = ModularSymbols(39, 2)
sage: t2 = m.T(2); t5 = m.T(5)
sage: t2*t5 - t5*t2 == 0
True
>>> from sage.all import *
>>> m = ModularSymbols(Integer(39), Integer(2))
>>> t2 = m.T(Integer(2)); t5 = m.T(Integer(5))
>>> t2*t5 - t5*t2 == Integer(0)
True
This tests the bug reported in Issue #1220:
sage: G = GammaH(36, [13, 19])
sage: G.modular_symbols()
Modular Symbols space of dimension 13 for Congruence Subgroup Gamma_H(36)
with H generated by [13, 19] of weight 2 with sign 0 over Rational Field
sage: G.modular_symbols().cuspidal_subspace()
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 13 for
Congruence Subgroup Gamma_H(36) with H generated by [13, 19] of weight 2 with sign 0
over Rational Field
>>> from sage.all import *
>>> G = GammaH(Integer(36), [Integer(13), Integer(19)])
>>> G.modular_symbols()
Modular Symbols space of dimension 13 for Congruence Subgroup Gamma_H(36)
with H generated by [13, 19] of weight 2 with sign 0 over Rational Field
>>> G.modular_symbols().cuspidal_subspace()
Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 13 for
Congruence Subgroup Gamma_H(36) with H generated by [13, 19] of weight 2 with sign 0
over Rational Field
This test catches a tricky corner case for spaces with character:
sage: ModularSymbols(DirichletGroup(20).1**3, weight=3, sign=1).cuspidal_subspace()
Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 6
and level 20, weight 3, character [1, -zeta4], sign 1,
over Cyclotomic Field of order 4 and degree 2
>>> from sage.all import *
>>> ModularSymbols(DirichletGroup(Integer(20)).gen(1)**Integer(3), weight=Integer(3), sign=Integer(1)).cuspidal_subspace()
Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 6
and level 20, weight 3, character [1, -zeta4], sign 1,
over Cyclotomic Field of order 4 and degree 2
This tests the bugs reported in Issue #20932:
sage: chi = kronecker_character(3*34603)
sage: ModularSymbols(chi, 2, sign=1, base_ring=GF(3)) # not tested # long time (600 seconds)
Modular Symbols space of dimension 11535 and level 103809, weight 2,
character [2, 2], sign 1, over Finite Field of size 3
sage: chi = kronecker_character(3*61379)
sage: ModularSymbols(chi, 2, sign=1, base_ring=GF(3)) # not tested # long time (1800 seconds)
Modular Symbols space of dimension 20460 and level 184137, weight 2,
character [2, 2], sign 1, over Finite Field of size 3
>>> from sage.all import *
>>> chi = kronecker_character(Integer(3)*Integer(34603))
>>> ModularSymbols(chi, Integer(2), sign=Integer(1), base_ring=GF(Integer(3))) # not tested # long time (600 seconds)
Modular Symbols space of dimension 11535 and level 103809, weight 2,
character [2, 2], sign 1, over Finite Field of size 3
>>> chi = kronecker_character(Integer(3)*Integer(61379))
>>> ModularSymbols(chi, Integer(2), sign=Integer(1), base_ring=GF(Integer(3))) # not tested # long time (1800 seconds)
Modular Symbols space of dimension 20460 and level 184137, weight 2,
character [2, 2], sign 1, over Finite Field of size 3
- sage.modular.modsym.modsym.ModularSymbols(group=1, weight=2, sign=0, base_ring=None, use_cache=True, custom_init=None)[source]#
Create an ambient space of modular symbols.
INPUT:
group
– A congruence subgroup or a Dirichlet character eps.weight
– int, the weight, which must be >= 2.sign
– int, The sign of the involution on modular symbols induced by complex conjugation. The default is 0, which means “no sign”, i.e., take the whole space.base_ring
– the base ring. Defaults to \(\QQ\) if no character is given, or to the minimal extension of \(\QQ\) containing the values of the character.custom_init
– a function that is called with self as input before any computations are done using self; this could be used to set a custom modular symbols presentation. If self is already in the cache and use_cache=True, then this function is not called.
EXAMPLES: First we create some spaces with trivial character:
sage: ModularSymbols(Gamma0(11),2).dimension() 3 sage: ModularSymbols(Gamma0(1),12).dimension() 3
>>> from sage.all import * >>> ModularSymbols(Gamma0(Integer(11)),Integer(2)).dimension() 3 >>> ModularSymbols(Gamma0(Integer(1)),Integer(12)).dimension() 3
If we give an integer N for the congruence subgroup, it defaults to \(\Gamma_0(N)\):
sage: ModularSymbols(1,12,-1).dimension() 1 sage: ModularSymbols(11,4, sign=1) Modular Symbols space of dimension 4 for Gamma_0(11) of weight 4 with sign 1 over Rational Field
>>> from sage.all import * >>> ModularSymbols(Integer(1),Integer(12),-Integer(1)).dimension() 1 >>> ModularSymbols(Integer(11),Integer(4), sign=Integer(1)) Modular Symbols space of dimension 4 for Gamma_0(11) of weight 4 with sign 1 over Rational Field
We create some spaces for \(\Gamma_1(N)\).
sage: ModularSymbols(Gamma1(13),2) Modular Symbols space of dimension 15 for Gamma_1(13) of weight 2 with sign 0 over Rational Field sage: ModularSymbols(Gamma1(13),2, sign=1).dimension() 13 sage: ModularSymbols(Gamma1(13),2, sign=-1).dimension() 2 sage: [ModularSymbols(Gamma1(7),k).dimension() for k in [2,3,4,5]] [5, 8, 12, 16] sage: ModularSymbols(Gamma1(5),11).dimension() 20
>>> from sage.all import * >>> ModularSymbols(Gamma1(Integer(13)),Integer(2)) Modular Symbols space of dimension 15 for Gamma_1(13) of weight 2 with sign 0 over Rational Field >>> ModularSymbols(Gamma1(Integer(13)),Integer(2), sign=Integer(1)).dimension() 13 >>> ModularSymbols(Gamma1(Integer(13)),Integer(2), sign=-Integer(1)).dimension() 2 >>> [ModularSymbols(Gamma1(Integer(7)),k).dimension() for k in [Integer(2),Integer(3),Integer(4),Integer(5)]] [5, 8, 12, 16] >>> ModularSymbols(Gamma1(Integer(5)),Integer(11)).dimension() 20
We create a space for \(\Gamma_H(N)\):
sage: G = GammaH(15,[4,13]) sage: M = ModularSymbols(G,2) sage: M.decomposition() [ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field, Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field ]
>>> from sage.all import * >>> G = GammaH(Integer(15),[Integer(4),Integer(13)]) >>> M = ModularSymbols(G,Integer(2)) >>> M.decomposition() [ Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field, Modular Symbols subspace of dimension 3 of Modular Symbols space of dimension 5 for Congruence Subgroup Gamma_H(15) with H generated by [4, 7] of weight 2 with sign 0 over Rational Field ]
We create a space with character:
sage: e = (DirichletGroup(13).0)^2 sage: e.order() 6 sage: M = ModularSymbols(e, 2); M Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2 sage: f = M.T(2).charpoly('x'); f x^4 + (-zeta6 - 1)*x^3 - 8*zeta6*x^2 + (10*zeta6 - 5)*x + 21*zeta6 - 21 sage: f.factor() (x - zeta6 - 2) * (x - 2*zeta6 - 1) * (x + zeta6 + 1)^2
>>> from sage.all import * >>> e = (DirichletGroup(Integer(13)).gen(0))**Integer(2) >>> e.order() 6 >>> M = ModularSymbols(e, Integer(2)); M Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta6], sign 0, over Cyclotomic Field of order 6 and degree 2 >>> f = M.T(Integer(2)).charpoly('x'); f x^4 + (-zeta6 - 1)*x^3 - 8*zeta6*x^2 + (10*zeta6 - 5)*x + 21*zeta6 - 21 >>> f.factor() (x - zeta6 - 2) * (x - 2*zeta6 - 1) * (x + zeta6 + 1)^2
We create a space with character over a larger base ring than the values of the character:
sage: # needs sage.rings.number_field sage: ModularSymbols(e, 2, base_ring=CyclotomicField(24)) Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta24^4], sign 0, over Cyclotomic Field of order 24 and degree 8
>>> from sage.all import * >>> # needs sage.rings.number_field >>> ModularSymbols(e, Integer(2), base_ring=CyclotomicField(Integer(24))) Modular Symbols space of dimension 4 and level 13, weight 2, character [zeta24^4], sign 0, over Cyclotomic Field of order 24 and degree 8
More examples of spaces with character:
sage: e = DirichletGroup(5, RationalField()).gen(); e Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1 sage: m = ModularSymbols(e, 2); m Modular Symbols space of dimension 2 and level 5, weight 2, character [-1], sign 0, over Rational Field
>>> from sage.all import * >>> e = DirichletGroup(Integer(5), RationalField()).gen(); e Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1 >>> m = ModularSymbols(e, Integer(2)); m Modular Symbols space of dimension 2 and level 5, weight 2, character [-1], sign 0, over Rational Field
sage: m.T(2).charpoly('x') x^2 - 1 sage: m = ModularSymbols(e, 6); m.dimension() 6 sage: m.T(2).charpoly('x') x^6 - 873*x^4 - 82632*x^2 - 1860496
>>> from sage.all import * >>> m.T(Integer(2)).charpoly('x') x^2 - 1 >>> m = ModularSymbols(e, Integer(6)); m.dimension() 6 >>> m.T(Integer(2)).charpoly('x') x^6 - 873*x^4 - 82632*x^2 - 1860496
We create a space of modular symbols with nontrivial character in characteristic 2.
sage: # needs sage.rings.finite_rings sage: G = DirichletGroup(13, GF(4,'a')); G Group of Dirichlet characters modulo 13 with values in Finite Field in a of size 2^2 sage: e = G.list()[2]; e Dirichlet character modulo 13 of conductor 13 mapping 2 |--> a + 1 sage: M = ModularSymbols(e,4); M Modular Symbols space of dimension 8 and level 13, weight 4, character [a + 1], sign 0, over Finite Field in a of size 2^2 sage: M.basis() ([X*Y,(1,0)], [X*Y,(1,5)], [X*Y,(1,10)], [X*Y,(1,11)], [X^2,(0,1)], [X^2,(1,10)], [X^2,(1,11)], [X^2,(1,12)]) sage: M.T(2).matrix() [ 0 0 0 0 0 0 1 1] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 a + 1 1 a] [ 0 0 0 0 0 1 a + 1 a] [ 0 0 0 0 a + 1 0 1 1] [ 0 0 0 0 0 a 1 a] [ 0 0 0 0 0 0 a + 1 a] [ 0 0 0 0 0 0 1 0]
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> G = DirichletGroup(Integer(13), GF(Integer(4),'a')); G Group of Dirichlet characters modulo 13 with values in Finite Field in a of size 2^2 >>> e = G.list()[Integer(2)]; e Dirichlet character modulo 13 of conductor 13 mapping 2 |--> a + 1 >>> M = ModularSymbols(e,Integer(4)); M Modular Symbols space of dimension 8 and level 13, weight 4, character [a + 1], sign 0, over Finite Field in a of size 2^2 >>> M.basis() ([X*Y,(1,0)], [X*Y,(1,5)], [X*Y,(1,10)], [X*Y,(1,11)], [X^2,(0,1)], [X^2,(1,10)], [X^2,(1,11)], [X^2,(1,12)]) >>> M.T(Integer(2)).matrix() [ 0 0 0 0 0 0 1 1] [ 0 0 0 0 0 0 0 0] [ 0 0 0 0 0 a + 1 1 a] [ 0 0 0 0 0 1 a + 1 a] [ 0 0 0 0 a + 1 0 1 1] [ 0 0 0 0 0 a 1 a] [ 0 0 0 0 0 0 a + 1 a] [ 0 0 0 0 0 0 1 0]
We illustrate the custom_init function, which can be used to make arbitrary changes to the modular symbols object before its presentation is computed:
sage: ModularSymbols_clear_cache() sage: def custom_init(M): ....: M.customize='hi' sage: M = ModularSymbols(1,12, custom_init=custom_init) sage: M.customize 'hi'
>>> from sage.all import * >>> ModularSymbols_clear_cache() >>> def custom_init(M): ... M.customize='hi' >>> M = ModularSymbols(Integer(1),Integer(12), custom_init=custom_init) >>> M.customize 'hi'
We illustrate the relation between custom_init and use_cache:
sage: def custom_init(M): ....: M.customize='hi2' sage: M = ModularSymbols(1,12, custom_init=custom_init) sage: M.customize 'hi' sage: M = ModularSymbols(1,12, custom_init=custom_init, use_cache=False) sage: M.customize 'hi2'
>>> from sage.all import * >>> def custom_init(M): ... M.customize='hi2' >>> M = ModularSymbols(Integer(1),Integer(12), custom_init=custom_init) >>> M.customize 'hi' >>> M = ModularSymbols(Integer(1),Integer(12), custom_init=custom_init, use_cache=False) >>> M.customize 'hi2'
- sage.modular.modsym.modsym.ModularSymbols_clear_cache()[source]#
Clear the global cache of modular symbols spaces.
EXAMPLES:
sage: sage.modular.modsym.modsym.ModularSymbols_clear_cache() sage: sorted(sage.modular.modsym.modsym._cache) [] sage: M = ModularSymbols(6,2) sage: sorted(sage.modular.modsym.modsym._cache) [(Congruence Subgroup Gamma0(6), 2, 0, Rational Field)] sage: sage.modular.modsym.modsym.ModularSymbols_clear_cache() sage: sorted(sage.modular.modsym.modsym._cache) []
>>> from sage.all import * >>> sage.modular.modsym.modsym.ModularSymbols_clear_cache() >>> sorted(sage.modular.modsym.modsym._cache) [] >>> M = ModularSymbols(Integer(6),Integer(2)) >>> sorted(sage.modular.modsym.modsym._cache) [(Congruence Subgroup Gamma0(6), 2, 0, Rational Field)] >>> sage.modular.modsym.modsym.ModularSymbols_clear_cache() >>> sorted(sage.modular.modsym.modsym._cache) []
- sage.modular.modsym.modsym.canonical_parameters(group, weight, sign, base_ring)[source]#
Return the canonically normalized parameters associated to a choice of group, weight, sign, and base_ring. That is, normalize each of these to be of the correct type, perform all appropriate type checking, etc.
EXAMPLES:
sage: p1 = sage.modular.modsym.modsym.canonical_parameters(5,int(2),1,QQ) ; p1 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p2 = sage.modular.modsym.modsym.canonical_parameters(Gamma0(5),2,1,QQ) ; p2 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) sage: p1 == p2 True sage: type(p1[1]) <class 'sage.rings.integer.Integer'>
>>> from sage.all import * >>> p1 = sage.modular.modsym.modsym.canonical_parameters(Integer(5),int(Integer(2)),Integer(1),QQ) ; p1 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) >>> p2 = sage.modular.modsym.modsym.canonical_parameters(Gamma0(Integer(5)),Integer(2),Integer(1),QQ) ; p2 (Congruence Subgroup Gamma0(5), 2, 1, Rational Field) >>> p1 == p2 True >>> type(p1[Integer(1)]) <class 'sage.rings.integer.Integer'>