Overconvergent \(p\)-adic modular forms for small primes¶
This module implements computations of Hecke operators and \(U_p\)-eigenfunctions on \(p\)-adic overconvergent modular forms of tame level 1, where \(p\) is one of the primes \(\{2, 3, 5, 7, 13\}\), using the algorithms described in [Loe2007].
AUTHORS:
David Loeffler (August 2008): initial version
David Loeffler (March 2009): extensively reworked
Lloyd Kilford (May 2009): add
slopes()
methodDavid Loeffler (June 2009): miscellaneous bug fixes and usability improvements
The Theory¶
Let \(p\) be one of the above primes, so \(X_0(p)\) has genus 0, and let
(an \(\eta\)-product of level \(p\) – see module sage.modular.etaproducts
).
Then one can show that \(f_p\) gives an isomorphism \(X_0(p) \to \mathbb{P}^1\).
Furthermore, if we work over \(\CC_p\), the \(r\)-overconvergent locus on \(X_0(p)\)
(or of \(X_0(1)\), via the canonical subgroup lifting), corresponds to the
\(p\)-adic disc
(This is Theorem 1 of [Loe2007].)
Hence if we fix an element \(c\) with \(|c| = p^{-\frac{12r}{p-1}}\), the space \(S_k^\dagger(1, r)\) of overconvergent \(p\)-adic modular forms has an orthonormal basis given by the functions \((cf)^n\). So any element can be written in the form \(E_k \times \sum_{n \ge 0} a_n (cf)^n\), where \(a_n \to 0\) as \(N \to \infty\), and any such sequence \(a_n\) defines a unique overconvergent form.
One can now find the matrix of Hecke operators in this basis, either by calculating \(q\)-expansions, or (for the special case of \(U_p\)) using a recurrence formula due to Kolberg.
An Extended Example¶
We create a space of 3-adic modular forms:
sage: M = OverconvergentModularForms(3, 8, 1/6, prec=60)
>>> from sage.all import *
>>> M = OverconvergentModularForms(Integer(3), Integer(8), Integer(1)/Integer(6), prec=Integer(60))
M = OverconvergentModularForms(3, 8, 1/6, prec=60)
Creating an element directly as a linear combination of basis vectors.
sage: f1 = M.3 + M.5; f1.q_expansion()
27*q^3 + 1055916/1093*q^4 + 19913121/1093*q^5 + 268430112/1093*q^6 + ...
sage: f1.coordinates(8)
[0, 0, 0, 1, 0, 1, 0, 0]
>>> from sage.all import *
>>> f1 = M.gen(3) + M.gen(5); f1.q_expansion()
27*q^3 + 1055916/1093*q^4 + 19913121/1093*q^5 + 268430112/1093*q^6 + ...
>>> f1.coordinates(Integer(8))
[0, 0, 0, 1, 0, 1, 0, 0]
f1 = M.3 + M.5; f1.q_expansion() f1.coordinates(8)
We can coerce from elements of classical spaces of modular forms:
sage: f2 = M(CuspForms(3, 8).0); f2
3-adic overconvergent modular form of weight-character 8 with q-expansion
q + 6*q^2 - 27*q^3 - 92*q^4 + 390*q^5 - 162*q^6 ...
>>> from sage.all import *
>>> f2 = M(CuspForms(Integer(3), Integer(8)).gen(0)); f2
3-adic overconvergent modular form of weight-character 8 with q-expansion
q + 6*q^2 - 27*q^3 - 92*q^4 + 390*q^5 - 162*q^6 ...
f2 = M(CuspForms(3, 8).0); f2
We express this in a basis, and see that the coefficients go to zero very fast:
sage: [x.valuation(3) for x in f2.coordinates(60)]
[+Infinity, -1, 3, 6, 10, 13, 18, 20, 24, 27, 31, 34, 39, 41, 45, 48, 52, 55, 61,
62, 66, 69, 73, 76, 81, 83, 87, 90, 94, 97, 102, 104, 108, 111, 115, 118, 124, 125,
129, 132, 136, 139, 144, 146, 150, 153, 157, 160, 165, 167, 171, 174, 178, 181,
188, 188, 192, 195, 199, 202]
>>> from sage.all import *
>>> [x.valuation(Integer(3)) for x in f2.coordinates(Integer(60))]
[+Infinity, -1, 3, 6, 10, 13, 18, 20, 24, 27, 31, 34, 39, 41, 45, 48, 52, 55, 61,
62, 66, 69, 73, 76, 81, 83, 87, 90, 94, 97, 102, 104, 108, 111, 115, 118, 124, 125,
129, 132, 136, 139, 144, 146, 150, 153, 157, 160, 165, 167, 171, 174, 178, 181,
188, 188, 192, 195, 199, 202]
[x.valuation(3) for x in f2.coordinates(60)]
This form has more level at \(p\), and hence is less overconvergent:
sage: f3 = M(CuspForms(9, 8).0); [x.valuation(3) for x in f3.coordinates(60)]
[+Infinity, -1, -1, 0, -4, -4, -2, -3, 0, 0, -1, -1, 1, 0, 3, 3, 3, 3, 5, 3, 7, 7,
6, 6, 8, 7, 10, 10, 8, 8, 10, 9, 12, 12, 12, 12, 14, 12, 17, 16, 15, 15, 17, 16,
19, 19, 18, 18, 20, 19, 22, 22, 22, 22, 24, 21, 25, 26, 24, 24]
>>> from sage.all import *
>>> f3 = M(CuspForms(Integer(9), Integer(8)).gen(0)); [x.valuation(Integer(3)) for x in f3.coordinates(Integer(60))]
[+Infinity, -1, -1, 0, -4, -4, -2, -3, 0, 0, -1, -1, 1, 0, 3, 3, 3, 3, 5, 3, 7, 7,
6, 6, 8, 7, 10, 10, 8, 8, 10, 9, 12, 12, 12, 12, 14, 12, 17, 16, 15, 15, 17, 16,
19, 19, 18, 18, 20, 19, 22, 22, 22, 22, 24, 21, 25, 26, 24, 24]
f3 = M(CuspForms(9, 8).0); [x.valuation(3) for x in f3.coordinates(60)]
An error will be raised for forms which are not sufficiently overconvergent:
sage: M(CuspForms(27, 8).0)
Traceback (most recent call last):
...
ValueError: Form is not overconvergent enough (form is only 1/12-overconvergent)
>>> from sage.all import *
>>> M(CuspForms(Integer(27), Integer(8)).gen(0))
Traceback (most recent call last):
...
ValueError: Form is not overconvergent enough (form is only 1/12-overconvergent)
M(CuspForms(27, 8).0)
Let’s compute some Hecke operators. Note that the coefficients of this matrix are \(p\)-adically tiny:
sage: M.hecke_matrix(3, 4).change_ring(Qp(3, prec=1))
[ 1 + O(3) 0 0 0]
[ 0 2*3^3 + O(3^4) 2*3^3 + O(3^4) 3^2 + O(3^3)]
[ 0 2*3^7 + O(3^8) 2*3^8 + O(3^9) 3^6 + O(3^7)]
[ 0 2*3^10 + O(3^11) 2*3^10 + O(3^11) 2*3^9 + O(3^10)]
>>> from sage.all import *
>>> M.hecke_matrix(Integer(3), Integer(4)).change_ring(Qp(Integer(3), prec=Integer(1)))
[ 1 + O(3) 0 0 0]
[ 0 2*3^3 + O(3^4) 2*3^3 + O(3^4) 3^2 + O(3^3)]
[ 0 2*3^7 + O(3^8) 2*3^8 + O(3^9) 3^6 + O(3^7)]
[ 0 2*3^10 + O(3^11) 2*3^10 + O(3^11) 2*3^9 + O(3^10)]
M.hecke_matrix(3, 4).change_ring(Qp(3, prec=1))
We compute the eigenfunctions of a 4x4 truncation:
sage: efuncs = M.eigenfunctions(4)
sage: for i in [1..3]:
....: print(efuncs[i].q_expansion(prec=4).change_ring(Qp(3, prec=20)))
(1 + O(3^20))*q
+ (2*3 + 3^15 + 3^16 + 3^17 + 2*3^19 + 2*3^20 + O(3^21))*q^2
+ (2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9
+ 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15
+ 2*3^16 + 3^17 + 2*3^18 + 2*3^19 + 3^21 + 3^22 + O(3^23))*q^3
+ O(q^4)
(1 + O(3^20))*q
+ (3 + 2*3^2 + 3^3 + 3^4 + 3^12 + 3^13 + 2*3^14
+ 3^15 + 2*3^17 + 3^18 + 3^19 + 3^20 + O(3^21))*q^2
+ (3^7 + 3^13 + 2*3^14 + 2*3^15 + 3^16 + 3^17 + 2*3^18
+ 3^20 + 2*3^21 + 2*3^22 + 2*3^23 + 2*3^25 + O(3^27))*q^3
+ O(q^4)
(1 + O(3^20))*q
+ (2*3 + 3^3 + 2*3^4 + 3^6 + 2*3^8 + 3^9 + 3^10
+ 2*3^11 + 2*3^13 + 3^16 + 3^18 + 3^19 + 3^20 + O(3^21))*q^2
+ (3^9 + 2*3^12 + 3^15 + 3^17 + 3^18 + 3^19 + 3^20
+ 2*3^22 + 2*3^23 + 2*3^27 + 2*3^28 + O(3^29))*q^3
+ O(q^4)
>>> from sage.all import *
>>> efuncs = M.eigenfunctions(Integer(4))
>>> for i in (ellipsis_range(Integer(1),Ellipsis,Integer(3))):
... print(efuncs[i].q_expansion(prec=Integer(4)).change_ring(Qp(Integer(3), prec=Integer(20))))
(1 + O(3^20))*q
+ (2*3 + 3^15 + 3^16 + 3^17 + 2*3^19 + 2*3^20 + O(3^21))*q^2
+ (2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9
+ 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 2*3^14 + 2*3^15
+ 2*3^16 + 3^17 + 2*3^18 + 2*3^19 + 3^21 + 3^22 + O(3^23))*q^3
+ O(q^4)
(1 + O(3^20))*q
+ (3 + 2*3^2 + 3^3 + 3^4 + 3^12 + 3^13 + 2*3^14
+ 3^15 + 2*3^17 + 3^18 + 3^19 + 3^20 + O(3^21))*q^2
+ (3^7 + 3^13 + 2*3^14 + 2*3^15 + 3^16 + 3^17 + 2*3^18
+ 3^20 + 2*3^21 + 2*3^22 + 2*3^23 + 2*3^25 + O(3^27))*q^3
+ O(q^4)
(1 + O(3^20))*q
+ (2*3 + 3^3 + 2*3^4 + 3^6 + 2*3^8 + 3^9 + 3^10
+ 2*3^11 + 2*3^13 + 3^16 + 3^18 + 3^19 + 3^20 + O(3^21))*q^2
+ (3^9 + 2*3^12 + 3^15 + 3^17 + 3^18 + 3^19 + 3^20
+ 2*3^22 + 2*3^23 + 2*3^27 + 2*3^28 + O(3^29))*q^3
+ O(q^4)
efuncs = M.eigenfunctions(4) for i in [1..3]: print(efuncs[i].q_expansion(prec=4).change_ring(Qp(3, prec=20)))
The first eigenfunction is a classical cusp form of level 3:
sage: (efuncs[1] - M(CuspForms(3, 8).0)).valuation()
13
>>> from sage.all import *
>>> (efuncs[Integer(1)] - M(CuspForms(Integer(3), Integer(8)).gen(0))).valuation()
13
(efuncs[1] - M(CuspForms(3, 8).0)).valuation()
The second is an Eisenstein series!
sage: (efuncs[2] - M(EisensteinForms(3, 8).1)).valuation()
10
>>> from sage.all import *
>>> (efuncs[Integer(2)] - M(EisensteinForms(Integer(3), Integer(8)).gen(1))).valuation()
10
(efuncs[2] - M(EisensteinForms(3, 8).1)).valuation()
The third is a genuinely new thing (not a classical modular form at all); the coefficients are almost certainly not algebraic over \(\QQ\). Note that the slope is 9, so Coleman’s classicality criterion (forms of slope \(< k-1\) are classical) does not apply.
sage: a3 = efuncs[3].q_expansion()[3]; a3
3^9 + 2*3^12 + 3^15 + 3^17 + 3^18 + 3^19 + 3^20 + 2*3^22 + 2*3^23 + 2*3^27
+ 2*3^28 + 3^32 + 3^33 + 2*3^34 + 3^38 + 2*3^39 + 3^40 + 2*3^41 + 3^44 + 3^45
+ 3^46 + 2*3^47 + 2*3^48 + 3^49 + 3^50 + 2*3^51 + 2*3^52 + 3^53 + 2*3^54 + 3^55
+ 3^56 + 3^57 + 2*3^58 + 2*3^59 + 3^60 + 2*3^61 + 2*3^63 + 2*3^64 + 3^65 + 2*3^67
+ 3^68 + 2*3^69 + 2*3^71 + 3^72 + 2*3^74 + 3^75 + 3^76 + 3^79 + 3^80 + 2*3^83
+ 2*3^84 + 3^85 + 2*3^87 + 3^88 + 2*3^89 + 2*3^90 + 2*3^91 + 3^92 + O(3^98)
sage: efuncs[3].slope()
9
>>> from sage.all import *
>>> a3 = efuncs[Integer(3)].q_expansion()[Integer(3)]; a3
3^9 + 2*3^12 + 3^15 + 3^17 + 3^18 + 3^19 + 3^20 + 2*3^22 + 2*3^23 + 2*3^27
+ 2*3^28 + 3^32 + 3^33 + 2*3^34 + 3^38 + 2*3^39 + 3^40 + 2*3^41 + 3^44 + 3^45
+ 3^46 + 2*3^47 + 2*3^48 + 3^49 + 3^50 + 2*3^51 + 2*3^52 + 3^53 + 2*3^54 + 3^55
+ 3^56 + 3^57 + 2*3^58 + 2*3^59 + 3^60 + 2*3^61 + 2*3^63 + 2*3^64 + 3^65 + 2*3^67
+ 3^68 + 2*3^69 + 2*3^71 + 3^72 + 2*3^74 + 3^75 + 3^76 + 3^79 + 3^80 + 2*3^83
+ 2*3^84 + 3^85 + 2*3^87 + 3^88 + 2*3^89 + 2*3^90 + 2*3^91 + 3^92 + O(3^98)
>>> efuncs[Integer(3)].slope()
9
a3 = efuncs[3].q_expansion()[3]; a3 efuncs[3].slope()
- class sage.modular.overconvergent.genus0.OverconvergentModularFormElement(parent, gexp=None, qexp=None)[source]¶
Bases:
ModuleElement
A class representing an element of a space of overconvergent modular forms.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: K.<w> = Qp(5).extension(x^7 - 5) sage: s = OverconvergentModularForms(5, 6, 1/21, base_ring=K).0 sage: s == loads(dumps(s)) True
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> K = Qp(Integer(5)).extension(x**Integer(7) - Integer(5), names=('w',)); (w,) = K._first_ngens(1) >>> s = OverconvergentModularForms(Integer(5), Integer(6), Integer(1)/Integer(21), base_ring=K).gen(0) >>> s == loads(dumps(s)) True
x = polygen(ZZ, 'x') K.<w> = Qp(5).extension(x^7 - 5) s = OverconvergentModularForms(5, 6, 1/21, base_ring=K).0 s == loads(dumps(s))
- additive_order()[source]¶
Return the additive order of this element.
This implements a required method for all elements deriving from
sage.modules.ModuleElement
.EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: R = Qp(13).extension(x^2 - 13, names='a') sage: M = OverconvergentModularForms(13, 10, 1/2, base_ring=R) sage: M.gen(0).additive_order() +Infinity sage: M(0).additive_order() 1
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> R = Qp(Integer(13)).extension(x**Integer(2) - Integer(13), names='a') >>> M = OverconvergentModularForms(Integer(13), Integer(10), Integer(1)/Integer(2), base_ring=R) >>> M.gen(Integer(0)).additive_order() +Infinity >>> M(Integer(0)).additive_order() 1
x = polygen(ZZ, 'x') R = Qp(13).extension(x^2 - 13, names='a') M = OverconvergentModularForms(13, 10, 1/2, base_ring=R) M.gen(0).additive_order() M(0).additive_order()
- base_extend(R)[source]¶
Return a copy of
self
but with coefficients in the given ring.EXAMPLES:
sage: M = OverconvergentModularForms(7, 10, 1/2, prec=5) sage: f = M.1 sage: f.base_extend(Qp(7, 4)) 7-adic overconvergent modular form of weight-character 10 with q-expansion (7 + O(7^5))*q + (6*7 + 4*7^2 + 7^3 + 6*7^4 + O(7^5))*q^2 + (5*7 + 5*7^2 + 7^4 + O(7^5))*q^3 + (7^2 + 4*7^3 + 3*7^4 + 2*7^5 + O(7^6))*q^4 + O(q^5)
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(7), Integer(10), Integer(1)/Integer(2), prec=Integer(5)) >>> f = M.gen(1) >>> f.base_extend(Qp(Integer(7), Integer(4))) 7-adic overconvergent modular form of weight-character 10 with q-expansion (7 + O(7^5))*q + (6*7 + 4*7^2 + 7^3 + 6*7^4 + O(7^5))*q^2 + (5*7 + 5*7^2 + 7^4 + O(7^5))*q^3 + (7^2 + 4*7^3 + 3*7^4 + 2*7^5 + O(7^6))*q^4 + O(q^5)
M = OverconvergentModularForms(7, 10, 1/2, prec=5) f = M.1 f.base_extend(Qp(7, 4))
- coordinates(prec=None)[source]¶
Return the coordinates of this modular form in terms of the basis of this space.
EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2, prec=15) sage: f = (M.0 + M.3); f.coordinates() [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] sage: f.coordinates(6) [1, 0, 0, 1, 0, 0] sage: OverconvergentModularForms(3, 0, 1/6)(f).coordinates(6) [1, 0, 0, 729, 0, 0] sage: f.coordinates(100) Traceback (most recent call last): ... ValueError: Precision too large for space
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2), prec=Integer(15)) >>> f = (M.gen(0) + M.gen(3)); f.coordinates() [1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] >>> f.coordinates(Integer(6)) [1, 0, 0, 1, 0, 0] >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(6))(f).coordinates(Integer(6)) [1, 0, 0, 729, 0, 0] >>> f.coordinates(Integer(100)) Traceback (most recent call last): ... ValueError: Precision too large for space
M = OverconvergentModularForms(3, 0, 1/2, prec=15) f = (M.0 + M.3); f.coordinates() f.coordinates(6) OverconvergentModularForms(3, 0, 1/6)(f).coordinates(6) f.coordinates(100)
- eigenvalue()[source]¶
Return the \(U_p\)-eigenvalue of this eigenform.
This raises an error unless this element was explicitly flagged as an eigenform, using the method
_notify_eigen()
.EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: f = M.eigenfunctions(3)[1] sage: f.eigenvalue() 3^2 + 3^4 + 2*3^6 + 3^7 + 3^8 + 2*3^9 + 2*3^10 + 3^12 + 3^16 + 2*3^17 + 3^18 + 3^20 + 2*3^21 + 3^22 + 2*3^23 + 3^25 + 3^26 + 2*3^27 + 2*3^29 + 3^30 + 3^31 + 3^32 + 3^33 + 3^34 + 3^36 + 3^40 + 2*3^41 + 3^43 + 3^44 + 3^45 + 3^46 + 3^48 + 3^49 + 3^50 + 2*3^51 + 3^52 + 3^54 + 2*3^57 + 2*3^59 + 3^60 + 3^61 + 2*3^63 + 2*3^66 + 2*3^67 + 3^69 + 2*3^72 + 3^74 + 2*3^75 + 3^76 + 2*3^77 + 2*3^78 + 2*3^80 + 3^81 + 2*3^82 + 3^84 + 2*3^85 + 2*3^86 + 3^87 + 3^88 + 2*3^89 + 2*3^91 + 3^93 + 3^94 + 3^95 + 3^96 + 3^98 + 2*3^99 + O(3^100) sage: M.gen(4).eigenvalue() Traceback (most recent call last): ... TypeError: eigenvalue only defined for eigenfunctions
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = M.eigenfunctions(Integer(3))[Integer(1)] >>> f.eigenvalue() 3^2 + 3^4 + 2*3^6 + 3^7 + 3^8 + 2*3^9 + 2*3^10 + 3^12 + 3^16 + 2*3^17 + 3^18 + 3^20 + 2*3^21 + 3^22 + 2*3^23 + 3^25 + 3^26 + 2*3^27 + 2*3^29 + 3^30 + 3^31 + 3^32 + 3^33 + 3^34 + 3^36 + 3^40 + 2*3^41 + 3^43 + 3^44 + 3^45 + 3^46 + 3^48 + 3^49 + 3^50 + 2*3^51 + 3^52 + 3^54 + 2*3^57 + 2*3^59 + 3^60 + 3^61 + 2*3^63 + 2*3^66 + 2*3^67 + 3^69 + 2*3^72 + 3^74 + 2*3^75 + 3^76 + 2*3^77 + 2*3^78 + 2*3^80 + 3^81 + 2*3^82 + 3^84 + 2*3^85 + 2*3^86 + 3^87 + 3^88 + 2*3^89 + 2*3^91 + 3^93 + 3^94 + 3^95 + 3^96 + 3^98 + 2*3^99 + O(3^100) >>> M.gen(Integer(4)).eigenvalue() Traceback (most recent call last): ... TypeError: eigenvalue only defined for eigenfunctions
M = OverconvergentModularForms(3, 0, 1/2) f = M.eigenfunctions(3)[1] f.eigenvalue() M.gen(4).eigenvalue()
- gexp()[source]¶
Return the formal power series in \(g\) corresponding to
self
.If this overconvergent modular form is \(E_k^\ast \times F(g)\) where \(g\) is the appropriately normalised parameter of \(X_0(p)\), the result is \(F\).
EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: f = M.eigenfunctions(3)[1] sage: f.gexp() (3^-3 + O(3^95))*g + (3^-1 + 1 + 2*3 + 3^2 + 2*3^3 + 3^5 + 3^7 + 3^10 + 3^11 + 3^14 + 3^15 + 3^16 + 2*3^19 + 3^21 + 3^22 + 2*3^23 + 2*3^24 + 3^26 + 2*3^27 + 3^29 + 3^31 + 3^34 + 2*3^35 + 2*3^36 + 3^38 + 2*3^39 + 3^41 + 2*3^42 + 2*3^43 + 2*3^44 + 2*3^46 + 2*3^47 + 3^48 + 2*3^49 + 2*3^50 + 3^51 + 2*3^54 + 2*3^55 + 2*3^56 + 3^57 + 2*3^58 + 2*3^59 + 2*3^60 + 3^61 + 3^62 + 3^63 + 3^64 + 2*3^65 + 3^67 + 3^68 + 2*3^69 + 3^70 + 2*3^71 + 2*3^74 + 3^76 + 2*3^77 + 3^78 + 2*3^79 + 2*3^80 + 3^84 + 2*3^85 + 2*3^86 + 3^88 + 2*3^89 + 3^91 + 3^92 + 2*3^94 + 3^95 + O(3^97))*g^2 + O(g^3)
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = M.eigenfunctions(Integer(3))[Integer(1)] >>> f.gexp() (3^-3 + O(3^95))*g + (3^-1 + 1 + 2*3 + 3^2 + 2*3^3 + 3^5 + 3^7 + 3^10 + 3^11 + 3^14 + 3^15 + 3^16 + 2*3^19 + 3^21 + 3^22 + 2*3^23 + 2*3^24 + 3^26 + 2*3^27 + 3^29 + 3^31 + 3^34 + 2*3^35 + 2*3^36 + 3^38 + 2*3^39 + 3^41 + 2*3^42 + 2*3^43 + 2*3^44 + 2*3^46 + 2*3^47 + 3^48 + 2*3^49 + 2*3^50 + 3^51 + 2*3^54 + 2*3^55 + 2*3^56 + 3^57 + 2*3^58 + 2*3^59 + 2*3^60 + 3^61 + 3^62 + 3^63 + 3^64 + 2*3^65 + 3^67 + 3^68 + 2*3^69 + 3^70 + 2*3^71 + 2*3^74 + 3^76 + 2*3^77 + 3^78 + 2*3^79 + 2*3^80 + 3^84 + 2*3^85 + 2*3^86 + 3^88 + 2*3^89 + 3^91 + 3^92 + 2*3^94 + 3^95 + O(3^97))*g^2 + O(g^3)
M = OverconvergentModularForms(3, 0, 1/2) f = M.eigenfunctions(3)[1] f.gexp()
- governing_term(r)[source]¶
The degree of the series term with largest norm on the \(r\)-overconvergent region.
EXAMPLES:
sage: o = OverconvergentModularForms(3, 0, 1/2) sage: f = o.eigenfunctions(10)[1] sage: f.governing_term(1/2) 1
>>> from sage.all import * >>> o = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = o.eigenfunctions(Integer(10))[Integer(1)] >>> f.governing_term(Integer(1)/Integer(2)) 1
o = OverconvergentModularForms(3, 0, 1/2) f = o.eigenfunctions(10)[1] f.governing_term(1/2)
- is_eigenform()[source]¶
Return
True
if this is an eigenform.At present this returns
False
unless this element was explicitly flagged as an eigenform, using the method_notify_eigen()
.EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: f = M.eigenfunctions(3)[1] sage: f.is_eigenform() True sage: M.gen(4).is_eigenform() False
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = M.eigenfunctions(Integer(3))[Integer(1)] >>> f.is_eigenform() True >>> M.gen(Integer(4)).is_eigenform() False
M = OverconvergentModularForms(3, 0, 1/2) f = M.eigenfunctions(3)[1] f.is_eigenform() M.gen(4).is_eigenform()
- is_integral()[source]¶
Test whether this element has \(q\)-expansion coefficients that are \(p\)-adically integral.
This should always be the case with eigenfunctions, but sometimes if \(n\) is very large this breaks down for unknown reasons!
EXAMPLES:
sage: M = OverconvergentModularForms(2, 0, 1/3) sage: q = QQ[['q']].gen() sage: M(q - 17*q^2 + O(q^3)).is_integral() True sage: M(q - q^2/2 + 6*q^7 + O(q^9)).is_integral() False
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(3)) >>> q = QQ[['q']].gen() >>> M(q - Integer(17)*q**Integer(2) + O(q**Integer(3))).is_integral() True >>> M(q - q**Integer(2)/Integer(2) + Integer(6)*q**Integer(7) + O(q**Integer(9))).is_integral() False
M = OverconvergentModularForms(2, 0, 1/3) q = QQ[['q']].gen() M(q - 17*q^2 + O(q^3)).is_integral() M(q - q^2/2 + 6*q^7 + O(q^9)).is_integral()
- prec()[source]¶
Return the series expansion precision of this overconvergent modular form.
This is not the same as the \(p\)-adic precision of the coefficients.
EXAMPLES:
sage: OverconvergentModularForms(5, 6, 1/3, prec=15).gen(1).prec() 15
>>> from sage.all import * >>> OverconvergentModularForms(Integer(5), Integer(6), Integer(1)/Integer(3), prec=Integer(15)).gen(Integer(1)).prec() 15
OverconvergentModularForms(5, 6, 1/3, prec=15).gen(1).prec()
- prime()[source]¶
If this is a \(p\)-adic modular form, return \(p\).
EXAMPLES:
sage: OverconvergentModularForms(2, 0, 1/2).an_element().prime() 2
>>> from sage.all import * >>> OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2)).an_element().prime() 2
OverconvergentModularForms(2, 0, 1/2).an_element().prime()
- q_expansion(prec=None)[source]¶
Return the \(q\)-expansion of
self
, to as high precision as it is known.EXAMPLES:
sage: OverconvergentModularForms(3, 4, 1/2).gen(0).q_expansion() 1 - 120/13*q - 1080/13*q^2 - 120/13*q^3 - 8760/13*q^4 - 15120/13*q^5 - 1080/13*q^6 - 41280/13*q^7 - 5400*q^8 - 120/13*q^9 - 136080/13*q^10 - 159840/13*q^11 - 8760/13*q^12 - 263760/13*q^13 - 371520/13*q^14 - 15120/13*q^15 - 561720/13*q^16 - 45360*q^17 - 1080/13*q^18 - 823200/13*q^19 + O(q^20)
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(4), Integer(1)/Integer(2)).gen(Integer(0)).q_expansion() 1 - 120/13*q - 1080/13*q^2 - 120/13*q^3 - 8760/13*q^4 - 15120/13*q^5 - 1080/13*q^6 - 41280/13*q^7 - 5400*q^8 - 120/13*q^9 - 136080/13*q^10 - 159840/13*q^11 - 8760/13*q^12 - 263760/13*q^13 - 371520/13*q^14 - 15120/13*q^15 - 561720/13*q^16 - 45360*q^17 - 1080/13*q^18 - 823200/13*q^19 + O(q^20)
OverconvergentModularForms(3, 4, 1/2).gen(0).q_expansion()
- r_ord(r)[source]¶
The \(p\)-adic valuation of the norm of
self
on the \(r\)-overconvergent region.EXAMPLES:
sage: o = OverconvergentModularForms(3, 0, 1/2) sage: t = o([1, 1, 1/3]) sage: t.r_ord(1/2) 1 sage: t.r_ord(2/3) 3
>>> from sage.all import * >>> o = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> t = o([Integer(1), Integer(1), Integer(1)/Integer(3)]) >>> t.r_ord(Integer(1)/Integer(2)) 1 >>> t.r_ord(Integer(2)/Integer(3)) 3
o = OverconvergentModularForms(3, 0, 1/2) t = o([1, 1, 1/3]) t.r_ord(1/2) t.r_ord(2/3)
- slope()[source]¶
Return the slope of this eigenform.
This is the valuation of its \(U_p\)-eigenvalue.
Raises an error unless this element was explicitly flagged as an eigenform, using the method
_notify_eigen()
.EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: f = M.eigenfunctions(3)[1] sage: f.slope() 2 sage: M.gen(4).slope() Traceback (most recent call last): ... TypeError: slope only defined for eigenfunctions
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = M.eigenfunctions(Integer(3))[Integer(1)] >>> f.slope() 2 >>> M.gen(Integer(4)).slope() Traceback (most recent call last): ... TypeError: slope only defined for eigenfunctions
M = OverconvergentModularForms(3, 0, 1/2) f = M.eigenfunctions(3)[1] f.slope() M.gen(4).slope()
- valuation()[source]¶
Return the \(p\)-adic valuation of this form.
This is the minimum of the \(p\)-adic valuations of its coordinates.
EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: (M.7).valuation() 0 sage: (3^18 * (M.2)).valuation() 18
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> (M.gen(7)).valuation() 0 >>> (Integer(3)**Integer(18) * (M.gen(2))).valuation() 18
M = OverconvergentModularForms(3, 0, 1/2) (M.7).valuation() (3^18 * (M.2)).valuation()
- valuation_plot(rmax=None)[source]¶
Draw a graph depicting the growth of the norm of this overconvergent modular form as it approaches the boundary of the overconvergent region.
EXAMPLES:
sage: o = OverconvergentModularForms(3, 0, 1/2) sage: f = o.eigenfunctions(4)[1] sage: f.valuation_plot() # needs sage.plot Graphics object consisting of 1 graphics primitive
>>> from sage.all import * >>> o = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = o.eigenfunctions(Integer(4))[Integer(1)] >>> f.valuation_plot() # needs sage.plot Graphics object consisting of 1 graphics primitive
o = OverconvergentModularForms(3, 0, 1/2) f = o.eigenfunctions(4)[1] f.valuation_plot() # needs sage.plot
- weight()[source]¶
Return the weight of this overconvergent modular form.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: R = Qp(13).extension(x^2 - 13, names='a') sage: M = OverconvergentModularForms(13, 10, 1/2, base_ring=R) sage: M.gen(0).weight() 10
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> R = Qp(Integer(13)).extension(x**Integer(2) - Integer(13), names='a') >>> M = OverconvergentModularForms(Integer(13), Integer(10), Integer(1)/Integer(2), base_ring=R) >>> M.gen(Integer(0)).weight() 10
x = polygen(ZZ, 'x') R = Qp(13).extension(x^2 - 13, names='a') M = OverconvergentModularForms(13, 10, 1/2, base_ring=R) M.gen(0).weight()
- sage.modular.overconvergent.genus0.OverconvergentModularForms(prime, weight, radius, base_ring=Rational Field, prec=20, char=None)[source]¶
Create a space of overconvergent \(p\)-adic modular forms of level \(\Gamma_0(p)\), over the given base ring. The base ring need not be a \(p\)-adic ring (the spaces we compute with typically have bases over \(\QQ\)).
INPUT:
prime
– a prime number \(p\), which must be one of the primes \(\{2, 3, 5, 7, 13\}\), or the congruence subgroup \(\Gamma_0(p)\) where \(p\) is one of these primesweight
– integer (which at present must be 0 or \(\ge 2\)), the weightradius
– a rational number in the interval \(\left( 0, \frac{p}{p+1} \right)\), the radius of overconvergencebase_ring
– (default: \(\QQ\)), a ring over which to compute; this need not be a \(p\)-adic ringprec
– integer (default: 20); the number of \(q\)-expansion terms to computechar
– a Dirichlet character modulo \(p\) orNone
(the default); hereNone
is interpreted as the trivial character modulo \(p\)
The character \(\chi\) and weight \(k\) must satisfy \((-1)^k = \chi(-1)\), and the base ring must contain an element \(v\) such that \({\rm ord}_p(v) = \frac{12 r}{p-1}\) where \(r\) is the radius of overconvergence (and \({\rm ord}_p\) is normalised so \({\rm ord}_p(p) = 1\)).
EXAMPLES:
sage: OverconvergentModularForms(3, 0, 1/2) Space of 3-adic 1/2-overconvergent modular forms of weight-character 0 over Rational Field sage: OverconvergentModularForms(3, 16, 1/2) Space of 3-adic 1/2-overconvergent modular forms of weight-character 16 over Rational Field sage: OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0) Space of 3-adic 1/2-overconvergent modular forms of weight-character (3, 3, [-1]) over Rational Field
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) Space of 3-adic 1/2-overconvergent modular forms of weight-character 0 over Rational Field >>> OverconvergentModularForms(Integer(3), Integer(16), Integer(1)/Integer(2)) Space of 3-adic 1/2-overconvergent modular forms of weight-character 16 over Rational Field >>> OverconvergentModularForms(Integer(3), Integer(3), Integer(1)/Integer(2), char=DirichletGroup(Integer(3),QQ).gen(0)) Space of 3-adic 1/2-overconvergent modular forms of weight-character (3, 3, [-1]) over Rational Field
OverconvergentModularForms(3, 0, 1/2) OverconvergentModularForms(3, 16, 1/2) OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0)
- class sage.modular.overconvergent.genus0.OverconvergentModularFormsSpace(prime, weight, radius, base_ring, prec, char)[source]¶
Bases:
Module
A space of overconvergent modular forms of level \(\Gamma_0(p)\), where \(p\) is a prime such that \(X_0(p)\) has genus 0.
Elements are represented as power series, with a formal power series \(F\) corresponding to the modular form \(E_k^\ast \times F(g)\) where \(E_k^\ast\) is the \(p\)-deprived Eisenstein series of weight-character \(k\), and \(g\) is a uniformiser of \(X_0(p)\) normalised so that the \(r\)-overconvergent region \(X_0(p)_{\ge r}\) corresponds to \(|g| \le 1\).
- Element[source]¶
alias of
OverconvergentModularFormElement
- base_extend(ring)[source]¶
Return the base extension of
self
to the given base ring.There must be a canonical map to this ring from the current base ring, otherwise a
TypeError
will be raised.EXAMPLES:
sage: M = OverconvergentModularForms(2, 0, 1/2, base_ring=Qp(2)) sage: x = polygen(ZZ, 'x') sage: M.base_extend(Qp(2).extension(x^2 - 2, names='w')) Space of 2-adic 1/2-overconvergent modular forms of weight-character 0 over 2-adic Eisenstein Extension ... sage: M.base_extend(QQ) Traceback (most recent call last): ... TypeError: Base extension of self (over '2-adic Field with capped relative precision 20') to ring 'Rational Field' not defined.
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2), base_ring=Qp(Integer(2))) >>> x = polygen(ZZ, 'x') >>> M.base_extend(Qp(Integer(2)).extension(x**Integer(2) - Integer(2), names='w')) Space of 2-adic 1/2-overconvergent modular forms of weight-character 0 over 2-adic Eisenstein Extension ... >>> M.base_extend(QQ) Traceback (most recent call last): ... TypeError: Base extension of self (over '2-adic Field with capped relative precision 20') to ring 'Rational Field' not defined.
M = OverconvergentModularForms(2, 0, 1/2, base_ring=Qp(2)) x = polygen(ZZ, 'x') M.base_extend(Qp(2).extension(x^2 - 2, names='w')) M.base_extend(QQ)
- change_ring(ring)[source]¶
Return the space corresponding to
self
but over the given base ring.EXAMPLES:
sage: M = OverconvergentModularForms(2, 0, 1/2) sage: M.change_ring(Qp(2)) Space of 2-adic 1/2-overconvergent modular forms of weight-character 0 over 2-adic Field with ...
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2)) >>> M.change_ring(Qp(Integer(2))) Space of 2-adic 1/2-overconvergent modular forms of weight-character 0 over 2-adic Field with ...
M = OverconvergentModularForms(2, 0, 1/2) M.change_ring(Qp(2))
- character()[source]¶
Return the character of
self
.For overconvergent forms, the weight and the character are unified into the concept of a weight-character, so this returns exactly the same thing as
weight()
.EXAMPLES:
sage: OverconvergentModularForms(3, 0, 1/2).character() 0 sage: type(OverconvergentModularForms(3, 0, 1/2).character()) <class '...weightspace.AlgebraicWeight'> sage: OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0).character() (3, 3, [-1])
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)).character() 0 >>> type(OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)).character()) <class '...weightspace.AlgebraicWeight'> >>> OverconvergentModularForms(Integer(3), Integer(3), Integer(1)/Integer(2), char=DirichletGroup(Integer(3),QQ).gen(0)).character() (3, 3, [-1])
OverconvergentModularForms(3, 0, 1/2).character() type(OverconvergentModularForms(3, 0, 1/2).character()) OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0).character()
- coordinate_vector(x)[source]¶
Write
x
as a vector with respect to the basis given byself.basis()
.Here
x
must be an element of this space or something that can be converted into one. Ifx
has precision less than the default precision ofself
, then the returned vector will be shorter.EXAMPLES:
sage: M = OverconvergentModularForms(Gamma0(3), 0, 1/3, prec=4) sage: M.coordinate_vector(M.gen(2)) (0, 0, 1, 0) sage: q = QQ[['q']].gen(); M.coordinate_vector(q - q^2 + O(q^4)) (0, 1/9, -13/81, 74/243) sage: M.coordinate_vector(q - q^2 + O(q^3)) (0, 1/9, -13/81)
>>> from sage.all import * >>> M = OverconvergentModularForms(Gamma0(Integer(3)), Integer(0), Integer(1)/Integer(3), prec=Integer(4)) >>> M.coordinate_vector(M.gen(Integer(2))) (0, 0, 1, 0) >>> q = QQ[['q']].gen(); M.coordinate_vector(q - q**Integer(2) + O(q**Integer(4))) (0, 1/9, -13/81, 74/243) >>> M.coordinate_vector(q - q**Integer(2) + O(q**Integer(3))) (0, 1/9, -13/81)
M = OverconvergentModularForms(Gamma0(3), 0, 1/3, prec=4) M.coordinate_vector(M.gen(2)) q = QQ[['q']].gen(); M.coordinate_vector(q - q^2 + O(q^4)) M.coordinate_vector(q - q^2 + O(q^3))
- cps_u(n, use_recurrence=False)[source]¶
Compute the characteristic power series of \(U_p\) acting on
self
, using an \(n\times n\) matrix.EXAMPLES:
sage: OverconvergentModularForms(3, 16, 1/2, base_ring=Qp(3)).cps_u(4) 1 + O(3^20) + (2 + 2*3 + 2*3^2 + 2*3^4 + 3^5 + 3^6 + 3^7 + 3^11 + 3^12 + 2*3^14 + 3^16 + 3^18 + O(3^19))*T + (2*3^3 + 3^5 + 3^6 + 3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 3^11 + 3^12 + 2*3^13 + 2*3^16 + 2*3^18 + O(3^19))*T^2 + (2*3^15 + 2*3^16 + 2*3^19 + 2*3^20 + 2*3^21 + O(3^22))*T^3 + (3^17 + 2*3^18 + 3^19 + 3^20 + 3^22 + 2*3^23 + 2*3^25 + 3^26 + O(3^27))*T^4 sage: OverconvergentModularForms(3, 16, 1/2, base_ring=Qp(3), prec=30).cps_u(10) 1 + O(3^20) + (2 + 2*3 + 2*3^2 + 2*3^4 + 3^5 + 3^6 + 3^7 + 2*3^15 + O(3^16))*T + (2*3^3 + 3^5 + 3^6 + 3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 3^14 + 3^15 + O(3^16))*T^2 + (3^14 + 2*3^15 + 2*3^16 + 3^17 + 3^18 + O(3^19))*T^3 + (3^17 + 2*3^18 + 3^19 + 3^20 + 3^21 + O(3^24))*T^4 + (3^29 + 2*3^32 + O(3^33))*T^5 + (2*3^44 + O(3^45))*T^6 + (2*3^59 + O(3^60))*T^7 + (2*3^78 + O(3^79))*T^8
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(16), Integer(1)/Integer(2), base_ring=Qp(Integer(3))).cps_u(Integer(4)) 1 + O(3^20) + (2 + 2*3 + 2*3^2 + 2*3^4 + 3^5 + 3^6 + 3^7 + 3^11 + 3^12 + 2*3^14 + 3^16 + 3^18 + O(3^19))*T + (2*3^3 + 3^5 + 3^6 + 3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 3^11 + 3^12 + 2*3^13 + 2*3^16 + 2*3^18 + O(3^19))*T^2 + (2*3^15 + 2*3^16 + 2*3^19 + 2*3^20 + 2*3^21 + O(3^22))*T^3 + (3^17 + 2*3^18 + 3^19 + 3^20 + 3^22 + 2*3^23 + 2*3^25 + 3^26 + O(3^27))*T^4 >>> OverconvergentModularForms(Integer(3), Integer(16), Integer(1)/Integer(2), base_ring=Qp(Integer(3)), prec=Integer(30)).cps_u(Integer(10)) 1 + O(3^20) + (2 + 2*3 + 2*3^2 + 2*3^4 + 3^5 + 3^6 + 3^7 + 2*3^15 + O(3^16))*T + (2*3^3 + 3^5 + 3^6 + 3^7 + 2*3^8 + 2*3^9 + 2*3^10 + 2*3^11 + 2*3^12 + 2*3^13 + 3^14 + 3^15 + O(3^16))*T^2 + (3^14 + 2*3^15 + 2*3^16 + 3^17 + 3^18 + O(3^19))*T^3 + (3^17 + 2*3^18 + 3^19 + 3^20 + 3^21 + O(3^24))*T^4 + (3^29 + 2*3^32 + O(3^33))*T^5 + (2*3^44 + O(3^45))*T^6 + (2*3^59 + O(3^60))*T^7 + (2*3^78 + O(3^79))*T^8
OverconvergentModularForms(3, 16, 1/2, base_ring=Qp(3)).cps_u(4) OverconvergentModularForms(3, 16, 1/2, base_ring=Qp(3), prec=30).cps_u(10)
Note
Uses the Hessenberg form of the Hecke matrix to compute the characteristic polynomial. Because of the use of relative precision here this tends to give better precision in the \(p\)-adic coefficients.
- eigenfunctions(n, F=None, exact_arith=True)[source]¶
Calculate approximations to eigenfunctions of
self
.These are the eigenfunctions of
self.hecke_matrix(p, n)
, which are approximations to the true eigenfunctions. Returns a list ofOverconvergentModularFormElement
objects, in increasing order of slope.INPUT:
n
– integer; the size of the matrix to useF
– eitherNone
or a field over which to calculate eigenvalues. If the field isNone
, the current base ring is used. If the base ring is not a \(p\)-adic ring, an error will be raised.exact_arith
– boolean (default:True
); ifTrue
, use exact rational arithmetic to calculate the matrix of the \(U\) operator and its characteristic power series, even when the base ring is an inexact \(p\)-adic ring. This is typically slower, but more numerically stable.
NOTE: Try using
set_verbose(1, 'sage/modular/overconvergent')
to get more feedback on what is going on in this algorithm. For even more feedback, use 2 instead of 1.EXAMPLES:
sage: X = OverconvergentModularForms(2, 2, 1/6).eigenfunctions(8, Qp(2, 100)) sage: X[1] 2-adic overconvergent modular form of weight-character 2 with q-expansion (1 + O(2^74))*q + (2^4 + 2^5 + 2^9 + 2^10 + 2^12 + 2^13 + 2^15 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^28 + 2^30 + 2^31 + 2^32 + 2^34 + 2^36 + 2^37 + 2^39 + 2^40 + 2^43 + 2^44 + 2^45 + 2^47 + 2^48 + 2^52 + 2^53 + 2^54 + 2^55 + 2^56 + 2^58 + 2^59 + 2^60 + 2^61 + 2^67 + 2^68 + 2^70 + 2^71 + 2^72 + 2^74 + 2^76 + O(2^78))*q^2 + (2^2 + 2^7 + 2^8 + 2^9 + 2^12 + 2^13 + 2^16 + 2^17 + 2^21 + 2^23 + 2^25 + 2^28 + 2^33 + 2^34 + 2^36 + 2^37 + 2^42 + 2^45 + 2^47 + 2^49 + 2^50 + 2^51 + 2^54 + 2^55 + 2^58 + 2^60 + 2^61 + 2^67 + 2^71 + 2^72 + O(2^76))*q^3 + (2^8 + 2^11 + 2^14 + 2^19 + 2^21 + 2^22 + 2^24 + 2^25 + 2^26 + 2^27 + 2^28 + 2^29 + 2^32 + 2^33 + 2^35 + 2^36 + 2^44 + 2^45 + 2^46 + 2^47 + 2^49 + 2^50 + 2^53 + 2^54 + 2^55 + 2^56 + 2^57 + 2^60 + 2^63 + 2^66 + 2^67 + 2^69 + 2^74 + 2^76 + 2^79 + 2^80 + 2^81 + O(2^82))*q^4 + (2 + 2^2 + 2^9 + 2^13 + 2^15 + 2^17 + 2^19 + 2^21 + 2^23 + 2^26 + 2^27 + 2^28 + 2^30 + 2^33 + 2^34 + 2^35 + 2^36 + 2^37 + 2^38 + 2^39 + 2^41 + 2^42 + 2^43 + 2^45 + 2^58 + 2^59 + 2^60 + 2^61 + 2^62 + 2^63 + 2^65 + 2^66 + 2^68 + 2^69 + 2^71 + 2^72 + O(2^75))*q^5 + (2^6 + 2^7 + 2^15 + 2^16 + 2^21 + 2^24 + 2^25 + 2^28 + 2^29 + 2^33 + 2^34 + 2^37 + 2^44 + 2^45 + 2^48 + 2^50 + 2^51 + 2^54 + 2^55 + 2^57 + 2^58 + 2^59 + 2^60 + 2^64 + 2^69 + 2^71 + 2^73 + 2^75 + 2^78 + O(2^80))*q^6 + (2^3 + 2^8 + 2^9 + 2^10 + 2^11 + 2^12 + 2^14 + 2^15 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^25 + 2^26 + 2^34 + 2^37 + 2^38 + 2^39 + 2^40 + 2^41 + 2^45 + 2^47 + 2^49 + 2^51 + 2^53 + 2^54 + 2^55 + 2^57 + 2^58 + 2^59 + 2^60 + 2^61 + 2^66 + 2^69 + 2^70 + 2^71 + 2^74 + 2^76 + O(2^77))*q^7 + O(q^8) sage: [x.slope() for x in X] [0, 4, 8, 14, 16, 18, 26, 30]
>>> from sage.all import * >>> X = OverconvergentModularForms(Integer(2), Integer(2), Integer(1)/Integer(6)).eigenfunctions(Integer(8), Qp(Integer(2), Integer(100))) >>> X[Integer(1)] 2-adic overconvergent modular form of weight-character 2 with q-expansion (1 + O(2^74))*q + (2^4 + 2^5 + 2^9 + 2^10 + 2^12 + 2^13 + 2^15 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^28 + 2^30 + 2^31 + 2^32 + 2^34 + 2^36 + 2^37 + 2^39 + 2^40 + 2^43 + 2^44 + 2^45 + 2^47 + 2^48 + 2^52 + 2^53 + 2^54 + 2^55 + 2^56 + 2^58 + 2^59 + 2^60 + 2^61 + 2^67 + 2^68 + 2^70 + 2^71 + 2^72 + 2^74 + 2^76 + O(2^78))*q^2 + (2^2 + 2^7 + 2^8 + 2^9 + 2^12 + 2^13 + 2^16 + 2^17 + 2^21 + 2^23 + 2^25 + 2^28 + 2^33 + 2^34 + 2^36 + 2^37 + 2^42 + 2^45 + 2^47 + 2^49 + 2^50 + 2^51 + 2^54 + 2^55 + 2^58 + 2^60 + 2^61 + 2^67 + 2^71 + 2^72 + O(2^76))*q^3 + (2^8 + 2^11 + 2^14 + 2^19 + 2^21 + 2^22 + 2^24 + 2^25 + 2^26 + 2^27 + 2^28 + 2^29 + 2^32 + 2^33 + 2^35 + 2^36 + 2^44 + 2^45 + 2^46 + 2^47 + 2^49 + 2^50 + 2^53 + 2^54 + 2^55 + 2^56 + 2^57 + 2^60 + 2^63 + 2^66 + 2^67 + 2^69 + 2^74 + 2^76 + 2^79 + 2^80 + 2^81 + O(2^82))*q^4 + (2 + 2^2 + 2^9 + 2^13 + 2^15 + 2^17 + 2^19 + 2^21 + 2^23 + 2^26 + 2^27 + 2^28 + 2^30 + 2^33 + 2^34 + 2^35 + 2^36 + 2^37 + 2^38 + 2^39 + 2^41 + 2^42 + 2^43 + 2^45 + 2^58 + 2^59 + 2^60 + 2^61 + 2^62 + 2^63 + 2^65 + 2^66 + 2^68 + 2^69 + 2^71 + 2^72 + O(2^75))*q^5 + (2^6 + 2^7 + 2^15 + 2^16 + 2^21 + 2^24 + 2^25 + 2^28 + 2^29 + 2^33 + 2^34 + 2^37 + 2^44 + 2^45 + 2^48 + 2^50 + 2^51 + 2^54 + 2^55 + 2^57 + 2^58 + 2^59 + 2^60 + 2^64 + 2^69 + 2^71 + 2^73 + 2^75 + 2^78 + O(2^80))*q^6 + (2^3 + 2^8 + 2^9 + 2^10 + 2^11 + 2^12 + 2^14 + 2^15 + 2^17 + 2^19 + 2^20 + 2^21 + 2^23 + 2^25 + 2^26 + 2^34 + 2^37 + 2^38 + 2^39 + 2^40 + 2^41 + 2^45 + 2^47 + 2^49 + 2^51 + 2^53 + 2^54 + 2^55 + 2^57 + 2^58 + 2^59 + 2^60 + 2^61 + 2^66 + 2^69 + 2^70 + 2^71 + 2^74 + 2^76 + O(2^77))*q^7 + O(q^8) >>> [x.slope() for x in X] [0, 4, 8, 14, 16, 18, 26, 30]
X = OverconvergentModularForms(2, 2, 1/6).eigenfunctions(8, Qp(2, 100)) X[1] [x.slope() for x in X]
- gen(i)[source]¶
Return the \(i\)-th module generator of
self
.EXAMPLES:
sage: M = OverconvergentModularForms(3, 2, 1/2, prec=4) sage: M.gen(0) 3-adic overconvergent modular form of weight-character 2 with q-expansion 1 + 12*q + 36*q^2 + 12*q^3 + O(q^4) sage: M.gen(1) 3-adic overconvergent modular form of weight-character 2 with q-expansion 27*q + 648*q^2 + 7290*q^3 + O(q^4) sage: M.gen(30) 3-adic overconvergent modular form of weight-character 2 with q-expansion O(q^4)
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(2), Integer(1)/Integer(2), prec=Integer(4)) >>> M.gen(Integer(0)) 3-adic overconvergent modular form of weight-character 2 with q-expansion 1 + 12*q + 36*q^2 + 12*q^3 + O(q^4) >>> M.gen(Integer(1)) 3-adic overconvergent modular form of weight-character 2 with q-expansion 27*q + 648*q^2 + 7290*q^3 + O(q^4) >>> M.gen(Integer(30)) 3-adic overconvergent modular form of weight-character 2 with q-expansion O(q^4)
M = OverconvergentModularForms(3, 2, 1/2, prec=4) M.gen(0) M.gen(1) M.gen(30)
- gens()[source]¶
Return a generator object that iterates over the (infinite) set of basis vectors of
self
.EXAMPLES:
sage: o = OverconvergentModularForms(3, 12, 1/2) sage: t = o.gens() sage: next(t) 3-adic overconvergent modular form of weight-character 12 with q-expansion 1 - 32760/61203943*q - 67125240/61203943*q^2 - ... sage: next(t) 3-adic overconvergent modular form of weight-character 12 with q-expansion 27*q + 19829193012/61203943*q^2 + 146902585770/61203943*q^3 + ...
>>> from sage.all import * >>> o = OverconvergentModularForms(Integer(3), Integer(12), Integer(1)/Integer(2)) >>> t = o.gens() >>> next(t) 3-adic overconvergent modular form of weight-character 12 with q-expansion 1 - 32760/61203943*q - 67125240/61203943*q^2 - ... >>> next(t) 3-adic overconvergent modular form of weight-character 12 with q-expansion 27*q + 19829193012/61203943*q^2 + 146902585770/61203943*q^3 + ...
o = OverconvergentModularForms(3, 12, 1/2) t = o.gens() next(t) next(t)
- hecke_matrix(m, n, use_recurrence=False, exact_arith=False, side='left')[source]¶
Calculate the matrix of the \(T_m\) operator, truncated to \(n \times n\).
INPUT:
m
– integer; determines the operator \(T_m\)n
– integer; truncate the matrix in the basis of this space to an \(n \times n\) matrixuse_recurrence
– boolean (default:False
); whether to use Kolberg style recurrences. IfFalse
, use naive \(q\)-expansion arguments.exact_arith
– boolean (default:True
); whether to do the computation to be done with rational arithmetic, even if the base ring is an inexact \(p\)-adic ring.This is useful as there can be precision loss issues (particularly with
use_recurrence=False
).side
–'left'
(default) or'right'
; if'left'
, the operator acts on the left on column vectors
EXAMPLES:
sage: OverconvergentModularForms(2, 0, 1/2).hecke_matrix(2, 4) [ 1 0 0 0] [ 0 24 64 0] [ 0 32 1152 4608] [ 0 0 3072 61440] sage: o = OverconvergentModularForms(2, 12, 1/2, base_ring=pAdicField(2)) sage: o.hecke_matrix(2, 3) * (1 + O(2^2)) [ 1 + O(2^2) 0 0] [ 0 2^3 + O(2^5) 2^6 + O(2^8)] [ 0 2^4 + O(2^6) 2^7 + 2^8 + O(2^9)] sage: o = OverconvergentModularForms(2, 12, 1/2, base_ring=pAdicField(2)) sage: o.hecke_matrix(2, 3, exact_arith=True) [ 1 0 0] [ 0 33881928/1414477 64] [ 0 -192898739923312/2000745183529 1626332544/1414477]
>>> from sage.all import * >>> OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2)).hecke_matrix(Integer(2), Integer(4)) [ 1 0 0 0] [ 0 24 64 0] [ 0 32 1152 4608] [ 0 0 3072 61440] >>> o = OverconvergentModularForms(Integer(2), Integer(12), Integer(1)/Integer(2), base_ring=pAdicField(Integer(2))) >>> o.hecke_matrix(Integer(2), Integer(3)) * (Integer(1) + O(Integer(2)**Integer(2))) [ 1 + O(2^2) 0 0] [ 0 2^3 + O(2^5) 2^6 + O(2^8)] [ 0 2^4 + O(2^6) 2^7 + 2^8 + O(2^9)] >>> o = OverconvergentModularForms(Integer(2), Integer(12), Integer(1)/Integer(2), base_ring=pAdicField(Integer(2))) >>> o.hecke_matrix(Integer(2), Integer(3), exact_arith=True) [ 1 0 0] [ 0 33881928/1414477 64] [ 0 -192898739923312/2000745183529 1626332544/1414477]
OverconvergentModularForms(2, 0, 1/2).hecke_matrix(2, 4) o = OverconvergentModularForms(2, 12, 1/2, base_ring=pAdicField(2)) o.hecke_matrix(2, 3) * (1 + O(2^2)) o = OverconvergentModularForms(2, 12, 1/2, base_ring=pAdicField(2)) o.hecke_matrix(2, 3, exact_arith=True)
Side switch:
sage: OverconvergentModularForms(2, 0, 1/2).hecke_matrix(2, 4, side='right') [ 1 0 0 0] [ 0 24 32 0] [ 0 64 1152 3072] [ 0 0 4608 61440]
>>> from sage.all import * >>> OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2)).hecke_matrix(Integer(2), Integer(4), side='right') [ 1 0 0 0] [ 0 24 32 0] [ 0 64 1152 3072] [ 0 0 4608 61440]
OverconvergentModularForms(2, 0, 1/2).hecke_matrix(2, 4, side='right')
- hecke_operator(f, m)[source]¶
Given an element \(f\) and an integer \(m\), calculates the Hecke operator \(T_m\) acting on \(f\).
The input may be either a “bare” power series, or an
OverconvergentModularFormElement
object; the return value will be of the same type.EXAMPLES:
sage: M = OverconvergentModularForms(3, 0, 1/2) sage: f = M.1 sage: M.hecke_operator(f, 3) 3-adic overconvergent modular form of weight-character 0 with q-expansion 2430*q + 265356*q^2 + 10670373*q^3 + 249948828*q^4 + 4113612864*q^5 + 52494114852*q^6 + O(q^7) sage: M.hecke_operator(f.q_expansion(), 3) 2430*q + 265356*q^2 + 10670373*q^3 + 249948828*q^4 + 4113612864*q^5 + 52494114852*q^6 + O(q^7)
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)) >>> f = M.gen(1) >>> M.hecke_operator(f, Integer(3)) 3-adic overconvergent modular form of weight-character 0 with q-expansion 2430*q + 265356*q^2 + 10670373*q^3 + 249948828*q^4 + 4113612864*q^5 + 52494114852*q^6 + O(q^7) >>> M.hecke_operator(f.q_expansion(), Integer(3)) 2430*q + 265356*q^2 + 10670373*q^3 + 249948828*q^4 + 4113612864*q^5 + 52494114852*q^6 + O(q^7)
M = OverconvergentModularForms(3, 0, 1/2) f = M.1 M.hecke_operator(f, 3) M.hecke_operator(f.q_expansion(), 3)
- is_exact()[source]¶
Return
True
if elements of this space are represented exactly.This would mean that there is no precision loss when doing arithmetic. As this is never true for overconvergent modular forms spaces, this method returns
False
.EXAMPLES:
sage: OverconvergentModularForms(13, 12, 0).is_exact() False
>>> from sage.all import * >>> OverconvergentModularForms(Integer(13), Integer(12), Integer(0)).is_exact() False
OverconvergentModularForms(13, 12, 0).is_exact()
- ngens()[source]¶
The number of generators of
self
(as a module over its base ring), i.e. infinity.EXAMPLES:
sage: M = OverconvergentModularForms(2, 4, 1/6) sage: M.ngens() +Infinity
>>> from sage.all import * >>> M = OverconvergentModularForms(Integer(2), Integer(4), Integer(1)/Integer(6)) >>> M.ngens() +Infinity
M = OverconvergentModularForms(2, 4, 1/6) M.ngens()
- normalising_factor()[source]¶
Return the normalising factor of
self
.The normalising factor \(c\) such that \(g = c f\) is a parameter for the \(r\)-overconvergent disc in \(X_0(p)\), where \(f\) is the standard uniformiser.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: L.<w> = Qp(7).extension(x^2 - 7) sage: OverconvergentModularForms(7, 0, 1/4, base_ring=L).normalising_factor() w + O(w^41)
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> L = Qp(Integer(7)).extension(x**Integer(2) - Integer(7), names=('w',)); (w,) = L._first_ngens(1) >>> OverconvergentModularForms(Integer(7), Integer(0), Integer(1)/Integer(4), base_ring=L).normalising_factor() w + O(w^41)
x = polygen(ZZ, 'x') L.<w> = Qp(7).extension(x^2 - 7) OverconvergentModularForms(7, 0, 1/4, base_ring=L).normalising_factor()
- prec()[source]¶
Return the series precision of
self
.Note that this is different from the \(p\)-adic precision of the base ring.
EXAMPLES:
sage: OverconvergentModularForms(3, 0, 1/2).prec() 20 sage: OverconvergentModularForms(3, 0, 1/2, prec=40).prec() 40
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)).prec() 20 >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2), prec=Integer(40)).prec() 40
OverconvergentModularForms(3, 0, 1/2).prec() OverconvergentModularForms(3, 0, 1/2, prec=40).prec()
- prime()[source]¶
Return the residue characteristic of
self
.This is the prime \(p\) such that this is a \(p\)-adic space.
EXAMPLES:
sage: OverconvergentModularForms(5, 12, 1/3).prime() 5
>>> from sage.all import * >>> OverconvergentModularForms(Integer(5), Integer(12), Integer(1)/Integer(3)).prime() 5
OverconvergentModularForms(5, 12, 1/3).prime()
- radius()[source]¶
The radius of overconvergence of this space.
EXAMPLES:
sage: OverconvergentModularForms(3, 0, 1/3).radius() 1/3
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(3)).radius() 1/3
OverconvergentModularForms(3, 0, 1/3).radius()
- recurrence_matrix(use_smithline=True)[source]¶
Return the recurrence matrix satisfied by the coefficients of \(U\).
This is a matrix \(R =(r_{rs})_{r,s=1,\dots,p}\) such that \(u_{ij} = \sum_{r,s=1}^p r_{rs} u_{i-r, j-s}\).
Uses an elegant construction which the author believes to be due to Smithline. See [Loe2007].
EXAMPLES:
sage: OverconvergentModularForms(2, 0, 0).recurrence_matrix() [ 48 1] [4096 0] sage: OverconvergentModularForms(2, 0, 1/2).recurrence_matrix() [48 64] [64 0] sage: OverconvergentModularForms(3, 0, 0).recurrence_matrix() [ 270 36 1] [ 26244 729 0] [531441 0 0] sage: OverconvergentModularForms(5, 0, 0).recurrence_matrix() [ 1575 1300 315 30 1] [ 162500 39375 3750 125 0] [ 4921875 468750 15625 0 0] [ 58593750 1953125 0 0 0] [244140625 0 0 0 0] sage: OverconvergentModularForms(7, 0, 0).recurrence_matrix() [ 4018 8624 5915 1904 322 28 1] [ 422576 289835 93296 15778 1372 49 0] [ 14201915 4571504 773122 67228 2401 0 0] [ 224003696 37882978 3294172 117649 0 0 0] [ 1856265922 161414428 5764801 0 0 0 0] [ 7909306972 282475249 0 0 0 0 0] [13841287201 0 0 0 0 0 0] sage: OverconvergentModularForms(13, 0, 0).recurrence_matrix() [ 15145 124852 354536 ...
>>> from sage.all import * >>> OverconvergentModularForms(Integer(2), Integer(0), Integer(0)).recurrence_matrix() [ 48 1] [4096 0] >>> OverconvergentModularForms(Integer(2), Integer(0), Integer(1)/Integer(2)).recurrence_matrix() [48 64] [64 0] >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(0)).recurrence_matrix() [ 270 36 1] [ 26244 729 0] [531441 0 0] >>> OverconvergentModularForms(Integer(5), Integer(0), Integer(0)).recurrence_matrix() [ 1575 1300 315 30 1] [ 162500 39375 3750 125 0] [ 4921875 468750 15625 0 0] [ 58593750 1953125 0 0 0] [244140625 0 0 0 0] >>> OverconvergentModularForms(Integer(7), Integer(0), Integer(0)).recurrence_matrix() [ 4018 8624 5915 1904 322 28 1] [ 422576 289835 93296 15778 1372 49 0] [ 14201915 4571504 773122 67228 2401 0 0] [ 224003696 37882978 3294172 117649 0 0 0] [ 1856265922 161414428 5764801 0 0 0 0] [ 7909306972 282475249 0 0 0 0 0] [13841287201 0 0 0 0 0 0] >>> OverconvergentModularForms(Integer(13), Integer(0), Integer(0)).recurrence_matrix() [ 15145 124852 354536 ...
OverconvergentModularForms(2, 0, 0).recurrence_matrix() OverconvergentModularForms(2, 0, 1/2).recurrence_matrix() OverconvergentModularForms(3, 0, 0).recurrence_matrix() OverconvergentModularForms(5, 0, 0).recurrence_matrix() OverconvergentModularForms(7, 0, 0).recurrence_matrix() OverconvergentModularForms(13, 0, 0).recurrence_matrix()
- slopes(n, use_recurrence=False)[source]¶
Compute the slopes of the \(U_p\) operator acting on
self
, using an \(n\times n\) matrix.EXAMPLES:
sage: OverconvergentModularForms(5, 2, 1/3, base_ring=Qp(5), prec=100).slopes(5) [0, 2, 5, 6, 9] sage: OverconvergentModularForms(2, 1, 1/3, char=DirichletGroup(4,QQ).0).slopes(5) [0, 2, 4, 6, 8]
>>> from sage.all import * >>> OverconvergentModularForms(Integer(5), Integer(2), Integer(1)/Integer(3), base_ring=Qp(Integer(5)), prec=Integer(100)).slopes(Integer(5)) [0, 2, 5, 6, 9] >>> OverconvergentModularForms(Integer(2), Integer(1), Integer(1)/Integer(3), char=DirichletGroup(Integer(4),QQ).gen(0)).slopes(Integer(5)) [0, 2, 4, 6, 8]
OverconvergentModularForms(5, 2, 1/3, base_ring=Qp(5), prec=100).slopes(5) OverconvergentModularForms(2, 1, 1/3, char=DirichletGroup(4,QQ).0).slopes(5)
- weight()[source]¶
Return the weight of
self
.For overconvergent forms, the weight and the character are unified into the concept of a weight-character, so this returns exactly the same thing as
character()
.EXAMPLES:
sage: OverconvergentModularForms(3, 0, 1/2).weight() 0 sage: type(OverconvergentModularForms(3, 0, 1/2).weight()) <class '...weightspace.AlgebraicWeight'> sage: OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0).weight() (3, 3, [-1])
>>> from sage.all import * >>> OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)).weight() 0 >>> type(OverconvergentModularForms(Integer(3), Integer(0), Integer(1)/Integer(2)).weight()) <class '...weightspace.AlgebraicWeight'> >>> OverconvergentModularForms(Integer(3), Integer(3), Integer(1)/Integer(2), char=DirichletGroup(Integer(3),QQ).gen(0)).weight() (3, 3, [-1])
OverconvergentModularForms(3, 0, 1/2).weight() type(OverconvergentModularForms(3, 0, 1/2).weight()) OverconvergentModularForms(3, 3, 1/2, char=DirichletGroup(3,QQ).0).weight()
- zero()[source]¶
Return the zero of this space.
EXAMPLES:
sage: x = polygen(ZZ, 'x') sage: K.<w> = Qp(13).extension(x^2 - 13) sage: M = OverconvergentModularForms(13, 20, radius=1/2, base_ring=K) sage: K.zero() 0
>>> from sage.all import * >>> x = polygen(ZZ, 'x') >>> K = Qp(Integer(13)).extension(x**Integer(2) - Integer(13), names=('w',)); (w,) = K._first_ngens(1) >>> M = OverconvergentModularForms(Integer(13), Integer(20), radius=Integer(1)/Integer(2), base_ring=K) >>> K.zero() 0
x = polygen(ZZ, 'x') K.<w> = Qp(13).extension(x^2 - 13) M = OverconvergentModularForms(13, 20, radius=1/2, base_ring=K) K.zero()