Path: blob/master/sage/modular/abvar/cuspidal_subgroup.py
4057 views
"""1Cuspidal subgroups of modular abelian varieties23AUTHORS:45- William Stein (2007-03, 2008-02)67EXAMPLES: We compute the cuspidal subgroup of `J_1(13)`::89sage: A = J1(13)10sage: C = A.cuspidal_subgroup(); C11Finite subgroup with invariants [19, 19] over QQ of Abelian variety J1(13) of dimension 212sage: C.gens()13[[(1/19, 0, 0, 9/19)], [(0, 1/19, 1/19, 18/19)]]14sage: C.order()1536116sage: C.invariants()17[19, 19]1819We compute the cuspidal subgroup of `J_0(54)`::2021sage: A = J0(54)22sage: C = A.cuspidal_subgroup(); C23Finite subgroup with invariants [3, 3, 3, 3, 3, 9] over QQ of Abelian variety J0(54) of dimension 424sage: C.gens()25[[(1/3, 0, 0, 0, 0, 1/3, 0, 2/3)], [(0, 1/3, 0, 0, 0, 2/3, 0, 1/3)], [(0, 0, 1/9, 1/9, 1/9, 1/9, 1/9, 2/9)], [(0, 0, 0, 1/3, 0, 1/3, 0, 0)], [(0, 0, 0, 0, 1/3, 1/3, 0, 1/3)], [(0, 0, 0, 0, 0, 0, 1/3, 2/3)]]26sage: C.order()27218728sage: C.invariants()29[3, 3, 3, 3, 3, 9]3031We compute the subgroup of the cuspidal subgroup generated by32rational cusps.3334::3536sage: C = J0(54).rational_cusp_subgroup(); C37Finite subgroup with invariants [3, 3, 9] over QQ of Abelian variety J0(54) of dimension 438sage: C.gens()39[[(1/3, 0, 0, 1/3, 2/3, 1/3, 0, 1/3)], [(0, 0, 1/9, 1/9, 7/9, 7/9, 1/9, 8/9)], [(0, 0, 0, 0, 0, 0, 1/3, 2/3)]]40sage: C.order()418142sage: C.invariants()43[3, 3, 9]4445This might not give us the exact rational torsion subgroup, since46it might be bigger than order `81`::4748sage: J0(54).rational_torsion_subgroup().multiple_of_order()492435051TESTS::5253sage: C = J0(54).cuspidal_subgroup()54sage: loads(dumps(C)) == C55True56sage: D = J0(54).rational_cusp_subgroup()57sage: loads(dumps(D)) == D58True59"""6061###########################################################################62# Copyright (C) 2007 William Stein <[email protected]> #63# Distributed under the terms of the GNU General Public License (GPL) #64# http://www.gnu.org/licenses/ #65###########################################################################6667from finite_subgroup import FiniteSubgroup68from sage.rings.all import infinity, QQ, gcd, ZZ69from sage.matrix.all import matrix70from sage.modular.arithgroup.all import is_Gamma071from sage.modular.cusps import Cusp7273class CuspidalSubgroup_generic(FiniteSubgroup):74def _compute_lattice(self, rational_only=False, rational_subgroup=False):75r"""76Return a list of vectors that define elements of the rational77homology that generate this finite subgroup.7879INPUT:808182- ``rational_only`` - bool (default: False); if83``True``, only use rational cusps.848586OUTPUT:878889- ``list`` - list of vectors909192EXAMPLES::9394sage: J = J0(37)95sage: C = sage.modular.abvar.cuspidal_subgroup.CuspidalSubgroup(J)96sage: C._compute_lattice()97Free module of degree 4 and rank 4 over Integer Ring98Echelon basis matrix:99[ 1 0 0 0]100[ 0 1 0 0]101[ 0 0 1 0]102[ 0 0 0 1/3]103sage: J = J0(43)104sage: C = sage.modular.abvar.cuspidal_subgroup.CuspidalSubgroup(J)105sage: C._compute_lattice()106Free module of degree 6 and rank 6 over Integer Ring107Echelon basis matrix:108[ 1 0 0 0 0 0]109[ 0 1/7 0 6/7 0 5/7]110[ 0 0 1 0 0 0]111[ 0 0 0 1 0 0]112[ 0 0 0 0 1 0]113[ 0 0 0 0 0 1]114sage: J = J0(22)115sage: C = sage.modular.abvar.cuspidal_subgroup.CuspidalSubgroup(J)116sage: C._compute_lattice()117Free module of degree 4 and rank 4 over Integer Ring118Echelon basis matrix:119[1/5 1/5 4/5 0]120[ 0 1 0 0]121[ 0 0 1 0]122[ 0 0 0 1/5]123sage: J = J1(13)124sage: C = sage.modular.abvar.cuspidal_subgroup.CuspidalSubgroup(J)125sage: C._compute_lattice()126Free module of degree 4 and rank 4 over Integer Ring127Echelon basis matrix:128[ 1/19 0 0 9/19]129[ 0 1/19 1/19 18/19]130[ 0 0 1 0]131[ 0 0 0 1]132133We compute with and without the optional134``rational_only`` option.135136::137138sage: J = J0(27); G = sage.modular.abvar.cuspidal_subgroup.CuspidalSubgroup(J)139sage: G._compute_lattice()140Free module of degree 2 and rank 2 over Integer Ring141Echelon basis matrix:142[1/3 0]143[ 0 1/3]144sage: G._compute_lattice(rational_only=True)145Free module of degree 2 and rank 2 over Integer Ring146Echelon basis matrix:147[1/3 0]148[ 0 1]149"""150A = self.abelian_variety()151Cusp = A.modular_symbols()152Amb = Cusp.ambient_module()153Eis = Amb.eisenstein_submodule()154155C = Amb.cusps()156N = Amb.level()157158if rational_subgroup:159# QQ-rational subgroup of cuspidal subgroup160assert A.is_ambient()161Q = Cusp.abvarquo_rational_cuspidal_subgroup()162return Q.V()163164if rational_only:165# subgroup generated by differences of rational cusps166if not is_Gamma0(A.group()):167raise NotImplementedError, 'computation of rational cusps only implemented in Gamma0 case.'168if not N.is_squarefree():169data = [n for n in range(2,N) if gcd(n,N) == 1]170C = [c for c in C if is_rational_cusp_gamma0(c, N, data)]171172v = [Amb([infinity, alpha]).element() for alpha in C]173cusp_matrix = matrix(QQ, len(v), Amb.dimension(), v)174175# TODO -- refactor something out here176# Now we project onto the cuspidal part.177B = Cusp.free_module().basis_matrix().stack(Eis.free_module().basis_matrix())178X = B.solve_left(cusp_matrix)179X = X.matrix_from_columns(range(Cusp.dimension()))180lattice = X.row_module(ZZ) + A.lattice()181return lattice182183class CuspidalSubgroup(CuspidalSubgroup_generic):184"""185EXAMPLES::186187sage: a = J0(65)[2]188sage: t = a.cuspidal_subgroup()189sage: t.order()1906191"""192def _repr_(self):193"""194String representation of the cuspidal subgroup.195196EXAMPLES::197198sage: G = J0(27).cuspidal_subgroup()199sage: G._repr_()200'Finite subgroup with invariants [3, 3] over QQ of Abelian variety J0(27) of dimension 1'201"""202return "Cuspidal subgroup %sover QQ of %s"%(self._invariants_repr(), self.abelian_variety())203204205def lattice(self):206"""207Returned cached tuple of vectors that define elements of the208rational homology that generate this finite subgroup.209210OUTPUT:211212213- ``tuple`` - cached214215216EXAMPLES::217218sage: J = J0(27)219sage: G = J.cuspidal_subgroup()220sage: G.lattice()221Free module of degree 2 and rank 2 over Integer Ring222Echelon basis matrix:223[1/3 0]224[ 0 1/3]225226Test that the result is cached::227228sage: G.lattice() is G.lattice()229True230"""231try:232return self.__lattice233except AttributeError:234lattice = self._compute_lattice(rational_only = False)235self.__lattice = lattice236return lattice237238class RationalCuspSubgroup(CuspidalSubgroup_generic):239"""240EXAMPLES::241242sage: a = J0(65)[2]243sage: t = a.rational_cusp_subgroup()244sage: t.order()2456246"""247def _repr_(self):248"""249String representation of the cuspidal subgroup.250251EXAMPLES::252253sage: G = J0(27).rational_cusp_subgroup()254sage: G._repr_()255'Finite subgroup with invariants [3] over QQ of Abelian variety J0(27) of dimension 1'256"""257return "Subgroup generated by differences of rational cusps %sover QQ of %s"%(self._invariants_repr(), self.abelian_variety())258259260def lattice(self):261"""262Return lattice that defines this group.263264OUTPUT: lattice265266EXAMPLES::267268sage: G = J0(27).rational_cusp_subgroup()269sage: G.lattice()270Free module of degree 2 and rank 2 over Integer Ring271Echelon basis matrix:272[1/3 0]273[ 0 1]274275Test that the result is cached.276277::278279sage: G.lattice() is G.lattice()280True281"""282try:283return self.__lattice284except AttributeError:285lattice = self._compute_lattice(rational_only = True)286self.__lattice = lattice287return lattice288289class RationalCuspidalSubgroup(CuspidalSubgroup_generic):290"""291EXAMPLES::292293sage: a = J0(65)[2]294sage: t = a.rational_cuspidal_subgroup()295sage: t.order()2966297"""298def _repr_(self):299"""300String representation of the cuspidal subgroup.301302EXAMPLES::303304sage: G = J0(27).rational_cuspidal_subgroup()305sage: G._repr_()306'Finite subgroup with invariants [3] over QQ of Abelian variety J0(27) of dimension 1'307"""308return "Rational cuspidal subgroup %sover QQ of %s"%(self._invariants_repr(), self.abelian_variety())309310def lattice(self):311"""312Return lattice that defines this group.313314OUTPUT: lattice315316EXAMPLES::317318sage: G = J0(27).rational_cuspidal_subgroup()319sage: G.lattice()320Free module of degree 2 and rank 2 over Integer Ring321Echelon basis matrix:322[1/3 0]323[ 0 1]324325Test that the result is cached.326327::328329sage: G.lattice() is G.lattice()330True331"""332try:333return self.__lattice334except AttributeError:335lattice = self._compute_lattice(rational_subgroup = True)336self.__lattice = lattice337return lattice338339def is_rational_cusp_gamma0(c, N, data):340"""341Return True if the rational number c is a rational cusp of level N.342This uses remarks in Glenn Steven's Ph.D. thesis.343344INPUT:345346347- ``c`` - a cusp348349- ``N`` - a positive integer350351- ``data`` - the list [n for n in range(2,N) if352gcd(n,N) == 1], which is passed in as a parameter purely for353efficiency reasons.354355356EXAMPLES::357358sage: from sage.modular.abvar.cuspidal_subgroup import is_rational_cusp_gamma0359sage: N = 27360sage: data = [n for n in range(2,N) if gcd(n,N) == 1]361sage: is_rational_cusp_gamma0(Cusp(1/3), N, data)362False363sage: is_rational_cusp_gamma0(Cusp(1), N, data)364True365sage: is_rational_cusp_gamma0(Cusp(oo), N, data)366True367sage: is_rational_cusp_gamma0(Cusp(2/9), N, data)368False369"""370num = c.numerator()371den = c.denominator()372for d in data:373if not c.is_gamma0_equiv(Cusp(num,d*den), N):374return False375return True376377378