Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- """ Elements of modular forms spaces
Class hierarchy:
- :class:`ModularForm_abstract`
- :class:`Newform`
- :class:`ModularFormElement`
- :class:`ModularFormElement_elliptic_curve`
- :class:`EisensteinSeries`
""" #***************************************************************************** # Copyright (C) 2004-2008 William Stein <wstein@gmail.com> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 2 of the License, or # (at your option) any later version. # http://www.gnu.org/licenses/ #***************************************************************************** from __future__ import absolute_import, division from six.moves import range
import sage.modular.hecke.element as element
from sage.rings.all import ZZ, QQ, Integer, RealField, ComplexField from sage.rings.fast_arith import prime_range from sage.arith.misc import euler_phi from sage.rings.morphism import RingHomomorphism from sage.rings.number_field.number_field import CyclotomicField from sage.rings.number_field.number_field_morphisms import NumberFieldEmbedding from sage.modular.modsym.space import is_ModularSymbolsSpace from sage.modular.modsym.modsym import ModularSymbols from sage.modules.free_module_element import vector from sage.misc.misc import verbose from sage.arith.srange import xsrange from sage.modular.dirichlet import DirichletGroup from sage.misc.superseded import deprecated_function_alias from sage.arith.all import lcm, divisors, moebius, sigma, factor from sage.structure.element import coercion_model, ModuleElement from sage.misc.cachefunc import cached_method from sage.functions.other import ceil
def is_ModularFormElement(x): """ Return True if x is a modular form.
EXAMPLES::
sage: from sage.modular.modform.element import is_ModularFormElement sage: is_ModularFormElement(5) False sage: is_ModularFormElement(ModularForms(11).0) True """
def delta_lseries(prec=53, max_imaginary_part=0, max_asymp_coeffs=40): r""" Return the L-series of the modular form Delta.
This actually returns an interface to Tim Dokchitser's program for computing with the L-series of the modular form `\Delta`.
INPUT:
- ``prec`` - integer (bits precision)
- ``max_imaginary_part`` - real number
- ``max_asymp_coeffs`` - integer
OUTPUT:
The L-series of `\Delta`.
EXAMPLES::
sage: L = delta_lseries() sage: L(1) 0.0374412812685155 """ # key = (prec, max_imaginary_part, max_asymp_coeffs) gammaV = [0, 1], weight = 12, eps = 1, prec = prec) max_imaginary_part=max_imaginary_part, max_asymp_coeffs=max_asymp_coeffs)
class ModularForm_abstract(ModuleElement): """ Constructor for generic class of a modular form. This should never be called directly; instead one should instantiate one of the derived classes of this class. """ def group(self): """ Return the group for which self is a modular form.
EXAMPLES::
sage: ModularForms(Gamma1(11), 2).gen(0).group() Congruence Subgroup Gamma1(11) """
def weight(self): """ Return the weight of self.
EXAMPLES::
sage: (ModularForms(Gamma1(9),2).6).weight() 2 """
def level(self): """ Return the level of self.
EXAMPLES::
sage: ModularForms(25,4).0.level() 25 """
def _repr_(self): """ Return the string representation of self.
EXAMPLES::
sage: ModularForms(25,4).0._repr_() 'q + O(q^6)'
sage: ModularForms(25,4).3._repr_() 'q^4 + O(q^6)' """
def __call__(self, x, prec=None): """ Evaluate the q-expansion of this modular form at x.
EXAMPLES::
sage: f = ModularForms(DirichletGroup(17).0^2,2).2
sage: q = f.q_expansion().parent().gen() sage: f(q^2 + O(q^7)) q^2 + (-zeta8^2 + 2)*q^4 + (zeta8 + 3)*q^6 + O(q^7)
sage: f(0) 0 """
def valuation(self): """ Return the valuation of self (i.e. as an element of the power series ring in q).
EXAMPLES::
sage: ModularForms(11,2).0.valuation() 1 sage: ModularForms(11,2).1.valuation() 0 sage: ModularForms(25,6).1.valuation() 2 sage: ModularForms(25,6).6.valuation() 7 """
def qexp(self, prec=None): """ Same as ``self.q_expansion(prec)``.
.. SEEALSO:: :meth:`q_expansion`
EXAMPLES::
sage: CuspForms(1,12).0.qexp() q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) """
def __eq__(self, other): """ Compare self to other.
EXAMPLES::
sage: f = ModularForms(6,4).0 sage: g = ModularForms(23,2).0 sage: f == g ## indirect doctest False sage: f == f True sage: f == loads(dumps(f)) True """ self.ambient_module() != other.ambient_module(): else:
def __ne__(self, other): """ Return True if ``self != other``.
EXAMPLES::
sage: f = Newforms(Gamma1(30), 2, names='a')[1] sage: g = ModularForms(23, 2).0 sage: f != g True sage: f != f False
TESTS:
The following used to fail (see :trac:`18068`)::
sage: f != loads(dumps(f)) False """
def _compute(self, X): """ Compute the coefficients of `q^n` of the power series of self, for `n` in the list `X`. The results are not cached. (Use coefficients for cached results).
EXAMPLES::
sage: f = ModularForms(18,2).1 sage: f.q_expansion(20) q + 8*q^7 + 4*q^10 + 14*q^13 - 4*q^16 + 20*q^19 + O(q^20) sage: f._compute([10,17]) [4, 0] sage: f._compute([]) [] """
def coefficients(self, X): """ The coefficients a_n of self, for integers n>=0 in the list X. If X is an Integer, return coefficients for indices from 1 to X.
This function caches the results of the compute function.
TESTS::
sage: e = DirichletGroup(11).gen() sage: f = EisensteinForms(e, 3).eisenstein_series()[0] sage: f.coefficients([0,1]) [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11, 1] sage: f.coefficients([0,1,2,3]) [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11, 1, 4*zeta10 + 1, -9*zeta10^3 + 1] sage: f.coefficients([2,3]) [4*zeta10 + 1, -9*zeta10^3 + 1]
Running this twice once revealed a bug, so we test it::
sage: f.coefficients([0,1,2,3]) [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11, 1, 4*zeta10 + 1, -9*zeta10^3 + 1] """
def __getitem__(self, n): """ Returns the `q^n` coefficient of the `q`-expansion of self or returns a list containing the `q^i` coefficients of self where `i` is in slice `n`.
EXAMPLES::
sage: f = ModularForms(DirichletGroup(17).0^2,2).2 sage: f.__getitem__(10) zeta8^3 - 5*zeta8^2 - 2*zeta8 + 10 sage: f[30] -2*zeta8^3 - 17*zeta8^2 + 4*zeta8 + 29 sage: f[10:15] [zeta8^3 - 5*zeta8^2 - 2*zeta8 + 10, -zeta8^3 + 11, -2*zeta8^3 - 6*zeta8^2 + 3*zeta8 + 9, 12, 2*zeta8^3 - 7*zeta8^2 + zeta8 + 14] """ return self.q_expansion().list()[n] else: else:
def padded_list(self, n): """ Return a list of length n whose entries are the first n coefficients of the q-expansion of self.
EXAMPLES::
sage: CuspForms(1,12).0.padded_list(20) [0, 1, -24, 252, -1472, 4830, -6048, -16744, 84480, -113643, -115920, 534612, -370944, -577738, 401856, 1217160, 987136, -6905934, 2727432, 10661420] """
def _latex_(self): """ Return the LaTeX expression of self.
EXAMPLES::
sage: ModularForms(25,4).0._latex_() 'q + O(q^{6})'
sage: ModularForms(25,4).4._latex_() 'q^{5} + O(q^{6})' """
def base_ring(self): """ Return the base_ring of self.
EXAMPLES::
sage: (ModularForms(117, 2).13).base_ring() Rational Field sage: (ModularForms(119, 2, base_ring=GF(7)).12).base_ring() Finite Field of size 7 """
def character(self, compute=True): """ Return the character of self. If ``compute=False``, then this will return None unless the form was explicitly created as an element of a space of forms with character, skipping the (potentially expensive) computation of the matrices of the diamond operators.
EXAMPLES::
sage: ModularForms(DirichletGroup(17).0^2,2).2.character() Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta8
sage: CuspForms(Gamma1(7), 3).gen(0).character() Dirichlet character modulo 7 of conductor 7 mapping 3 |--> -1 sage: CuspForms(Gamma1(7), 3).gen(0).character(compute = False) is None True sage: M = CuspForms(Gamma1(7), 5).gen(0).character() Traceback (most recent call last): ... ValueError: Form is not an eigenvector for <3> """ else: # do the expensive computation
def __bool__(self): """ Return ``True`` if ``self`` is nonzero, and ``False`` if not.
EXAMPLES::
sage: bool(ModularForms(25,6).6) True """
__nonzero__ = __bool__
def prec(self): """ Return the precision to which self.q_expansion() is currently known. Note that this may be 0.
EXAMPLES::
sage: M = ModularForms(2,14) sage: f = M.0 sage: f.prec() 0
sage: M.prec(20) 20 sage: f.prec() 0 sage: x = f.q_expansion() ; f.prec() 20 """
def q_expansion(self, prec=None): r""" The `q`-expansion of the modular form to precision `O(q^\text{prec})`. This function takes one argument, which is the integer prec.
EXAMPLES:
We compute the cusp form `\Delta`::
sage: delta = CuspForms(1,12).0 sage: delta.q_expansion() q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6)
We compute the `q`-expansion of one of the cusp forms of level 23::
sage: f = CuspForms(23,2).0 sage: f.q_expansion() q - q^3 - q^4 + O(q^6) sage: f.q_expansion(10) q - q^3 - q^4 - 2*q^6 + 2*q^7 - q^8 + 2*q^9 + O(q^10) sage: f.q_expansion(2) q + O(q^2) sage: f.q_expansion(1) O(q^1) sage: f.q_expansion(0) O(q^0) sage: f.q_expansion(-1) Traceback (most recent call last): ... ValueError: prec (= -1) must be non-negative """
else:
def atkin_lehner_eigenvalue(self, d=None, embedding=None): """ Return the eigenvalue of the Atkin-Lehner operator `W_d` acting on ``self``.
INPUT:
- ``d`` -- a positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d` (default: `d = N`)
- ``embedding`` -- (optional) embedding of the base ring of ``self`` into another ring
OUTPUT:
The Atkin-Lehner eigenvalue of `W_d` on ``self``. This is returned as an element of the codomain of ``embedding`` if specified, and in (a suitable extension of) the base field of ``self`` otherwise.
If ``self`` is not an eigenform for `W_d`, a ``ValueError`` is raised.
.. SEEALSO::
:meth:`atkin_lehner_action` (especially for the conventions used to define the operator `W_d`).
EXAMPLES::
sage: [x.atkin_lehner_eigenvalue() for x in ModularForms(53).newforms('a')] [1, -1]
sage: f = Newforms(Gamma1(15), 3, names='a')[2]; f q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6) sage: f.atkin_lehner_eigenvalue(5) a2
sage: CuspForms(DirichletGroup(5).0, 5).newforms()[0].atkin_lehner_eigenvalue() Traceback (most recent call last): ... ValueError: q + (-zeta4 - 1)*q^2 + (6*zeta4 - 6)*q^3 - 14*zeta4*q^4 + (15*zeta4 + 20)*q^5 + O(q^6) is not an eigenform for W_5
TESTS:
Check that the bug reported at :trac:`18061` is fixed::
sage: K.<i> = CyclotomicField(4) sage: f = Newforms(Gamma1(30), 2, K, names='a')[1] # long time sage: f.atkin_lehner_eigenvalue() # long time Traceback (most recent call last): ... ValueError: q - i*q^2 + i*q^3 - q^4 + (-i - 2)*q^5 + O(q^6) is not an eigenform for W_30
"""
def atkin_lehner_action(self, d, embedding=None): r""" Return the result of the Atkin-Lehner operator `W_d` on ``self``.
INPUT:
- ``d`` -- a positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d`
- ``embedding`` -- (optional) embedding of the base ring of ``self`` into another ring
OUTPUT:
A pair `(w, f^*)` where `f^*` is a modular form and `w` is a scalar such that `W_d f = w f^*`. The parent of `w` is the codomain of ``embedding`` if specified, otherwise it is (a suitable extension of) the coefficient field of `f`.
.. NOTE::
The definition of the operator `W_d` differs from the one used in [AL1978]_. On the space of modular forms of weight `k`, the operator is defined in both cases by a weight `k` action of a matrix of the form
.. math::
W_d = \begin{pmatrix} dx & y \\ Nz & dw \end{pmatrix}
with `\det W_d = d`. The definitions differ in two respects:
- Congruence conditions: in Sage, the matrix is chosen to satisfy the conditions `z \equiv 1 \pmod d` and `w \equiv 1 \pmod{N/d}`; in [AL1978]_, the conditions are `x \equiv 1 \pmod{N/d}` and `y \equiv 1 \pmod d`.
- Absolute value: due to different definitions of the weight `k` action, the pseudo-eigenvalue returned by this method has absolute value `d^{k/2 - 1}`, while the pseudo-eigenvalue defined in [AL1978]_ has absolute value 1.
Consequently, given a newform `f` of weight `k` and character `\epsilon`, the pseudo-eigenvalue `w` returned by this method and the pseudo-eigenvalue `\lambda_d(f)` defined in [AL1978]_ are related by
.. math::
w = \epsilon_{N/d}(d) d^{k/2 - 1} \lambda_d(f),
where `\epsilon_{N/d}` is the prime-to-`d` part of `\epsilon`.
EXAMPLES::
sage: sage.modular.modform.element.ModularForm_abstract.atkin_lehner_action(CuspForms(2, 8).0, 8) Traceback (most recent call last): ... NotImplementedError """
# The methods period() and lseries() below currently live # in ModularForm_abstract so they are inherited by Newform (which # does *not* derive from ModularFormElement).
def period(self, M, prec=53): r""" Return the period of ``self`` with respect to `M`.
INPUT:
- ``self`` -- a cusp form `f` of weight 2 for `Gamma_0(N)`
- ``M`` -- an element of `\Gamma_0(N)`
- ``prec`` -- (default: 53) the working precision in bits. If `f` is a normalised eigenform, then the output is correct to approximately this number of bits.
OUTPUT:
A numerical approximation of the period `P_f(M)`. This period is defined by the following integral over the complex upper half-plane, for any `\alpha` in `\Bold{P}^1(\QQ)`:
.. MATH::
P_f(M) = 2 \pi i \int_\alpha^{M(\alpha)} f(z) dz.
This is independent of the choice of `\alpha`.
EXAMPLES::
sage: C = Newforms(11, 2)[0] sage: m = C.group()(matrix([[-4, -3], [11, 8]])) sage: C.period(m) -0.634604652139776 - 1.45881661693850*I
sage: f = Newforms(15, 2)[0] sage: g = Gamma0(15)(matrix([[-4, -3], [15, 11]])) sage: f.period(g) # abs tol 1e-15 2.17298044293747e-16 - 1.59624222213178*I
If `E` is an elliptic curve over `\QQ` and `f` is the newform associated to `E`, then the periods of `f` are in the period lattice of `E` up to an integer multiple::
sage: E = EllipticCurve('11a3') sage: f = E.newform() sage: g = Gamma0(11)([3, 1, 11, 4]) sage: f.period(g) 0.634604652139777 + 1.45881661693850*I sage: omega1, omega2 = E.period_lattice().basis() sage: -2/5*omega1 + omega2 0.634604652139777 + 1.45881661693850*I
The integer multiple is 5 in this case, which is explained by the fact that there is a 5-isogeny between the elliptic curves `J_0(5)` and `E`.
The elliptic curve `E` has a pair of modular symbols attached to it, which can be computed using the method :meth:`sage.schemes.elliptic_curves.ell_rational_field.EllipticCurve_rational_field.modular_symbol`. These can be used to express the periods of `f` as exact linear combinations of the real and the imaginary period of `E`::
sage: s = E.modular_symbol(sign=+1) sage: t = E.modular_symbol(sign=-1, implementation="sage") sage: s(3/11), t(3/11) (1/10, 1/2) sage: s(3/11)*omega1 + t(3/11)*2*omega2.imag()*I 0.634604652139777 + 1.45881661693850*I
ALGORITHM:
We use the series expression from [Cre1997]_, Chapter II, Proposition 2.10.3. The algorithm sums the first `T` terms of this series, where `T` is chosen in such a way that the result would approximate `P_f(M)` with an absolute error of at most `2^{-\text{prec}}` if all computations were done exactly.
Since the actual precision is finite, the output is currently *not* guaranteed to be correct to ``prec`` bits of precision.
TESTS::
sage: C = Newforms(11, 2)[0] sage: g = Gamma0(15)(matrix([[-4, -3], [15, 11]])) sage: C.period(g) Traceback (most recent call last): ... TypeError: matrix [-4 -3] [15 11] is not an element of Congruence Subgroup Gamma0(11)
sage: f = Newforms(Gamma0(15), 4)[0] sage: f.period(g) Traceback (most recent call last): ... ValueError: period pairing only defined for cusp forms of weight 2
sage: S = Newforms(Gamma1(17), 2, names='a') sage: f = S[1] sage: g = Gamma1(17)([18, 1, 17, 1]) sage: f.period(g) Traceback (most recent call last): ... NotImplementedError: period pairing only implemented for cusp forms of trivial character
sage: E = ModularForms(Gamma0(4), 2).eisenstein_series()[0] sage: gamma = Gamma0(4)([1, 0, 4, 1]) sage: E.period(gamma) Traceback (most recent call last): ... NotImplementedError: Don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead)
sage: E = EllipticCurve('19a1') sage: M = Gamma0(19)([10, 1, 19, 2]) sage: E.newform().period(M) # abs tol 1e-14 -1.35975973348831 + 1.09365931898146e-16*I
"""
# coefficients of the matrix M return R.zero()
# We bound the tail of the series by means of the triangle # inequality and the following bounds (tau(n) = #divisors(n)): # mu_N <= mu_dN # |a_n(f)| <= tau(n)*sqrt(n) (holds if f is a newform) # tau(n) <= sqrt(3)*sqrt(n) for all n >= 1 # This gives a correct but somewhat coarse lower bound on the # number of terms needed. We ignore rounding errors. / ((abs(eps - 1) + 2) * R(3).sqrt())).log() / mu_dN.log()).ceil()
*((eps - 1) * mu_N ** n + mu_dN ** n * (mu_d ** (n * b) - eps * mu_d ** (n * c))) for n in range(1, numterms + 1))
def lseries(self, embedding=0, prec=53, max_imaginary_part=0, max_asymp_coeffs=40, conjugate=None): r""" Return the L-series of the weight k cusp form `f` on `\Gamma_0(N)`.
This actually returns an interface to Tim Dokchitser's program for computing with the L-series of the cusp form.
INPUT:
- ``embedding`` - either an embedding of the coefficient field of self into `\CC`, or an integer `i` between 0 and D-1 where D is the degree of the coefficient field (meaning to pick the `i`-th embedding). (Default: 0)
- ``prec`` - integer (bits precision). Default: 53.
- ``max_imaginary_part`` - real number. Default: 0.
- ``max_asymp_coeffs`` - integer. Default: 40.
- ``conjugate`` -- deprecated synonym for ``embedding``.
For more information on the significance of the last three arguments, see :mod:`~sage.lfunctions.dokchitser`.
.. note::
If an explicit embedding is given, but this embedding is specified to smaller precision than ``prec``, it will be automatically refined to precision ``prec``.
OUTPUT:
The L-series of the cusp form, as a :class:`sage.lfunctions.dokchitser.Dokchitser` object.
EXAMPLES::
sage: f = CuspForms(2,8).newforms()[0] sage: L = f.lseries() sage: L L-series associated to the cusp form q - 8*q^2 + 12*q^3 + 64*q^4 - 210*q^5 + O(q^6) sage: L(1) 0.0884317737041015 sage: L(0.5) 0.0296568512531983
As a consistency check, we verify that the functional equation holds::
sage: abs(L.check_functional_equation()) < 1.0e-20 True
For non-rational newforms we can specify an embedding of the coefficient field::
sage: f = Newforms(43, names='a')[1] sage: K = f.hecke_eigenvalue_field() sage: phi1, phi2 = K.embeddings(CC) sage: L = f.lseries(embedding=phi1) sage: L L-series associated to the cusp form q + a1*q^2 - a1*q^3 + (-a1 + 2)*q^5 + O(q^6), a1=-1.41421356237310 sage: L(1) 0.620539857407845 sage: L = f.lseries(embedding=1) sage: L(1) 0.921328017272472
For backward-compatibility, ``conjugate`` is accepted as a synonym for ``embedding``::
sage: f.lseries(conjugate=1) doctest:...: DeprecationWarning: The argument 'conjugate' for 'lseries' is deprecated -- use the synonym 'embedding' See http://trac.sagemath.org/19668 for details. L-series associated to the cusp form q + a1*q^2 - a1*q^3 + (-a1 + 2)*q^5 + O(q^6), a1=1.41421356237310
An example with a non-real coefficient field (`\QQ(\zeta_3)` in this case)::
sage: f = Newforms(Gamma1(13), 2, names='a')[0] sage: f.lseries(embedding=0)(1) 0.298115272465799 - 0.0402203326076734*I sage: f.lseries(embedding=1)(1) 0.298115272465799 + 0.0402203326076732*I
We compute with the L-series of the Eisenstein series `E_4`::
sage: f = ModularForms(1,4).0 sage: L = f.lseries() sage: L(1) -0.0304484570583933 sage: L = eisenstein_series_lseries(4) sage: L(1) -0.0304484570583933
Consistency check with delta_lseries (which computes coefficients in pari)::
sage: delta = CuspForms(1,12).0 sage: L = delta.lseries() sage: L(1) 0.0374412812685155 sage: L = delta_lseries() sage: L(1) 0.0374412812685155
We check that :trac:`5262` is fixed::
sage: E = EllipticCurve('37b2') sage: h = Newforms(37)[1] sage: Lh = h.lseries() sage: LE = E.lseries() sage: Lh(1), LE(1) (0.725681061936153, 0.725681061936153) sage: CuspForms(1, 30).0.lseries().eps -1.00000000000000
We can change the precision (in bits)::
sage: f = Newforms(389, names='a')[0] sage: L = f.lseries(prec=30) sage: abs(L(1)) < 2^-30 True sage: L = f.lseries(prec=53) sage: abs(L(1)) < 2^-53 True sage: L = f.lseries(prec=100) sage: abs(L(1)) < 2^-100 True
sage: f = Newforms(27, names='a')[0] sage: L = f.lseries() sage: L(1) 0.588879583428483 """
# compute the requested embedding # Target of embedding might have precision less than desired, so # need to refine else:
# key = (prec, max_imaginary_part, max_asymp_coeffs)
else:
gammaV = [0, 1], weight = l, eps = e, poles = poles, prec = prec) # Find out how many coefficients of the Dirichlet series are needed # in order to compute to the required precision
# renormalize so that coefficient of q is 1
max_imaginary_part=max_imaginary_part, max_asymp_coeffs=max_asymp_coeffs) else: % (self, K.variable_name(), emb(K.gen())))
cuspform_lseries = deprecated_function_alias(16917, lseries)
def symsquare_lseries(self, chi=None, embedding=0, prec=53): r""" Compute the symmetric square L-series of this modular form, twisted by the character `\chi`.
INPUT:
- ``chi`` -- Dirichlet character to twist by, or None (default None, interpreted as the trivial character). - ``embedding`` -- embedding of the coefficient field into `\RR` or `\CC`, or an integer `i` (in which case take the `i`-th embedding) - ``prec`` -- The desired precision in bits (default 53).
OUTPUT: The symmetric square L-series of the cusp form, as a :class:`sage.lfunctions.dokchitser.Dokchitser` object.
EXAMPLES::
sage: CuspForms(1, 12).0.symsquare_lseries()(22) 0.999645711124771
An example twisted by a nontrivial character::
sage: psi = DirichletGroup(7).0^2 sage: L = CuspForms(1, 16).0.symsquare_lseries(psi) sage: L(22) 0.998407750967420 - 0.00295712911510708*I
An example with coefficients not in `\QQ`::
sage: F = Newforms(1, 24, names='a')[0] sage: K = F.hecke_eigenvalue_field() sage: phi = K.embeddings(RR)[0] sage: L = F.symsquare_lseries(embedding=phi) sage: L(5) verbose -1 (...: dokchitser.py, __call__) Warning: Loss of 8 decimal digits due to cancellation -3.57698266793901e19
TESTS::
sage: CuspForms(1,16).0.symsquare_lseries(prec=200).check_functional_equation().abs() < 1.0e-80 True sage: CuspForms(1, 12).0.symsquare_lseries(prec=1000)(22) # long time (20s) 0.999645711124771397835729622033153189549796658647254961493709341358991830134499267117001769570658192128781135161587571716303826382489492569725002840546129937149159065273765309218543427544527498868033604310899372849565046516553245752253255585377793879866297612679545029546953895098375829822346290125161
Check that :trac:`23247` is fixed::
sage: F = Newforms(1,12)[0] sage: chi = DirichletGroup(7).0 sage: abs(F.symsquare_lseries(chi).check_functional_equation()) < 1e-5 True
AUTHORS:
- Martin Raum (2011) -- original code posted to sage-nt - David Loeffler (2015) -- added support for twists, integrated into Sage library """ raise NotImplementedError("Symmetric square L-functions only implemented for level 1")
# compute the requested embedding # Target of embedding might have precision less than desired, so # need to refine else:
else:
eps, prec=prec) else: eps * C((0, 1)), prec=prec)
# utility function for Dirichlet convolution of series for n in range(1, 1 + min(len(A), len(B)))]
# The Dirichlet series for \zeta(2 s - 2 k + 2) for n in xsrange(1, lcoeffs_prec + 1) ] # The Dirichlet series for 1 / \zeta(s - k + 1)
# If the base ring is QQ we pass the coefficients to GP/PARI as exact # rationals. Otherwise, need to use the embedding.
else:
pari_precode=pari_precode)
def petersson_norm(self, embedding=0, prec=53): r""" Compute the Petersson scalar product of f with itself:
.. MATH::
\langle f, f \rangle = \int_{\Gamma_0(N) \backslash \mathbb{H}} |f(x + iy)|^2 y^k\, \mathrm{d}x\, \mathrm{d}y.
Only implemented for N = 1 at present. It is assumed that `f` has real coefficients. The norm is computed as a special value of the symmetric square L-function, using the identity
.. MATH::
\langle f, f \rangle = \frac{(k-1)! L(\mathrm{Sym}^2 f, k)}{2^{2k-1} \pi^{k+1}}
INPUT:
- ``embedding``: embedding of the coefficient field into `\RR` or `\CC`, or an integer `i` (interpreted as the `i`-th embedding) (default: 0) - ``prec`` (integer, default 53): precision in bits
EXAMPLES::
sage: CuspForms(1, 16).0.petersson_norm() verbose -1 (...: dokchitser.py, __call__) Warning: Loss of 2 decimal digits due to cancellation 2.16906134759063e-6
The Petersson norm depends on a choice of embedding::
sage: set_verbose(-2, "dokchitser.py") # disable precision-loss warnings sage: F = Newforms(1, 24, names='a')[0] sage: F.petersson_norm(embedding=0) 0.000107836545077234 sage: F.petersson_norm(embedding=1) 0.000128992800758160
TESTS:
Verify that the Petersson norm is a quadratic form::
sage: F, G = CuspForms(1, 24).basis() sage: X = lambda u: u.petersson_norm(prec=100) sage: (X(F + G) + X(F - G) - 2*X(F) - 2*X(G)).abs() < 1e-25 True """
def _q_expansion_bound(self, eps): r""" This function takes as input a modular form, ``self`` and a Dirichlet character ``eps`` and returns an integer bound such that if ``self`` and its twist by ``eps`` have the same q-expansion up to this bound, then they are equal.
The bound is taken from [Mu1997]_. See also [Shi1971]_, Proposition 3.64.
INPUT:
- ``eps`` -- a Dirichlet character
OUTPUT:
A positive integer.
EXAMPLES:
Here is an example that can easily be checked by hand. ::
sage: M = ModularForms(Gamma0(11), 2) sage: C = M.cuspidal_submodule() sage: f = C.gens()[0] sage: F = CyclotomicField(5) sage: D = DirichletGroup(11, F) sage: eps = D.gens()[0] sage: f._q_expansion_bound(eps) 22
The level of ``self`` does not have to be related to the conductor of eps. ::
sage: M = ModularForms(Gamma0(1), 12) sage: C = M.cuspidal_submodule() sage: Delta = C.gens()[0] sage: F = CyclotomicField(12) sage: D = DirichletGroup(13, F) sage: eps = D.gens()[0] sage: Delta._q_expansion_bound(eps) 182 """ chi.conductor() * eps.conductor()])
@cached_method def has_cm(self): r""" Return whether the modular form ``self`` has complex multiplication.
OUTPUT:
Boolean
.. SEEALSO::
- :meth:`cm_discriminant` (to return the CM field) - :meth:`sage.schemes.elliptic_curves.ell_rational_field.has_cm`
EXAMPLES::
sage: G = DirichletGroup(21); eps = G.0 * G.1 sage: Newforms(eps, 2)[0].has_cm() True
This example illustrates what happens when candidate_characters(self) is the empty list. ::
sage: M = ModularForms(Gamma0(1), 12) sage: C = M.cuspidal_submodule() sage: Delta = C.gens()[0] sage: Delta.has_cm() False
We now compare the function has_cm between elliptic curves and their associated modular forms. ::
sage: E = EllipticCurve([-1, 0]) sage: f = E.modular_form() sage: f.has_cm() True sage: E.has_cm() == f.has_cm() True
Here is a non-cm example coming from elliptic curves. ::
sage: E = EllipticCurve('11a') sage: f = E.modular_form() sage: f.has_cm() False sage: E.has_cm() == f.has_cm() True """
# If there are no candidate characters, then self cannot have CM.
# Test each prime and discard characters for which eps(p) != 1 when f[p] != 0. # We only have to test the CM condition at primes that do not # divide the level of self.
# Evaluating characters is cheap, while computing f[p] is # expensive, so if eps(p) = 1 for all p, then we don't bother to # compute f[p].
# f doesn't have CM return False
# go on to next prime
# can't happen (except in weight 1, which isn't implemented yet # anyway) raise ArithmeticError("Got multiple characters in has_cm")
def cm_discriminant(self): r""" Return the discriminant of the CM field associated to this form. An error will be raised if the form isn't of CM type.
EXAMPLES::
sage: Newforms(49, 2)[0].cm_discriminant() -7 sage: CuspForms(1, 12).gen(0).cm_discriminant() Traceback (most recent call last): ... ValueError: Not a CM form """
class Newform(ModularForm_abstract): def __init__(self, parent, component, names, check=True): r""" Initialize a Newform object.
INPUT:
- ``parent`` - An ambient cuspidal space of modular forms for which self is a newform.
- ``component`` - A simple component of a cuspidal modular symbols space of any sign corresponding to this newform.
- ``check`` - If check is ``True``, check that parent and component have the same weight, level, and character, that component has sign 1 and is simple, and that the types are correct on all inputs.
EXAMPLES::
sage: sage.modular.modform.element.Newform(CuspForms(11,2), ModularSymbols(11,2,sign=1).cuspidal_subspace(), 'a') q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6)
sage: f = Newforms(DirichletGroup(5).0, 7,names='a')[0]; f[2].trace(f.base_ring().base_field()) -5*zeta4 - 5 """ raise TypeError("parent must be a space of modular forms") raise TypeError("component must be a space of modular symbols") raise ValueError("parent and component must be defined by the same congruence subgroup") raise ValueError("parent and component must have the same weight") raise ValueError("component must be cuspidal") raise ValueError("component must be simple")
def _name(self): """ Return the name of the generator of the Hecke eigenvalue field of self. Note that a name exists even when this field is QQ.
EXAMPLES::
sage: [ f._name() for f in Newforms(38,4,names='a') ] ['a0', 'a1', 'a2'] """
def _compute_q_expansion(self, prec): """ Return the q-expansion of self to precision prec.
EXAMPLES::
sage: forms = Newforms(31, 6, names='a') sage: forms[0]._compute_q_expansion(10) q + a0*q^2 + (5/704*a0^4 + 43/704*a0^3 - 61/88*a0^2 - 197/44*a0 + 717/88)*q^3 + (a0^2 - 32)*q^4 + (-31/352*a0^4 - 249/352*a0^3 + 111/22*a0^2 + 218/11*a0 - 2879/44)*q^5 + (-1/352*a0^4 - 79/352*a0^3 - 67/44*a0^2 + 13/22*a0 - 425/44)*q^6 + (17/88*a0^4 + 133/88*a0^3 - 405/44*a0^2 - 1005/22*a0 - 35/11)*q^7 + (a0^3 - 64*a0)*q^8 + (39/352*a0^4 + 441/352*a0^3 - 93/44*a0^2 - 441/22*a0 - 5293/44)*q^9 + O(q^10) sage: forms[0]._compute_q_expansion(15) q + a0*q^2 + (5/704*a0^4 + 43/704*a0^3 - 61/88*a0^2 - 197/44*a0 + 717/88)*q^3 + (a0^2 - 32)*q^4 + (-31/352*a0^4 - 249/352*a0^3 + 111/22*a0^2 + 218/11*a0 - 2879/44)*q^5 + (-1/352*a0^4 - 79/352*a0^3 - 67/44*a0^2 + 13/22*a0 - 425/44)*q^6 + (17/88*a0^4 + 133/88*a0^3 - 405/44*a0^2 - 1005/22*a0 - 35/11)*q^7 + (a0^3 - 64*a0)*q^8 + (39/352*a0^4 + 441/352*a0^3 - 93/44*a0^2 - 441/22*a0 - 5293/44)*q^9 + (15/176*a0^4 - 135/176*a0^3 - 185/11*a0^2 + 311/11*a0 + 2635/22)*q^10 + (-291/704*a0^4 - 3629/704*a0^3 + 1139/88*a0^2 + 10295/44*a0 - 21067/88)*q^11 + (-75/176*a0^4 - 645/176*a0^3 + 475/22*a0^2 + 1503/11*a0 - 5651/22)*q^12 + (207/704*a0^4 + 2977/704*a0^3 + 581/88*a0^2 - 3307/44*a0 - 35753/88)*q^13 + (-5/22*a0^4 + 39/11*a0^3 + 763/22*a0^2 - 2296/11*a0 - 2890/11)*q^14 + O(q^15) """
def __eq__(self, other): """ Return True if self equals other, and False otherwise.
EXAMPLES::
sage: f1, f2 = Newforms(17,4,names='a') sage: f1.__eq__(f1) True sage: f1.__eq__(f2) False
We test comparison of equal newforms with different parents (see :trac:`18478`)::
sage: f = Newforms(Gamma1(11), 2)[0]; f q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) sage: g = Newforms(Gamma0(11), 2)[0]; g q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) sage: f == g True
sage: f = Newforms(DirichletGroup(4)[1], 5)[0]; f q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6) sage: g = Newforms(Gamma1(4), 5)[0]; g q - 4*q^2 + 16*q^4 - 14*q^5 + O(q^6) sage: f == g True
""" or self.weight() != other.weight()): return False self.character() != other.character()): # The two parents may have different Sturm bounds in case # one of them is a space of cusp forms with character # (possibly trivial, i.e. for the group Gamma0(n)) and the # other is a space of cusp forms for Gamma1(n). It is # safe to take the smaller bound because we have checked # that the characters agree. other.parent().sturm_bound()) # other is a ModularFormElement
def abelian_variety(self): """ Return the abelian variety associated to self.
EXAMPLES::
sage: Newforms(14,2)[0] q - q^2 - 2*q^3 + q^4 + O(q^6) sage: Newforms(14,2)[0].abelian_variety() Newform abelian subvariety 14a of dimension 1 of J0(14) sage: Newforms(1, 12)[0].abelian_variety() Traceback (most recent call last): ... TypeError: f must have weight 2
"""
def hecke_eigenvalue_field(self): r""" Return the field generated over the rationals by the coefficients of this newform.
EXAMPLES::
sage: ls = Newforms(35, 2, names='a') ; ls [q + q^3 - 2*q^4 - q^5 + O(q^6), q + a1*q^2 + (-a1 - 1)*q^3 + (-a1 + 2)*q^4 + q^5 + O(q^6)] sage: ls[0].hecke_eigenvalue_field() Rational Field sage: ls[1].hecke_eigenvalue_field() Number Field in a1 with defining polynomial x^2 + x - 4 """
def coefficient(self, n): """ Return the coefficient of `q^n` in the power series of self.
INPUT:
- ``n`` - a positive integer
OUTPUT:
- the coefficient of `q^n` in the power series of self.
EXAMPLES::
sage: f = Newforms(11)[0]; f q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) sage: f.coefficient(100) -8
sage: g = Newforms(23, names='a')[0]; g q + a0*q^2 + (-2*a0 - 1)*q^3 + (-a0 - 1)*q^4 + 2*a0*q^5 + O(q^6) sage: g.coefficient(3) -2*a0 - 1 """
def _compute(self, X): """ Compute the coefficients of `q^n` of the power series of self, for `n` in the list `X`. The results are not cached. (Use coefficients for cached results).
EXAMPLES::
sage: f = Newforms(39,4,names='a')[1] ; f q + a1*q^2 - 3*q^3 + (2*a1 + 5)*q^4 + (-2*a1 + 14)*q^5 + O(q^6) sage: f._compute([2,3,7]) [a1, -3, -2*a1 + 2] sage: f._compute([]) []
Check that :trac:`20793` is fixed::
sage: f = Newforms(83, 2, names='a')[1]; f q + a1*q^2 + (1/2*a1^4 - 1/2*a1^3 - 7/2*a1^2 + 3/2*a1 + 4)*q^3 + (a1^2 - 2)*q^4 + (-1/2*a1^5 - 1/2*a1^4 + 9/2*a1^3 + 7/2*a1^2 - 8*a1 - 2)*q^5 + O(q^6) sage: K = f.hecke_eigenvalue_field(); K Number Field in a1 with defining polynomial x^6 - x^5 - 9*x^4 + 7*x^3 + 20*x^2 - 12*x - 8 sage: l = f.coefficients(20); l[-1] -a1^4 + 5*a1^2 - 4 sage: l[-1].parent() is K True """
def element(self): """ Find an element of the ambient space of modular forms which represents this newform.
.. note::
This can be quite expensive. Also, the polynomial defining the field of Hecke eigenvalues should be considered random, since it is generated by a random sum of Hecke operators. (The field itself is not random, of course.)
EXAMPLES::
sage: ls = Newforms(38,4,names='a') sage: ls[0] q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6) sage: ls # random [q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6), q - 2*q^2 + (-a1 - 2)*q^3 + 4*q^4 + (2*a1 + 10)*q^5 + O(q^6), q + 2*q^2 + (1/2*a2 - 1)*q^3 + 4*q^4 + (-3/2*a2 + 12)*q^5 + O(q^6)] sage: type(ls[0]) <class 'sage.modular.modform.element.Newform'> sage: ls[2][3].minpoly() x^2 - 9*x + 2 sage: ls2 = [ x.element() for x in ls ] sage: ls2 # random [q - 2*q^2 - 2*q^3 + 4*q^4 - 9*q^5 + O(q^6), q - 2*q^2 + (-a1 - 2)*q^3 + 4*q^4 + (2*a1 + 10)*q^5 + O(q^6), q + 2*q^2 + (1/2*a2 - 1)*q^3 + 4*q^4 + (-3/2*a2 + 12)*q^5 + O(q^6)] sage: type(ls2[0]) <class 'sage.modular.modform.cuspidal_submodule.CuspidalSubmodule_g0_Q_with_category.element_class'> sage: ls2[2][3].minpoly() x^2 - 9*x + 2 """
def is_cuspidal(self): """ Return True. For compatibility with elements of modular forms spaces.
EXAMPLES::
sage: Newforms(11, 2)[0].is_cuspidal() True """
def modular_symbols(self, sign=0): """ Return the subspace with the specified sign of the space of modular symbols corresponding to this newform.
EXAMPLES::
sage: f = Newforms(18,4)[0] sage: f.modular_symbols() Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 18 for Gamma_0(18) of weight 4 with sign 0 over Rational Field sage: f.modular_symbols(1) Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 11 for Gamma_0(18) of weight 4 with sign 1 over Rational Field """
@cached_method def modsym_eigenspace(self, sign=0): """ Return a submodule of dimension 1 or 2 of the ambient space of the sign 0 modular symbols space associated to ``self``, base-extended to the Hecke eigenvalue field, which is an eigenspace for the Hecke operators with the same eigenvalues as this newform, *and* is an eigenspace for the star involution of the appropriate sign if the sign is not 0.
EXAMPLES::
sage: N = Newform("37a") sage: N.modular_symbols(0) Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 5 for Gamma_0(37) of weight 2 with sign 0 over Rational Field sage: M = N.modular_symbols(0) sage: V = N.modsym_eigenspace(1); V Vector space of degree 5 and dimension 1 over Rational Field Basis matrix: [ 0 1 -1 1 0] sage: V.0 in M.free_module() True sage: V=N.modsym_eigenspace(-1); V Vector space of degree 5 and dimension 1 over Rational Field Basis matrix: [ 0 0 0 1 -1/2] sage: V.0 in M.free_module() True """ else: # silly thing: can't do Ms.eigenvector(), even when Ms is simple, # because it can't be relied on to choose the coefficient fields # consistently
# should really return a modular symbol submodule object, but these are # not implemented over non-minimal base rings
def _defining_modular_symbols(self): """ Return the modular symbols space corresponding to self.
EXAMPLES::
sage: Newforms(43,2,names='a') [q - 2*q^2 - 2*q^3 + 2*q^4 - 4*q^5 + O(q^6), q + a1*q^2 - a1*q^3 + (-a1 + 2)*q^5 + O(q^6)] sage: [ x._defining_modular_symbols() for x in Newforms(43,2,names='a') ] [Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field] sage: ModularSymbols(43,2,sign=1).cuspidal_subspace().new_subspace().decomposition() [ Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field, Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 4 for Gamma_0(43) of weight 2 with sign 1 over Rational Field ] """
def number(self): """ Return the index of this space in the list of simple, new, cuspidal subspaces of the full space of modular symbols for this weight and level.
EXAMPLES::
sage: Newforms(43, 2, names='a')[1].number() 1 """
def __bool__(self): """ Return ``True``, as newforms are never zero.
EXAMPLES::
sage: bool(Newforms(14,2)[0]) True """
__nonzero__ = __bool__
def character(self): r""" The nebentypus character of this newform (as a Dirichlet character with values in the field of Hecke eigenvalues of the form).
EXAMPLES::
sage: Newforms(Gamma1(7), 4,names='a')[1].character() Dirichlet character modulo 7 of conductor 7 mapping 3 |--> 1/2*a1 sage: chi = DirichletGroup(3).0; Newforms(chi, 7)[0].character() == chi True """
########################### # Atkin--Lehner operators # ###########################
def _atkin_lehner_action_from_qexp(self, Q, embedding=None): """ Return the result of the Atkin-Lehner operator `W_Q` on ``self``, using a formula based on `q`-expansions.
INPUT:
- ``self`` -- a newform `f`
- ``Q`` -- a prime power exactly dividing the level of ``self``
- ``embedding`` -- (optional) embedding of the coefficient field of `f` into a field containing the relevant Gauss sums
OUTPUT:
A pair `(w, f^*)` where `f^*` is a :class:`Newform` and `w` is a scalar such that `W_Q f = w f^*`. The parent of `w` is the codomain of ``embedding`` if specified, otherwise it is (a suitable extension of) the coefficient field of `f`.
.. NOTE::
This method assumes that the `Q`-th coefficient in the `q`-expansion of ``self`` is non-zero.
TESTS::
sage: f = Newforms(Gamma0(18), 4)[0]; f q + 2*q^2 + 4*q^4 - 6*q^5 + O(q^6) sage: f._atkin_lehner_action_from_qexp(2) (-2, q + 2*q^2 + 4*q^4 - 6*q^5 + O(q^6)) sage: f._atkin_lehner_action_from_qexp(9) Traceback (most recent call last): ... ValueError: a_Q must be nonzero
An example with odd weight::
sage: f = Newforms(Gamma1(15), 3, names='a')[2]; f q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6) sage: f._atkin_lehner_action_from_qexp(5) (a2, q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6))
"""
else: # eps_Q is primitive of conductor Q
def _atkin_lehner_action_from_modsym(self, d, embedding=None): """ Return the result of the Atkin-Lehner operator `W_d` on ``self``, using the action of `W_d` on modular symbols.
INPUT:
- ``self`` -- a newform `f`
- ``d`` -- a positive integer exactly dividing the level of ``self``
- ``embedding`` -- (optional) embedding of the coefficient field of `f` into a field containing the relevant Gauss sums
OUTPUT:
A pair `(w, f^*)` where `f^*` is a :class:`Newform` and `w` is a scalar such that `W_d f = w f^*`. The parent of `w` is the codomain of ``embedding`` if specified, otherwise it is (a suitable extension of) the coefficient field of `f`.
.. NOTE::
This algorithm only works if the character of `f` is trivial at `d`, so `f^* = f`. Nonetheless we return the pair `(w, f)` for consistency.
EXAMPLES::
sage: F = Newforms(Gamma1(15), 3, names='a')[2] sage: F._atkin_lehner_action_from_modsym(5) (a2, q + a2*q^2 + (-a2 - 2)*q^3 - q^4 - a2*q^5 + O(q^6)) sage: _ == F._atkin_lehner_action_from_qexp(5) True """ raise ValueError("character must be trivial at d")
def atkin_lehner_action(self, d, embedding=None): """ Return the result of the Atkin-Lehner operator `W_d` on ``self``.
INPUT:
- ``d`` -- a positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d`
- ``embedding`` -- (optional) embedding of the base ring of ``self`` into another ring
OUTPUT:
A pair `(w, f^*)` where `f^*` is a :class:`Newform` and `w` is a scalar such that `W_d f = w f^*`. This `w` is called the Atkin-Lehner pseudo-eigenvalue of `W_d` acting on `f`.
The parent of `w` is the codomain of ``embedding`` if specified, otherwise it is (a suitable extension of) the coefficient field of `f`.
ALGORITHM:
The action is computed using the results of [AL1978]_, Sections 1 and 2.
.. SEEALSO::
For the conventions used to define the operator `W_d`, see :meth:`ModularForm_abstract.atkin_lehner_action`.
EXAMPLES::
sage: f = Newforms(Gamma1(30), 2, names='a')[1] sage: emb = f.base_ring().complex_embeddings()[0] sage: for d in divisors(30): ....: print(f.atkin_lehner_action(d, embedding=emb)) (1.00000000000000, q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6)) (1.00000000000000*I, q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6)) (-1.00000000000000*I, q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6)) (-0.894427190999916 + 0.447213595499958*I, q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6)) (1.00000000000000, q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6)) (-0.447213595499958 - 0.894427190999916*I, q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6)) (0.447213595499958 + 0.894427190999916*I, q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6)) (-0.894427190999916 + 0.447213595499958*I, q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6))
The above computation can also be done exactly:
sage: K.<z> = CyclotomicField(20) # long time sage: g = Newforms(Gamma1(30), 2, K, names='a')[1] # long time sage: for d in divisors(30): # long time ....: print(g.atkin_lehner_action(d)) # long time (1, q - z^5*q^2 + z^5*q^3 - q^4 + (-z^5 - 2)*q^5 + O(q^6)) (z^5, q - z^5*q^2 + z^5*q^3 - q^4 + (-z^5 - 2)*q^5 + O(q^6)) (-z^5, q - z^5*q^2 + z^5*q^3 - q^4 + (-z^5 - 2)*q^5 + O(q^6)) (2/5*z^7 + 4/5*z^6 - 1/5*z^5 - 4/5*z^4 + 2/5*z^3 - 2/5, q + z^5*q^2 - z^5*q^3 - q^4 + (z^5 - 2)*q^5 + O(q^6)) (1, q - z^5*q^2 + z^5*q^3 - q^4 + (-z^5 - 2)*q^5 + O(q^6)) (-4/5*z^7 + 2/5*z^6 + 2/5*z^5 - 2/5*z^4 - 4/5*z^3 - 1/5, q + z^5*q^2 - z^5*q^3 - q^4 + (z^5 - 2)*q^5 + O(q^6)) (4/5*z^7 - 2/5*z^6 - 2/5*z^5 + 2/5*z^4 + 4/5*z^3 + 1/5, q + z^5*q^2 - z^5*q^3 - q^4 + (z^5 - 2)*q^5 + O(q^6)) (2/5*z^7 + 4/5*z^6 - 1/5*z^5 - 4/5*z^4 + 2/5*z^3 - 2/5, q + z^5*q^2 - z^5*q^3 - q^4 + (z^5 - 2)*q^5 + O(q^6))
We can compute the eigenvalue of `W_{p^e}` in certain cases where the `p`-th coefficient of `f` is zero:
sage: f = Newforms(169, names='a')[0]; f q + a0*q^2 + 2*q^3 + q^4 - a0*q^5 + O(q^6) sage: f[13] 0 sage: f.atkin_lehner_eigenvalue(169) -1
TESTS::
sage: K.<a> = QuadraticField(1129) sage: f = Newforms(Gamma0(20), 8, base_ring=K)[2]; f q + (2*a - 10)*q^3 + 125*q^5 + O(q^6) sage: f.atkin_lehner_action(2) (-1, q + (2*a - 10)*q^3 + 125*q^5 + O(q^6))
sage: f = Newforms(Gamma1(11), 2)[0] sage: f.atkin_lehner_action(2) Traceback (most recent call last): ... ValueError: d (= 2) does not divide the level (= 11)
""" # normalise d
else: raise NotImplementedError("Unable to determine local constant at prime %s" % q)
def twist(self, chi, level=None, check=True): r""" Return the twist of the newform ``self`` by the Dirichlet character ``chi``.
If ``self`` is a newform `f` with character `\epsilon` and `q`-expansion
.. MATH::
f(q) = \sum_{n=1}^\infty a_n q^n,
then the twist by `\chi` is the unique newform `f\otimes\chi` with character `\epsilon\chi^2` and `q`-expansion
.. MATH::
(f\otimes\chi)(q) = \sum_{n=1}^\infty b_n q^n
satisfying `b_n = \chi(n) a_n` for all but finitely many `n`.
INPUT:
- ``chi`` -- a Dirichlet character. Note that Sage must be able to determine a common base field into which both the Hecke eigenvalue field of self, and the field of values of ``chi``, can be embedded.
- ``level`` -- (optional) the level `N` of the twisted form. By default, the algorithm tries to compute `N` using [AL1978]_, Theorem 3.1.
- ``check`` -- (optional) boolean; if ``True`` (default), ensure that the space of modular symbols that is computed is genuinely simple and new. This makes it less likely that a wrong result is returned if an incorrect ``level`` is specified.
OUTPUT:
The form `f\otimes\chi` as an element of the set of newforms for `\Gamma_1(N)` with character `\epsilon\chi^2`.
EXAMPLES::
sage: G = DirichletGroup(3, base_ring=QQ) sage: Delta = Newforms(SL2Z, 12)[0]; Delta q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) sage: Delta.twist(G[0]) == Delta True sage: Delta.twist(G[1]) # long time (about 5 s) q + 24*q^2 - 1472*q^4 - 4830*q^5 + O(q^6)
sage: M = CuspForms(Gamma1(13), 2) sage: f = M.newforms('a')[0]; f q + a0*q^2 + (-2*a0 - 4)*q^3 + (-a0 - 1)*q^4 + (2*a0 + 3)*q^5 + O(q^6) sage: f.twist(G[1]) q - a0*q^2 + (-a0 - 1)*q^4 + (-2*a0 - 3)*q^5 + O(q^6)
sage: f = Newforms(Gamma1(30), 2, names='a')[1]; f q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6) sage: f.twist(f.character()) Traceback (most recent call last): ... NotImplementedError: cannot calculate 5-primary part of the level of the twist of q + a1*q^2 - a1*q^3 - q^4 + (a1 - 2)*q^5 + O(q^6) by Dirichlet character modulo 5 of conductor 5 mapping 2 |--> -1 sage: f.twist(f.character(), level=30) q - a1*q^2 + a1*q^3 - q^4 + (-a1 - 2)*q^5 + O(q^6)
TESTS:
We test that feeding inappropriate values of the ``level`` parameter is handled gracefully::
sage: chi = DirichletGroup(1)[0] sage: Delta.twist(chi, level=3) Traceback (most recent call last): ... ValueError: twist of q - 24*q^2 + 252*q^3 - 1472*q^4 + 4830*q^5 + O(q^6) by Dirichlet character modulo 1 of conductor 1 is not a newform of level 3
Twisting and twisting back works::
sage: f = Newforms(11)[0] sage: chi = DirichletGroup(5).0 sage: f.twist(chi).twist(~chi, level=11) == f True
AUTHORS:
- Peter Bruin (April 2015)
""" # See [AL1978], Theorem 3.1. continue % (q, self, chi))
# determine the character of the twisted form
# create an ambient space
# pull out the eigenspace continue else: raise RuntimeError('unable to identify modular symbols for twist of %s by %s' % (self, chi))
class ModularFormElement(ModularForm_abstract, element.HeckeModuleElement): def __init__(self, parent, x, check=True): r""" An element of a space of modular forms.
INPUT:
- ``parent`` - ModularForms (an ambient space of modular forms)
- ``x`` - a vector on the basis for parent
- ``check`` - if check is ``True``, check the types of the inputs.
OUTPUT:
- ``ModularFormElement`` - a modular form
EXAMPLES::
sage: M = ModularForms(Gamma0(11),2) sage: f = M.0 sage: f.parent() Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field """ raise TypeError("First argument must be an ambient space of modular forms.")
def _compute_q_expansion(self, prec): """ Computes the q-expansion of self to precision prec.
EXAMPLES::
sage: f = EllipticCurve('37a').modular_form() sage: f.q_expansion() ## indirect doctest q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6)
sage: f._compute_q_expansion(10) q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + 6*q^6 - q^7 + 6*q^9 + O(q^10) """
def _add_(self, other): """ Add self to other.
EXAMPLES::
sage: f = ModularForms(DirichletGroup(17).0^2,2).2 sage: g = ModularForms(DirichletGroup(17).0^2,2).1 sage: f q + (-zeta8^2 + 2)*q^2 + (zeta8 + 3)*q^3 + (-2*zeta8^2 + 3)*q^4 + (-zeta8 + 5)*q^5 + O(q^6)
sage: g 1 + (-14/73*zeta8^3 + 57/73*zeta8^2 + 13/73*zeta8 - 6/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 - 52/73*zeta8 + 24/73)*q^3 + (-81/73*zeta8^3 + 189/73*zeta8^2 - 3/73*zeta8 + 153/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 100/73*zeta8 + 156/73)*q^5 + O(q^6)
sage: f+g ## indirect doctest 1 + q + (-14/73*zeta8^3 - 16/73*zeta8^2 + 13/73*zeta8 + 140/73)*q^2 + (-90/73*zeta8^3 + 64/73*zeta8^2 + 21/73*zeta8 + 243/73)*q^3 + (-81/73*zeta8^3 + 43/73*zeta8^2 - 3/73*zeta8 + 372/73)*q^4 + (72/73*zeta8^3 + 124/73*zeta8^2 + 27/73*zeta8 + 521/73)*q^5 + O(q^6) """
def __mul__(self, other): r""" Calculate the product self * other.
This tries to determine the characters of self and other, in order to avoid having to compute a (potentially very large) Gamma1 space. Note that this might lead to a modular form that is defined with respect to a larger subgroup than the factors are.
An example with character::
sage: f = ModularForms(DirichletGroup(3).0, 3).0 sage: f * f 1 + 108*q^2 + 144*q^3 + 2916*q^4 + 8640*q^5 + O(q^6) sage: (f*f).parent() Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(3) of weight 6 over Rational Field sage: (f*f*f).parent() Modular Forms space of dimension 4, character [-1] and weight 9 over Rational Field
An example where the character is computed on-the-fly::
sage: f = ModularForms(Gamma1(3), 5).0 sage: f*f 1 - 180*q^2 - 480*q^3 + 8100*q^4 + 35712*q^5 + O(q^6) sage: (f*f).parent() Modular Forms space of dimension 4 for Congruence Subgroup Gamma0(3) of weight 10 over Rational Field
sage: f = ModularForms(Gamma1(3), 7).0 sage: f*f q^2 - 54*q^4 + 128*q^5 + O(q^6) sage: (f*f).parent() Modular Forms space of dimension 5 for Congruence Subgroup Gamma0(3) of weight 14 over Rational Field
An example with no character::
sage: f = ModularForms(Gamma1(5), 2).0 sage: f*f 1 + 120*q^3 - 240*q^4 + 480*q^5 + O(q^6) sage: (f*f).parent() Modular Forms space of dimension 5 for Congruence Subgroup Gamma1(5) of weight 4 over Rational Field
TESTS:
This shows that the issue at :trac:`7548` is fixed::
sage: M = CuspForms(Gamma0(5*3^2), 2) sage: f = M.basis()[0] sage: 2*f 2*q - 2*q^4 + O(q^6) sage: f*2 2*q - 2*q^4 + O(q^6) """
# boring case: scalar multiplication
# first ensure the levels are equal raise NotImplementedError("Cannot multiply forms of different levels")
# find out about characters
# now do the math else:
modform_lseries = deprecated_function_alias(16917, ModularForm_abstract.lseries)
def atkin_lehner_action(self, d, embedding=None): """ Return the result of the Atkin-Lehner operator `W_d` on ``self``.
INPUT:
- ``d`` -- a positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d`
- ``embedding`` -- ignored (but accepted for compatibility with :meth:`Newform.atkin_lehner_action`)
OUTPUT:
The Atkin-Lehner eigenvalue of `W_d` on ``self``. This is either `1` or `-1`.
If ``self`` is not an eigenform for `W_d`, a ``ValueError`` is raised.
.. SEEALSO::
For the conventions used to define the operator `W_d`, see :meth:`ModularForm_abstract.atkin_lehner_action`.
EXAMPLES::
sage: CuspForms(1, 30).0.atkin_lehner_eigenvalue() 1 sage: CuspForms(2, 8).0.atkin_lehner_eigenvalue() Traceback (most recent call last): ... NotImplementedError: Don't know how to compute Atkin-Lehner matrix acting on this space (try using a newform constructor instead) """ + " (try using a newform constructor instead)") elif f == -self: return QQ(-1), f else: raise ValueError("%r is not an eigenform for W_%r" % (self, d))
def twist(self, chi, level=None): r""" Return the twist of the modular form ``self`` by the Dirichlet character ``chi``.
If ``self`` is a modular form `f` with character `\epsilon` and `q`-expansion
.. MATH::
f(q) = \sum_{n=0}^\infty a_n q^n,
then the twist by `\chi` is a modular form `f_\chi` with character `\epsilon\chi^2` and `q`-expansion
.. MATH::
f_\chi(q) = \sum_{n=0}^\infty \chi(n) a_n q^n.
INPUT:
- ``chi`` -- a Dirichlet character
- ``level`` -- (optional) the level `N` of the twisted form. By default, the algorithm chooses some not necessarily minimal value for `N` using [AL1978]_, Proposition 3.1, (See also [Kob1993]_, Proposition III.3.17, for a simpler but slightly weaker bound.)
OUTPUT:
The form `f_\chi` as an element of the space of modular forms for `\Gamma_1(N)` with character `\epsilon\chi^2`.
EXAMPLES::
sage: f = CuspForms(11, 2).0 sage: f.parent() Cuspidal subspace of dimension 1 of Modular Forms space of dimension 2 for Congruence Subgroup Gamma0(11) of weight 2 over Rational Field sage: f.q_expansion(6) q - 2*q^2 - q^3 + 2*q^4 + q^5 + O(q^6) sage: eps = DirichletGroup(3).0 sage: eps.parent() Group of Dirichlet characters modulo 3 with values in Cyclotomic Field of order 2 and degree 1 sage: f_eps = f.twist(eps) sage: f_eps.parent() Cuspidal subspace of dimension 9 of Modular Forms space of dimension 16 for Congruence Subgroup Gamma0(99) of weight 2 over Cyclotomic Field of order 2 and degree 1 sage: f_eps.q_expansion(6) q + 2*q^2 + 2*q^4 - q^5 + O(q^6)
Modular forms without character are supported::
sage: M = ModularForms(Gamma1(5), 2) sage: f = M.gen(0); f 1 + 60*q^3 - 120*q^4 + 240*q^5 + O(q^6) sage: chi = DirichletGroup(2)[0] sage: f.twist(chi) 60*q^3 + 240*q^5 + O(q^6)
The base field of the twisted form is extended if necessary::
sage: E4 = ModularForms(1, 4).gen(0) sage: E4.parent() Modular Forms space of dimension 1 for Modular Group SL(2,Z) of weight 4 over Rational Field sage: chi = DirichletGroup(5)[1] sage: chi.base_ring() Cyclotomic Field of order 4 and degree 2 sage: E4_chi = E4.twist(chi) sage: E4_chi.parent() Modular Forms space of dimension 10, character [-1] and weight 4 over Cyclotomic Field of order 4 and degree 2
REFERENCES:
- [AL1978]_
- [Kob1993]_
AUTHORS:
- \L. J. P. Kilford (2009-08-28)
- Peter Bruin (2015-03-30)
""" # See [AL1978], Proposition 3.1. else: # See [AL1978], Proposition 3.1.
class ModularFormElement_elliptic_curve(ModularFormElement): r""" A modular form attached to an elliptic curve over `\QQ`. """ def __init__(self, parent, E): """ Modular form attached to an elliptic curve as an element of a space of modular forms.
EXAMPLES::
sage: E = EllipticCurve('5077a') sage: f = E.modular_form() sage: f q - 2*q^2 - 3*q^3 + 2*q^4 - 4*q^5 + O(q^6) sage: f.q_expansion(10) q - 2*q^2 - 3*q^3 + 2*q^4 - 4*q^5 + 6*q^6 - 4*q^7 + 6*q^9 + O(q^10) sage: f.parent() Modular Forms space of dimension 423 for Congruence Subgroup Gamma0(5077) of weight 2 over Rational Field
sage: E = EllipticCurve('37a') sage: f = E.modular_form() ; f q - 2*q^2 - 3*q^3 + 2*q^4 - 2*q^5 + O(q^6) sage: f == loads(dumps(f)) True """ ## parent.find_in_space( E.q_expansion(parent.hecke_bound()) ))
def elliptic_curve(self): """ Return elliptic curve associated to self.
EXAMPLES::
sage: E = EllipticCurve('11a') sage: f = E.modular_form() sage: f.elliptic_curve() Elliptic Curve defined by y^2 + y = x^3 - x^2 - 10*x - 20 over Rational Field sage: f.elliptic_curve() is E True """
def _compute_element(self): """ Compute self as a linear combination of the basis elements of parent.
EXAMPLES::
sage: EllipticCurve('11a1').modular_form()._compute_element() (1, 0) sage: EllipticCurve('389a1').modular_form()._compute_element() (1, -2, -2, 2, -3, 4, -5, 0, 1, 6, -4, -4, -3, 10, 6, -4, -6, -2, 5, -6, 10, 8, -4, 0, 4, 6, 4, -10, -6, -12, 4, 8, 0) """ ## return S.find_in_space( self.__E.q_expansion( S.q_expansion_basis()[0].prec() ) ) + [0] * ( M.dimension() - S.dimension() )
def _compute_q_expansion(self, prec): r""" The `q`-expansion of the modular form to precision `O(q^\text{prec})`. This function takes one argument, which is the integer prec.
EXAMPLES::
sage: E = EllipticCurve('11a') ; f = E.modular_form() sage: f._compute_q_expansion(10) q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10)
sage: f._compute_q_expansion(30) q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 - 2*q^10 + q^11 - 2*q^12 + 4*q^13 + 4*q^14 - q^15 - 4*q^16 - 2*q^17 + 4*q^18 + 2*q^20 + 2*q^21 - 2*q^22 - q^23 - 4*q^25 - 8*q^26 + 5*q^27 - 4*q^28 + O(q^30)
sage: f._compute_q_expansion(10) q - 2*q^2 - q^3 + 2*q^4 + q^5 + 2*q^6 - 2*q^7 - 2*q^9 + O(q^10) """
def atkin_lehner_action(self, d, embedding=None): """ Return the result of the Atkin-Lehner operator `W_d` on ``self``.
INPUT:
- ``d`` -- a positive integer exactly dividing the level `N` of ``self``, i.e. `d` divides `N` and is coprime to `N/d`
- ``embedding`` -- ignored (but accepted for compatibility with :meth:`Newform.atkin_lehner_action`)
OUTPUT:
The pair ``(w, self)`` where `w` is the Atkin-Lehner eigenvalue of `W_d` on ``self``. This is either `1` or `-1`.
EXAMPLES::
sage: EllipticCurve('57a1').newform().atkin_lehner_eigenvalue() 1 sage: EllipticCurve('57b1').newform().atkin_lehner_eigenvalue() -1 sage: EllipticCurve('57b1').newform().atkin_lehner_eigenvalue(19) 1 """ else: # The space of modular symbols attached to E is # one-dimensional.
class EisensteinSeries(ModularFormElement): """ An Eisenstein series.
EXAMPLES::
sage: E = EisensteinForms(1,12) sage: E.eisenstein_series() [ 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6) ] sage: E = EisensteinForms(11,2) sage: E.eisenstein_series() [ 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) ] sage: E = EisensteinForms(Gamma1(7),2) sage: E.set_precision(4) sage: E.eisenstein_series() [ 1/4 + q + 3*q^2 + 4*q^3 + O(q^4), 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4) ] """ def __init__(self, parent, vector, t, chi, psi): """ An Eisenstein series.
EXAMPLES::
sage: E = EisensteinForms(1,12) ## indirect doctest sage: E.eisenstein_series() [ 691/65520 + q + 2049*q^2 + 177148*q^3 + 4196353*q^4 + 48828126*q^5 + O(q^6) ] sage: E = EisensteinForms(11,2) sage: E.eisenstein_series() [ 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + O(q^6) ] sage: E = EisensteinForms(Gamma1(7),2) sage: E.set_precision(4) sage: E.eisenstein_series() [ 1/4 + q + 3*q^2 + 4*q^3 + O(q^4), 1/7*zeta6 - 3/7 + q + (-2*zeta6 + 1)*q^2 + (3*zeta6 - 2)*q^3 + O(q^4), q + (-zeta6 + 2)*q^2 + (zeta6 + 2)*q^3 + O(q^4), -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + O(q^4), q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + O(q^4) ] """ raise ArithmeticError("Incompatible moduli") raise ArithmeticError("Incompatible base rings") #if not isinstance(t, int): raise TypeError, "weight must be an int" and psi.is_trivial() and t==1: raise ArithmeticError("If chi and psi are trivial and k=2, then t must be >1.")
def _compute_q_expansion(self, prec=None): """ Compute the q-expansion of self to precision prec.
EXAMPLES::
sage: EisensteinForms(11,2).eisenstein_series()[0]._compute_q_expansion(10) 5/12 + q + 3*q^2 + 4*q^3 + 7*q^4 + 6*q^5 + 12*q^6 + 8*q^7 + 15*q^8 + 13*q^9 + O(q^10) """ prec = self.parent().prec()
def _compute(self, X): r""" Compute the coefficients of `q^n` of the power series of self, for `n` in the list `X`. The results are not cached. (Use coefficients for cached results).
EXAMPLES::
sage: e = DirichletGroup(11).gen() sage: f = EisensteinForms(e, 3).eisenstein_series()[0] sage: f._compute([3,4,5]) [-9*zeta10^3 + 1, 16*zeta10^2 + 4*zeta10 + 1, 25*zeta10^3 - 25*zeta10^2 + 25*zeta10 - 24]
""" else: # general case
def __compute_weight2_trivial_character(self, X): r""" Compute coefficients for self an Eisenstein series of the form `E_2 - t*E_2(q^t)`. Computes `a_n` for each `n \in X`.
EXAMPLES::
sage: EisensteinForms(14,2).eisenstein_series()[0]._EisensteinSeries__compute_weight2_trivial_character([0]) [1/24] sage: EisensteinForms(14,2).eisenstein_series()[0]._EisensteinSeries__compute_weight2_trivial_character([0,4,11,38]) [1/24, 1, 12, 20] """ pass else:
def __compute_general_case(self, X): """ Returns the list coefficients of `q^n` of the power series of self, for `n` in the list `X`. The results are not cached. (Use coefficients for cached results).
General case (except weight 2, trivial character, where this is wrong!) `\chi` is a primitive character of conductor `L` `\psi` is a primitive character of conductor `M` We have `MLt \mid N`, and
.. MATH::
E_k(chi,psi,t) = c_0 + sum_{m \geq 1}[sum_{n|m} psi(n) * chi(m/n) * n^(k-1)] q^{mt},
with `c_0=0` if `L>1`, and `c_0=L(1-k,psi)/2` if `L=1` (that second `L` is an `L`-function `L`).
EXAMPLES::
sage: e = DirichletGroup(11).gen() sage: f = EisensteinForms(e, 3).eisenstein_series()[0] sage: f._EisensteinSeries__compute_general_case([1]) [1] sage: f._EisensteinSeries__compute_general_case([2]) [4*zeta10 + 1] sage: f._EisensteinSeries__compute_general_case([0,1,2]) [15/11*zeta10^3 - 9/11*zeta10^2 - 26/11*zeta10 - 10/11, 1, 4*zeta10 + 1] """ else: for d in divisors(m)]))
def __defining_parameters(self): r""" Return defining parameters for ``self``.
EXAMPLES::
sage: EisensteinForms(11,2).eisenstein_series()[0]._EisensteinSeries__defining_parameters() (-1/24, Dirichlet character modulo 1 of conductor 1, Dirichlet character modulo 1 of conductor 1, Rational Field, 2, 11, 1, 1) """ else:
def chi(self): """ Return the parameter chi associated to self.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].chi() Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16 """
def psi(self): """ Return the parameter psi associated to self.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].psi() Dirichlet character modulo 17 of conductor 1 mapping 3 |--> 1 """
def t(self): """ Return the parameter t associated to self.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].t() 1 """
def parameters(self): """ Return chi, psi, and t, which are the defining parameters of self.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].parameters() (Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16, Dirichlet character modulo 17 of conductor 1 mapping 3 |--> 1, 1) """
def L(self): """ Return the conductor of self.chi().
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].L() 17 """
def M(self): """ Return the conductor of self.psi().
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].M() 1 """
def character(self): """ Return the character associated to self.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].character() Dirichlet character modulo 17 of conductor 17 mapping 3 |--> zeta16
sage: chi = DirichletGroup(7)[4] sage: E = EisensteinForms(chi).eisenstein_series() ; E [ -1/7*zeta6 - 2/7 + q + (2*zeta6 - 1)*q^2 + (-3*zeta6 + 1)*q^3 + (-2*zeta6 - 1)*q^4 + (5*zeta6 - 4)*q^5 + O(q^6), q + (zeta6 + 1)*q^2 + (-zeta6 + 3)*q^3 + (zeta6 + 2)*q^4 + (zeta6 + 4)*q^5 + O(q^6) ] sage: E[0].character() == chi True sage: E[1].character() == chi True
TESTS::
sage: [ [ f.character() == chi for f in EisensteinForms(chi).eisenstein_series() ] for chi in DirichletGroup(17) ] [[True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], [], [True, True], []]
sage: [ [ f.character() == chi for f in EisensteinForms(chi).eisenstein_series() ] for chi in DirichletGroup(16) ] [[True, True, True, True, True], [], [True, True], [], [True, True, True, True], [], [True, True], []] """
def new_level(self): """ Return level at which self is new.
EXAMPLES::
sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].level() 17 sage: EisensteinForms(DirichletGroup(17).0,99).eisenstein_series()[1].new_level() 17 sage: [ [x.level(), x.new_level()] for x in EisensteinForms(DirichletGroup(60).0^2,2).eisenstein_series() ] [[60, 2], [60, 3], [60, 2], [60, 5], [60, 2], [60, 2], [60, 2], [60, 3], [60, 2], [60, 2], [60, 2]] """ |