Path: blob/master/sage/modular/hecke/hecke_operator.py
4072 views
"""1Hecke operators2"""34#*****************************************************************************5# Copyright (C) 2004 William Stein <[email protected]>6#7# Distributed under the terms of the GNU General Public License (GPL)8#9# This code is distributed in the hope that it will be useful,10# but WITHOUT ANY WARRANTY; without even the implied warranty of11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU12# General Public License for more details.13#14# The full text of the GPL is available at:15#16# http://www.gnu.org/licenses/17#*****************************************************************************18192021import sage.algebras.algebra_element22from sage.categories.homset import End23import sage.rings.arith as arith24from sage.rings.integer import Integer2526import algebra27import morphism282930def is_HeckeOperator(x):31r"""32Return True if x is of type HeckeOperator.3334EXAMPLES::3536sage: from sage.modular.hecke.hecke_operator import is_HeckeOperator37sage: M = ModularSymbols(Gamma0(7), 4)38sage: is_HeckeOperator(M.T(3))39True40sage: is_HeckeOperator(M.T(3) + M.T(5))41False42"""43return isinstance(x, HeckeOperator)4445def is_HeckeAlgebraElement(x):46r"""47Return True if x is of type HeckeAlgebraElement.4849EXAMPLES::5051sage: from sage.modular.hecke.hecke_operator import is_HeckeAlgebraElement52sage: M = ModularSymbols(Gamma0(7), 4)53sage: is_HeckeAlgebraElement(M.T(3))54True55sage: is_HeckeAlgebraElement(M.T(3) + M.T(5))56True57"""58return isinstance(x, HeckeAlgebraElement)5960class HeckeAlgebraElement(sage.algebras.algebra_element.AlgebraElement):61r"""62Base class for elements of Hecke algebras.63"""64def __init__(self, parent):65r"""66Create an element of a Hecke algebra.6768EXAMPLES::6970sage: R = ModularForms(Gamma0(7), 4).hecke_algebra()71sage: sage.modular.hecke.hecke_operator.HeckeAlgebraElement(R) # please don't do this!72Generic element of a structure73"""74if not algebra.is_HeckeAlgebra(parent):75raise TypeError, "parent (=%s) must be a Hecke algebra"%parent76sage.algebras.algebra_element.AlgebraElement.__init__(self, parent)7778def domain(self):79r"""80The domain of this operator. This is the Hecke module associated to the81parent Hecke algebra.8283EXAMPLE::8485sage: R = ModularForms(Gamma0(7), 4).hecke_algebra()86sage: sage.modular.hecke.hecke_operator.HeckeAlgebraElement(R).domain()87Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field88"""8990return self.parent().module()9192def codomain(self):93r"""94The codomain of this operator. This is the Hecke module associated to the95parent Hecke algebra.9697EXAMPLE::9899sage: R = ModularForms(Gamma0(7), 4).hecke_algebra()100sage: sage.modular.hecke.hecke_operator.HeckeAlgebraElement(R).codomain()101Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field102"""103return self.parent().module()104105def hecke_module_morphism(self):106"""107Return the endomorphism of Hecke modules defined by the matrix108attached to this Hecke operator.109110EXAMPLES::111112sage: M = ModularSymbols(Gamma1(13))113sage: t = M.hecke_operator(2)114sage: t115Hecke operator T_2 on Modular Symbols space of dimension 15 for Gamma_1(13) of weight 2 with sign 0 and over Rational Field116sage: t.hecke_module_morphism()117Hecke module morphism T_2 defined by the matrix118[ 2 1 0 0 0 0 0 0 0 0 0 0 0 0 -1]119[ 0 2 0 1 0 0 0 -1 0 0 0 0 0 0 0]120[ 0 0 2 0 0 1 -1 1 0 -1 0 1 -1 0 0]121[ 0 0 0 2 1 0 1 0 0 0 1 -1 0 0 0]122[ 0 0 1 0 2 0 0 0 0 1 -1 0 0 0 1]123[ 1 0 0 0 0 2 0 0 0 0 0 0 1 0 0]124[ 0 0 0 0 0 0 0 1 -1 1 -1 0 -1 1 1]125[ 0 0 0 0 0 0 0 -1 1 1 0 0 -1 1 0]126[ 0 0 0 0 0 0 -1 -1 0 1 -1 -1 1 0 -1]127[ 0 0 0 0 0 0 -2 0 2 -2 0 2 -2 1 -1]128[ 0 0 0 0 0 0 0 0 2 -1 1 0 0 1 -1]129[ 0 0 0 0 0 0 -1 1 2 -1 1 0 -2 2 0]130[ 0 0 0 0 0 0 0 0 1 1 0 -1 0 0 0]131[ 0 0 0 0 0 0 -1 1 1 0 1 1 -1 0 0]132[ 0 0 0 0 0 0 2 0 0 0 2 -1 0 1 -1]133Domain: Modular Symbols space of dimension 15 for Gamma_1(13) of weight ...134Codomain: Modular Symbols space of dimension 15 for Gamma_1(13) of weight ...135"""136try:137return self.__hecke_module_morphism138except AttributeError:139T = self.matrix()140M = self.domain()141H = End(M)142if isinstance(self, HeckeOperator):143name = "T_%s"%self.index()144else:145name = ""146self.__hecke_module_morphism = morphism.HeckeModuleMorphism_matrix(H, T, name)147return self.__hecke_module_morphism148149def _add_(self, other):150"""151Add self to other.152153EXAMPLES::154155sage: M = ModularSymbols(11)156sage: t = M.hecke_operator(2)157sage: t158Hecke operator T_2 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field159sage: t + t # indirect doctest160Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field defined by:161[ 6 0 -2]162[ 0 -4 0]163[ 0 0 -4]164165We can also add Hecke operators with different indexes::166167sage: M = ModularSymbols(Gamma1(6),4)168sage: t2 = M.hecke_operator(2); t3 = M.hecke_operator(3)169sage: t2 + t3170Hecke operator on Modular Symbols space of dimension 6 for Gamma_1(6) of weight 4 with sign 0 and over Rational Field defined by:171[ 35 0 0 -8/7 24/7 -16/7]172[ 4 28 0 19/7 -57/7 38/7]173[ 18 0 9 -40/7 22/7 18/7]174[ 0 18 4 -22/7 -18/7 54/7]175[ 0 18 4 13/7 -53/7 54/7]176[ 0 18 4 13/7 -18/7 19/7]177sage: (t2 - t3).charpoly('x')178x^6 + 36*x^5 + 104*x^4 - 3778*x^3 + 7095*x^2 - 3458*x179"""180return self.parent()(self.matrix() + other.matrix(), check=False)181182def __call__(self, x):183"""184Apply this Hecke operator to `x`.185186EXAMPLES::187188sage: M = ModularSymbols(11); t2 = M.hecke_operator(2)189sage: t2(M.gen(0))1903*(1,0) - (1,9)191192::193194sage: t2 = M.hecke_operator(2); t3 = M.hecke_operator(3)195sage: t3(t2(M.gen(0)))19612*(1,0) - 2*(1,9)197sage: (t3*t2)(M.gen(0))19812*(1,0) - 2*(1,9)199"""200T = self.hecke_module_morphism()201return T(x)202203def __rmul__(self, left):204"""205EXAMPLES::206207sage: M = ModularSymbols(11); t2 = M.hecke_operator(2)208sage: 2*t2209Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field defined by:210[ 6 0 -2]211[ 0 -4 0]212[ 0 0 -4]213"""214return self.parent()(left * self.matrix())215216def _sub_(self, other):217"""218Compute the difference of self and other, where other has already been219coerced into the parent of self.220221EXAMPLES::222223sage: M = ModularSymbols(Gamma1(6),4)224sage: t2 = M.hecke_operator(2); t3 = M.hecke_operator(3)225sage: t2 - t3 # indirect doctest226Hecke operator on Modular Symbols space of dimension 6 for Gamma_1(6) of weight 4 with sign 0 and over Rational Field defined by:227[ -19 0 0 4/7 -12/7 8/7]228[ 4 -26 0 -17/7 51/7 -34/7]229[ -18 0 7 -12/7 -6/7 18/7]230[ 0 -18 4 -16/7 34/7 -18/7]231[ 0 -18 4 -23/7 41/7 -18/7]232[ 0 -18 4 -23/7 34/7 -11/7]233"""234return self.parent()(self.matrix() - other.matrix(), check=False)235236def apply_sparse(self, x):237"""238Apply this Hecke operator to x, where we avoid computing the matrix239of x if possible.240241EXAMPLES::242243sage: M = ModularSymbols(11)244sage: T = M.hecke_operator(23)245sage: T.apply_sparse(M.gen(0))24624*(1,0) - 5*(1,9)247"""248if x not in self.domain():249raise TypeError, "x (=%s) must be in %s"%(x, self.domain())250# Generic implementation which doesn't actually do anything251# special regarding sparseness. Override this for speed.252T = self.hecke_module_morphism()253return T(x)254255def charpoly(self, var='x'):256"""257Return the characteristic polynomial of this Hecke operator.258259INPUT:260261262- ``var`` - string (default: 'x')263264265OUTPUT: a monic polynomial in the given variable.266267EXAMPLES::268269sage: M = ModularSymbols(Gamma1(6),4)270sage: M.hecke_operator(2).charpoly('x')271x^6 - 14*x^5 + 29*x^4 + 172*x^3 - 124*x^2 - 320*x + 256272"""273return self.matrix().charpoly(var)274275def decomposition(self):276"""277Decompose the Hecke module under the action of this Hecke278operator.279280EXAMPLES::281282sage: M = ModularSymbols(11)283sage: t2 = M.hecke_operator(2)284sage: t2.decomposition()285[286Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field,287Modular Symbols subspace of dimension 2 of Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field288]289290::291292sage: M = ModularSymbols(33, sign=1).new_submodule()293sage: T = M.hecke_operator(2)294sage: T.decomposition()295[296Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field,297Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 6 for Gamma_0(33) of weight 2 with sign 1 over Rational Field298]299"""300try:301return self.__decomposition302except AttributeError:303pass304if isinstance(self, HeckeOperator) and \305arith.gcd(self.index(), self.domain().level()) == 1:306D = self.hecke_module_morphism().decomposition(is_diagonalizable=True)307else:308# TODO: There are other weaker hypotheses that imply diagonalizability.309D = self.hecke_module_morphism().decomposition()310D.sort()311D.set_immutable()312self.__decomposition = D313return D314315def det(self):316"""317Return the determinant of this Hecke operator.318319EXAMPLES::320321sage: M = ModularSymbols(23)322sage: T = M.hecke_operator(3)323sage: T.det()324100325"""326return self.hecke_module_morphism().det()327328def fcp(self, var='x'):329"""330Return the factorization of the characteristic polynomial of this331Hecke operator.332333EXAMPLES::334335sage: M = ModularSymbols(23)336sage: T = M.hecke_operator(3)337sage: T.fcp('x')338(x - 4) * (x^2 - 5)^2339"""340return self.hecke_module_morphism().fcp(var)341342def image(self):343"""344Return the image of this Hecke operator.345346EXAMPLES::347348sage: M = ModularSymbols(23)349sage: T = M.hecke_operator(3)350sage: T.fcp('x')351(x - 4) * (x^2 - 5)^2352sage: T.image()353Modular Symbols subspace of dimension 5 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field354sage: (T-4).image()355Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field356sage: (T**2-5).image()357Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field358"""359return self.hecke_module_morphism().image()360361def kernel(self):362"""363Return the kernel of this Hecke operator.364365EXAMPLES::366367sage: M = ModularSymbols(23)368sage: T = M.hecke_operator(3)369sage: T.fcp('x')370(x - 4) * (x^2 - 5)^2371sage: T.kernel()372Modular Symbols subspace of dimension 0 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field373sage: (T-4).kernel()374Modular Symbols subspace of dimension 1 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field375sage: (T**2-5).kernel()376Modular Symbols subspace of dimension 4 of Modular Symbols space of dimension 5 for Gamma_0(23) of weight 2 with sign 0 over Rational Field377"""378return self.hecke_module_morphism().kernel()379380def trace(self):381"""382Return the trace of this Hecke operator.383384::385386sage: M = ModularSymbols(1,12)387sage: T = M.hecke_operator(2)388sage: T.trace()3892001390"""391return self.hecke_module_morphism().trace()392393def __getitem__(self, ij):394"""395EXAMPLE::396397sage: M = ModularSymbols(1,12)398sage: T = M.hecke_operator(2).matrix_form()399sage: T[0,0]400-24401"""402return self.matrix()[ij]403404405class HeckeAlgebraElement_matrix(HeckeAlgebraElement):406r"""407An element of the Hecke algebra represented by a matrix.408"""409def __init__(self, parent, A):410r"""411Initialise an element from a matrix. This *must* be over the base ring412of self and have the right size.413414This is a bit overkill as similar checks will be performed by the call415and coerce methods of the parent of self, but it can't hurt to be416paranoid. Any fancy coercion / base_extension / etc happens there, not417here.418419TESTS::420421sage: T = ModularForms(Gamma0(7), 4).hecke_algebra()422sage: M = sage.modular.hecke.hecke_operator.HeckeAlgebraElement_matrix(T, matrix(QQ,3,[2,3,0,1,2,3,7,8,9])); M423Hecke operator on Modular Forms space of dimension 3 for Congruence Subgroup Gamma0(7) of weight 4 over Rational Field defined by:424[2 3 0]425[1 2 3]426[7 8 9]427sage: loads(dumps(M)) == M428True429sage: sage.modular.hecke.hecke_operator.HeckeAlgebraElement_matrix(T, matrix(Integers(2),3,[2,3,0,1,2,3,7,8,9]))430Traceback (most recent call last):431...432TypeError: base ring of matrix (Ring of integers modulo 2) does not match base ring of space (Rational Field)433sage: sage.modular.hecke.hecke_operator.HeckeAlgebraElement_matrix(T, matrix(QQ,2,[2,3,0,1]))434Traceback (most recent call last):435...436TypeError: A must be a square matrix of rank 3437"""438HeckeAlgebraElement.__init__(self, parent)439if not sage.matrix.all.is_Matrix(A):440raise TypeError, "A must be a matrix"441if not A.base_ring() == self.parent().base_ring():442raise TypeError, "base ring of matrix (%s) does not match base ring of space (%s)" % (A.base_ring(), self.parent().base_ring())443if not A.nrows() == A.ncols() == self.parent().module().rank():444raise TypeError, "A must be a square matrix of rank %s" % self.parent().module().rank()445self.__matrix = A446447def __cmp__(self, other):448r"""449Compare self to other, where the coercion model has already ensured450that other has the same parent as self.451452EXAMPLES::453454sage: T = ModularForms(SL2Z, 12).hecke_algebra()455sage: m = T(matrix(QQ, 2, [1,2,0,1]), check=False); n = T.hecke_operator(14)456sage: m == n457False458sage: m == n.matrix_form()459False460sage: n.matrix_form() == T(matrix(QQ, 2, [4051542498456, 384163586352000, 0, 401856]), check=False)461True462"""463if not isinstance(other, HeckeAlgebraElement_matrix):464if isinstance(other, HeckeOperator):465return cmp(self, other.matrix_form())466else:467raise RuntimeError, "Bug in coercion code" # can't get here.468return cmp(self.__matrix, other.__matrix)469470def _repr_(self):471r"""472String representation of self.473474EXAMPLES::475476sage: M = ModularSymbols(1,12)477sage: M.hecke_operator(2).matrix_form()._repr_()478'Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field defined by:\n[ -24 0 0]\n[ 0 -24 0]\n[4860 0 2049]'479sage: ModularForms(Gamma0(100)).hecke_operator(4).matrix_form()._repr_()480'Hecke operator on Modular Forms space of dimension 24 for Congruence Subgroup Gamma0(100) of weight 2 over Rational Field defined by:\n24 x 24 dense matrix over Rational Field'481"""482return "Hecke operator on %s defined by:\n%s"%(self.parent().module(), self.__matrix)483484def _latex_(self):485r"""486Latex representation of self (just prints the matrix)487488EXAMPLE::489490sage: M = ModularSymbols(1,12)491sage: M.hecke_operator(2).matrix_form()._latex_()492'\\left(\\begin{array}{rrr}\n-24 & 0 & 0 \\\\\n0 & -24 & 0 \\\\\n4860 & 0 & 2049\n\\end{array}\\right)'493"""494return self.__matrix._latex_()495496def matrix(self):497"""498Return the matrix that defines this Hecke algebra element.499500EXAMPLES::501502sage: M = ModularSymbols(1,12)503sage: T = M.hecke_operator(2).matrix_form()504sage: T.matrix()505[ -24 0 0]506[ 0 -24 0]507[4860 0 2049]508"""509return self.__matrix510511def _mul_(self, other):512r"""513Multiply self by other (which has already been coerced into an element514of the parent of self).515516EXAMPLES::517518sage: M = ModularSymbols(1,12)519sage: T = M.hecke_operator(2).matrix_form()520sage: T * T # indirect doctest521Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(1) of weight 12 with sign 0 over Rational Field defined by:522[ 576 0 0]523[ 0 576 0]524[9841500 0 4198401]525"""526return self.parent()(other.matrix() * self.matrix(), check=False)527528529class DiamondBracketOperator(HeckeAlgebraElement_matrix):530r"""531The diamond bracket operator `\langle d \rangle` for some `d \in \ZZ /532N\ZZ` (which need not be a unit, although if it is not, the operator will533be zero).534"""535def __init__(self, parent, d):536r"""537Standard init function.538539EXAMPLE::540541sage: M = ModularSymbols(Gamma1(5),6)542sage: d = M.diamond_bracket_operator(2); d # indirect doctest543Diamond bracket operator <2> on Modular Symbols space of dimension 10 for Gamma_1(5) of weight 6 with sign 0 and over Rational Field544sage: type(d)545<class 'sage.modular.hecke.hecke_operator.DiamondBracketOperator'>546sage: d.matrix()547[ 0 1 0 0 0 0 0 0 0 0]548[ 1 0 0 0 0 0 0 0 0 0]549[ 0 0 0 0 0 0 0 1 0 0]550[ 0 0 -8/17 -1 14/17 11/17 0 -8/17 14/17 11/17]551[ 0 0 0 0 0 0 0 0 1 0]552[ 0 0 0 0 0 0 0 0 0 1]553[ 0 0 16/17 0 -11/17 12/17 -1 16/17 -11/17 12/17]554[ 0 0 1 0 0 0 0 0 0 0]555[ 0 0 0 0 1 0 0 0 0 0]556[ 0 0 0 0 0 1 0 0 0 0]557sage: d**4 == 1558True559"""560self.__d = d561A = parent.diamond_bracket_matrix(d)562HeckeAlgebraElement_matrix.__init__(self, parent, A)563564def _repr_(self):565r"""566EXAMPLE::567568sage: ModularSymbols(Gamma1(5), 6).diamond_bracket_operator(2)._repr_()569'Diamond bracket operator <2> on Modular Symbols space of dimension 10 for Gamma_1(5) of weight 6 with sign 0 and over Rational Field'570"""571return "Diamond bracket operator <%s> on %s" % (self.__d, self.domain())572573def _latex_(self):574r"""575EXAMPLE::576577sage: latex(ModularSymbols(Gamma1(5), 12).diamond_bracket_operator(2)) # indirect doctest578\langle 2 \rangle579"""580return r"\langle %s \rangle" % self.__d581582class HeckeOperator(HeckeAlgebraElement):583r"""584The Hecke operator `T_n` for some `n` (which need not be coprime to the585level). The matrix is not computed until it is needed.586"""587def __init__(self, parent, n):588"""589EXAMPLES::590591sage: M = ModularSymbols(11)592sage: H = M.hecke_operator(2005); H593Hecke operator T_2005 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field594sage: H == loads(dumps(H))595True596597We create a Hecke operator of large index (greater than 32 bits)::598599sage: M1 = ModularSymbols(21,2)600sage: M1.hecke_operator(13^9)601Hecke operator T_10604499373 on Modular Symbols space of dimension 5 for Gamma_0(21) of weight 2 with sign 0 over Rational Field602"""603HeckeAlgebraElement.__init__(self, parent)604if not isinstance(n, (int,long,Integer)):605raise TypeError, "n must be an int"606self.__n = int(n)607608def __cmp__(self, other):609r"""610Compare self and other (where the coercion model has already ensured611that self and other have the same parent). Hecke operators on the same612space compare as equal if and only if their matrices are equal, so we613check if the indices are the same and if not we compute the matrices614(which is potentially expensive).615616EXAMPLES::617618sage: M = ModularSymbols(Gamma0(7), 4)619sage: m = M.hecke_operator(3)620sage: m == m621True622sage: m == 2*m623False624sage: m == M.hecke_operator(5)625False626627These last two tests involve a coercion::628629sage: m == m.matrix_form()630True631sage: m == m.matrix()632False633"""634635if not isinstance(other, HeckeOperator):636if isinstance(other, HeckeAlgebraElement_matrix):637return cmp(self.matrix_form(), other)638else:639raise RuntimeError, "Bug in coercion code" # can't get here640641if self.__n == other.__n:642return 0643return cmp(self.matrix(), other.matrix())644645def _repr_(self):646r"""647String representation of self648649EXAMPLE::650651sage: ModularSymbols(Gamma0(7), 4).hecke_operator(6)._repr_()652'Hecke operator T_6 on Modular Symbols space of dimension 4 for Gamma_0(7) of weight 4 with sign 0 over Rational Field'653"""654return "Hecke operator T_%s on %s"%(self.__n, self.domain())655656def _latex_(self):657r"""658LaTeX representation of self659660EXAMPLE::661662sage: ModularSymbols(Gamma0(7), 4).hecke_operator(6)._latex_()663'T_{6}'664"""665return "T_{%s}"%self.__n666667def _mul_(self, other):668"""669Multiply this Hecke operator by another element of the same algebra. If670the other element is of the form `T_m` for some m, we check whether the671product is equal to `T_{mn}` and return that; if the product is not672(easily seen to be) of the form `T_{mn}`, then we calculate the product673of the two matrices and return a Hecke algebra element defined by that.674675EXAMPLES: We create the space of modular symbols of level676`11` and weight `2`, then compute `T_2`677and `T_3` on it, along with their composition.678679::680681sage: M = ModularSymbols(11)682sage: t2 = M.hecke_operator(2); t3 = M.hecke_operator(3)683sage: t2*t3 # indirect doctest684Hecke operator T_6 on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field685sage: t3.matrix() * t2.matrix()686[12 0 -2]687[ 0 2 0]688[ 0 0 2]689sage: (t2*t3).matrix()690[12 0 -2]691[ 0 2 0]692[ 0 0 2]693694When we compute `T_2^5` the result is not (easily seen to695be) a Hecke operator of the form `T_n`, so it is returned696as a Hecke module homomorphism defined as a matrix::697698sage: t2**5699Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field defined by:700[243 0 -55]701[ 0 -32 0]702[ 0 0 -32]703"""704if isinstance(other, HeckeOperator) and other.parent() == self.parent():705n = None706if arith.gcd(self.__n, other.__n) == 1:707n = self.__n * other.__n708else:709P = set(arith.prime_divisors(self.domain().level()))710if P.issubset(set(arith.prime_divisors(self.__n))) and \711P.issubset(set(arith.prime_divisors(other.__n))):712n = self.__n * other.__n713if n:714return HeckeOperator(self.parent(), n)715# otherwise716return self.matrix_form() * other717718def index(self):719"""720Return the index of this Hecke operator, i.e., if this Hecke721operator is `T_n`, return the int `n`.722723EXAMPLES::724725sage: T = ModularSymbols(11).hecke_operator(17)726sage: T.index()72717728"""729return self.__n730731def matrix(self, *args, **kwds):732"""733Return the matrix underlying this Hecke operator.734735EXAMPLES::736737sage: T = ModularSymbols(11).hecke_operator(17)738sage: T.matrix()739[18 0 -4]740[ 0 -2 0]741[ 0 0 -2]742"""743try:744return self.__matrix745except AttributeError:746self.__matrix = self.parent().hecke_matrix(self.__n, *args, **kwds)747return self.__matrix748749def matrix_form(self):750"""751Return the matrix form of this element of a Hecke algebra.752753::754755sage: T = ModularSymbols(11).hecke_operator(17)756sage: T.matrix_form()757Hecke operator on Modular Symbols space of dimension 3 for Gamma_0(11) of weight 2 with sign 0 over Rational Field defined by:758[18 0 -4]759[ 0 -2 0]760[ 0 0 -2]761"""762try:763return self.__matrix_form764except AttributeError:765self.__matrix_form = self.parent()(self.matrix(), check=False)766return self.__matrix_form767768769770