Path: blob/master/src/sage/modular/abvar/finite_subgroup.py
8820 views
r"""1Finite subgroups of modular abelian varieties23Sage can compute with fairly general finite subgroups of modular4abelian varieties. Elements of finite order are represented by5equivalence classes of elements in `H_1(A,\QQ)`6modulo `H_1(A,\ZZ)`. A finite subgroup can be7defined by giving generators and via various other constructions.8Given a finite subgroup, one can compute generators, as well as the9structure as an abstract group. Arithmetic on subgroups is also10supported, including adding two subgroups together, checking11inclusion, etc.1213TODO: Intersection, action of Hecke operators.1415AUTHORS:1617- William Stein (2007-03)1819EXAMPLES::2021sage: J = J0(33)22sage: C = J.cuspidal_subgroup()23sage: C24Finite subgroup with invariants [10, 10] over QQ of Abelian variety J0(33) of dimension 325sage: C.order()2610027sage: C.gens()28[[(1/10, 0, 1/10, 1/10, 1/10, 3/10)], [(0, 1/5, 1/10, 0, 1/10, 9/10)], [(0, 0, 1/2, 0, 1/2, 1/2)]]29sage: C.0 + C.130[(1/10, 1/5, 1/5, 1/10, 1/5, 6/5)]31sage: 10*(C.0 + C.1)32[(0, 0, 0, 0, 0, 0)]33sage: G = C.subgroup([C.0 + C.1]); G34Finite subgroup with invariants [10] over QQbar of Abelian variety J0(33) of dimension 335sage: G.gens()36[[(1/10, 1/5, 1/5, 1/10, 1/5, 1/5)]]37sage: G.order()381039sage: G <= C40True41sage: G >= C42False4344We make a table of the order of the cuspidal subgroup for the first45few levels::4647sage: for N in range(11,40): print N, J0(N).cuspidal_subgroup().order()48...4911 55012 15113 15214 65315 85416 15517 45618 15719 35820 65921 86022 256123 116224 86325 16426 216527 96628 366729 76830 1926931 57032 87133 1007234 487335 487436 127537 37638 1357739 567879TESTS::8081sage: G = J0(11).finite_subgroup([[1/3,0], [0,1/5]]); G82Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 183sage: loads(dumps(G)) == G84True85sage: loads(dumps(G.0)) == G.086True87"""8889###########################################################################90# Copyright (C) 2007 William Stein <[email protected]> #91# Distributed under the terms of the GNU General Public License (GPL) #92# http://www.gnu.org/licenses/ #93###########################################################################9495from sage.modules.module import Module_old96from sage.modules.free_module import is_FreeModule97from sage.structure.element import ModuleElement98from sage.structure.sequence import Sequence99from sage.rings.all import gcd, lcm, QQ, ZZ, QQbar, Integer, composite_field100from sage.misc.misc import prod101102import abvar as abelian_variety103from sage.categories.fields import Fields104_Fields = Fields()105106class FiniteSubgroup(Module_old):107def __init__(self, abvar, field_of_definition=QQ):108"""109A finite subgroup of a modular abelian variety.110111INPUT:112113114- ``abvar`` - a modular abelian variety115116- ``field_of_definition`` - a field over which this117group is defined.118119120EXAMPLES: This is an abstract base class, so there are no instances121of this class itself.122123::124125sage: A = J0(37)126sage: G = A.torsion_subgroup(3); G127Finite subgroup with invariants [3, 3, 3, 3] over QQ of Abelian variety J0(37) of dimension 2128sage: type(G)129<class 'sage.modular.abvar.finite_subgroup.FiniteSubgroup_lattice'>130sage: from sage.modular.abvar.finite_subgroup import FiniteSubgroup131sage: isinstance(G, FiniteSubgroup)132True133"""134if field_of_definition not in _Fields:135raise TypeError, "field_of_definition must be a field"136if not abelian_variety.is_ModularAbelianVariety(abvar):137raise TypeError, "abvar must be a modular abelian variety"138Module_old.__init__(self, ZZ)139self.__abvar = abvar140self.__field_of_definition = field_of_definition141142################################################################143# DERIVED CLASS MUST OVERRIDE THE lattice METHOD144################################################################145def lattice(self):146"""147Return the lattice corresponding to this subgroup in the rational148homology of the modular Jacobian product. The elements of the149subgroup are represented by vectors in the ambient vector space150(the rational homology), and this returns the lattice they span.151EXAMPLES::152153sage: J = J0(33); C = J[0].cuspidal_subgroup(); C154Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)155sage: C.lattice()156Free module of degree 6 and rank 2 over Integer Ring157Echelon basis matrix:158[ 1/5 13/5 -2 -4/5 2 -1/5]159[ 0 3 -2 -1 2 0]160"""161raise NotImplementedError162163def _relative_basis_matrix(self):164"""165Return matrix of this finite subgroup, but relative to the homology166of the parent abelian variety.167168EXAMPLES::169170sage: A = J0(43)[1]; A171Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)172sage: C = A.cuspidal_subgroup(); C173Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)174sage: C._relative_basis_matrix()175[ 1 0 0 0]176[ 0 1/7 6/7 5/7]177[ 0 0 1 0]178[ 0 0 0 1]179"""180try:181return self.__relative_basis_matrix182except AttributeError:183M = self.__abvar.lattice().coordinate_module(self.lattice()).basis_matrix()184self.__relative_basis_matrix = M185return M186187# General functionality188def __cmp__(self, other):189"""190Compare this finite subgroup to other.191192If other is not a modular abelian variety finite subgroup, then the193types of self and other are compared. If other is a finite194subgroup, and the ambient abelian varieties are equal, then the195subgroups themselves are compared, by comparing their full modules.196If the containing abelian varieties are not equal and their ambient197varieties are different they are compared; if they are the same,198then a NotImplemnetedError is raised (this is temporary).199200EXAMPLES: We first compare to subgroups of `J_0(37)`::201202sage: A = J0(37)203sage: G = A.torsion_subgroup(3); G.order()20481205sage: H = A.cuspidal_subgroup(); H.order()2063207sage: H < G208True209sage: H.is_subgroup(G)210True211sage: H < 5 #random (meaningless since it depends on memory layout)212False213sage: 5 < H #random (meaningless since it depends on memory layout)214True215216The ambient varieties are compared::217218sage: cmp(A[0].cuspidal_subgroup(), J0(11).cuspidal_subgroup())2191220221Comparing subgroups sitting in different abelian varieties::222223sage: cmp(A[0].cuspidal_subgroup(), A[1].cuspidal_subgroup())224-1225"""226if not isinstance(other, FiniteSubgroup):227return cmp(type(self), type(other))228A = self.abelian_variety()229B = other.abelian_variety()230if not A.in_same_ambient_variety(B):231return cmp(A.ambient_variety(), B.ambient_variety())232L = A.lattice() + B.lattice()233# Minus sign because order gets reversed in passing to lattices.234return -cmp(self.lattice() + L, other.lattice() + L)235236def is_subgroup(self, other):237"""238Return True exactly if self is a subgroup of other, and both are239defined as subgroups of the same ambient abelian variety.240241EXAMPLES::242243sage: C = J0(22).cuspidal_subgroup()244sage: H = C.subgroup([C.0])245sage: K = C.subgroup([C.1])246sage: H.is_subgroup(K)247False248sage: K.is_subgroup(H)249False250sage: K.is_subgroup(C)251True252sage: H.is_subgroup(C)253True254"""255# We use that self is contained in other, whether other is256# either a finite group or an abelian variety, if and only257# if self doesn't shrink when intersected with other.258try:259return self.intersection(other).order() == self.order()260except TypeError:261return False262263def __add__(self, other):264"""265Return the sum of two subgroups.266267EXAMPLES::268269sage: C = J0(22).cuspidal_subgroup()270sage: C.gens()271[[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]272sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])273sage: A + B == C274True275"""276if not isinstance(other, FiniteSubgroup):277raise TypeError, "only addition of two finite subgroups is defined"278A = self.abelian_variety()279B = other.abelian_variety()280if not A.in_same_ambient_variety(B):281raise ValueError("self and other must be in the same ambient Jacobian")282K = composite_field(self.field_of_definition(), other.field_of_definition())283lattice = self.lattice() + other.lattice()284if A != B:285lattice += C.lattice()286287return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=K)288289def exponent(self):290"""291Return the exponent of this finite abelian group.292293OUTPUT: Integer294295EXAMPLES::296297sage: t = J0(33).hecke_operator(7)298sage: G = t.kernel()[0]; G299Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3300sage: G.exponent()3014302"""303try:304return self.__exponent305except AttributeError:306e = lcm(self.invariants())307self.__exponent = e308return e309310def intersection(self, other):311"""312Return the intersection of the finite subgroups self and other.313314INPUT:315316317- ``other`` - a finite group318319320OUTPUT: a finite group321322EXAMPLES::323324sage: E11a0, E11a1, B = J0(33)325sage: G = E11a0.torsion_subgroup(6); H = E11a0.torsion_subgroup(9)326sage: G.intersection(H)327Finite subgroup with invariants [3, 3] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)328sage: W = E11a1.torsion_subgroup(15)329sage: G.intersection(W)330Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)331sage: E11a0.intersection(E11a1)[0]332Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)333334We intersect subgroups of different abelian varieties.335336::337338sage: E11a0, E11a1, B = J0(33)339sage: G = E11a0.torsion_subgroup(5); H = E11a1.torsion_subgroup(5)340sage: G.intersection(H)341Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)342sage: E11a0.intersection(E11a1)[0]343Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)344345We intersect abelian varieties with subgroups::346347sage: t = J0(33).hecke_operator(7)348sage: G = t.kernel()[0]; G349Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3350sage: A = J0(33).old_subvariety()351sage: A.intersection(G)352Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)353sage: A.hecke_operator(7).kernel()[0]354Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)355sage: B = J0(33).new_subvariety()356sage: B.intersection(G)357Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)358sage: B.hecke_operator(7).kernel()[0]359Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)360sage: A.intersection(B)[0]361Finite subgroup with invariants [3, 3] over QQ of Abelian subvariety of dimension 2 of J0(33)362"""363A = self.abelian_variety()364if abelian_variety.is_ModularAbelianVariety(other):365amb = other366B = other367M = B.lattice().scale(Integer(1)/self.exponent())368K = composite_field(self.field_of_definition(), other.base_field())369else:370amb = A371if not isinstance(other, FiniteSubgroup):372raise TypeError, "only addition of two finite subgroups is defined"373B = other.abelian_variety()374if A.ambient_variety() != B.ambient_variety():375raise TypeError, "finite subgroups must be in the same ambient product Jacobian"376M = other.lattice()377K = composite_field(self.field_of_definition(), other.field_of_definition())378379L = self.lattice()380if A != B:381# TODO: This might be way slower than what we could do if382# we think more carefully.383C = A + B384L = L + C.lattice()385M = M + C.lattice()386W = L.intersection(M).intersection(amb.vector_space())387return FiniteSubgroup_lattice(amb, W, field_of_definition=K)388389def __mul__(self, right):390"""391Multiply this subgroup by the rational number right.392393If right is an integer the result is a subgroup of self. If right394is a rational number `n/m`, then this group is first395divided by `m` then multiplied by `n`.396397INPUT:398399400- ``right`` - a rational number401402403OUTPUT: a subgroup404405EXAMPLES::406407sage: J = J0(37)408sage: H = J.cuspidal_subgroup(); H.order()4093410sage: G = H * 3; G.order()4111412sage: G = H * (1/2); G.order()41348414sage: J.torsion_subgroup(2) + H == G415True416sage: G = H*(3/2); G.order()41716418sage: J = J0(42)419sage: G = J.cuspidal_subgroup(); factor(G.order())4202^8 * 3^2421sage: (G * 3).order()422256423sage: (G * 0).order()4241425sage: (G * (1/5)).order()42622500000000427"""428lattice = self.lattice().scale(right)429return FiniteSubgroup_lattice(self.abelian_variety(), lattice,430field_of_definition = self.field_of_definition())431432def __rmul__(self, left):433"""434Multiply this finite subgroup on the left by an integer.435436EXAMPLES::437438sage: J = J0(42)439sage: G = J.cuspidal_subgroup(); factor(G.order())4402^8 * 3^2441sage: H = G.__rmul__(2)442sage: H.order().factor()4432^4 * 3^2444sage: 2*G445Finite subgroup with invariants [6, 24] over QQ of Abelian variety J0(42) of dimension 5446"""447return self * left448449def abelian_variety(self):450"""451Return the abelian variety that this is a finite subgroup of.452453EXAMPLES::454455sage: J = J0(42)456sage: G = J.rational_torsion_subgroup(); G457Torsion subgroup of Abelian variety J0(42) of dimension 5458sage: G.abelian_variety()459Abelian variety J0(42) of dimension 5460"""461return self.__abvar462463def field_of_definition(self):464"""465Return the field over which this finite modular abelian variety466subgroup is defined. This is a field over which this subgroup is467defined.468469EXAMPLES::470471sage: J = J0(42)472sage: G = J.rational_torsion_subgroup(); G473Torsion subgroup of Abelian variety J0(42) of dimension 5474sage: G.field_of_definition()475Rational Field476"""477return self.__field_of_definition478479def _repr_(self):480"""481Return string representation of this finite subgroup.482483EXAMPLES::484485sage: J = J0(42)486sage: G = J.torsion_subgroup(3); G._repr_()487'Finite subgroup with invariants [3, 3, 3, 3, 3, 3, 3, 3, 3, 3] over QQ of Abelian variety J0(42) of dimension 5'488"""489K = self.__field_of_definition490if K == QQbar:491field = "QQbar"492elif K == QQ:493field = "QQ"494else:495field = str(K)496return "Finite subgroup %sover %s of %s"%(self._invariants_repr(), field, self.__abvar)497498def _invariants_repr(self):499"""500The string representation of the 'invariants' part of this group.501502We make this a separate function so it is possible to create finite503subgroups that don't print their invariants, since printing them504could be expensive.505506EXAMPLES::507508sage: J0(42).cuspidal_subgroup()._invariants_repr()509'with invariants [2, 2, 12, 48] '510"""511return 'with invariants %s '%(self.invariants(), )512513def order(self):514"""515Return the order (number of elements) of this finite subgroup.516517EXAMPLES::518519sage: J = J0(42)520sage: C = J.cuspidal_subgroup()521sage: C.order()5222304523"""524try:525return self.__order526except AttributeError:527if self.__abvar.dimension() == 0:528self.__order = ZZ(1)529return self.__order530o = prod(self.invariants())531self.__order = o532return o533534def gens(self):535"""536Return generators for this finite subgroup.537538EXAMPLES: We list generators for several cuspidal subgroups::539540sage: J0(11).cuspidal_subgroup().gens()541[[(0, 1/5)]]542sage: J0(37).cuspidal_subgroup().gens()543[[(0, 0, 0, 1/3)]]544sage: J0(43).cuspidal_subgroup().gens()545[[(0, 1/7, 0, 6/7, 0, 5/7)]]546sage: J1(13).cuspidal_subgroup().gens()547[[(1/19, 0, 0, 9/19)], [(0, 1/19, 1/19, 18/19)]]548sage: J0(22).torsion_subgroup(6).gens()549[[(1/6, 0, 0, 0)], [(0, 1/6, 0, 0)], [(0, 0, 1/6, 0)], [(0, 0, 0, 1/6)]]550"""551try:552return self.__gens553except AttributeError:554pass555556B = [TorsionPoint(self, v) for v in self.lattice().basis() if v.denominator() > 1]557self.__gens = Sequence(B, immutable=True)558return self.__gens559560def gen(self, n):561r"""562Return `n^{th}` generator of self.563564EXAMPLES::565566sage: J = J0(23)567sage: C = J.torsion_subgroup(3)568sage: C.gens()569[[(1/3, 0, 0, 0)], [(0, 1/3, 0, 0)], [(0, 0, 1/3, 0)], [(0, 0, 0, 1/3)]]570sage: C.gen(0)571[(1/3, 0, 0, 0)]572sage: C.gen(3)573[(0, 0, 0, 1/3)]574sage: C.gen(4)575Traceback (most recent call last):576...577IndexError: list index out of range578579Negative indices wrap around::580581sage: C.gen(-1)582[(0, 0, 0, 1/3)]583"""584return self.gens()[n]585586def __call__(self, x):587r"""588Coerce `x` into this finite subgroup.589590This works when the abelian varieties that contains x and self are591the same, or if `x` is coercible into the rational homology592(viewed as an abstract `\QQ`-vector space).593594EXAMPLES: We first construct the `11`-torsion subgroup of595`J_0(23)`::596597sage: J = J0(23)598sage: G = J.torsion_subgroup(11)599sage: G.invariants()600[11, 11, 11, 11]601602We also construct the cuspidal subgroup.603604::605606sage: C = J.cuspidal_subgroup()607sage: C.invariants()608[11]609610Coercing something into its parent returns it::611612sage: G(G.0) is G.0613True614615We coerce an element from the cuspidal subgroup into the616`11`-torsion subgroup::617618sage: z = G(C.0); z619[(1/11, 10/11, 0, 8/11)]620sage: z.parent() == G621True622623We coerce a list, which defines an element of the underlying624``full_module`` into `G`, and verify an625equality::626627sage: x = G([1/11, 1/11, 0, -1/11])628sage: x == G([1/11, 1/11, 0, 10/11])629True630631Finally we attempt to coerce in an element that shouldn't work,632since is is not in `G`::633634sage: G(J.torsion_subgroup(3).0)635Traceback (most recent call last):636...637TypeError: x does not define an element of self638"""639if isinstance(x, TorsionPoint):640if x.parent() is self:641return x642elif x.parent() == self:643return TorsionPoint(self, x.element(), check=False)644elif x.parent().abelian_variety() == self.abelian_variety():645return self(x.element())646else:647raise TypeError, "x does not define an element of self"648else:649z = self.abelian_variety().vector_space()(x)650if not z in self.lattice():651raise TypeError, "x does not define an element of self"652return TorsionPoint(self, z, check=False)653654655def __contains__(self, x):656"""657Returns True if x is contained in this finite subgroup.658659EXAMPLES: We define two distinct finite subgroups of660`J_0(27)`::661662sage: G1 = J0(27).rational_cusp_subgroup(); G1663Finite subgroup with invariants [3] over QQ of Abelian variety J0(27) of dimension 1664sage: G1.0665[(1/3, 0)]666sage: G2 = J0(27).cuspidal_subgroup(); G2667Finite subgroup with invariants [3, 3] over QQ of Abelian variety J0(27) of dimension 1668sage: G2.gens()669[[(1/3, 0)], [(0, 1/3)]]670671Now we check whether various elements are in `G_1` and672`G_2`::673674sage: G2.0 in G1675True676sage: G2.1 in G1677False678sage: G1.0 in G1679True680sage: G1.0 in G2681True682683The integer `0` is in, since it coerces in::684685sage: 0 in G1686True687688Elements that have a completely different ambient product Jacobian689are never in `G`::690691sage: J0(23).cuspidal_subgroup().0 in G1692False693sage: J0(23).cuspidal_subgroup()(0) in G1694False695"""696try:697self(x)698except TypeError:699return False700return True701702def subgroup(self, gens):703"""704Return the subgroup of self spanned by the given generators, which705all must be elements of self.706707EXAMPLES::708709sage: J = J0(23)710sage: G = J.torsion_subgroup(11); G711Finite subgroup with invariants [11, 11, 11, 11] over QQ of Abelian variety J0(23) of dimension 2712713We create the subgroup of the 11-torsion subgroup of714`J_0(23)` generated by the first `11`-torsion715point::716717sage: H = G.subgroup([G.0]); H718Finite subgroup with invariants [11] over QQbar of Abelian variety J0(23) of dimension 2719sage: H.invariants()720[11]721722We can also create a subgroup from a list of objects that coerce723into the ambient rational homology.724725::726727sage: H == G.subgroup([[1/11,0,0,0]])728True729"""730if not isinstance(gens, (tuple, list)):731raise TypeError, "gens must be a list or tuple"732A = self.abelian_variety()733lattice = A._ambient_lattice().span([self(g).element() for g in gens])734return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=QQbar)735736def invariants(self):737r"""738Return elementary invariants of this abelian group, by which we739mean a nondecreasing (immutable) sequence of integers740`n_i`, `1 \leq i \leq k`, with `n_i`741dividing `n_{i+1}`, and such that this group is abstractly742isomorphic to743`\ZZ/n_1\ZZ \times\cdots\times \ZZ/n_k\ZZ.`744745EXAMPLES::746747sage: J = J0(38)748sage: C = J.cuspidal_subgroup(); C749Finite subgroup with invariants [3, 45] over QQ of Abelian variety J0(38) of dimension 4750sage: v = C.invariants(); v751[3, 45]752sage: v[0] = 5753Traceback (most recent call last):754...755ValueError: object is immutable; please change a copy instead.756sage: type(v[0])757<type 'sage.rings.integer.Integer'>758759::760761sage: C * 3762Finite subgroup with invariants [15] over QQ of Abelian variety J0(38) of dimension 4763764An example involving another cuspidal subgroup::765766sage: C = J0(22).cuspidal_subgroup(); C767Finite subgroup with invariants [5, 5] over QQ of Abelian variety J0(22) of dimension 2768sage: C.lattice()769Free module of degree 4 and rank 4 over Integer Ring770Echelon basis matrix:771[1/5 1/5 4/5 0]772[ 0 1 0 0]773[ 0 0 1 0]774[ 0 0 0 1/5]775sage: C.invariants()776[5, 5]777"""778try:779return self.__invariants780except AttributeError:781pass782M = self.lattice().coordinate_module(self.abelian_variety().lattice())783E = M.basis_matrix().change_ring(ZZ).elementary_divisors()784v = [Integer(x) for x in E if x != 1]785I = Sequence(v)786I.sort()787I.set_immutable()788self.__invariants = I789return I790791class FiniteSubgroup_lattice(FiniteSubgroup):792def __init__(self, abvar, lattice, field_of_definition=QQbar, check=True):793"""794A finite subgroup of a modular abelian variety that is defined by a795given lattice.796797INPUT:798799800- ``abvar`` - a modular abelian variety801802- ``lattice`` - a lattice that contains the lattice of803abvar804805- ``field_of_definition`` - the field of definition806of this finite group scheme807808- ``check`` - bool (default: True) whether or not to809check that lattice contains the abvar lattice.810811812EXAMPLES::813814sage: J = J0(11)815sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G816Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1817"""818if check:819if not is_FreeModule(lattice) or lattice.base_ring() != ZZ:820raise TypeError, "lattice must be a free module over ZZ"821if not abelian_variety.is_ModularAbelianVariety(abvar):822raise TypeError, "abvar must be a modular abelian variety"823if not abvar.lattice().is_submodule(lattice):824lattice += abvar.lattice()825if lattice.rank() != abvar.lattice().rank():826raise ValueError, "lattice must contain the lattice of abvar with finite index"827FiniteSubgroup.__init__(self, abvar, field_of_definition)828self.__lattice = lattice829830def lattice(self):831r"""832Return lattice that defines this finite subgroup.833834EXAMPLES::835836sage: J = J0(11)837sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G838Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1839sage: G.lattice()840Free module of degree 2 and rank 2 over Integer Ring841Echelon basis matrix:842[1/3 0]843[ 0 1/5]844"""845return self.__lattice846847###########################################################################848# Elements of finite order849###########################################################################850851class TorsionPoint(ModuleElement):852def __init__(self, parent, element, check=True):853"""854An element of a finite subgroup of a modular abelian variety.855856INPUT:857858859- ``parent`` - a finite subgroup of a modular abelian860variety861862- ``element`` - a QQ vector space element that863represents this element in terms of the ambient rational homology864865- ``check`` - bool (default: True) whether to check866that element is in the appropriate vector space867868869EXAMPLES: The following calls the TorsionPoint constructor870implicitly::871872sage: J = J0(11)873sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G874Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1875sage: type(G.0)876<class 'sage.modular.abvar.finite_subgroup.TorsionPoint'>877"""878ModuleElement.__init__(self, parent)879if check:880if not element in parent.abelian_variety().vector_space():881raise TypeError, "element must be a vector in the abelian variety's rational homology (embedded in the ambient Jacobian product)"882if element.denominator() == 1:883element = element.parent().zero_vector()884self.__element = element885886def element(self):887"""888Return an underlying QQ-vector space element that defines this889element of a modular abelian variety. This is a vector in the890ambient Jacobian variety's rational homology.891892EXAMPLES: We create some elements of `J_0(11)`::893894sage: J = J0(11)895sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G896Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1897sage: G.0.element()898(1/3, 0)899900The underlying element is a vector over the rational numbers::901902sage: v = (G.0-G.1).element(); v903(1/3, -1/5)904sage: type(v)905<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>906"""907return self.__element908909def _repr_(self):910r"""911Return string representation of this finite subgroup element. Since912they are represented as equivalences classes of rational homology913modulo integral homology, we represent an element corresponding to914`v` in the rational homology by ``[v]``.915916EXAMPLES::917918sage: J = J0(11)919sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G920Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1921sage: G.0._repr_()922'[(1/3, 0)]'923"""924return '[%s]'%self.__element925926def _add_(self, other):927"""928Add two finite subgroup elements with the same parent. This is929called implicitly by +.930931INPUT:932933934- ``other`` - a TorsionPoint with the same parent as935self936937938OUTPUT: a TorsionPoint939940EXAMPLES::941942sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])943sage: G.0._add_(G.1)944[(1/3, 1/5)]945sage: G.0 + G.1946[(1/3, 1/5)]947"""948return TorsionPoint(self.parent(), self.__element + other.__element, check=False)949950def _sub_(self, other):951"""952Subtract two finite subgroup elements with the same parent. This is953called implicitly by +.954955INPUT:956957958- ``other`` - a TorsionPoint with the same parent as959self960961962OUTPUT: a TorsionPoint963964EXAMPLES::965966sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])967sage: G.0._sub_(G.1)968[(1/3, -1/5)]969sage: G.0 - G.1970[(1/3, -1/5)]971"""972return TorsionPoint(self.parent(), self.__element - other.__element, check=False)973974def _neg_(self):975"""976Negate a finite subgroup element.977978EXAMPLES::979980sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])981sage: G.0._neg_()982[(-1/3, 0)]983"""984return TorsionPoint(self.parent(), -self.__element, check=False)985986def _rmul_(self, left):987"""988Left multiply a finite subgroup element by an integer.989990EXAMPLES::991992sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])993sage: G.0._rmul_(2)994[(2/3, 0)]995sage: 2*G.0996[(2/3, 0)]997"""998return TorsionPoint(self.parent(), ZZ(left) * self.__element, check=False)9991000def _lmul_(self, right):1001"""1002Right multiply a finite subgroup element by an integer.10031004EXAMPLES::10051006sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1007sage: G.0._lmul_(2)1008[(2/3, 0)]1009sage: G.0 * 21010[(2/3, 0)]1011"""1012return TorsionPoint(self.parent(), self.__element * right, check=False)10131014def __cmp__(self, right):1015"""1016Compare self and right.10171018INPUT:101910201021- ``self, right`` - elements of the same finite1022abelian variety subgroup.102310241025OUTPUT: -1, 0, or 110261027EXAMPLES::10281029sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1030sage: cmp(G.0, G.1)103111032sage: cmp(G.0, G.0)103301034sage: 3*G.0 == 01035True1036sage: 3*G.0 == 5*G.11037True10381039We make sure things that shouldn't be equal aren't::10401041sage: H = J0(14).finite_subgroup([[1/3,0]])1042sage: G.0 == H.01043False1044sage: cmp(G.0, H.0)1045-11046sage: G.01047[(1/3, 0)]1048sage: H.01049[(1/3, 0)]1050"""1051if not isinstance(right, TorsionPoint):1052return cmp(type(self), type(right))1053A = self.parent().abelian_variety()1054B = right.parent().abelian_variety()1055if A.groups() != B.groups():1056return cmp(A,B)1057elif self.__element.change_ring(QQ) - right.__element.change_ring(QQ) in A.lattice() + B.lattice():1058return 01059else:1060return cmp(self.__element, right.__element)10611062def additive_order(self):1063"""1064Return the additive order of this element.10651066EXAMPLES::10671068sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1069sage: G.0.additive_order()107031071sage: G.1.additive_order()107251073sage: (G.0 + G.1).additive_order()1074151075sage: (3*G.0).additive_order()107611077"""1078return self._relative_element().denominator()10791080def _relative_element(self):1081"""1082Return coordinates of this element in terms of basis for the1083integral homology of the containing abelian variety.10841085OUTPUT: vector10861087EXAMPLES::10881089sage: A = J0(43)[1]; A1090Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)1091sage: C = A.cuspidal_subgroup(); C1092Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)1093sage: x = C.0; x1094[(0, 1/7, 0, 6/7, 0, 5/7)]1095sage: x._relative_element()1096(0, 1/7, 6/7, 5/7)1097"""1098return self.parent().abelian_variety().lattice().coordinate_vector(self.__element)1099110011011102