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 -*- Space of boundary modular symbols
Used mainly for computing the cuspidal subspace of modular symbols. The space of boundary symbols of sign 0 is isomorphic as a Hecke module to the dual of the space of Eisenstein series, but this does not give a useful method of computing Eisenstein series, since there is no easy way to extract the constant terms.
We represent boundary modular symbols as a sum of Manin symbols of the form `[P, u/v]`, where `u/v` is a cusp for our group `G`. The group of boundary modular symbols naturally embeds into a vector space `B_k(G)` (see Stein, section 8.4, or Merel, section 1.4, where this space is called `\CC[\Gamma \backslash \QQ]_k`, for a definition), which is a finite dimensional `\QQ` vector space of dimension equal to the number of cusps for `G`. The embedding takes `[P, u/v]` to `P(u,v)\cdot [(u,v)]`. We represent the basis vectors by pairs `[(u,v)]` with u, v coprime. On `B_k(G)`, we have the relations
.. MATH::
[\gamma \cdot (u,v)] = [(u,v)]
for all `\gamma \in G` and
.. MATH::
[(\lambda u, \lambda v)] = \operatorname{sign}(\lambda)^k [(u,v)]
for all `\lambda \in \QQ^\times`.
It's possible for these relations to kill a class, i.e., for a pair `[(u,v)]` to be 0. For example, when `N=4` and `k=3` then `(-1,-2)` is equivalent mod `\Gamma_1(4)` to `(1,2)` since `2=-2 \bmod 4` and `1=-1 \bmod 2`. But since `k` is odd, `[(-1,-2)]` is also equivalent to `-[(1,2)]`. Thus this symbol is equivalent to its negative, hence 0 (notice that this wouldn't be the case in characteristic 2). This happens for any irregular cusp when the weight is odd; there are no irregular cusps on `\Gamma_1(N)` except when `N = 4`, but there can be more on `\Gamma_H` groups. See also prop 2.30 of Stein's Ph.D. thesis.
In addition, in the case that our space is of sign `\sigma = 1` or `-1`, we also have the relation `[(-u,v)] = \sigma \cdot [(u,v)]`. This relation can also combine with the above to kill a cusp class - for instance, take (u,v) = (1,3) for `\Gamma_1(5)`. Then since the cusp `\tfrac{1}{3}` is `\Gamma_1(5)`-equivalent to the cusp `-\tfrac{1}{3}`, we have that `[(1,3)] = [(-1,3)]`. Now, on the minus subspace, we also have that `[(-1,3)] = -[(1,3)]`, which means this class must vanish. Notice that this cannot be used to show that `[(1,0)]` or `[(0,1)]` is 0.
.. note::
Special care must be taken when working with the images of the cusps 0 and `\infty` in `B_k(G)`. For all cusps *except* 0 and `\infty`, multiplying the cusp by -1 corresponds to taking `[(u,v)]` to `[(-u,v)]` in `B_k(G)`. This means that `[(u,v)]` is equivalent to `[(-u,v)]` whenever `\tfrac{u}{v}` is equivalent to `-\tfrac{u}{v}`, except in the case of 0 and `\infty`. We have the following conditions for `[(1,0)]` and `[(0,1)]`:
- `[(0,1)] = \sigma \cdot [(0,1)]`, so `[(0,1)]` is 0 exactly when `\sigma = -1`.
- `[(1,0)] = \sigma \cdot [(-1,0)]` and `[(1,0)] = (-1)^k [(-1,0)]`, so `[(1,0)] = 0` whenever `\sigma \ne (-1)^k`.
.. note::
For all the spaces of boundary symbols below, no work is done to determine the cusps for G at creation time. Instead, cusps are added as they are discovered in the course of computation. As a result, the rank of a space can change as a computation proceeds.
REFERENCES:
- Merel, "Universal Fourier expansions of modular forms." Springer LNM 1585 (1994), pg. 59-95.
- Stein, "Modular Forms, a computational approach." AMS (2007). """
#***************************************************************************** # Copyright (C) 2005 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/ #*****************************************************************************
""" Create a boundary symbol.
INPUT:
- ``parent`` - BoundarySpace; a space of boundary modular symbols
- ``x`` - a dict with integer keys and values in the base field of parent.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(32), sign=-1).boundary_space() sage: B(Cusp(1,8)) [1/8] sage: B.0 [1/8] sage: type(B.0) <class 'sage.modular.modsym.boundary.BoundarySpaceElement'> """
r""" Return self as a vector on the QQ-vector space with basis self.parent()._known_cusps().
EXAMPLES::
sage: B = ModularSymbols(18,4,sign=1).boundary_space() sage: x = B(Cusp(1/2)) ; x [1/2] sage: x.coordinate_vector() (1) sage: ((18/5)*x).coordinate_vector() (18/5) sage: B(Cusp(0)) [0] sage: x.coordinate_vector() (1) sage: x = B(Cusp(1/2)) ; x [1/2] sage: x.coordinate_vector() (1, 0) """
""" Return the string representation of self.
EXAMPLES::
sage: ModularSymbols(Gamma0(11), 2).boundary_space()(Cusp(0))._repr_() '[0]' sage: (-6*ModularSymbols(Gamma0(11), 2).boundary_space()(Cusp(0)))._repr_() '-6*[0]' """
# can't inherit arithmetic operations from HeckeModule, because basis # dimension might change!
""" Return self + other. Assumes that other is a BoundarySpaceElement.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(16), 4).boundary_space() sage: x = B(Cusp(2/7)) ; y = B(Cusp(13/16)) sage: x + y # indirect doctest [2/7] + [13/16] sage: x + x # indirect doctest 2*[2/7] """ else:
""" Return self - other. Assumes that other is a BoundarySpaceElement.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(16), 4).boundary_space() sage: x = B(Cusp(2/7)) ; y = B(Cusp(13/16)) sage: x - y # indirect doctest [2/7] - [13/16] sage: x - x # indirect doctest 0 """ else:
""" Return self \* other. Assumes that other can be coerced into self.parent().base_ring().
EXAMPLES::
sage: B = ModularSymbols(Gamma1(16), 4).boundary_space() sage: x = B(Cusp(2/7)) sage: x*5 # indirect doctest 5*[2/7] sage: x*-3/5 # indirect doctest -3/5*[2/7] """
""" Return other \* self. Assumes that other can be coerced into self.parent().base_ring().
EXAMPLES::
sage: B = ModularSymbols(Gamma1(16), 4).boundary_space() sage: x = B(Cusp(13/16)) sage: 11*x # indirect doctest 11*[13/16] sage: 1/3*x # indirect doctest 1/3*[13/16] """
""" Return -self.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(16), 4).boundary_space() sage: x = B(Cusp(2/7)) sage: -x # indirect doctest -[2/7] sage: -x + x # indirect doctest 0 """
group = arithgroup.Gamma0(1), weight = 2, sign = 0, base_ring = rings.QQ, character = None): """ Space of boundary symbols for a congruence subgroup of SL_2(Z).
This class is an abstract base class, so only derived classes should be instantiated.
INPUT:
- ``weight`` - int, the weight
- ``group`` - arithgroup.congroup_generic.CongruenceSubgroup, a congruence subgroup.
- ``sign`` - int, either -1, 0, or 1
- ``base_ring`` - rings.Ring (defaults to the rational numbers)
EXAMPLES::
sage: B = ModularSymbols(Gamma0(11),2).boundary_space() sage: isinstance(B, sage.modular.modsym.boundary.BoundarySpace) True sage: B == loads(dumps(B)) True """ raise ArithmeticError("weight must be at least 2") raise TypeError("group must be a congruence subgroup") raise TypeError("base_ring must be a commutative ring") self.__sign, self.__base_ring) = (group, weight, character, sign, base_ring)
""" EXAMPLES::
sage: B2 = ModularSymbols(11, 2).boundary_space() sage: B4 = ModularSymbols(11, 4).boundary_space() sage: B2 == B4 False sage: B2 == ModularSymbols(17, 2).boundary_space() False """
(other.group(), other.weight(), other.character()), op)
""" Return the list of cusps found so far.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(12), 4).boundary_space() sage: B._known_cusps() [] sage: ls = [ B(Cusp(i,10)) for i in range(10) ] sage: B._known_cusps() [0, 1/10, 1/5] """
""" Return True if self is a space of boundary symbols associated to an ambient space of modular symbols.
EXAMPLES::
sage: M = ModularSymbols(Gamma1(6), 4) sage: M.is_ambient() True sage: M.boundary_space().is_ambient() True """
""" Return the congruence subgroup associated to this space of boundary modular symbols.
EXAMPLES::
sage: ModularSymbols(GammaH(14,[9]), 2).boundary_space().group() Congruence Subgroup Gamma_H(14) with H generated by [9] """
""" Return the weight of this space of boundary modular symbols.
EXAMPLES::
sage: ModularSymbols(Gamma1(9), 5).boundary_space().weight() 5 """
""" Return the Dirichlet character associated to this space of boundary modular symbols.
EXAMPLES::
sage: ModularSymbols(DirichletGroup(7).0, 6).boundary_space().character() Dirichlet character modulo 7 of conductor 7 mapping 3 |--> zeta6 """
""" Return the sign of the complex conjugation involution on this space of boundary modular symbols.
EXAMPLES::
sage: ModularSymbols(13,2,sign=-1).boundary_space().sign() -1 """
""" Return the i-th generator of this space.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(24), 4).boundary_space() sage: B.gen(0) Traceback (most recent call last): ... ValueError: only 0 generators known for Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(24) of weight 4 and over Rational Field sage: B(Cusp(1/3)) [1/3] sage: B.gen(0) [1/3] """
""" Return the length of self, i.e. the dimension of the underlying vector space.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(36),4,sign=1).boundary_space() sage: B.__len__() 0 sage: len(B) 0 sage: x = B(Cusp(0)) ; y = B(Cusp(oo)) ; len(B) 2 """
""" Return the underlying free module for self.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(7), 5, sign=-1).boundary_space() sage: B.free_module() Sparse vector space of dimension 0 over Rational Field sage: x = B(Cusp(0)) ; y = B(Cusp(1/7)) ; B.free_module() Sparse vector space of dimension 2 over Rational Field """
""" The rank of the space generated by boundary symbols that have been found so far in the course of computing the boundary map.
.. warning::
This number may change as more elements are coerced into this space!! (This is an implementation detail that will likely change.)
EXAMPLES::
sage: M = ModularSymbols(Gamma0(72), 2) ; B = M.boundary_space() sage: B.rank() 0 sage: _ = [ B(x) for x in M.basis() ] sage: B.rank() 16 """
##################################################################### # Coercion #####################################################################
""" Coerce the Manin symbol x into self. (That is, return the image of x under the boundary map.)
Assumes that x is associated to the same space of modular symbols as self.
EXAMPLES::
sage: M = ModularSymbols(Gamma1(5), 4) ; B = M.boundary_space() sage: [ B(x) for x in M.basis() ] [-[2/5], -[-1/5], -[1/2], -[1/2], -[1/4], -[1/4]] sage: [ B._coerce_in_manin_symbol(x) for x in M.manin_symbols_basis() ] [-[2/5], -[-1/5], -[1/2], -[1/2], -[1/4], -[1/4]] """ else:
""" Coerce x into a boundary symbol space.
If x is a modular symbol (with the same group, weight, character, sign, and base field), this returns the image of that modular symbol under the boundary map.
EXAMPLES::
sage: M = ModularSymbols(Gamma0(15), 2) ; B = M.boundary_space() sage: B(M.0) [Infinity] - [0] sage: B(Cusp(1)) [0] sage: B(Cusp(oo)) [Infinity] sage: B(7) Traceback (most recent call last): ... TypeError: Coercion of 7 (of type <type 'sage.rings.integer.Integer'>) into Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(15) of weight 2 and over Rational Field not (yet) defined. """
return self._coerce_in_manin_symbol(x)
raise TypeError("x (=%s) must be an element of a space of modular symbols of type ModularSymbolsAmbient"%x) raise TypeError("x (=%s) must have level %s but has level %s"%( x, self.level(), M.level())) return self(0)
y = dict([(i,x[i]) for i in range(len(x))]) return BoundarySpaceElement(self, y)
""" Return the string representation of self.
EXAMPLES::
sage: sage.modular.modsym.boundary.BoundarySpace(Gamma0(3), 2)._repr_() 'Space of Boundary Modular Symbols of weight 2 for Congruence Subgroup Gamma0(3) with sign 0 and character [1] over Rational Field' """ " %s with sign %s and character %s over %s")%( self.weight(), self.group(), self.sign(), self.character()._repr_short_(), self.base_ring())
""" Return the index of the first cusp in self._known_cusps() equivalent to cusp, or -1 if cusp is not equivalent to any cusp found so far.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(21), 4).boundary_space() sage: B._cusp_index(Cusp(0)) -1 sage: _ = B(Cusp(oo)) sage: _ = B(Cusp(0)) sage: B._cusp_index(Cusp(0)) 1 """
""" Initialize a space of boundary symbols of weight k for Gamma_0(N) over base field F.
INPUT:
- ``level`` - int, the level
- ``weight`` - integer weight = 2.
- ``sign`` - int, either -1, 0, or 1
- ``F`` - field
EXAMPLES::
sage: B = ModularSymbols(Gamma0(2), 5).boundary_space() sage: type(B) <class 'sage.modular.modsym.boundary.BoundarySpace_wtk_g0_with_category'> sage: B == loads(dumps(B)) True """ raise ArithmeticError("sign must be an int in [-1,0,1]") raise ArithmeticError("level must be positive") weight = weight, group = arithgroup.Gamma0(level), sign = sign, base_ring = F)
""" Return the string representation of self.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(97), 3).boundary_space() sage: B._repr_() 'Space of Boundary Modular Symbols for Congruence Subgroup Gamma0(97) of weight 3 and over Rational Field' """ "and over %s")%(self.group(), self.weight(), self.base_ring())
""" Coerce the cusp c into this boundary symbol space.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(17), 6).boundary_space() sage: B._coerce_cusp(Cusp(0)) [0] sage: B = ModularSymbols(Gamma0(17), 6, sign=-1).boundary_space() sage: B._coerce_cusp(Cusp(0)) 0 sage: B = ModularSymbols(Gamma0(16), 4).boundary_space() sage: [ B(Cusp(i,4)) for i in range(4) ] [[0], [1/4], [1/2], [3/4]] sage: B = ModularSymbols(Gamma0(16), 4, sign=1).boundary_space() sage: [ B(Cusp(i,4)) for i in range(4) ] [[0], [1/4], [1/2], [1/4]] sage: B = ModularSymbols(Gamma0(16), 4, sign=-1).boundary_space() sage: [ B(Cusp(i,4)) for i in range(4) ] [0, [1/4], 0, -[1/4]] """
# see if we've already found this cusp
# see if we've already found -c return self(0)
# found a new cusp class
# See if the new cusp is killed by sign relations. The # relevant relations (for cusps other than 0 and Infinity) # are: # # [(u,v)] = (-1)^k [(-u,-v)] # [(u,v)] = [gamma * (u,v)] # [(-u,v)] = sign * [(u,v)] # # So since k is always even on Gamma0, we have that [(u,v)] = # 0 from the above relations exactly when (u,v) = gamma*(-u,v) # and the sign is -1. # NOTE: this code looks wrong. One should do the # following: # # - if c is 0, if the sign is -1, append & return 0 # - if c is Infinity, then if the sign # is not equal to (-1)**self.weight(), then # append & return 0 # - otherwise, if the sign is -1, and c is # equivalent to -c, append & return 0. # # Interestingly, the code below does precisely that. # (It's important to recall that for Gamma0, odd weight # spaces are 0.)
""" Determine whether or not c1 and c2 are equivalent for self.
EXAMPLES::
sage: B = ModularSymbols(Gamma0(24), 6).boundary_space() sage: B._is_equiv(Cusp(0), Cusp(oo)) False sage: B._is_equiv(Cusp(0), Cusp(1)) True """
""" Initialize a space of boundary modular symbols for Gamma1(N).
INPUT:
- ``level`` - int, the level
- ``weight`` - int, the weight = 2
- ``sign`` - int, either -1, 0, or 1
- ``F`` - base ring
EXAMPLES::
sage: from sage.modular.modsym.boundary import BoundarySpace_wtk_g1 sage: B = BoundarySpace_wtk_g1(17, 2, 0, QQ) ; B Boundary Modular Symbols space for Gamma_1(17) of weight 2 over Rational Field sage: B == loads(dumps(B)) True """ raise ArithmeticError("sign must be an int in [-1,0,1]") raise ArithmeticError("level must be positive")
weight = weight, group = arithgroup.Gamma1(level), sign = sign, base_ring = F)
""" Return the string representation of self.
EXAMPLES::
sage: ModularSymbols(Gamma1(5), 3, sign=1).boundary_space()._repr_() 'Boundary Modular Symbols space for Gamma_1(5) of weight 3 over Rational Field' """ "over %s")%(self.level(),self.weight(), self.base_ring())
""" Return True if c1 and c2 are equivalent cusps for self, and False otherwise.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(10), 4).boundary_space() sage: B._is_equiv(Cusp(0), Cusp(1/5)) (False, 0) sage: B._is_equiv(Cusp(4/5), Cusp(1/5)) (True, -1) sage: B._is_equiv(Cusp(-4/5), Cusp(1/5)) (True, 1) """
""" Returns a pair (i, t), where i is the index of the first cusp in self._known_cusps() which is equivalent to cusp, and t is 1 or -1 as cusp is Gamma1-equivalent to plus or minus self._known_cusps()[i]. If cusp is not equivalent to any known cusp, return (-1, 0).
EXAMPLES::
sage: B = ModularSymbols(Gamma1(11),2).boundary_space() sage: B._cusp_index(Cusp(1/11)) (-1, 0) sage: B._cusp_index(Cusp(10/11)) (-1, 0) sage: B._coerce_cusp(Cusp(1/11)) [1/11] sage: B._cusp_index(Cusp(1/11)) (0, 1) sage: B._cusp_index(Cusp(10/11)) (0, -1) """
""" Coerce a cusp into this boundary symbol space.
EXAMPLES::
sage: B = ModularSymbols(Gamma1(4), 4).boundary_space() sage: B._coerce_cusp(Cusp(1/2)) [1/2] sage: B._coerce_cusp(Cusp(1/4)) [1/4] sage: B._coerce_cusp(Cusp(3/4)) [1/4] sage: B = ModularSymbols(Gamma1(5), 3, sign=-1).boundary_space() sage: B._coerce_cusp(Cusp(0)) 0 sage: B._coerce_cusp(Cusp(oo)) [Infinity] sage: B = ModularSymbols(Gamma1(2), 3, sign=-1).boundary_space() sage: B._coerce_cusp(Cusp(0)) 0 sage: B._coerce_cusp(Cusp(oo)) 0 sage: B = ModularSymbols(Gamma1(7), 3).boundary_space() sage: [ B(Cusp(i,7)) for i in range(7) ] [[0], [1/7], [2/7], [3/7], -[3/7], -[2/7], -[1/7]] sage: B._is_equiv(Cusp(1,6), Cusp(5,6)) (True, 1) sage: B._is_equiv(Cusp(1,6), Cusp(0)) (True, -1) sage: B(Cusp(0)) [0] sage: B = ModularSymbols(Gamma1(7), 3, sign=1).boundary_space() sage: [ B(Cusp(i,7)) for i in range(7) ] [[0], 0, 0, 0, 0, 0, 0] sage: B = ModularSymbols(Gamma1(7), 3, sign=-1).boundary_space() sage: [ B(Cusp(i,7)) for i in range(7) ] [0, [1/7], [2/7], [3/7], -[3/7], -[2/7], -[1/7]] """
return self(0) else:
# found a new cusp class
# Does cusp class vanish because of - relations? (See note at top # of file.) self._is_zero.append(len(g)-1) return self(0)
# Does class vanish because of sign relations? The relevant # relations are # # [(u,v)] = (-1)^k [(-u,-v)] # [(u,v)] = sign * [(-u,v)] # [(u,v)] = eps * (-1)^k [(-u,v)] # # where, in the last line, (u,v) is Gamma1-equivalent to # (-u,v) or (u,-v) as eps is 1 or -1. # # Thus (other than for 0 and Infinity), we have that [(u,v)] # can only be killed by sign relations when: # # - (u,v) is Gamma1-equivalent to (-u,v) or (u,-v), and # - eps is 1 and sign is -1, or eps is -1 and sign is not # (-1)^k. # self._is_zero.append(len(g)-1) return self(0) else: (eps == -1 and sign != (-1)**self.weight())):
""" Initialize a space of boundary modular symbols for GammaH(N).
INPUT:
- ``group`` - congruence subgroup Gamma_H(N).
- ``weight`` - int, the weight = 2
- ``sign`` - int, either -1, 0, or 1
- ``F`` - base ring
EXAMPLES::
sage: from sage.modular.modsym.boundary import BoundarySpace_wtk_gamma_h sage: B = BoundarySpace_wtk_gamma_h(GammaH(13,[3]), 2, 0, QQ) ; B Boundary Modular Symbols space for Congruence Subgroup Gamma_H(13) with H generated by [3] of weight 2 over Rational Field sage: B == loads(dumps(B)) True """ raise ArithmeticError("sign must be an int in [-1,0,1]")
weight = weight, group = group, sign = sign, base_ring = F)
""" Return the string representation of self.
EXAMPLES::
sage: ModularSymbols(GammaH(7,[2]), 4).boundary_space()._repr_() 'Boundary Modular Symbols space for Congruence Subgroup Gamma_H(7) with H generated by [2] of weight 4 over Rational Field' """ "over %s")%(self.group(),self.weight(), self.base_ring())
""" Return a pair of the form (b, t), where b is True if c1 and c2 are equivalent cusps for self, and False otherwise, and t gives extra information about the equivalence between c1 and c2.
EXAMPLES::
sage: B = ModularSymbols(GammaH(7,[2]), 4).boundary_space() sage: B._is_equiv(Cusp(0), Cusp(1/7)) (False, 0) sage: B._is_equiv(Cusp(2/7), Cusp(1/7)) (True, 1) sage: B._is_equiv(Cusp(3/7), Cusp(1/7)) (True, -1) """
""" Returns a pair (i, t), where i is the index of the first cusp in self._known_cusps() which is equivalent to cusp, and t is 1 or -1 as cusp is GammaH-equivalent to plus or minus self._known_cusps()[i]. If cusp is not equivalent to any known cusp, return (-1, 0).
EXAMPLES::
sage: M = ModularSymbols(GammaH(9,[4]), 3) sage: B = M.boundary_space() sage: B._cusp_index(Cusp(0)) (-1, 0) sage: _ = [ B(x) for x in M.basis() ] sage: B._cusp_index(Cusp(0)) (1, -1) sage: B._cusp_index(Cusp(5/6)) (3, 1) """
""" Coerce the cusp c into self.
EXAMPLES::
sage: B = ModularSymbols(GammaH(10,[9]), 2).boundary_space() sage: B(Cusp(0)) [0] sage: B(Cusp(1/3)) [1/3] sage: B(Cusp(1/13)) [1/3] sage: B = ModularSymbols(GammaH(25, [6]), 2).boundary_space() sage: B._coerce_cusp(Cusp(0)) [0]
::
sage: B = ModularSymbols(GammaH(11,[3]), 3).boundary_space() sage: [ B(Cusp(i,11)) for i in range(11) ] [[0], [1/11], -[1/11], [1/11], [1/11], [1/11], -[1/11], -[1/11], -[1/11], [1/11], -[1/11]] sage: B._is_equiv(Cusp(0), Cusp(1,11)) (False, 0) sage: B._is_equiv(Cusp(oo), Cusp(1,11)) (True, 1) sage: B = ModularSymbols(GammaH(11,[3]), 3, sign=1).boundary_space() sage: [ B(Cusp(i,11)) for i in range(11) ] [[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] sage: B = ModularSymbols(GammaH(11,[3]), 3, sign=-1).boundary_space() sage: [ B(Cusp(i,11)) for i in range(11) ] [0, [1/11], -[1/11], [1/11], [1/11], [1/11], -[1/11], -[1/11], -[1/11], [1/11], -[1/11]] """
if i2 in self._is_zero: return self(0) return BoundarySpaceElement(self, {i2:sign*(eps**k)})
# found a new cusp class
# Does cusp class vanish because of - relations? (See note at top # of file.) self._is_zero.append(len(g)-1) return self(0)
# Does class vanish because of sign relations? The relevant # relations are # # [(u,v)] = (-1)^k [(-u,-v)] # [(u,v)] = sign * [(-u,v)] # [(u,v)] = eps * (-1)^k [(-u,v)] # # where, in the last line, (u,v) is GammaH-equivalent to # (-u,v) or (u,-v) as eps is 1 or -1. # # Thus (other than for 0 and Infinity), we have that [(u,v)] # can only be killed by sign relations when: # # - (u,v) is GammaH-equivalent to (-u,v) or (u,-v), and # - eps is 1 and sign is -1, or eps is -1 and sign is not # (-1)^k. # # (Notice that while this description looks identical to that # of Gamma1, it differs in that the condition of being GammaH # equivalent is weaker than that of being Gamma1 equivalent # when H is larger than {1}.) # self._is_zero.append(len(g)-1) return self(0) else: (eps == -1 and sign != (-1)**self.weight())):
""" Space of boundary modular symbols with given weight, character, and sign.
INPUT:
- ``eps`` - dirichlet.DirichletCharacter, the "Nebentypus" character.
- ``weight`` - int, the weight = 2
- ``sign`` - int, either -1, 0, or 1
EXAMPLES::
sage: B = ModularSymbols(DirichletGroup(6).0, 4).boundary_space() ; B Boundary Modular Symbols space of level 6, weight 4, character [-1] and dimension 0 over Rational Field sage: type(B) <class 'sage.modular.modsym.boundary.BoundarySpace_wtk_eps_with_category'> sage: B == loads(dumps(B)) True """ raise ArithmeticError("sign must be an int in [-1,0,1]") raise ArithmeticError("level must be positive") weight = weight, group = arithgroup.Gamma1(level), sign = sign, base_ring = eps.base_ring(), character = eps)
""" Return the string representation of self.
EXAMPLES::
sage: ModularSymbols(DirichletGroup(6).0, 4).boundary_space()._repr_() 'Boundary Modular Symbols space of level 6, weight 4, character [-1] and dimension 0 over Rational Field' """ "and dimension %s over %s")%(self.level(), self.weight(), self.character()._repr_short_(), self.rank(), self.base_ring())
""" Return a pair (b, t), where b is True if c1 and c2 are equivalent cusps for self, and False otherwise, and t gives extra information about the equivalence of c1 and c2.
EXAMPLES::
sage: B = ModularSymbols(DirichletGroup(12).1, 3).boundary_space() sage: B._is_equiv(Cusp(0), Cusp(1/3)) (False, None) sage: B._is_equiv(Cusp(2/3), Cusp(1/3)) (True, 5) sage: B._is_equiv(Cusp(3/4), Cusp(1/4)) (True, 7) """
""" Returns a pair (i, s), where i is the index of the first cusp in self._known_cusps() which is equivalent to cusp, and such that cusp is Gamma0-equivalent to self.character()(s) times self._known_cusps()[i]. If cusp is not equivalent to any known cusp, return (-1, 0).
EXAMPLES::
sage: B = ModularSymbols(DirichletGroup(11).0**3, 5).boundary_space() sage: B._cusp_index(Cusp(0)) (-1, 0) sage: B._coerce_cusp(Cusp(0)) [0] sage: B._cusp_index(Cusp(0)) (0, 1) sage: B._coerce_cusp(Cusp(1,11)) [1/11] sage: B._cusp_index(Cusp(2,11)) (1, -zeta10^2) """
""" Coerce the cusp c into self.
EXAMPLES::
sage: B = ModularSymbols(DirichletGroup(13).0**3, 5, sign=0).boundary_space() sage: [ B(Cusp(i,13)) for i in range(13) ] [[0], [1/13], -zeta4*[1/13], [1/13], -[1/13], -zeta4*[1/13], -zeta4*[1/13], zeta4*[1/13], zeta4*[1/13], [1/13], -[1/13], zeta4*[1/13], -[1/13]] sage: B._is_equiv(Cusp(oo), Cusp(1,13)) (True, 1) sage: B._is_equiv(Cusp(0), Cusp(1,13)) (False, None) sage: B = ModularSymbols(DirichletGroup(13).0**3, 5, sign=1).boundary_space() sage: [ B(Cusp(i,13)) for i in range(13) ] [[0], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] sage: B._coerce_cusp(Cusp(oo)) 0 sage: B = ModularSymbols(DirichletGroup(13).0**3, 5, sign=-1).boundary_space() sage: [ B(Cusp(i,13)) for i in range(13) ] [0, [1/13], -zeta4*[1/13], [1/13], -[1/13], -zeta4*[1/13], -zeta4*[1/13], zeta4*[1/13], zeta4*[1/13], [1/13], -[1/13], zeta4*[1/13], -[1/13]] sage: B = ModularSymbols(DirichletGroup(13).0**4, 5, sign=1).boundary_space() sage: B._coerce_cusp(Cusp(0)) [0] sage: B = ModularSymbols(DirichletGroup(13).0**4, 5, sign=-1).boundary_space() sage: B._coerce_cusp(Cusp(0)) 0 """
# found a new cusp class
############################################################### # TODO?: This is a very dumb way to check for solutions to an # equation (see Prop 2.30 of Stein's Ph.D. thesis for which # equation); however, computing the cusp equivalence for the # boundary map takes much less time than computing the kernel # of the boundary map, so it's not worth optimizing this now. ###############################################################
# Does class vanish because of sign relations? The relevant # relations are # # [(u,v)] = (-1)^k [(-u,-v)] # [(u,v)] = sign * [(-u,v)] # [(u,v)] = eps(d) * [(-u,v)] # # where, in the last line, eps is the character defining # our space, and [a,b;c,d] takes (u,v) to (-u,v). # # Thus (other than for 0 and Infinity), we have that [(u,v)] # can only be killed by sign relations when the sign is not # equal to eps(d). # self._is_zero.append(len(g)-1) return self(0) else:
|