Path: blob/master/sage/modular/abvar/finite_subgroup.py
4069 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, is_Field, Integer, composite_field100from sage.misc.misc import prod101102import abvar as abelian_variety103104class FiniteSubgroup(Module_old):105def __init__(self, abvar, field_of_definition=QQ):106"""107A finite subgroup of a modular abelian variety.108109INPUT:110111112- ``abvar`` - a modular abelian variety113114- ``field_of_definition`` - a field over which this115group is defined.116117118EXAMPLES: This is an abstract base class, so there are no instances119of this class itself.120121::122123sage: A = J0(37)124sage: G = A.torsion_subgroup(3); G125Finite subgroup with invariants [3, 3, 3, 3] over QQ of Abelian variety J0(37) of dimension 2126sage: type(G)127<class 'sage.modular.abvar.finite_subgroup.FiniteSubgroup_lattice'>128sage: from sage.modular.abvar.finite_subgroup import FiniteSubgroup129sage: isinstance(G, FiniteSubgroup)130True131"""132if not is_Field(field_of_definition):133raise TypeError, "field_of_definition must be a field"134if not abelian_variety.is_ModularAbelianVariety(abvar):135raise TypeError, "abvar must be a modular abelian variety"136Module_old.__init__(self, ZZ)137self.__abvar = abvar138self.__field_of_definition = field_of_definition139140################################################################141# DERIVED CLASS MUST OVERRIDE THE lattice METHOD142################################################################143def lattice(self):144"""145Return the lattice corresponding to this subgroup in the rational146homology of the modular Jacobian product. The elements of the147subgroup are represented by vectors in the ambient vector space148(the rational homology), and this returns the lattice they span.149EXAMPLES::150151sage: J = J0(33); C = J[0].cuspidal_subgroup(); C152Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)153sage: C.lattice()154Free module of degree 6 and rank 2 over Integer Ring155Echelon basis matrix:156[ 1/5 13/5 -2 -4/5 2 -1/5]157[ 0 3 -2 -1 2 0]158"""159raise NotImplementedError160161def _relative_basis_matrix(self):162"""163Return matrix of this finite subgroup, but relative to the homology164of the parent abelian variety.165166EXAMPLES::167168sage: A = J0(43)[1]; A169Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)170sage: C = A.cuspidal_subgroup(); C171Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)172sage: C._relative_basis_matrix()173[ 1 0 0 0]174[ 0 1/7 6/7 5/7]175[ 0 0 1 0]176[ 0 0 0 1]177"""178try:179return self.__relative_basis_matrix180except AttributeError:181M = self.__abvar.lattice().coordinate_module(self.lattice()).basis_matrix()182self.__relative_basis_matrix = M183return M184185# General functionality186def __cmp__(self, other):187"""188Compare this finite subgroup to other.189190If other is not a modular abelian variety finite subgroup, then the191types of self and other are compared. If other is a finite192subgroup, and the ambient abelian varieties are equal, then the193subgroups themselves are compared, by comparing their full modules.194If the containing abelian varieties are not equal and their ambient195varieties are different they are compared; if they are the same,196then a NotImplemnetedError is raised (this is temporary).197198EXAMPLES: We first compare to subgroups of `J_0(37)`::199200sage: A = J0(37)201sage: G = A.torsion_subgroup(3); G.order()20281203sage: H = A.cuspidal_subgroup(); H.order()2043205sage: H < G206True207sage: H.is_subgroup(G)208True209sage: H < 5 #random (meaningless since it depends on memory layout)210False211sage: 5 < H #random (meaningless since it depends on memory layout)212True213214The ambient varieties are compared::215216sage: cmp(A[0].cuspidal_subgroup(), J0(11).cuspidal_subgroup())2171218219Comparing subgroups sitting in different abelian varieties::220221sage: cmp(A[0].cuspidal_subgroup(), A[1].cuspidal_subgroup())222-1223"""224if not isinstance(other, FiniteSubgroup):225return cmp(type(self), type(other))226A = self.abelian_variety()227B = other.abelian_variety()228if not A.in_same_ambient_variety(B):229return cmp(A.ambient_variety(), B.ambient_variety())230L = A.lattice() + B.lattice()231# Minus sign because order gets reversed in passing to lattices.232return -cmp(self.lattice() + L, other.lattice() + L)233234def is_subgroup(self, other):235"""236Return True exactly if self is a subgroup of other, and both are237defined as subgroups of the same ambient abelian variety.238239EXAMPLES::240241sage: C = J0(22).cuspidal_subgroup()242sage: H = C.subgroup([C.0])243sage: K = C.subgroup([C.1])244sage: H.is_subgroup(K)245False246sage: K.is_subgroup(H)247False248sage: K.is_subgroup(C)249True250sage: H.is_subgroup(C)251True252"""253# We use that self is contained in other, whether other is254# either a finite group or an abelian variety, if and only255# if self doesn't shrink when intersected with other.256try:257return self.intersection(other).order() == self.order()258except TypeError:259return False260261def __add__(self, other):262"""263Return the sum of two subgroups.264265EXAMPLES::266267sage: C = J0(22).cuspidal_subgroup()268sage: C.gens()269[[(1/5, 1/5, 4/5, 0)], [(0, 0, 0, 1/5)]]270sage: A = C.subgroup([C.0]); B = C.subgroup([C.1])271sage: A + B == C272True273"""274if not isinstance(other, FiniteSubgroup):275raise TypeError, "only addition of two finite subgroups is defined"276A = self.abelian_variety()277B = other.abelian_variety()278if not A.in_same_ambient_variety(B):279raise ValueError("self and other must be in the same ambient Jacobian")280K = composite_field(self.field_of_definition(), other.field_of_definition())281lattice = self.lattice() + other.lattice()282if A != B:283lattice += C.lattice()284285return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=K)286287def exponent(self):288"""289Return the exponent of this finite abelian group.290291OUTPUT: Integer292293EXAMPLES::294295sage: t = J0(33).hecke_operator(7)296sage: G = t.kernel()[0]; G297Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3298sage: G.exponent()2994300"""301try:302return self.__exponent303except AttributeError:304e = lcm(self.invariants())305self.__exponent = e306return e307308def intersection(self, other):309"""310Return the intersection of the finite subgroups self and other.311312INPUT:313314315- ``other`` - a finite group316317318OUTPUT: a finite group319320EXAMPLES::321322sage: E11a0, E11a1, B = J0(33)323sage: G = E11a0.torsion_subgroup(6); H = E11a0.torsion_subgroup(9)324sage: G.intersection(H)325Finite subgroup with invariants [3, 3] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)326sage: W = E11a1.torsion_subgroup(15)327sage: G.intersection(W)328Finite subgroup with invariants [] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)329sage: E11a0.intersection(E11a1)[0]330Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)331332We intersect subgroups of different abelian varieties.333334::335336sage: E11a0, E11a1, B = J0(33)337sage: G = E11a0.torsion_subgroup(5); H = E11a1.torsion_subgroup(5)338sage: G.intersection(H)339Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)340sage: E11a0.intersection(E11a1)[0]341Finite subgroup with invariants [5] over QQ of Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33)342343We intersect abelian varieties with subgroups::344345sage: t = J0(33).hecke_operator(7)346sage: G = t.kernel()[0]; G347Finite subgroup with invariants [2, 2, 2, 2, 4, 4] over QQ of Abelian variety J0(33) of dimension 3348sage: A = J0(33).old_subvariety()349sage: A.intersection(G)350Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)351sage: A.hecke_operator(7).kernel()[0]352Finite subgroup with invariants [2, 2, 2, 2] over QQ of Abelian subvariety of dimension 2 of J0(33)353sage: B = J0(33).new_subvariety()354sage: B.intersection(G)355Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)356sage: B.hecke_operator(7).kernel()[0]357Finite subgroup with invariants [4, 4] over QQ of Abelian subvariety of dimension 1 of J0(33)358sage: A.intersection(B)[0]359Finite subgroup with invariants [3, 3] over QQ of Abelian subvariety of dimension 2 of J0(33)360"""361A = self.abelian_variety()362if abelian_variety.is_ModularAbelianVariety(other):363amb = other364B = other365M = B.lattice().scale(Integer(1)/self.exponent())366K = composite_field(self.field_of_definition(), other.base_field())367else:368amb = A369if not isinstance(other, FiniteSubgroup):370raise TypeError, "only addition of two finite subgroups is defined"371B = other.abelian_variety()372if A.ambient_variety() != B.ambient_variety():373raise TypeError, "finite subgroups must be in the same ambient product Jacobian"374M = other.lattice()375K = composite_field(self.field_of_definition(), other.field_of_definition())376377L = self.lattice()378if A != B:379# TODO: This might be way slower than what we could do if380# we think more carefully.381C = A + B382L = L + C.lattice()383M = M + C.lattice()384W = L.intersection(M).intersection(amb.vector_space())385return FiniteSubgroup_lattice(amb, W, field_of_definition=K)386387def __mul__(self, right):388"""389Multiply this subgroup by the rational number right.390391If right is an integer the result is a subgroup of self. If right392is a rational number `n/m`, then this group is first393divided by `m` then multiplied by `n`.394395INPUT:396397398- ``right`` - a rational number399400401OUTPUT: a subgroup402403EXAMPLES::404405sage: J = J0(37)406sage: H = J.cuspidal_subgroup(); H.order()4073408sage: G = H * 3; G.order()4091410sage: G = H * (1/2); G.order()41148412sage: J.torsion_subgroup(2) + H == G413True414sage: G = H*(3/2); G.order()41516416sage: J = J0(42)417sage: G = J.cuspidal_subgroup(); factor(G.order())4182^8 * 3^2419sage: (G * 3).order()420256421sage: (G * 0).order()4221423sage: (G * (1/5)).order()42422500000000425"""426lattice = self.lattice().scale(right)427return FiniteSubgroup_lattice(self.abelian_variety(), lattice,428field_of_definition = self.field_of_definition())429430def __rmul__(self, left):431"""432Multiply this finite subgroup on the left by an integer.433434EXAMPLES::435436sage: J = J0(42)437sage: G = J.cuspidal_subgroup(); factor(G.order())4382^8 * 3^2439sage: H = G.__rmul__(2)440sage: H.order().factor()4412^4 * 3^2442sage: 2*G443Finite subgroup with invariants [6, 24] over QQ of Abelian variety J0(42) of dimension 5444"""445return self * left446447def abelian_variety(self):448"""449Return the abelian variety that this is a finite subgroup of.450451EXAMPLES::452453sage: J = J0(42)454sage: G = J.rational_torsion_subgroup(); G455Torsion subgroup of Abelian variety J0(42) of dimension 5456sage: G.abelian_variety()457Abelian variety J0(42) of dimension 5458"""459return self.__abvar460461def field_of_definition(self):462"""463Return the field over which this finite modular abelian variety464subgroup is defined. This is a field over which this subgroup is465defined.466467EXAMPLES::468469sage: J = J0(42)470sage: G = J.rational_torsion_subgroup(); G471Torsion subgroup of Abelian variety J0(42) of dimension 5472sage: G.field_of_definition()473Rational Field474"""475return self.__field_of_definition476477def _repr_(self):478"""479Return string representation of this finite subgroup.480481EXAMPLES::482483sage: J = J0(42)484sage: G = J.torsion_subgroup(3); G._repr_()485'Finite subgroup with invariants [3, 3, 3, 3, 3, 3, 3, 3, 3, 3] over QQ of Abelian variety J0(42) of dimension 5'486"""487K = self.__field_of_definition488if K == QQbar:489field = "QQbar"490elif K == QQ:491field = "QQ"492else:493field = str(K)494return "Finite subgroup %sover %s of %s"%(self._invariants_repr(), field, self.__abvar)495496def _invariants_repr(self):497"""498The string representation of the 'invariants' part of this group.499500We make this a separate function so it is possible to create finite501subgroups that don't print their invariants, since printing them502could be expensive.503504EXAMPLES::505506sage: J0(42).cuspidal_subgroup()._invariants_repr()507'with invariants [2, 2, 12, 48] '508"""509return 'with invariants %s '%(self.invariants(), )510511def order(self):512"""513Return the order (number of elements) of this finite subgroup.514515EXAMPLES::516517sage: J = J0(42)518sage: C = J.cuspidal_subgroup()519sage: C.order()5202304521"""522try:523return self.__order524except AttributeError:525if self.__abvar.dimension() == 0:526self.__order = ZZ(1)527return self.__order528o = prod(self.invariants())529self.__order = o530return o531532def gens(self):533"""534Return generators for this finite subgroup.535536EXAMPLES: We list generators for several cuspidal subgroups::537538sage: J0(11).cuspidal_subgroup().gens()539[[(0, 1/5)]]540sage: J0(37).cuspidal_subgroup().gens()541[[(0, 0, 0, 1/3)]]542sage: J0(43).cuspidal_subgroup().gens()543[[(0, 1/7, 0, 6/7, 0, 5/7)]]544sage: J1(13).cuspidal_subgroup().gens()545[[(1/19, 0, 0, 9/19)], [(0, 1/19, 1/19, 18/19)]]546sage: J0(22).torsion_subgroup(6).gens()547[[(1/6, 0, 0, 0)], [(0, 1/6, 0, 0)], [(0, 0, 1/6, 0)], [(0, 0, 0, 1/6)]]548"""549try:550return self.__gens551except AttributeError:552pass553554B = [TorsionPoint(self, v) for v in self.lattice().basis() if v.denominator() > 1]555self.__gens = Sequence(B, immutable=True)556return self.__gens557558def gen(self, n):559r"""560Return `n^{th}` generator of self.561562EXAMPLES::563564sage: J = J0(23)565sage: C = J.torsion_subgroup(3)566sage: C.gens()567[[(1/3, 0, 0, 0)], [(0, 1/3, 0, 0)], [(0, 0, 1/3, 0)], [(0, 0, 0, 1/3)]]568sage: C.gen(0)569[(1/3, 0, 0, 0)]570sage: C.gen(3)571[(0, 0, 0, 1/3)]572sage: C.gen(4)573Traceback (most recent call last):574...575IndexError: list index out of range576577Negative indices wrap around::578579sage: C.gen(-1)580[(0, 0, 0, 1/3)]581"""582return self.gens()[n]583584def __call__(self, x):585r"""586Coerce `x` into this finite subgroup.587588This works when the abelian varieties that contains x and self are589the same, or if `x` is coercible into the rational homology590(viewed as an abstract `\QQ`-vector space).591592EXAMPLES: We first construct the `11`-torsion subgroup of593`J_0(23)`::594595sage: J = J0(23)596sage: G = J.torsion_subgroup(11)597sage: G.invariants()598[11, 11, 11, 11]599600We also construct the cuspidal subgroup.601602::603604sage: C = J.cuspidal_subgroup()605sage: C.invariants()606[11]607608Coercing something into its parent returns it::609610sage: G(G.0) is G.0611True612613We coerce an element from the cuspidal subgroup into the614`11`-torsion subgroup::615616sage: z = G(C.0); z617[(1/11, 10/11, 0, 8/11)]618sage: z.parent() == G619True620621We coerce a list, which defines an element of the underlying622``full_module`` into `G`, and verify an623equality::624625sage: x = G([1/11, 1/11, 0, -1/11])626sage: x == G([1/11, 1/11, 0, 10/11])627True628629Finally we attempt to coerce in an element that shouldn't work,630since is is not in `G`::631632sage: G(J.torsion_subgroup(3).0)633Traceback (most recent call last):634...635TypeError: x does not define an element of self636"""637if isinstance(x, TorsionPoint):638if x.parent() is self:639return x640elif x.parent() == self:641return TorsionPoint(self, x.element(), check=False)642elif x.parent().abelian_variety() == self.abelian_variety():643return self(x.element())644else:645raise TypeError, "x does not define an element of self"646else:647z = self.abelian_variety().vector_space()(x)648if not z in self.lattice():649raise TypeError, "x does not define an element of self"650return TorsionPoint(self, z, check=False)651652653def __contains__(self, x):654"""655Returns True if x is contained in this finite subgroup.656657EXAMPLES: We define two distinct finite subgroups of658`J_0(27)`::659660sage: G1 = J0(27).rational_cusp_subgroup(); G1661Finite subgroup with invariants [3] over QQ of Abelian variety J0(27) of dimension 1662sage: G1.0663[(1/3, 0)]664sage: G2 = J0(27).cuspidal_subgroup(); G2665Finite subgroup with invariants [3, 3] over QQ of Abelian variety J0(27) of dimension 1666sage: G2.gens()667[[(1/3, 0)], [(0, 1/3)]]668669Now we check whether various elements are in `G_1` and670`G_2`::671672sage: G2.0 in G1673True674sage: G2.1 in G1675False676sage: G1.0 in G1677True678sage: G1.0 in G2679True680681The integer `0` is in, since it coerces in::682683sage: 0 in G1684True685686Elements that have a completely different ambient product Jacobian687are never in `G`::688689sage: J0(23).cuspidal_subgroup().0 in G1690False691sage: J0(23).cuspidal_subgroup()(0) in G1692False693"""694try:695self(x)696except TypeError:697return False698return True699700def subgroup(self, gens):701"""702Return the subgroup of self spanned by the given generators, which703all must be elements of self.704705EXAMPLES::706707sage: J = J0(23)708sage: G = J.torsion_subgroup(11); G709Finite subgroup with invariants [11, 11, 11, 11] over QQ of Abelian variety J0(23) of dimension 2710711We create the subgroup of the 11-torsion subgroup of712`J_0(23)` generated by the first `11`-torsion713point::714715sage: H = G.subgroup([G.0]); H716Finite subgroup with invariants [11] over QQbar of Abelian variety J0(23) of dimension 2717sage: H.invariants()718[11]719720We can also create a subgroup from a list of objects that coerce721into the ambient rational homology.722723::724725sage: H == G.subgroup([[1/11,0,0,0]])726True727"""728if not isinstance(gens, (tuple, list)):729raise TypeError, "gens must be a list or tuple"730A = self.abelian_variety()731lattice = A._ambient_lattice().span([self(g).element() for g in gens])732return FiniteSubgroup_lattice(self.abelian_variety(), lattice, field_of_definition=QQbar)733734def invariants(self):735r"""736Return elementary invariants of this abelian group, by which we737mean a nondecreasing (immutable) sequence of integers738`n_i`, `1 \leq i \leq k`, with `n_i`739dividing `n_{i+1}`, and such that this group is abstractly740isomorphic to741`\ZZ/n_1\ZZ \times\cdots\times \ZZ/n_k\ZZ.`742743EXAMPLES::744745sage: J = J0(38)746sage: C = J.cuspidal_subgroup(); C747Finite subgroup with invariants [3, 45] over QQ of Abelian variety J0(38) of dimension 4748sage: v = C.invariants(); v749[3, 45]750sage: v[0] = 5751Traceback (most recent call last):752...753ValueError: object is immutable; please change a copy instead.754sage: type(v[0])755<type 'sage.rings.integer.Integer'>756757::758759sage: C * 3760Finite subgroup with invariants [15] over QQ of Abelian variety J0(38) of dimension 4761762An example involving another cuspidal subgroup::763764sage: C = J0(22).cuspidal_subgroup(); C765Finite subgroup with invariants [5, 5] over QQ of Abelian variety J0(22) of dimension 2766sage: C.lattice()767Free module of degree 4 and rank 4 over Integer Ring768Echelon basis matrix:769[1/5 1/5 4/5 0]770[ 0 1 0 0]771[ 0 0 1 0]772[ 0 0 0 1/5]773sage: C.invariants()774[5, 5]775"""776try:777return self.__invariants778except AttributeError:779pass780M = self.lattice().coordinate_module(self.abelian_variety().lattice())781E = M.basis_matrix().change_ring(ZZ).elementary_divisors()782v = [Integer(x) for x in E if x != 1]783I = Sequence(v)784I.sort()785I.set_immutable()786self.__invariants = I787return I788789class FiniteSubgroup_lattice(FiniteSubgroup):790def __init__(self, abvar, lattice, field_of_definition=QQbar, check=True):791"""792A finite subgroup of a modular abelian variety that is defined by a793given lattice.794795INPUT:796797798- ``abvar`` - a modular abelian variety799800- ``lattice`` - a lattice that contains the lattice of801abvar802803- ``field_of_definition`` - the field of definition804of this finite group scheme805806- ``check`` - bool (default: True) whether or not to807check that lattice contains the abvar lattice.808809810EXAMPLES::811812sage: J = J0(11)813sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G814Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1815"""816if check:817if not is_FreeModule(lattice) or lattice.base_ring() != ZZ:818raise TypeError, "lattice must be a free module over ZZ"819if not abelian_variety.is_ModularAbelianVariety(abvar):820raise TypeError, "abvar must be a modular abelian variety"821if not abvar.lattice().is_submodule(lattice):822lattice += abvar.lattice()823if lattice.rank() != abvar.lattice().rank():824raise ValueError, "lattice must contain the lattice of abvar with finite index"825FiniteSubgroup.__init__(self, abvar, field_of_definition)826self.__lattice = lattice827828def lattice(self):829r"""830Return lattice that defines this finite subgroup.831832EXAMPLES::833834sage: J = J0(11)835sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G836Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1837sage: G.lattice()838Free module of degree 2 and rank 2 over Integer Ring839Echelon basis matrix:840[1/3 0]841[ 0 1/5]842"""843return self.__lattice844845###########################################################################846# Elements of finite order847###########################################################################848849class TorsionPoint(ModuleElement):850def __init__(self, parent, element, check=True):851"""852An element of a finite subgroup of a modular abelian variety.853854INPUT:855856857- ``parent`` - a finite subgroup of a modular abelian858variety859860- ``element`` - a QQ vector space element that861represents this element in terms of the ambient rational homology862863- ``check`` - bool (default: True) whether to check864that element is in the appropriate vector space865866867EXAMPLES: The following calls the TorsionPoint constructor868implicitly::869870sage: J = J0(11)871sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G872Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1873sage: type(G.0)874<class 'sage.modular.abvar.finite_subgroup.TorsionPoint'>875"""876ModuleElement.__init__(self, parent)877if check:878if not element in parent.abelian_variety().vector_space():879raise TypeError, "element must be a vector in the abelian variety's rational homology (embedded in the ambient Jacobian product)"880if element.denominator() == 1:881element = element.parent().zero_vector()882self.__element = element883884def element(self):885"""886Return an underlying QQ-vector space element that defines this887element of a modular abelian variety. This is a vector in the888ambient Jacobian variety's rational homology.889890EXAMPLES: We create some elements of `J_0(11)`::891892sage: J = J0(11)893sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G894Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1895sage: G.0.element()896(1/3, 0)897898The underlying element is a vector over the rational numbers::899900sage: v = (G.0-G.1).element(); v901(1/3, -1/5)902sage: type(v)903<type 'sage.modules.vector_rational_dense.Vector_rational_dense'>904"""905return self.__element906907def _repr_(self):908r"""909Return string representation of this finite subgroup element. Since910they are represented as equivalences classes of rational homology911modulo integral homology, we represent an element corresponding to912`v` in the rational homology by ``[v]``.913914EXAMPLES::915916sage: J = J0(11)917sage: G = J.finite_subgroup([[1/3,0], [0,1/5]]); G918Finite subgroup with invariants [15] over QQbar of Abelian variety J0(11) of dimension 1919sage: G.0._repr_()920'[(1/3, 0)]'921"""922return '[%s]'%self.__element923924def _add_(self, other):925"""926Add two finite subgroup elements with the same parent. This is927called implicitly by +.928929INPUT:930931932- ``other`` - a TorsionPoint with the same parent as933self934935936OUTPUT: a TorsionPoint937938EXAMPLES::939940sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])941sage: G.0._add_(G.1)942[(1/3, 1/5)]943sage: G.0 + G.1944[(1/3, 1/5)]945"""946return TorsionPoint(self.parent(), self.__element + other.__element, check=False)947948def _sub_(self, other):949"""950Subtract two finite subgroup elements with the same parent. This is951called implicitly by +.952953INPUT:954955956- ``other`` - a TorsionPoint with the same parent as957self958959960OUTPUT: a TorsionPoint961962EXAMPLES::963964sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])965sage: G.0._sub_(G.1)966[(1/3, -1/5)]967sage: G.0 - G.1968[(1/3, -1/5)]969"""970return TorsionPoint(self.parent(), self.__element - other.__element, check=False)971972def _neg_(self):973"""974Negate a finite subgroup element.975976EXAMPLES::977978sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])979sage: G.0._neg_()980[(-1/3, 0)]981"""982return TorsionPoint(self.parent(), -self.__element, check=False)983984def _rmul_(self, left):985"""986Left multiply a finite subgroup element by an integer.987988EXAMPLES::989990sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])991sage: G.0._rmul_(2)992[(2/3, 0)]993sage: 2*G.0994[(2/3, 0)]995"""996return TorsionPoint(self.parent(), ZZ(left) * self.__element, check=False)997998def _lmul_(self, right):999"""1000Right multiply a finite subgroup element by an integer.10011002EXAMPLES::10031004sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1005sage: G.0._lmul_(2)1006[(2/3, 0)]1007sage: G.0 * 21008[(2/3, 0)]1009"""1010return TorsionPoint(self.parent(), self.__element * right, check=False)10111012def __cmp__(self, right):1013"""1014Compare self and right.10151016INPUT:101710181019- ``self, right`` - elements of the same finite1020abelian variety subgroup.102110221023OUTPUT: -1, 0, or 110241025EXAMPLES::10261027sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1028sage: cmp(G.0, G.1)102911030sage: cmp(G.0, G.0)103101032sage: 3*G.0 == 01033True1034sage: 3*G.0 == 5*G.11035True10361037We make sure things that shouldn't be equal aren't::10381039sage: H = J0(14).finite_subgroup([[1/3,0]])1040sage: G.0 == H.01041False1042sage: cmp(G.0, H.0)1043-11044sage: G.01045[(1/3, 0)]1046sage: H.01047[(1/3, 0)]1048"""1049if not isinstance(right, TorsionPoint):1050return cmp(type(self), type(right))1051A = self.parent().abelian_variety()1052B = right.parent().abelian_variety()1053if A.groups() != B.groups():1054return cmp(A,B)1055elif self.__element.change_ring(QQ) - right.__element.change_ring(QQ) in A.lattice() + B.lattice():1056return 01057else:1058return cmp(self.__element, right.__element)10591060def additive_order(self):1061"""1062Return the additive order of this element.10631064EXAMPLES::10651066sage: J = J0(11); G = J.finite_subgroup([[1/3,0], [0,1/5]])1067sage: G.0.additive_order()106831069sage: G.1.additive_order()107051071sage: (G.0 + G.1).additive_order()1072151073sage: (3*G.0).additive_order()107411075"""1076return self._relative_element().denominator()10771078def _relative_element(self):1079"""1080Return coordinates of this element in terms of basis for the1081integral homology of the containing abelian variety.10821083OUTPUT: vector10841085EXAMPLES::10861087sage: A = J0(43)[1]; A1088Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)1089sage: C = A.cuspidal_subgroup(); C1090Finite subgroup with invariants [7] over QQ of Simple abelian subvariety 43b(1,43) of dimension 2 of J0(43)1091sage: x = C.0; x1092[(0, 1/7, 0, 6/7, 0, 5/7)]1093sage: x._relative_element()1094(0, 1/7, 6/7, 5/7)1095"""1096return self.parent().abelian_variety().lattice().coordinate_vector(self.__element)1097109810991100