Element class for Pollack-Stevens’ modular symbols#
This is the class of elements in the spaces of Pollack-Steven’s modular symbols as described in [PS2011].
EXAMPLES:
sage: E = EllipticCurve('11a')
sage: phi = E.pollack_stevens_modular_symbol(); phi
Modular symbol of level 11 with values in Sym^0 Q^2
sage: phi.weight() # Note that weight k=2 of a modular form corresponds here to weight 0
0
sage: phi.values()
[-1/5, 1, 0]
sage: phi.is_ordinary(11)
True
sage: phi_lift = phi.lift(11, 5, eigensymbol = True) # long time
sage: phi_lift.padic_lseries().series(5) # long time
O(11^5) + (10 + 3*11 + 6*11^2 + 9*11^3 + O(11^4))*T + (6 + 3*11 + 2*11^2 + O(11^3))*T^2 + (2 + 2*11 + O(11^2))*T^3 + (5 + O(11))*T^4 + O(T^5)
>>> from sage.all import *
>>> E = EllipticCurve('11a')
>>> phi = E.pollack_stevens_modular_symbol(); phi
Modular symbol of level 11 with values in Sym^0 Q^2
>>> phi.weight() # Note that weight k=2 of a modular form corresponds here to weight 0
0
>>> phi.values()
[-1/5, 1, 0]
>>> phi.is_ordinary(Integer(11))
True
>>> phi_lift = phi.lift(Integer(11), Integer(5), eigensymbol = True) # long time
>>> phi_lift.padic_lseries().series(Integer(5)) # long time
O(11^5) + (10 + 3*11 + 6*11^2 + 9*11^3 + O(11^4))*T + (6 + 3*11 + 2*11^2 + O(11^3))*T^2 + (2 + 2*11 + O(11^2))*T^3 + (5 + O(11))*T^4 + O(T^5)
sage: A = ModularSymbols(Gamma1(8),4).decomposition()[0].plus_submodule().new_subspace()
sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space
sage: phi = ps_modsym_from_simple_modsym_space(A)
sage: phi.values()
[(-1, 0, 0), (1, 0, 0), (-9, -6, -4)]
>>> from sage.all import *
>>> A = ModularSymbols(Gamma1(Integer(8)),Integer(4)).decomposition()[Integer(0)].plus_submodule().new_subspace()
>>> from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space
>>> phi = ps_modsym_from_simple_modsym_space(A)
>>> phi.values()
[(-1, 0, 0), (1, 0, 0), (-9, -6, -4)]
- class sage.modular.pollack_stevens.modsym.PSModSymAction(actor, MSspace)[source]#
Bases:
Action
Create the action
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: g = phi._map._codomain._act._Sigma0(matrix(ZZ,2,2,[1,2,3,4])) sage: phi * g # indirect doctest Modular symbol of level 11 with values in Sym^0 Q^2
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> g = phi._map._codomain._act._Sigma0(matrix(ZZ,Integer(2),Integer(2),[Integer(1),Integer(2),Integer(3),Integer(4)])) >>> phi * g # indirect doctest Modular symbol of level 11 with values in Sym^0 Q^2
- class sage.modular.pollack_stevens.modsym.PSModularSymbolElement(map_data, parent, construct=False)[source]#
Bases:
ModuleElement
Initialize a modular symbol
EXAMPLES:
sage: E = EllipticCurve('37a') sage: phi = E.pollack_stevens_modular_symbol()
>>> from sage.all import * >>> E = EllipticCurve('37a') >>> phi = E.pollack_stevens_modular_symbol()
- Tq_eigenvalue(q, p=None, M=None, check=True)[source]#
Eigenvalue of \(T_q\) modulo \(p^M\)
INPUT:
q
– prime of the Hecke operatorp
– prime we are working modulo (default: None)M
– degree of accuracy of approximation (default: None)check
– check thatself
is an eigensymbol
OUTPUT:
Constant \(c\) such that \(self|T_q - c * self\) has valuation greater than or equal to \(M\) (if it exists), otherwise raises ValueError
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: phi_ord = phi.p_stabilize(p = 3, ap = E.ap(3), M = 10, ordinary = True) sage: phi_ord.Tq_eigenvalue(2,3,10) + 2 O(3^10) sage: phi_ord.Tq_eigenvalue(3,3,10) 2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + 2*3^9 + O(3^10) sage: phi_ord.Tq_eigenvalue(3,3,100) Traceback (most recent call last): ... ValueError: result not determined to high enough precision
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> phi_ord = phi.p_stabilize(p = Integer(3), ap = E.ap(Integer(3)), M = Integer(10), ordinary = True) >>> phi_ord.Tq_eigenvalue(Integer(2),Integer(3),Integer(10)) + Integer(2) O(3^10) >>> phi_ord.Tq_eigenvalue(Integer(3),Integer(3),Integer(10)) 2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + 2*3^9 + O(3^10) >>> phi_ord.Tq_eigenvalue(Integer(3),Integer(3),Integer(100)) Traceback (most recent call last): ... ValueError: result not determined to high enough precision
- diagonal_valuation(p)[source]#
Return the minimum of the diagonal valuation on the values of self
INPUT:
p
– a positive integral prime
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: phi.diagonal_valuation(2) 0 sage: phi.diagonal_valuation(3) 0 sage: phi.diagonal_valuation(5) -1 sage: phi.diagonal_valuation(7) 0
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> phi.diagonal_valuation(Integer(2)) 0 >>> phi.diagonal_valuation(Integer(3)) 0 >>> phi.diagonal_valuation(Integer(5)) -1 >>> phi.diagonal_valuation(Integer(7)) 0
- dict()[source]#
Return dictionary on the modular symbol self, where keys are generators and values are the corresponding values of self on generators
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: Set([x.moment(0) for x in phi.dict().values()]) == Set([-1/5, 1, 0]) True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> Set([x.moment(Integer(0)) for x in phi.dict().values()]) == Set([-Integer(1)/Integer(5), Integer(1), Integer(0)]) True
- evaluate_twisted(a, chi)[source]#
Return \(\Phi_{\chi}(\{a/p\}-\{\infty\})\) where \(\Phi\) is
self
and \(\chi\) is a quadratic characterINPUT:
a
– integer in the range range(p)chi
– the modulus of a quadratic character.
OUTPUT:
The distribution \(\Phi_{\chi}(\{a/p\}-\{\infty\})\).
EXAMPLES:
sage: E = EllipticCurve('17a1') sage: L = E.padic_lseries(5, implementation="pollackstevens", precision=4) #long time sage: D = L.quadratic_twist() # long time sage: L.symbol().evaluate_twisted(1,D) # long time (1 + 5 + 3*5^2 + 5^3 + O(5^4), 5^2 + O(5^3), 1 + O(5^2), 2 + O(5)) sage: E = EllipticCurve('40a4') sage: L = E.padic_lseries(7, implementation="pollackstevens", precision=4) #long time sage: D = L.quadratic_twist() # long time sage: L.symbol().evaluate_twisted(1,D) # long time (4 + 6*7 + 3*7^2 + O(7^4), 6*7 + 6*7^2 + O(7^3), 6 + O(7^2), 1 + O(7))
>>> from sage.all import * >>> E = EllipticCurve('17a1') >>> L = E.padic_lseries(Integer(5), implementation="pollackstevens", precision=Integer(4)) #long time >>> D = L.quadratic_twist() # long time >>> L.symbol().evaluate_twisted(Integer(1),D) # long time (1 + 5 + 3*5^2 + 5^3 + O(5^4), 5^2 + O(5^3), 1 + O(5^2), 2 + O(5)) >>> E = EllipticCurve('40a4') >>> L = E.padic_lseries(Integer(7), implementation="pollackstevens", precision=Integer(4)) #long time >>> D = L.quadratic_twist() # long time >>> L.symbol().evaluate_twisted(Integer(1),D) # long time (4 + 6*7 + 3*7^2 + O(7^4), 6*7 + 6*7^2 + O(7^3), 6 + O(7^2), 1 + O(7))
- hecke(ell, algorithm='prep')[source]#
Return self | \(T_{\ell}\) by making use of the precomputations in self.prep_hecke()
INPUT:
ell
– a primealgorithm
– a string, either ‘prep’ (default) or ‘naive’
OUTPUT:
The image of this element under the Hecke operator \(T_{\ell}\)
ALGORITHMS:
If
algorithm == 'prep'
, precomputes a list of matrices that only depend on the level, then uses them to speed up the action.If
algorithm == 'naive'
, just acts by the matrices defining the Hecke operator. That is, it computes sum_a self | [1,a,0,ell] + self | [ell,0,0,1], the last term occurring only if the level is prime to ell.
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: phi.hecke(2) == phi * E.ap(2) True sage: phi.hecke(3) == phi * E.ap(3) True sage: phi.hecke(5) == phi * E.ap(5) True sage: phi.hecke(101) == phi * E.ap(101) True sage: all(phi.hecke(p, algorithm='naive') == phi * E.ap(p) for p in [2,3,5,101]) # long time True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> phi.hecke(Integer(2)) == phi * E.ap(Integer(2)) True >>> phi.hecke(Integer(3)) == phi * E.ap(Integer(3)) True >>> phi.hecke(Integer(5)) == phi * E.ap(Integer(5)) True >>> phi.hecke(Integer(101)) == phi * E.ap(Integer(101)) True >>> all(phi.hecke(p, algorithm='naive') == phi * E.ap(p) for p in [Integer(2),Integer(3),Integer(5),Integer(101)]) # long time True
- is_Tq_eigensymbol(q, p=None, M=None)[source]#
Determine if self is an eigenvector for \(T_q\) modulo \(p^M\)
INPUT:
q
– prime of the Hecke operatorp
– prime we are working moduloM
– degree of accuracy of approximation
OUTPUT:
True/False
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: phi_ord = phi.p_stabilize(p = 3, ap = E.ap(3), M = 10, ordinary = True) sage: phi_ord.is_Tq_eigensymbol(2,3,10) True sage: phi_ord.is_Tq_eigensymbol(2,3,100) False sage: phi_ord.is_Tq_eigensymbol(2,3,1000) False sage: phi_ord.is_Tq_eigensymbol(3,3,10) True sage: phi_ord.is_Tq_eigensymbol(3,3,100) False
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> phi_ord = phi.p_stabilize(p = Integer(3), ap = E.ap(Integer(3)), M = Integer(10), ordinary = True) >>> phi_ord.is_Tq_eigensymbol(Integer(2),Integer(3),Integer(10)) True >>> phi_ord.is_Tq_eigensymbol(Integer(2),Integer(3),Integer(100)) False >>> phi_ord.is_Tq_eigensymbol(Integer(2),Integer(3),Integer(1000)) False >>> phi_ord.is_Tq_eigensymbol(Integer(3),Integer(3),Integer(10)) True >>> phi_ord.is_Tq_eigensymbol(Integer(3),Integer(3),Integer(100)) False
- is_ordinary(p=None, P=None)[source]#
Return true if the \(p\)-th eigenvalue is a \(p\)-adic unit.
INPUT:
p
– a positive integral prime, or None (default None)P
– a prime of the base ring above \(p\), or None. This is ignored unless the base ring is a number field.
OUTPUT:
True/False
EXAMPLES:
sage: E = EllipticCurve('11a1') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.is_ordinary(2) False sage: E.ap(2) -2 sage: phi.is_ordinary(3) True sage: E.ap(3) -1 sage: phip = phi.p_stabilize(3,20) sage: phip.is_ordinary() True
>>> from sage.all import * >>> E = EllipticCurve('11a1') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.is_ordinary(Integer(2)) False >>> E.ap(Integer(2)) -2 >>> phi.is_ordinary(Integer(3)) True >>> E.ap(Integer(3)) -1 >>> phip = phi.p_stabilize(Integer(3),Integer(20)) >>> phip.is_ordinary() True
A number field example. Here there are multiple primes above \(p\), and \(\phi\) is ordinary at one but not the other.:
sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space sage: f = Newforms(32, 8, names='a')[1] sage: phi = ps_modsym_from_simple_modsym_space(f.modular_symbols(1)) sage: (p1, _), (p2, _) = phi.base_ring().ideal(3).factor() sage: phi.is_ordinary(p1) != phi.is_ordinary(p2) True sage: phi.is_ordinary(3) Traceback (most recent call last): ... TypeError: P must be an ideal
>>> from sage.all import * >>> from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space >>> f = Newforms(Integer(32), Integer(8), names='a')[Integer(1)] >>> phi = ps_modsym_from_simple_modsym_space(f.modular_symbols(Integer(1))) >>> (p1, _), (p2, _) = phi.base_ring().ideal(Integer(3)).factor() >>> phi.is_ordinary(p1) != phi.is_ordinary(p2) True >>> phi.is_ordinary(Integer(3)) Traceback (most recent call last): ... TypeError: P must be an ideal
- minus_part()[source]#
Return the minus part of self – i.e. self - self | [1,0,0,-1]
Note that we haven’t divided by 2. Is this a problem?
OUTPUT:
self – self | [1,0,0,-1]
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: (phi.plus_part()+phi.minus_part()) == phi * 2 True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> (phi.plus_part()+phi.minus_part()) == phi * Integer(2) True
- plus_part()[source]#
Return the plus part of self – i.e.
self + self | [1,0,0,-1]
.Note that we haven’t divided by 2. Is this a problem?
OUTPUT:
self + self | [1,0,0,-1]
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: (phi.plus_part()+phi.minus_part()) == 2 * phi True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> (phi.plus_part()+phi.minus_part()) == Integer(2) * phi True
- valuation(p=None)[source]#
Return the valuation of
self
at \(p\).Here the valuation is the minimum of the valuations of the values of
self
.INPUT:
p
– prime
OUTPUT:
The valuation of
self
at \(p\)
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: phi.valuation(2) 0 sage: phi.valuation(3) 0 sage: phi.valuation(5) -1 sage: phi.valuation(7) 0 sage: phi.valuation() Traceback (most recent call last): ... ValueError: you must specify a prime sage: phi2 = phi.lift(11, M=2) sage: phi2.valuation() 0 sage: phi2.valuation(3) Traceback (most recent call last): ... ValueError: inconsistent prime sage: phi2.valuation(11) 0
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> phi.valuation(Integer(2)) 0 >>> phi.valuation(Integer(3)) 0 >>> phi.valuation(Integer(5)) -1 >>> phi.valuation(Integer(7)) 0 >>> phi.valuation() Traceback (most recent call last): ... ValueError: you must specify a prime >>> phi2 = phi.lift(Integer(11), M=Integer(2)) >>> phi2.valuation() 0 >>> phi2.valuation(Integer(3)) Traceback (most recent call last): ... ValueError: inconsistent prime >>> phi2.valuation(Integer(11)) 0
- values()[source]#
Return the values of the symbol
self
on our chosen generators.The generators are listed in
self.dict()
.EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.values() [-1/5, 1, 0] sage: sorted(phi.dict()) [ [-1 -1] [ 0 -1] [1 0] [ 3 2], [ 1 3], [0 1] ] sage: sorted(phi.values()) == sorted(phi.dict().values()) True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.values() [-1/5, 1, 0] >>> sorted(phi.dict()) [ [-1 -1] [ 0 -1] [1 0] [ 3 2], [ 1 3], [0 1] ] >>> sorted(phi.values()) == sorted(phi.dict().values()) True
- weight()[source]#
Return the weight of this Pollack-Stevens modular symbol.
This is \(k-2\), where \(k\) is the usual notion of weight for modular forms!
EXAMPLES:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: phi.weight() 0
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> phi.weight() 0
- class sage.modular.pollack_stevens.modsym.PSModularSymbolElement_dist(map_data, parent, construct=False)[source]#
Bases:
PSModularSymbolElement
- padic_lseries(*args, **kwds)[source]#
Return the \(p\)-adic L-series of this modular symbol.
EXAMPLES:
sage: E = EllipticCurve('37a') sage: phi = E.pollack_stevens_modular_symbol() sage: L = phi.lift(37, M=6, eigensymbol=True).padic_lseries(); L # long time 37-adic L-series of Modular symbol of level 37 with values in Space of 37-adic distributions with k=0 action and precision cap 7 sage: L.series(2) # long time O(37^6) + (4 + 37 + 36*37^2 + 19*37^3 + 21*37^4 + O(37^5))*T + O(T^2)
>>> from sage.all import * >>> E = EllipticCurve('37a') >>> phi = E.pollack_stevens_modular_symbol() >>> L = phi.lift(Integer(37), M=Integer(6), eigensymbol=True).padic_lseries(); L # long time 37-adic L-series of Modular symbol of level 37 with values in Space of 37-adic distributions with k=0 action and precision cap 7 >>> L.series(Integer(2)) # long time O(37^6) + (4 + 37 + 36*37^2 + 19*37^3 + 21*37^4 + O(37^5))*T + O(T^2)
- precision_relative()[source]#
Return the number of moments of each value of
self
.EXAMPLES:
sage: D = OverconvergentDistributions(0, 5, 10) sage: M = PollackStevensModularSymbols(Gamma0(5), coefficients=D) sage: f = M(1) sage: f.precision_relative() 1
>>> from sage.all import * >>> D = OverconvergentDistributions(Integer(0), Integer(5), Integer(10)) >>> M = PollackStevensModularSymbols(Gamma0(Integer(5)), coefficients=D) >>> f = M(Integer(1)) >>> f.precision_relative() 1
- reduce_precision(M)[source]#
Only hold on to \(M\) moments of each value of self
EXAMPLES:
sage: D = OverconvergentDistributions(0, 5, 10) sage: M = PollackStevensModularSymbols(Gamma0(5), coefficients=D) sage: f = M(1) sage: f.reduce_precision(1) Modular symbol of level 5 with values in Space of 5-adic distributions with k=0 action and precision cap 10
>>> from sage.all import * >>> D = OverconvergentDistributions(Integer(0), Integer(5), Integer(10)) >>> M = PollackStevensModularSymbols(Gamma0(Integer(5)), coefficients=D) >>> f = M(Integer(1)) >>> f.reduce_precision(Integer(1)) Modular symbol of level 5 with values in Space of 5-adic distributions with k=0 action and precision cap 10
- specialize(new_base_ring=None)[source]#
Return the underlying classical symbol of weight \(k\).
Namely, this applies the canonical map \(D_k \to Sym^k\) to all values of
self
.EXAMPLES:
sage: D = OverconvergentDistributions(0, 5, 10); M = PollackStevensModularSymbols(Gamma0(5), coefficients=D); M Space of overconvergent modular symbols for Congruence Subgroup Gamma0(5) with sign 0 and values in Space of 5-adic distributions with k=0 action and precision cap 10 sage: f = M(1) sage: f.specialize() Modular symbol of level 5 with values in Sym^0 Z_5^2 sage: f.specialize().values() [1 + O(5), 1 + O(5), 1 + O(5)] sage: f.values() [1 + O(5), 1 + O(5), 1 + O(5)] sage: f.specialize().parent() Space of modular symbols for Congruence Subgroup Gamma0(5) with sign 0 and values in Sym^0 Z_5^2 sage: f.specialize().parent().coefficient_module() Sym^0 Z_5^2 sage: f.specialize().parent().coefficient_module().is_symk() True sage: f.specialize(Qp(5,20)) Modular symbol of level 5 with values in Sym^0 Q_5^2
>>> from sage.all import * >>> D = OverconvergentDistributions(Integer(0), Integer(5), Integer(10)); M = PollackStevensModularSymbols(Gamma0(Integer(5)), coefficients=D); M Space of overconvergent modular symbols for Congruence Subgroup Gamma0(5) with sign 0 and values in Space of 5-adic distributions with k=0 action and precision cap 10 >>> f = M(Integer(1)) >>> f.specialize() Modular symbol of level 5 with values in Sym^0 Z_5^2 >>> f.specialize().values() [1 + O(5), 1 + O(5), 1 + O(5)] >>> f.values() [1 + O(5), 1 + O(5), 1 + O(5)] >>> f.specialize().parent() Space of modular symbols for Congruence Subgroup Gamma0(5) with sign 0 and values in Sym^0 Z_5^2 >>> f.specialize().parent().coefficient_module() Sym^0 Z_5^2 >>> f.specialize().parent().coefficient_module().is_symk() True >>> f.specialize(Qp(Integer(5),Integer(20))) Modular symbol of level 5 with values in Sym^0 Q_5^2
- class sage.modular.pollack_stevens.modsym.PSModularSymbolElement_symk(map_data, parent, construct=False)[source]#
Bases:
PSModularSymbolElement
- completions(p, M)[source]#
If \(K\) is the base_ring of self, this function takes all maps \(K\to \QQ_p\) and applies them to self return a list of (modular symbol,map: \(K\to \QQ_p\)) as map varies over all such maps.
Note
This only returns all completions when \(p\) splits completely in \(K\)
INPUT:
p
– primeM
– precision
OUTPUT:
A list of tuples (modular symbol,map: \(K\to \QQ_p\)) as map varies over all such maps
EXAMPLES:
sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space sage: D = ModularSymbols(67,2,1).cuspidal_submodule().new_subspace().decomposition()[1] sage: f = ps_modsym_from_simple_modsym_space(D) sage: S = f.completions(41,10); S [(Modular symbol of level 67 with values in Sym^0 Q_41^2, Ring morphism: From: Number Field in alpha with defining polynomial x^2 + 3*x + 1 To: 41-adic Field with capped relative precision 10 Defn: alpha |--> 5 + 22*41 + 19*41^2 + 10*41^3 + 28*41^4 + 22*41^5 + 9*41^6 + 25*41^7 + 40*41^8 + 8*41^9 + O(41^10)), (Modular symbol of level 67 with values in Sym^0 Q_41^2, Ring morphism: From: Number Field in alpha with defining polynomial x^2 + 3*x + 1 To: 41-adic Field with capped relative precision 10 Defn: alpha |--> 33 + 18*41 + 21*41^2 + 30*41^3 + 12*41^4 + 18*41^5 + 31*41^6 + 15*41^7 + 32*41^9 + O(41^10))] sage: TestSuite(S[0][0]).run(skip=['_test_category'])
>>> from sage.all import * >>> from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space >>> D = ModularSymbols(Integer(67),Integer(2),Integer(1)).cuspidal_submodule().new_subspace().decomposition()[Integer(1)] >>> f = ps_modsym_from_simple_modsym_space(D) >>> S = f.completions(Integer(41),Integer(10)); S [(Modular symbol of level 67 with values in Sym^0 Q_41^2, Ring morphism: From: Number Field in alpha with defining polynomial x^2 + 3*x + 1 To: 41-adic Field with capped relative precision 10 Defn: alpha |--> 5 + 22*41 + 19*41^2 + 10*41^3 + 28*41^4 + 22*41^5 + 9*41^6 + 25*41^7 + 40*41^8 + 8*41^9 + O(41^10)), (Modular symbol of level 67 with values in Sym^0 Q_41^2, Ring morphism: From: Number Field in alpha with defining polynomial x^2 + 3*x + 1 To: 41-adic Field with capped relative precision 10 Defn: alpha |--> 33 + 18*41 + 21*41^2 + 30*41^3 + 12*41^4 + 18*41^5 + 31*41^6 + 15*41^7 + 32*41^9 + O(41^10))] >>> TestSuite(S[Integer(0)][Integer(0)]).run(skip=['_test_category'])
- lift(p=None, M=None, alpha=None, new_base_ring=None, algorithm=None, eigensymbol=False, check=True)[source]#
Return a (\(p\)-adic) overconvergent modular symbol with \(M\) moments which lifts self up to an Eisenstein error
Here the Eisenstein error is a symbol whose system of Hecke eigenvalues equals \(\ell+1\) for \(T_\ell\) when \(\ell\) does not divide \(Np\) and 1 for \(U_q\) when \(q\) divides \(Np\).
INPUT:
p
– primeM
– integer equal to the number of momentsalpha
– \(U_p\) eigenvaluenew_base_ring
– change of base ringalgorithm
– ‘stevens’ or ‘greenberg’ (default ‘stevens’)eigensymbol
– if True, lifts to Hecke eigensymbol (self must be a \(p\)-ordinary eigensymbol)
(Note:
eigensymbol = True
does not just indicate to the code that self is an eigensymbol; it solves a wholly different problem, lifting an eigensymbol to an eigensymbol.)OUTPUT:
An overconvergent modular symbol whose specialization equals self, up to some Eisenstein error if
eigensymbol
is False. Ifeigensymbol = True
then the output will be an overconvergent Hecke eigensymbol (and it will lift the input exactly, the Eisenstein error disappears).EXAMPLES:
sage: E = EllipticCurve('11a') sage: f = E.pollack_stevens_modular_symbol() sage: g = f.lift(11,4,algorithm='stevens',eigensymbol=True) sage: g.is_Tq_eigensymbol(2) True sage: g.Tq_eigenvalue(3) 10 + 10*11 + 10*11^2 + 10*11^3 + O(11^4) sage: g.Tq_eigenvalue(11) 1 + O(11^4)
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> f = E.pollack_stevens_modular_symbol() >>> g = f.lift(Integer(11),Integer(4),algorithm='stevens',eigensymbol=True) >>> g.is_Tq_eigensymbol(Integer(2)) True >>> g.Tq_eigenvalue(Integer(3)) 10 + 10*11 + 10*11^2 + 10*11^3 + O(11^4) >>> g.Tq_eigenvalue(Integer(11)) 1 + O(11^4)
We check that lifting and then specializing gives back the original symbol:
sage: g.specialize() == f True
>>> from sage.all import * >>> g.specialize() == f True
Another example, which showed precision loss in an earlier version of the code:
sage: E = EllipticCurve('37a') sage: p = 5 sage: prec = 4 sage: phi = E.pollack_stevens_modular_symbol() sage: Phi = phi.p_stabilize_and_lift(p,prec, algorithm='stevens', eigensymbol=True) # long time sage: Phi.Tq_eigenvalue(5,M = 4) # long time 3 + 2*5 + 4*5^2 + 2*5^3 + O(5^4)
>>> from sage.all import * >>> E = EllipticCurve('37a') >>> p = Integer(5) >>> prec = Integer(4) >>> phi = E.pollack_stevens_modular_symbol() >>> Phi = phi.p_stabilize_and_lift(p,prec, algorithm='stevens', eigensymbol=True) # long time >>> Phi.Tq_eigenvalue(Integer(5),M = Integer(4)) # long time 3 + 2*5 + 4*5^2 + 2*5^3 + O(5^4)
Another example:
sage: from sage.modular.pollack_stevens.padic_lseries import pAdicLseries sage: E = EllipticCurve('37a') sage: p = 5 sage: prec = 6 sage: phi = E.pollack_stevens_modular_symbol() sage: Phi = phi.p_stabilize_and_lift(p=p,M=prec,alpha=None,algorithm='stevens',eigensymbol=True) #long time sage: L = pAdicLseries(Phi) # long time sage: L.symbol() is Phi # long time True
>>> from sage.all import * >>> from sage.modular.pollack_stevens.padic_lseries import pAdicLseries >>> E = EllipticCurve('37a') >>> p = Integer(5) >>> prec = Integer(6) >>> phi = E.pollack_stevens_modular_symbol() >>> Phi = phi.p_stabilize_and_lift(p=p,M=prec,alpha=None,algorithm='stevens',eigensymbol=True) #long time >>> L = pAdicLseries(Phi) # long time >>> L.symbol() is Phi # long time True
Examples using Greenberg’s algorithm:
sage: E = EllipticCurve('11a') sage: phi = E.pollack_stevens_modular_symbol() sage: Phi = phi.lift(11,8,algorithm='greenberg',eigensymbol=True) sage: Phi2 = phi.lift(11,8,algorithm='stevens',eigensymbol=True) sage: Phi == Phi2 True
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> phi = E.pollack_stevens_modular_symbol() >>> Phi = phi.lift(Integer(11),Integer(8),algorithm='greenberg',eigensymbol=True) >>> Phi2 = phi.lift(Integer(11),Integer(8),algorithm='stevens',eigensymbol=True) >>> Phi == Phi2 True
An example in higher weight:
sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space sage: f = ps_modsym_from_simple_modsym_space(Newforms(7, 4)[0].modular_symbols(1)) sage: fs = f.p_stabilize(5) sage: FsG = fs.lift(M=6, eigensymbol=True,algorithm='greenberg') # long time sage: FsG.values()[0] # long time 5^-1 * (2*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^7), O(5^6), 2*5^2 + 3*5^3 + O(5^5), O(5^4), 5^2 + O(5^3), O(5^2)) sage: FsS = fs.lift(M=6, eigensymbol=True,algorithm='stevens') # long time sage: FsS == FsG # long time True
>>> from sage.all import * >>> from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space >>> f = ps_modsym_from_simple_modsym_space(Newforms(Integer(7), Integer(4))[Integer(0)].modular_symbols(Integer(1))) >>> fs = f.p_stabilize(Integer(5)) >>> FsG = fs.lift(M=Integer(6), eigensymbol=True,algorithm='greenberg') # long time >>> FsG.values()[Integer(0)] # long time 5^-1 * (2*5 + 5^2 + 3*5^3 + 4*5^4 + O(5^7), O(5^6), 2*5^2 + 3*5^3 + O(5^5), O(5^4), 5^2 + O(5^3), O(5^2)) >>> FsS = fs.lift(M=Integer(6), eigensymbol=True,algorithm='stevens') # long time >>> FsS == FsG # long time True
- p_stabilize(p=None, M=20, alpha=None, ap=None, new_base_ring=None, ordinary=True, check=True)[source]#
Return the \(p\)-stabilization of self to level \(N p\) on which \(U_p\) acts by \(\alpha\).
Note that since \(\alpha\) is \(p\)-adic, the resulting symbol is just an approximation to the true \(p\)-stabilization (depending on how well \(\alpha\) is approximated).
INPUT:
p
– prime not dividing the level of selfM
– (default: 20) precision of \(\QQ_p\)alpha
– \(U_p\) eigenvalueap
– Hecke eigenvaluenew_base_ring
– change of base ringordinary
– (default:True
) whether to return the ordinary(at
p
) eigensymbol.
check
– (default:True
) whether to perform extra sanity checks
OUTPUT:
A modular symbol with the same Hecke eigenvalues as self away from \(p\) and eigenvalue \(\alpha\) at \(p\). The eigenvalue \(\alpha\) depends on the parameter
ordinary
.If
ordinary
== True: the unique modular symbol of level \(N p\) with the same Hecke eigenvalues as self away from \(p\) and unit eigenvalue at \(p\); else the unique modular symbol of level \(N p\) with the same Hecke eigenvalues as self away from \(p\) and non-unit eigenvalue at \(p\).EXAMPLES:
sage: E = EllipticCurve('11a') sage: p = 5 sage: prec = 4 sage: phi = E.pollack_stevens_modular_symbol() sage: phis = phi.p_stabilize(p,M = prec) sage: phis Modular symbol of level 55 with values in Sym^0 Q_5^2 sage: phis.hecke(7) == phis*E.ap(7) True sage: phis.hecke(5) == phis*E.ap(5) False sage: phis.hecke(3) == phis*E.ap(3) True sage: phis.Tq_eigenvalue(5) 1 + 4*5 + 3*5^2 + 2*5^3 + O(5^4) sage: phis.Tq_eigenvalue(5,M = 3) 1 + 4*5 + 3*5^2 + O(5^3) sage: phis = phi.p_stabilize(p,M = prec,ordinary=False) sage: phis.Tq_eigenvalue(5) 5 + 5^2 + 2*5^3 + O(5^5)
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> p = Integer(5) >>> prec = Integer(4) >>> phi = E.pollack_stevens_modular_symbol() >>> phis = phi.p_stabilize(p,M = prec) >>> phis Modular symbol of level 55 with values in Sym^0 Q_5^2 >>> phis.hecke(Integer(7)) == phis*E.ap(Integer(7)) True >>> phis.hecke(Integer(5)) == phis*E.ap(Integer(5)) False >>> phis.hecke(Integer(3)) == phis*E.ap(Integer(3)) True >>> phis.Tq_eigenvalue(Integer(5)) 1 + 4*5 + 3*5^2 + 2*5^3 + O(5^4) >>> phis.Tq_eigenvalue(Integer(5),M = Integer(3)) 1 + 4*5 + 3*5^2 + O(5^3) >>> phis = phi.p_stabilize(p,M = prec,ordinary=False) >>> phis.Tq_eigenvalue(Integer(5)) 5 + 5^2 + 2*5^3 + O(5^5)
A complicated example (with nontrivial character):
sage: chi = DirichletGroup(24)([-1, -1, -1]) sage: f = Newforms(chi,names='a')[0] sage: from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space sage: phi = ps_modsym_from_simple_modsym_space(f.modular_symbols(1)) sage: phi11, h11 = phi.completions(11,20)[0] sage: phi11s = phi11.p_stabilize() sage: phi11s.is_Tq_eigensymbol(11) # long time True
>>> from sage.all import * >>> chi = DirichletGroup(Integer(24))([-Integer(1), -Integer(1), -Integer(1)]) >>> f = Newforms(chi,names='a')[Integer(0)] >>> from sage.modular.pollack_stevens.space import ps_modsym_from_simple_modsym_space >>> phi = ps_modsym_from_simple_modsym_space(f.modular_symbols(Integer(1))) >>> phi11, h11 = phi.completions(Integer(11),Integer(20))[Integer(0)] >>> phi11s = phi11.p_stabilize() >>> phi11s.is_Tq_eigensymbol(Integer(11)) # long time True
- p_stabilize_and_lift(p, M, alpha=None, ap=None, new_base_ring=None, ordinary=True, algorithm='greenberg', eigensymbol=False, check=True)[source]#
\(p\)-stabilize and lift self
INPUT:
p
– prime, not dividing the level of selfM
– precisionalpha
– (default: None) the \(U_p\) eigenvalue, if knownap
– (default: None) the Hecke eigenvalue at p (before stabilizing), if knownnew_base_ring
– (default: None) if specified, force the resulting eigensymbol to take values in the given ringordinary
– (default:True
) whether to return the ordinary(at
p
) eigensymbol.
algorithm
– (default: ‘greenberg’) a string, either ‘greenberg’ or ‘stevens’, specifying whether to use the lifting algorithm of M.Greenberg or that of Pollack–Stevens. The latter one solves the difference equation, which is not needed. The option to use Pollack–Stevens’ algorithm here is just for historical reasons.eigensymbol
– (default:False
) if True, return an overconvergent eigensymbol. Otherwise just perform a naive liftcheck
– (default:True
) whether to perform extra sanity checks
OUTPUT:
\(p\)-stabilized and lifted version of self.
EXAMPLES:
sage: E = EllipticCurve('11a') sage: f = E.pollack_stevens_modular_symbol() sage: g = f.p_stabilize_and_lift(3,10) # long time sage: g.Tq_eigenvalue(5) # long time 1 + O(3^10) sage: g.Tq_eigenvalue(7) # long time 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10) sage: g.Tq_eigenvalue(3) # long time 2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + 2*3^9 + O(3^10)
>>> from sage.all import * >>> E = EllipticCurve('11a') >>> f = E.pollack_stevens_modular_symbol() >>> g = f.p_stabilize_and_lift(Integer(3),Integer(10)) # long time >>> g.Tq_eigenvalue(Integer(5)) # long time 1 + O(3^10) >>> g.Tq_eigenvalue(Integer(7)) # long time 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10) >>> g.Tq_eigenvalue(Integer(3)) # long time 2 + 3^2 + 2*3^3 + 2*3^4 + 2*3^6 + 3^8 + 2*3^9 + O(3^10)