Path: blob/master/sage/modular/modsym/manin_symbols.py
4097 views
# -*- coding: utf-8 -*-1"""2Manin symbols34This module defines the class ManinSymbol. A Manin Symbol of5weight `k`, level `N` has the form `[P(X,Y),(u:v)]` where6`P(X,Y)\in\mathbb{Z}[X,Y]` is homogeneous of weight `k-2` and7`(u:v)\in\mathbb{P}^1(\mathbb{Z}/N\mathbb{Z}).` The ManinSymbol class8holds a "monomial Manin Symbol" of the simpler form9`[X^iY^{k-2-i},(u:v)]`, which is stored as a triple `(i,u,v)`; the10weight and level are obtained from the parent structure, which is a11ManinSymbolList.1213Integer matrices `[a,b;c,d]` act on Manin Symbols on the right,14sending `[P(X,Y),(u,v)]` to `[P(aX+bY,cX+dY),(u,v)g]`. Diagonal15matrices (with `b=c=0`, such as `I=[-1,0;0,1]` and `J=[-1,0;0,-1]`)16and anti-diagonal matrices (with `a=d=0`, such as `S=[0,-1;1,0]`) map17monomial Manin Symbols to monomial Manin Symbols, up to a scalar18factor. For general matrices (such as `T=[0,1,-1,-1]` and19`T^2=[-1,-1;0,1]`) the image of a monomial Manin Symbol is expressed20as a formal sum of monomial Manin Symbols, with integer coefficients.2122There are various different classes holding lists of Manin symbols of23different types. The hierarchy is as follows:2425::2627class ManinSymbolList(SageObject)2829class ManinSymbolList_group(ManinSymbolList)30class ManinSymbolList_gamma0(ManinSymbolList_group)31class ManinSymbolList_gamma1(ManinSymbolList_group)32class ManinSymbolList_gamma_h(ManinSymbolList_group)3334class ManinSymbolList_character(ManinSymbolList)3536"""3738#*****************************************************************************39# Sage: System for Algebra and Geometry Experimentation40#41# Copyright (C) 2005 William Stein <[email protected]>42#43# Distributed under the terms of the GNU General Public License (GPL)44#45# This code is distributed in the hope that it will be useful,46# but WITHOUT ANY WARRANTY; without even the implied warranty of47# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU48# General Public License for more details.49#50# The full text of the GPL is available at:51#52# http://www.gnu.org/licenses/53#*****************************************************************************5455import sage.matrix.all56import sage.modular.cusps as cusps57import sage.modular.modsym.p1list as p1list58import sage.modular.modsym.g1list as g1list59import sage.modular.modsym.ghlist as ghlist60import sage.modular.modsym.modular_symbols61import sage.rings.arith as arith62import sage.rings.all as rings6364from sage.structure.sage_object import SageObject6566from apply import apply_to_monomial6768def is_ManinSymbol(x):69"""70Returns True if ``x`` is a ManinSymbol.7172EXAMPLES::7374sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma0, is_ManinSymbol75sage: m = ManinSymbolList_gamma0(6, 4)76sage: is_ManinSymbol(m[3])77False78sage: s = ManinSymbol(m,m[3])79sage: s80[Y^2,(1,2)]81sage: is_ManinSymbol(s)82True8384"""85return isinstance(x, ManinSymbol)8687class ManinSymbolList(SageObject):88"""89Base class for lists of all Manin symbols for a given weight, group or character.90"""91def __init__(self, weight, list):92"""93Constructor for a ManinSymbolList.9495INPUT:9697- ``weight``- the weight of the symbols.98- ``list``- the list of symbols.99100On construction, a ManinSymbolList constructs a dict for101rapid determination of the index of any given symbol.102103This is a base class only; users will only directly construct104objects in the derived classes ManinSymbolList_gamma0,105ManinSymbolList_gamma1, ManinSymbolList_gamma_h,106ManinSymbolList_gamma_character. Many standard methods are107only implemented in the derived classes.108109EXAMPLES::110111sage: from sage.modular.modsym.manin_symbols import ManinSymbolList112sage: ManinSymbolList(6,P1List(11))113<class 'sage.modular.modsym.manin_symbols.ManinSymbolList'>114115"""116self._weight = weight117self._list = list118self._index = dict([(list[i],i) for i in range(len(list))])119120def __cmp__(self, right):121"""122Comparison function for ManinSymbolList objects.123124EXAMPLES::125126sage: from sage.modular.modsym.manin_symbols import ManinSymbolList127sage: m1 = ManinSymbolList(6,P1List(11))128sage: m2 = ManinSymbolList(6,P1List(13))129sage: m3 = ManinSymbolList(4,P1List(11))130sage: m1 < m2131True132sage: m2 < m3133False134sage: m1 < m3135False136"""137if not isinstance(right, ManinSymbolList):138return cmp(type(self), type(right))139return cmp((self._weight, self._list), (right._weight, right._list))140141def __getitem__(self, n):142"""143Returns the `n`th ManinSymbol in this ManinSymbolList144145EXAMPLES::146147sage: from sage.modular.modsym.manin_symbols import ManinSymbolList148sage: m = ManinSymbolList(6,P1List(11))149sage: m[4]150(1, 3)151"""152return self._list[n]153154def __len__(self):155"""156Returns the length of this ManinSymbolList157158EXAMPLES::159160sage: from sage.modular.modsym.manin_symbols import ManinSymbolList161sage: m = ManinSymbolList(6,P1List(11))162sage: len(m)16312164"""165return len(self._list)166167def apply(self, j, X):168"""169Apply the matrix `X=[a,b;c,d]` to the `j`-th Manin symbol.170171Implemented in derived classes.172173EXAMPLES::174175sage: from sage.modular.modsym.manin_symbols import ManinSymbolList176sage: m = ManinSymbolList(6,P1List(11))177sage: m.apply(10, [1,2,0,1])178Traceback (most recent call last):179...180NotImplementedError: Only implemented in derived classes181182"""183raise NotImplementedError, "Only implemented in derived classes"184185def _apply_S_only_0pm1(self):186"""187Return True if the coefficient when applying the S relation is188always 0, 1, or -1. This is useful for optimizing code in189relation_matrix.py.190191EXAMPLES::192193sage: eps = DirichletGroup(4).gen(0)194sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character195sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()196True197sage: eps = DirichletGroup(7).gen(0)198sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character199sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()200False201"""202return False # derived classes could overload and put True203204def apply_S(self, j):205"""206Apply the matrix `S=[0,-1;1,0]` to the `j`-th Manin symbol.207208Implemented in derived classes.209210EXAMPLES::211212sage: from sage.modular.modsym.manin_symbols import ManinSymbolList213sage: m = ManinSymbolList(6,P1List(11))214sage: m.apply_S(10)215Traceback (most recent call last):216...217NotImplementedError: Only implemented in derived classes218"""219raise NotImplementedError, "Only implemented in derived classes"220221def apply_I(self, j):222"""223Apply the matrix `I=[-1,0;0,1]` to the `j`-th Manin symbol.224225Implemented in derived classes.226227EXAMPLES::228229sage: from sage.modular.modsym.manin_symbols import ManinSymbolList230sage: m = ManinSymbolList(6,P1List(11))231sage: m.apply_I(10)232Traceback (most recent call last):233...234NotImplementedError: Only implemented in derived classes235"""236raise NotImplementedError, "Only implemented in derived classes"237238def apply_T(self, j):239"""240Apply the matrix `T=[0,1;-1,-1]` to the `j`-th Manin symbol.241242Implemented in derived classes.243244EXAMPLES::245246sage: from sage.modular.modsym.manin_symbols import ManinSymbolList247sage: m = ManinSymbolList(6,P1List(11))248sage: m.apply_T(10)249Traceback (most recent call last):250...251NotImplementedError: Only implemented in derived classes252"""253raise NotImplementedError, "Only implemented in derived classes"254255def apply_TT(self, j):256"""257Apply the matrix `TT=T^2=[-1,-1;0,1]` to the `j`-th Manin symbol.258259Implemented in derived classes.260261EXAMPLES::262263sage: from sage.modular.modsym.manin_symbols import ManinSymbolList264sage: m = ManinSymbolList(6,P1List(11))265sage: m.apply_TT(10)266Traceback (most recent call last):267...268NotImplementedError: Only implemented in derived classes269"""270raise NotImplementedError, "Only implemented in derived classes"271272def index(self, x):273"""274Return the index of ``x`` in the list of Manin symbols, where ``x`` is a2753-tuple of ints. If ``x`` is not in the list, then return -1.276277INPUT:278279- ``x`` - 3-tuple of integers, `(i,u,v)` defining a valid Manin symbol, which need not be normalized.280281OUTPUT:282283(``int``) the index of the normalized Manin symbol equivalent to `(i,u,v)`.284285EXAMPLES::286287sage: from sage.modular.modsym.manin_symbols import ManinSymbolList288sage: m = ManinSymbolList(6,P1List(11))289sage: m.index(m[2])2902291sage: all([i == m.index(m[i]) for i in xrange(len(m))])292True293"""294if self._index.has_key(x):295return self._index[x]296x = self.normalize(x)297try:298return self._index[x]299except KeyError:300return -1301302def manin_symbol_list(self):303"""304Returns all the ManinSymbols in this ManinSymbolList as a list305306Cached for subsequent calls.307308OUTPUT:309310a list of ``ManinSymbol`` objects, which is a copy of the complete list311of Manin symbols.312313EXAMPLES::314315sage: from sage.modular.modsym.manin_symbols import ManinSymbolList316sage: m = ManinSymbolList(6,P1List(11))317sage: m.manin_symbol_list() # not implemented for the base class318319::320321sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0322sage: m = ManinSymbolList_gamma0(6, 4)323sage: m.manin_symbol_list()324[[Y^2,(0,1)],325[Y^2,(1,0)],326[Y^2,(1,1)],327...328[X^2,(3,1)],329[X^2,(3,2)]]330331"""332import copy333try:334return copy.copy(self.__manin_symbol_list)335except AttributeError:336self.__manin_symbol_list = [self.manin_symbol(i) \337for i in xrange(len(self))]338return copy.copy(self.__manin_symbol_list)339340def manin_symbol(self, i):341"""342Returns the i'th ManinSymbol in this ManinSymbolList.343344INPUT:345346347- ``i`` - integer, a valid index of a symbol in this list.348349350OUTPUT:351352``ManinSymbol`` - the `i`'th Manin symbol in the list.353354EXAMPLES::355356sage: from sage.modular.modsym.manin_symbols import ManinSymbolList357sage: m = ManinSymbolList(6,P1List(11))358sage: m.manin_symbol(3) # not implemented for base class359360::361362sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0363sage: m = ManinSymbolList_gamma0(6, 4)364sage: s = m.manin_symbol(3); s365[Y^2,(1,2)]366sage: type(s)367<class 'sage.modular.modsym.manin_symbols.ManinSymbol'>368"""369return ManinSymbol(self, self._list[int(i)])370371def normalize(self, x):372"""373Returns a normalized ManinSymbol from x.374375To be implemented in derived classes.376377EXAMPLES::378379sage: from sage.modular.modsym.manin_symbols import ManinSymbolList380sage: m = ManinSymbolList(6,P1List(11))381sage: m.normalize((0,6,7)) # not implemented in base class382383"""384raise NotImplementedError, "Only implemented in derived classes"385386def weight(self):387"""388Returns the weight of the ManinSymbols in this ManinSymbolList.389390391OUTPUT:392393``integer`` - the weight of the Manin symbols in the list.394395EXAMPLES::396397sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0398sage: m = ManinSymbolList_gamma0(6, 4)399sage: m.weight()4004401"""402return self._weight403404class ManinSymbolList_group(ManinSymbolList):405"""406Base class for Manin symbol lists for a given group.407408INPUT:409410411- ``level`` - integer level412413- ``weight`` - integer weight414415- ``syms`` - something with a normalize and list416method, e.g., P1List.417418EXAMPLES::419420sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_group421sage: ManinSymbolList_group(11, 2, P1List(11))422<class 'sage.modular.modsym.manin_symbols.ManinSymbolList_group'>423424"""425def __init__(self, level, weight, syms):426"""427Constructor for class ManinSymbolList_group.428429INPUT:430431- ``level`` - integer level432433- ``weight`` - integer weight434435- ``syms`` - something with a normalize and list method, e.g., P1List.436437EXAMPLES::438439sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_group440sage: ManinSymbolList_group(11, 2, P1List(11))441<class 'sage.modular.modsym.manin_symbols.ManinSymbolList_group'>442443"""444self.__level = level445self.__syms = syms # syms is anything with a normalize and list method.446447# The list returned from P1List is guaranteed to be sorted.448# Thus each list constructed below is also sorted. This is449# important since the index function assumes the list is sorted.450L = [(i, u, v) for i in range(weight - 2 + 1) \451for u, v in syms.list()]452ManinSymbolList.__init__(self, weight, L)453454def level(self):455"""456Return the level of this ManinSymbolList.457458EXAMPLES::459460sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0461sage: ManinSymbolList_gamma0(5,2).level()4625463464::465466sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1467sage: ManinSymbolList_gamma1(51,2).level()46851469470::471472sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h473sage: ManinSymbolList_gamma_h(GammaH(117, [4]),2).level()474117475"""476return self.__level477478def apply_S(self, j):479"""480Apply the matrix `S=[0,-1,1,0]` to the `j`-th Manin symbol.481482INPUT:483484- ``j`` - (int) a symbol index485486OUTPUT:487488``(k, s)`` where k is the index of the symbol obtained by acting on the489`j`'th symbol with `S`, and `s` is the parity of of the `j`'th symbol490(a Python ``int``, either 1 or -1).491492EXAMPLE::493494sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0495sage: m = ManinSymbolList_gamma0(5,8)496sage: m.apply_S(4)497(40, 1)498sage: [m.apply_S(i) for i in xrange(len(m))]499[(37, 1),500(36, 1),501(41, 1),502(39, 1),503(40, 1),504(38, 1),505(31, -1),506(30, -1),507(35, -1),508(33, -1),509(34, -1),510(32, -1),511...512(4, 1),513(2, 1)]514"""515i, u, v = self._list[j]516k = self.index((self._weight-2-i, v, -u))517if i%2==0:518return k, 1519else:520return k, -1521522def _apply_S_only_0pm1(self):523"""524Return True if the coefficient when applying the S relation is525always 0, 1, or -1. This is useful for optimizing code in526relation_matrix.py.527528EXAMPLES::529530sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0531sage: ManinSymbolList_gamma0(5,8)._apply_S_only_0pm1()532True533"""534return True535536def apply_I(self, j):537"""538Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol.539540INPUT:541542- ``j`` - (int) a symbol index543544OUTPUT:545546``(k, s)`` where k is the index of the symbol obtained by acting on the547`j`'th symbol with `I`, and `s` is the parity of of the `j`'th symbol548(a Python ``int``, either 1 or -1)549550EXAMPLE::551552sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0553sage: m = ManinSymbolList_gamma0(5,8)554sage: m.apply_I(4)555(3, 1)556sage: [m.apply_I(i) for i in xrange(10)]557[(0, 1),558(1, 1),559(5, 1),560(4, 1),561(3, 1),562(2, 1),563(6, -1),564(7, -1),565(11, -1),566(10, -1)]567"""568i, u, v = self._list[j]569k = self.index((i, -u, v))570if i%2==0:571return k, 1572else:573return k, -1574575def apply_T(self, j):576"""577Apply the matrix `T=[0,1,-1,-1]` to the `j`-th Manin symbol.578579INPUT:580581- ``j`` - (int) a symbol index582583OUTPUT: see documentation for apply()584585EXAMPLE::586587sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0588sage: m = ManinSymbolList_gamma0(5,8)589sage: m.apply_T(4)590[(3, 1), (9, -6), (15, 15), (21, -20), (27, 15), (33, -6), (39, 1)]591sage: [m.apply_T(i) for i in xrange(10)]592[[(5, 1), (11, -6), (17, 15), (23, -20), (29, 15), (35, -6), (41, 1)],593[(0, 1), (6, -6), (12, 15), (18, -20), (24, 15), (30, -6), (36, 1)],594[(4, 1), (10, -6), (16, 15), (22, -20), (28, 15), (34, -6), (40, 1)],595[(2, 1), (8, -6), (14, 15), (20, -20), (26, 15), (32, -6), (38, 1)],596[(3, 1), (9, -6), (15, 15), (21, -20), (27, 15), (33, -6), (39, 1)],597[(1, 1), (7, -6), (13, 15), (19, -20), (25, 15), (31, -6), (37, 1)],598[(5, 1), (11, -5), (17, 10), (23, -10), (29, 5), (35, -1)],599[(0, 1), (6, -5), (12, 10), (18, -10), (24, 5), (30, -1)],600[(4, 1), (10, -5), (16, 10), (22, -10), (28, 5), (34, -1)],601[(2, 1), (8, -5), (14, 10), (20, -10), (26, 5), (32, -1)]]602"""603k = self._weight604i, u, v = self._list[j]605u, v = self.__syms.normalize(v,-u-v)606if (k-2) % 2 == 0:607s = 1608else:609s = -1610z = []611a = rings.ZZ(k-2-i)612for j in range(k-2-i+1):613m = self.index((j, u, v))614z.append((m, s * a.binomial(j)))615s *= -1616return z617618def apply_TT(self, j):619"""620Apply the matrix `TT=[-1,-1,0,1]` to the `j`-th Manin symbol.621622INPUT:623624- ``j`` - (int) a symbol index625626OUTPUT: see documentation for apply()627628EXAMPLE::629630sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0631sage: m = ManinSymbolList_gamma0(5,8)632sage: m.apply_TT(4)633[(38, 1)]634sage: [m.apply_TT(i) for i in xrange(10)]635[[(37, 1)],636[(41, 1)],637[(39, 1)],638[(40, 1)],639[(38, 1)],640[(36, 1)],641[(31, -1), (37, 1)],642[(35, -1), (41, 1)],643[(33, -1), (39, 1)],644[(34, -1), (40, 1)]]645"""646k = self._weight647i, u, v = self._list[j]648u, v = self.__syms.normalize(-u-v,u)649if (k-2-i) % 2 == 0:650s = 1651else:652s = -1653z = []654a = rings.ZZ(i)655for j in range(i+1):656m = self.index((k-2-i+j, u, v))657z.append((m, s * a.binomial(j)))658s *= -1659return z660661def apply(self, j, m):662r"""663Apply the matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.664665INPUT:666667- ``j`` - (int) a symbol index668669- ``m = [a, b, c, d]`` a list of 4 integers, which defines a 2x2 matrix.670671672OUTPUT:673674a list of pairs `(j_i, \alpha_i)`, where each `\alpha_i` is a nonzero675integer, `j_i` is an integer (index of the `j_i`-th Manin symbol), and676`\sum_i \alpha_i\*x_{j_i}` is the image of the j-th Manin symbol under677the right action of the matrix [a,b;c,d]. Here the right action of678g=[a,b;c,d] on a Manin symbol `[P(X,Y),(u,v)]` is679`[P(aX+bY,cX+dY),(u,v)\*g]`.680681EXAMPLE::682683sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0684sage: m = ManinSymbolList_gamma0(5,8)685sage: m.apply(40,[2,3,1,1])686[(0, 729), (6, 2916), (12, 4860), (18, 4320), (24, 2160), (30, 576), (36, 64)]687688"""689a, b, c, d = m[0], m[1], m[2], m[3]690i, u, v = self[j]691P = apply_to_monomial(i, self._weight-2, a, b, c, d)692m = self.index((0, u*a+v*c, u*b+v*d))693if m == -1:694return []695r = len(self.__syms)696return [(m + r*k, P[k]) for k in range(self._weight-2+1)697if P[k] != 0]698699def normalize(self, x):700"""701Returns the normalization of the ModSym ``x`` with respect to this702list.703704INPUT:705706- ``x`` - (3-tuple of ints) a tuple defining a ManinSymbol.707708OUTPUT:709710``(i,u,v)`` - (3-tuple of ints) another tuple defining the associated711normalized ManinSymbol.712713EXAMPLE::714715sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0716sage: m = ManinSymbolList_gamma0(5,8)717sage: [m.normalize(s.tuple()) for s in m.manin_symbol_list()][:10]718[(0, 0, 1),719(0, 1, 0),720(0, 1, 1),721(0, 1, 2),722(0, 1, 3),723(0, 1, 4),724(1, 0, 1),725(1, 1, 0),726(1, 1, 1),727(1, 1, 2)]728"""729u,v = self.__syms.normalize(x[1],x[2])730return (x[0],u,v)731732733class ManinSymbolList_gamma0(ManinSymbolList_group):734r"""735Class for Manin Symbols for `\Gamma_0(N)`.736737INPUT:738739- ``level`` - (integer): the level.740741- ``weight`` - (integer): the weight.742743EXAMPLE::744745sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0746sage: m = ManinSymbolList_gamma0(5,2); m747Manin Symbol List of weight 2 for Gamma0(5)748sage: m.manin_symbol_list()749[(0,1), (1,0), (1,1), (1,2), (1,3), (1,4)]750sage: m = ManinSymbolList_gamma0(6,4); m751Manin Symbol List of weight 4 for Gamma0(6)752sage: len(m)75336754"""755def __init__(self, level, weight):756"""757Constructor for a ModularSymbolList for Gamma_0(N)758759EXAMPLES::760761sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0762sage: M11 = ManinSymbolList_gamma0(11,2)763sage: M11764Manin Symbol List of weight 2 for Gamma0(11)765sage: M11 == loads(dumps(M11))766True767"""768ManinSymbolList_group.__init__(self, level, weight, p1list.P1List(level))769770def __repr__(self):771"""772String representation.773774EXAMPLES::775776sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma0777sage: M11 = ManinSymbolList_gamma0(11,2)778sage: str(M11)779'Manin Symbol List of weight 2 for Gamma0(11)'780781"""782return "Manin Symbol List of weight %s for Gamma0(%s)"%(783self.weight(), self.level())784785786class ManinSymbolList_gamma1(ManinSymbolList_group):787r"""788Class for Manin Symbols for `\Gamma_1(N)`.789790INPUT:791792- ``level`` - (integer): the level.793794- ``weight`` - (integer): the weight.795796EXAMPLE::797798sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1799sage: m = ManinSymbolList_gamma1(5,2); m800Manin Symbol List of weight 2 for Gamma1(5)801sage: m.manin_symbol_list()802[(0,1),803(0,2),804(0,3),805...806(4,3),807(4,4)]808sage: m = ManinSymbolList_gamma1(6,4); m809Manin Symbol List of weight 4 for Gamma1(6)810sage: len(m)81172812sage: m == loads(dumps(m))813True814"""815def __init__(self, level, weight):816"""817Constructor for a ModularSymbolList for `\Gamma_0(N)`.818819EXAMPLES::820821sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1822sage: M11 = ManinSymbolList_gamma1(11,2)823sage: M11824Manin Symbol List of weight 2 for Gamma1(11)825"""826ManinSymbolList_group.__init__(self, level, weight, g1list.G1list(level))827828def __repr__(self):829"""830Return the string representation of this ManinSymbbol list.831832EXAMPLES::833834sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma1835sage: M11 = ManinSymbolList_gamma1(11,4)836sage: str(M11)837'Manin Symbol List of weight 4 for Gamma1(11)'838"""839return "Manin Symbol List of weight %s for Gamma1(%s)"%(840self.weight(), self.level())841842843class ManinSymbolList_gamma_h(ManinSymbolList_group):844r"""845Class for Manin Symbols for `\Gamma_H(N)`.846847INPUT:848849- ``group`` - (integer): the congruence subgroup.850851- ``weight`` - (integer): the weight.852853EXAMPLE::854855sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h856sage: G = GammaH(117, [4])857sage: m = ManinSymbolList_gamma_h(G,2); m858Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(117) with H generated by [4]859sage: m.manin_symbol_list()[100:110]860[(1,88),861(1,89),862(1,90),863(1,91),864(1,92),865(1,93),866(1,94),867(1,95),868(1,96),869(1,97)]870sage: len(m.manin_symbol_list())8712016872sage: m == loads(dumps(m))873True874"""875def __init__(self, group, weight):876r"""877Constructor for Manin Symbols for `\Gamma_H(N)`.878879EXAMPLE::880881sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma_h882sage: G = GammaH(117, [4])883sage: m = ManinSymbolList_gamma_h(G,2); m884Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(117) with H generated by [4]885"""886self.__group = group887ManinSymbolList_group.__init__(self, group.level(), weight, ghlist.GHlist(group))888889def group(self):890"""891Return the group associated to self.892893EXAMPLES::894895sage: ModularSymbols(GammaH(12, [5]), 2).manin_symbols().group()896Congruence Subgroup Gamma_H(12) with H generated by [5]897"""898return self.__group899900def __repr__(self):901"""902Return the string representation of self.903904EXAMPLES::905906sage: ModularSymbols(GammaH(12, [5]), 2).manin_symbols().__repr__()907'Manin Symbol List of weight 2 for Congruence Subgroup Gamma_H(12) with H generated by [5]'908"""909return "Manin Symbol List of weight %s for %s"%(910self.weight(), self.group())911912913class ManinSymbolList_character(ManinSymbolList):914"""915List of Manin Symbols with character.916917INPUT:918919- ``character`` - (DirichletCharacter) the Dirichlet character.920921- ``weight`` - (integer) the weight.922923EXAMPLE::924925sage: eps = DirichletGroup(4).gen(0)926sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character927sage: m = ManinSymbolList_character(eps,2); m928Manin Symbol List of weight 2 for Gamma1(4) with character [-1]929sage: m.manin_symbol_list()930[(0,1), (1,0), (1,1), (1,2), (1,3), (2,1)]931sage: m == loads(dumps(m))932True933"""934def __init__(self, character, weight):935"""936Constructor for objects of class ManinSymbolList_character937938INPUT:939940941- ``character`` - (DirichletCharacter) the Dirichlet character.942943- ``weight`` - (integer) the weight.944945EXAMPLE::946947sage: eps = DirichletGroup(4).gen(0)948sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character949sage: m = ManinSymbolList_character(eps,2); m950Manin Symbol List of weight 2 for Gamma1(4) with character [-1]951sage: m.manin_symbol_list()952[(0,1), (1,0), (1,1), (1,2), (1,3), (2,1)]953954"""955self.__level = character.modulus()956self.__P1 = p1list.P1List(self.level())957958# We make a copy of the character *only* to program around what seems959# to be a bug in the cPickle module in some obscure case.960# If we don't due this, then this doctest fails.961# sage: M = ModularSymbols(DirichletGroup(5).0)962# sage: loads(dumps(M)) == M963964self.__character = character.__copy__()965966# The list returned from P1List is guaranteed to be sorted.967# Thus each list constructed below is also sorted. This is968# important since the index function assumes the list is sorted.969L = [(i, u, v) for i in range(weight-2+1) \970for u, v in self.__P1.list()]971self.__list = L972ManinSymbolList.__init__(self, weight, L)973974def __repr__(self):975"""976Standard function returning string representation.977978EXAMPLE::979980sage: eps = DirichletGroup(4).gen(0)981sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character982sage: m = ManinSymbolList_character(eps,2); m983Manin Symbol List of weight 2 for Gamma1(4) with character [-1]984sage: str(m) # indirect doctest985'Manin Symbol List of weight 2 for Gamma1(4) with character [-1]'986"""987return "Manin Symbol List of weight %s for Gamma1(%s) with character %s"%(988self.weight(), self.level(), self.character()._repr_short_())989990def level(self):991"""992Return the level of this ManinSymbolList.993994OUTPUT:995996``integer`` - the level of the symbols in this list.997998EXAMPLES::9991000sage: eps = DirichletGroup(4).gen(0)1001sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1002sage: ManinSymbolList_character(eps,4).level()100341004"""1005return self.__level10061007def apply(self, j, m):1008"""1009Apply the integer matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.10101011INPUT:101210131014- ``j`` (integer): the index of the symbol to act on.10151016- ``m`` (list of ints): `[a,b,c,d]` where `m = [a, b; c, d]` is the matrix to be applied.101710181019OUTPUT:10201021A list of pairs `(j, c_i)`, where each `c_i` is an1022integer, `j` is an integer (the `j`-th Manin symbol), and the1023sum `c_i*x_i` is the image of self under the right action1024of the matrix `[a,b;c,d]`. Here the right action of1025`g=[a,b;c,d]` on a Manin symbol `[P(X,Y),(u,v)]` is by1026definition `[P(aX+bY,cX+dY),(u,v)*g]`.10271028EXAMPLES::10291030sage: eps = DirichletGroup(4).gen(0)1031sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1032sage: m = ManinSymbolList_character(eps,4)1033sage: m[6]1034(1, 0, 1)1035sage: m.apply(4, [1,0,0,1])1036[(4, 1)]1037sage: m.apply(1, [-1,0,0,1])1038[(1, -1)]1039"""1040a, b, c, d = m[0], m[1], m[2], m[3]1041i, u, v = self[int(j)]1042P = apply_to_monomial(i, self._weight-2, a, b, c, d)1043m, s = self.index((0, u*a+v*c, u*b+v*d))1044if m == -1 or s == 0:1045return []1046r = len(self.__P1)1047return [(m + r*k, s*P[k]) for k in range(self._weight-2+1)1048if P[k] != 0]10491050def apply_S(self, j):1051"""1052Apply the matrix `S=[0,1;-1,0]` to the `j`-th Manin symbol.10531054INPUT:10551056- ``j`` - (integer) a symbol index.10571058OUTPUT:10591060``(k, s)`` where `k` is the index of the symbol obtained by acting1061on the `j`'th symbol with `S`, and `s` is the parity of the1062`j`'th symbol.10631064EXAMPLE::10651066sage: eps = DirichletGroup(4).gen(0)1067sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1068sage: m = ManinSymbolList_character(eps,2); m1069Manin Symbol List of weight 2 for Gamma1(4) with character [-1]1070sage: m.apply_S(4)1071(2, -1)1072sage: [m.apply_S(i) for i in xrange(len(m))]1073[(1, 1), (0, -1), (4, 1), (5, -1), (2, -1), (3, 1)]1074"""1075i, u, v = self._list[j]1076k, s = self.index((self._weight-2-i, v, -u))1077if i%2==0:1078return k, s1079else:1080return k, -s10811082def _apply_S_only_0pm1(self):1083"""1084Return True if the coefficient when applying the S relation is1085always 0, 1, or -1. This is useful for optimizing code in1086relation_matrix.py.10871088EXAMPLES::10891090sage: eps = DirichletGroup(4).gen(0)1091sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1092sage: ManinSymbolList_character(eps,2)._apply_S_only_0pm1()1093True1094sage: ManinSymbolList_character(DirichletGroup(13).0,2)._apply_S_only_0pm1()1095False1096"""1097return self.__character.order() <= 210981099def apply_I(self, j):1100"""1101Apply the matrix `I=[-1,0,0,1]` to the `j`-th Manin symbol.11021103INPUT:11041105- ``j`` - (integer) a symbol index11061107OUTPUT:11081109``(k, s)`` where `k` is the index of the symbol obtained by acting1110on the `j`'th symbol with `I`, and `s` is the parity of of the1111`j`'th symbol.11121113EXAMPLE::11141115sage: eps = DirichletGroup(4).gen(0)1116sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1117sage: m = ManinSymbolList_character(eps,2); m1118Manin Symbol List of weight 2 for Gamma1(4) with character [-1]1119sage: m.apply_I(4)1120(2, -1)1121sage: [m.apply_I(i) for i in xrange(len(m))]1122[(0, 1), (1, -1), (4, -1), (3, -1), (2, -1), (5, 1)]1123"""1124i, u, v = self._list[j]1125k, s = self.index((i, -u, v))1126if i%2==0:1127return k, s1128else:1129return k, -s11301131def apply_T(self, j):1132"""1133Apply the matrix `T=[0,1,-1,-1]` to the j-th Manin symbol.11341135INPUT:11361137- ``j`` - (integer) a symbol index.11381139OUTPUT:11401141A list of pairs `(j, c_i)`, where each `c_i` is an1142integer, `j` is an integer (the `j`-th Manin symbol), and the1143sum `c_i*x_i` is the image of self under the right action1144of the matrix `T`.11451146EXAMPLE::11471148sage: eps = DirichletGroup(4).gen(0)1149sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1150sage: m = ManinSymbolList_character(eps,2); m1151Manin Symbol List of weight 2 for Gamma1(4) with character [-1]1152sage: m.apply_T(4)1153[(1, -1)]1154sage: [m.apply_T(i) for i in xrange(len(m))]1155[[(4, 1)], [(0, -1)], [(3, 1)], [(5, 1)], [(1, -1)], [(2, 1)]]1156"""1157k = self._weight1158i, u, v = self._list[j]1159u, v, r = self.__P1.normalize_with_scalar(v,-u-v)1160r = self.__character(r)1161if (k-2) % 2 == 0:1162s = r1163else:1164s = -r1165z = []1166a = rings.ZZ(k-2-i)1167for j in range(k-2-i+1):1168m, r = self.index((j, u, v))1169z.append((m, s * r * a.binomial(j)))1170s *= -11171return z11721173def apply_TT(self, j):1174"""1175Apply the matrix `TT=[-1,-1,0,1]` to the `j`-th Manin symbol.11761177INPUT:11781179- ``j`` - (integer) a symbol index11801181OUTPUT:11821183A list of pairs `(j, c_i)`, where each `c_i` is an1184integer, `j` is an integer (the `j`-th Manin symbol), and the1185sum `c_i*x_i` is the image of self under the right action1186of the matrix `T^2`.11871188EXAMPLE::11891190sage: eps = DirichletGroup(4).gen(0)1191sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1192sage: m = ManinSymbolList_character(eps,2); m1193Manin Symbol List of weight 2 for Gamma1(4) with character [-1]1194sage: m.apply_TT(4)1195[(0, 1)]1196sage: [m.apply_TT(i) for i in xrange(len(m))]1197[[(1, -1)], [(4, -1)], [(5, 1)], [(2, 1)], [(0, 1)], [(3, 1)]]1198"""1199k = self._weight1200i, u, v = self._list[j]1201u, v, r = self.__P1.normalize_with_scalar(-u-v,u)1202r = self.__character(r)1203if (k-2-i) % 2 == 0:1204s = r1205else:1206s = -r1207z = []1208a = rings.ZZ(i)1209for j in range(i+1):1210m, r = self.index((k-2-i+j, u, v))1211z.append((m, s * r * a.binomial(j)))1212s *= -11213return z12141215def character(self):1216"""1217Return the character of this ManinSymbolList_character object.12181219OUTPUT:12201221The Dirichlet character of this Manin symbol list.12221223EXAMPLE::12241225sage: eps = DirichletGroup(4).gen(0)1226sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1227sage: m = ManinSymbolList_character(eps,2); m1228Manin Symbol List of weight 2 for Gamma1(4) with character [-1]1229sage: m.character()1230Dirichlet character modulo 4 of conductor 4 mapping 3 |--> -112311232"""1233return self.__character12341235def index(self, x):1236"""1237Returns the index in the list of standard Manin symbols of a1238symbol that is equivalent, modulo a scalar `s`, to1239``x``. Returns the index and the scalar.12401241If ``x`` is not in the list, return (-1, 0).12421243INPUT:12441245- ``x`` - 3-tuple of integers `(i,u,v)`, defining an element of this list of Manin symbols, which need not be normalized.12461247OUTPUT:12481249``(i, s)`` where i (``int``) is the index of the Manin symbol1250equivalent to `(i,u,v)` (or -1) and ``s`` is the scalar (an element of1251the base field) or the int 0.12521253EXAMPLE::12541255sage: eps = DirichletGroup(4).gen(0)1256sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1257sage: m = ManinSymbolList_character(eps,4); m1258Manin Symbol List of weight 4 for Gamma1(4) with character [-1]1259sage: [m.index(s.tuple()) for s in m.manin_symbol_list()]1260[(0, 1),1261(1, 1),1262(2, 1),1263(3, 1),1264...1265(16, 1),1266(17, 1)]1267"""1268if self._index.has_key(x):1269return self._index[x], 11270x, s= self.normalize(x)1271try:1272return self._index[x], s1273except KeyError:1274return -1, 012751276def normalize(self, x):1277"""1278Returns the normalization of the Manin Symbol ``x`` with respect to this1279list, together with the normalizing scalar.12801281INPUT:12821283- ``x`` - 3-tuple of integers ``(i,u,v)``, defining an element of this1284list of Manin symbols, which need not be normalized.12851286OUTPUT:12871288``((i,u,v),s)``, where ``(i,u,v)`` is the normalized Manin symbol equivalent1289to ``x``, and ``s`` is the normalizing scalar.12901291EXAMPLE::12921293sage: eps = DirichletGroup(4).gen(0)1294sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_character1295sage: m = ManinSymbolList_character(eps,4); m1296Manin Symbol List of weight 4 for Gamma1(4) with character [-1]1297sage: [m.normalize(s.tuple()) for s in m.manin_symbol_list()]1298[((0, 0, 1), 1),1299((0, 1, 0), 1),1300((0, 1, 1), 1),1301...1302((2, 1, 3), 1),1303((2, 2, 1), 1)]1304"""1305u,v,s = self.__P1.normalize_with_scalar(x[1],x[2])1306return (x[0],u,v), self.__character(s)130713081309# class x__ManinSymbolList_gamma1(ManinSymbolList):1310# r"""1311# List of Manin symbols for `\Gamma_1(N)`.13121313# EXAMPLE::13141315# sage: from sage.modular.modsym.manin_symbols import ManinSymbolList_gamma01316# sage: m = ManinSymbolList_gamma0(5,2); m1317# Manin Symbol List of weight 2 for Gamma0(5)1318# sage: m.manin_symbol_list()1319# [(0,1), (1,0), (1,1), (1,2), (1,3), (1,4)]1320# sage: m = ManinSymbolList_gamma0(6,4); m1321# Manin Symbol List of weight 4 for Gamma0(6)1322# sage: len(m)1323# 361324# """1325# def __init__(self, level, weight):1326# r"""1327# Constructor for list of Manin symbols for `\Gamma_1(N)`.1328# """1329# self.__level = level1330# self.__G1 = g1list.G1list(self.level())1331# # The list returned from P1List is guaranteed to be sorted.1332# # Thus each list constructed below is also sorted. This is1333# # important since the index function assumes the list is sorted.1334# L = [(i, u, v) for i in range(weight-2+1) for \1335# u, v in self.__G1.list()]1336# ManinSymbolList.__init__(self, weight, L)13371338# def __repr__(self):1339# """1340# Returns a string representation for this ManinSymbol list.1341# """1342# return "Manin Symbol List of weight %s for Gamma1(%s)"%(1343# self.weight(), self.level())13441345# def apply_S(self, j):1346# """1347# Apply the matrix `S=[0,1,-1,0]` to the j-th Manin symbol.13481349# INPUT:13501351# - `j` - (int) a symbol index13521353# OUTPUT:13541355# (k, s) where k is the index of the symbol obtained by acting1356# on the `j`'th symbol with `S`, and `s` is the parity of of the1357# `j`'th symbol.13581359# """1360# i, u, v = self._list[j]1361# k = self.index((self._weight-2-i, v, -u))1362# if i%2==0:1363# return k, 11364# else:1365# return k, -113661367# def apply_I(self, j):1368# """1369# Apply the matrix `I=[-1,0,0,1]` to the j-th Manin symbol.13701371# INPUT:13721373# - `j` - (int) a symbol index13741375# OUTPUT:13761377# (k, s) where k is the index of the symbol obtained by acting1378# on the `j`'th symbol with `I`, and `s` is the parity of of the1379# `j`'th symbol.13801381# """1382# i, u, v = self._list[j]1383# k = self.index((i, -u, v))1384# if i%2==0:1385# return k, 11386# else:1387# return k, -113881389# def apply_J(self, j):1390# """1391# Apply the matrix `J=[-1,0,0,-1]` to the j-th Manin symbol.13921393# INPUT:13941395# - `j` - (int) a symbol index13961397# OUTPUT:13981399# (k, s) where k is the index of the symbol obtained by acting1400# on the `j`'th symbol with `J`, and `s` is 1.14011402# """1403# """1404# Apply 2x2 matrix J = [-1,0,0,-1].1405# """1406# i, u, v = self._list[j]1407# N = self.__level1408# return self.index((i, -u, -v)), 114091410# def apply_T(self, j):1411# """1412# Apply the matrix `T=[0,1,-1,-1]` to the j-th Manin symbol.14131414# INPUT:14151416# - `j` - (int) a symbol index14171418# OUTPUT: see documentation for apply()14191420# """1421# k = self._weight1422# i, u, v = self._list[j]1423# u, v = self.__G1.normalize(v,-u-v)1424# if (k-2) % 2 == 0:1425# s = 11426# else:1427# s = -11428# z = []1429# for j in range(k-2-i +1):1430# m = self.index((j, u, v))1431# z.append((m,s*arith.binomial(k-2-i,j)))1432# s *= -11433# return z14341435# def apply_TT(self, j):1436# """1437# Apply the matrix `TT=[-1,-1,0,1]` to the j-th Manin symbol.14381439# INPUT:14401441# - `j` - (int) a symbol index14421443# OUTPUT: see documentation for apply()14441445# """1446# k = self._weight1447# i, u, v = self._list[j]1448# u, v = self.__G1.normalize(-u-v,u)1449# if (k-2-i) % 2 == 0:1450# s = 11451# else:1452# s = -11453# z = []1454# for j in range(i+1):1455# m = self.index((k-2-i+j, u, v))1456# z.append((m,s*arith.binomial(i,j)))1457# s *= -11458# return z14591460# def apply(self, j, m):1461# """1462# Apply the integer matrix `m=[a,b;c,d]` to the `j`-th Manin symbol.14631464# INPUT:14651466# - ``j`` - (integer): the index of the symbol to act on.14671468# - ``m`` - `m = [a, b; c, d]`, a list of 4 integers.146914701471# OUTPUT: a list of pairs (j, c_i), where each c_i is an1472# integer, j is an integer (the j-th Manin symbol), and the sum1473# c_i\*x_i is the image of self under the right action of the1474# matrix [a,b;c,d]. Here the right action of g=[a,b;c,d] on a Manin1475# symbol [P(X,Y),(u,v)] is [P(aX+bY,cX+dY),(u,v)\*g].1476# """1477# a, b, c, d = m[0], m[1], m[2], m[3]1478# i, u, v = self[j]1479# P = apply_to_monomial(i, self._weight-2, a, b, c, d)1480# m = self.index((0, u*a+v*c, u*b+v*d))1481# if m == -1:1482# return []1483# r = len(self.__G1)1484# return [(m + r*k, P[k]) for k in range(self._weight-2+1)1485# if P[k] != 0]14861487# def normalize(self, x):1488# """1489# Returns the normalization of the ModSym x with respect to this1490# list.1491# """1492# u,v = self.__G1.normalize(x[1],x[2])1493# return (x[0],u,v)149414951496class ManinSymbol(SageObject):1497r"""1498A Manin symbol `[X^i\cdot Y^{k-2-i},(u,v)]`.14991500INPUT:15011502- ``parent`` - ManinSymbolList.15031504- ``t`` - a 3-tuple `(i,u,v)` of integers.15051506EXAMPLES::15071508sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01509sage: m = ManinSymbolList_gamma0(5,2)1510sage: s = ManinSymbol(m,(2,2,3)); s1511(2,3)1512sage: s == loads(dumps(s))1513True15141515::15161517sage: m = ManinSymbolList_gamma0(5,8)1518sage: s = ManinSymbol(m,(2,2,3)); s1519[X^2*Y^4,(2,3)]15201521"""1522def __init__(self, parent, t):1523r"""1524Create a Manin symbol `[X^i*Y^{k-2-i},(u,v)]`, where1525`k` is the weight.15261527INPUT:152815291530- ``parent`` - ManinSymbolList15311532- ``t`` - a 3-tuple (i,u,v) of int's.15331534EXAMPLES::15351536sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01537sage: m = ManinSymbolList_gamma0(5,2)1538sage: s = ManinSymbol(m,(2,2,3)); s1539(2,3)15401541::15421543sage: m = ManinSymbolList_gamma0(5,8)1544sage: s = ManinSymbol(m,(2,2,3)); s1545[X^2*Y^4,(2,3)]15461547"""1548if not isinstance(parent, ManinSymbolList):1549raise TypeError, "parent (=%s) must be of type ManinSymbolList."%(1550parent)1551self.__parent = parent1552if not isinstance(t, tuple):1553raise TypeError, "t (=%s) must be of type tuple."%t1554self.__t = t15551556def tuple(self):1557r"""1558Return the 3-tuple `(i,u,v)` of this ManinSymbol.15591560EXAMPLES::15611562sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01563sage: m = ManinSymbolList_gamma0(5,8)1564sage: s = ManinSymbol(m,(2,2,3))1565sage: s.tuple()1566(2, 2, 3)15671568"""1569return self.__t15701571def __get_i(self):1572"""1573Return the `i` field of this ManinSymbol `(i,u,v)`.15741575EXAMPLES::15761577sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01578sage: m = ManinSymbolList_gamma0(5,8)1579sage: s = ManinSymbol(m,(2,2,3))1580sage: s._ManinSymbol__get_i()158121582sage: s.i158321584"""1585return self.__t[0]15861587i = property(__get_i)1588def __get_u(self):1589"""1590Return the `u` field of this ManinSymbol `(i,u,v)`.15911592EXAMPLES::15931594sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01595sage: m = ManinSymbolList_gamma0(5,8)1596sage: s = ManinSymbol(m,(2,2,3))1597sage: s.u # indirect doctest159821599"""1600return self.__t[1]1601u = property(__get_u)16021603def __get_v(self):1604"""1605Return the `v` field of this ManinSymbol `(i,u,v)`.16061607EXAMPLES::16081609sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01610sage: m = ManinSymbolList_gamma0(5,8)1611sage: s = ManinSymbol(m,(2,2,3))1612sage: s.v # indirect doctest161331614"""1615return self.__t[2]1616v = property(__get_v)16171618def _repr_(self):1619"""1620Returns a string representation of this ManinSymbol.16211622EXAMPLES::16231624sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01625sage: m = ManinSymbolList_gamma0(5,8)1626sage: s = ManinSymbol(m,(2,2,3))1627sage: str(s) # indirect doctest1628'[X^2*Y^4,(2,3)]'1629"""1630if self.weight() > 2:1631polypart = _print_polypart(self.i, self.weight()-2-self.i)1632return "[%s,(%s,%s)]"%\1633(polypart, self.u, self.v)1634return "(%s,%s)"%(self.u, self.v)16351636def _latex_(self):1637"""1638Returns a LaTeX representation of this ManinSymbol.16391640EXAMPLES::16411642sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01643sage: m = ManinSymbolList_gamma0(5,8)1644sage: s = ManinSymbol(m,(2,2,3))1645sage: latex(s) # indirect doctest1646[X^2*Y^4,(2,3)]1647"""1648return self._repr_()16491650def __cmp__(self, other):1651"""1652Comparison function for ManinSymbols.16531654EXAMPLES::16551656sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01657sage: m = ManinSymbolList_gamma0(5,8)1658sage: slist = m.manin_symbol_list()1659sage: cmp(slist[10],slist[20])1660-11661sage: cmp(slist[20],slist[10])166211663sage: cmp(slist[20],slist[20])166401665"""1666if not isinstance(other, ManinSymbol):1667return -11668if self.__t == other.__t:1669return 01670return cmp(self.tuple(), other.tuple())16711672def __mul__(self, matrix):1673"""1674Returns the result of applying a matrix to this ManinSymbol.167516761677EXAMPLES::16781679sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01680sage: m = ManinSymbolList_gamma0(5,2)1681sage: s = ManinSymbol(m,(0,2,3))1682sage: s*[1,2,0,1]1683(2,7)16841685::16861687sage: m = ManinSymbolList_gamma0(5,8)1688sage: s = ManinSymbol(m,(2,2,3))1689sage: s*[1,2,0,1]1690Traceback (most recent call last):1691...1692NotImplementedError: ModSym * Matrix only implemented in weight 216931694"""1695if self.weight() > 2:1696raise NotImplementedError, "ModSym * Matrix only implemented in weight 2"1697if sage.matrix.all.is_Matrix(matrix):1698assert matrix.nrows() == 2 and matrix.ncols()==2, "matrix must be 2x2"1699matrix = matrix.list()1700return ManinSymbol(self.parent(), \1701(self.i,1702matrix[0]*self.u + matrix[2]*self.v,\1703matrix[1]*self.u + matrix[3]*self.v))1704raise ArithmeticError, "Multiplication of %s by %s not defined."%(self, matrix)170517061707def apply(self, a,b,c,d):1708"""1709Return the image of self under the matrix `[a,b;c,d]`.17101711Not implemented for raw ManinSymbol objects, only for members1712of ManinSymbolLists.17131714EXAMPLE::17151716sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01717sage: m = ManinSymbolList_gamma0(5,2)1718sage: m.apply(10,[1,0,0,1]) # not implemented for base class1719"""1720raise NotImplementedError17211722def __copy__(self):1723"""1724Return a copy of this ManinSymbol.17251726EXAMPLES::17271728sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01729sage: m = ManinSymbolList_gamma0(5,8)1730sage: s = ManinSymbol(m,(2,2,3))1731sage: s2 = copy(s)1732sage: s21733[X^2*Y^4,(2,3)]17341735"""1736return ManinSymbol(self.parent(), (self.i, self.u, self.v))17371738def lift_to_sl2z(self, N=None):1739r"""1740Returns a lift of this Manin Symbol to `SL_2(\mathbb{Z})`.17411742If this Manin symbol is `(c,d)` and `N` is its level, this1743function returns a list `[a,b, c',d']` that defines a 2x21744matrix with determinant 1 and integer entries, such that1745`c=c'` (mod `N`) and `d=d'` (mod `N`).17461747EXAMPLES::17481749sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01750sage: m = ManinSymbolList_gamma0(5,8)1751sage: s = ManinSymbol(m,(2,2,3))1752sage: s1753[X^2*Y^4,(2,3)]1754sage: s.lift_to_sl2z()1755[1, 1, 2, 3]17561757"""1758if N is None:1759N = self.level()1760if N == 1:1761return [1,0,0,1]1762c = self.u1763d = self.v1764g, z1, z2 = arith.XGCD(c,d)17651766# We're lucky: z1*c + z2*d = 1.1767if g==1:1768return [z2, -z1, c, d]17691770# Have to try harder.1771if c == 0:1772c += N;1773if d == 0:1774d += N;1775m = c;17761777# compute prime-to-d part of m.1778while True:1779g = arith.GCD(m,d)1780if g == 1:1781break1782m //= g17831784# compute prime-to-N part of m.1785while True:1786g = arith.GCD(m,N);1787if g == 1:1788break1789m //= g1790d += N*m1791g, z1, z2 = arith.XGCD(c,d)1792assert g==11793return [z2, -z1, c, d]17941795def endpoints(self, N=None):1796r"""1797Returns cusps `alpha`, `beta` such that this Manin symbol, viewed as a1798symbol for level `N`, is `X^i*Y^{k-2-i} \{alpha, beta\}`.17991800EXAMPLES::18011802sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01803sage: m = ManinSymbolList_gamma0(5,8)1804sage: s = ManinSymbol(m,(2,2,3)); s1805[X^2*Y^4,(2,3)]1806sage: s.endpoints()1807(1/3, 1/2)1808"""1809if N is None:1810N = self.parent().level()1811else:1812N=int(N)1813if N < 1:1814raise ArithmeticError, "N must be positive"1815a,b,c,d = self.lift_to_sl2z()1816return cusps.Cusp(b,d), cusps.Cusp(a,c)18171818def parent(self):1819"""1820Return the parent of this ManinSymbol.182118221823EXAMPLES::18241825sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01826sage: m = ManinSymbolList_gamma0(5,8)1827sage: s = ManinSymbol(m,(2,2,3))1828sage: s.parent()1829Manin Symbol List of weight 8 for Gamma0(5)1830"""1831return self.__parent18321833def weight(self):1834"""1835Return the weight of this ManinSymbol.18361837EXAMPLES::18381839sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01840sage: m = ManinSymbolList_gamma0(5,8)1841sage: s = ManinSymbol(m,(2,2,3))1842sage: s.weight()1843818441845"""1846return self.__parent.weight()18471848def level(self):1849"""1850Return the level of this ManinSymbol.18511852EXAMPLES::18531854sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01855sage: m = ManinSymbolList_gamma0(5,8)1856sage: s = ManinSymbol(m,(2,2,3))1857sage: s.level()1858518591860"""1861return self.__parent.level()18621863def modular_symbol_rep(self):1864"""1865Returns a representation of self as a formal sum of modular1866symbols.18671868The result is not cached.18691870EXAMPLES::18711872sage: from sage.modular.modsym.manin_symbols import ManinSymbol, ManinSymbolList_gamma01873sage: m = ManinSymbolList_gamma0(5,8)1874sage: s = ManinSymbol(m,(2,2,3))1875sage: s.modular_symbol_rep()1876144*X^6*{1/3, 1/2} - 384*X^5*Y*{1/3, 1/2} + 424*X^4*Y^2*{1/3, 1/2} - 248*X^3*Y^3*{1/3, 1/2} + 81*X^2*Y^4*{1/3, 1/2} - 14*X*Y^5*{1/3, 1/2} + Y^6*{1/3, 1/2}187718781879"""1880# TODO: It would likely be much better to do this slightly more directly1881from sage.modular.modsym.modular_symbols import ModularSymbol1882x = ModularSymbol(self.__parent, self.i, 0, rings.infinity)1883a,b,c,d = self.lift_to_sl2z()1884return x.apply([a,b,c,d])18851886def _print_polypart(i, j):1887r"""1888Helper function for printing the polynomial part `X^iY^j` of a ManinSymbol.18891890EXAMPLES::18911892sage: from sage.modular.modsym.manin_symbols import _print_polypart1893sage: _print_polypart(2,3)1894'X^2*Y^3'1895sage: _print_polypart(2,0)1896'X^2'1897sage: _print_polypart(0,1)1898'Y'1899"""1900if i > 1:1901xpart = "X^%s"%i1902elif i == 1:1903xpart = "X"1904else:1905xpart = ""1906if j > 1:1907ypart = "Y^%s"%j1908elif j == 1:1909ypart = "Y"1910else:1911ypart = ""1912if len(xpart) > 0 and len(ypart) > 0:1913times = "*"1914else:1915times = ""1916if len(xpart + ypart) > 0:1917polypart = "%s%s%s"%(xpart, times, ypart)1918else:1919polypart = ""1920return polypart192119221923