Path: blob/master/sage/modular/abvar/abvar_ambient_jacobian.py
4100 views
"""1Ambient Jacobian Abelian Variety23TESTS::45sage: loads(dumps(J0(37))) == J0(37)6True7sage: loads(dumps(J1(13))) == J1(13)8True9"""1011import weakref12from sage.structure.sequence import Sequence1314from abvar import (ModularAbelianVariety_modsym_abstract, ModularAbelianVariety,15simple_factorization_of_modsym_space, modsym_lattices,16ModularAbelianVariety_modsym)17from sage.rings.all import QQ1819from sage.modular.modsym.modsym import ModularSymbols20import morphism212223_cache = {}2425def ModAbVar_ambient_jacobian(group):26"""27Return the ambient Jacobian attached to a given congruence28subgroup.2930The result is cached using a weakref. This function is called31internally by modular abelian variety constructors.3233INPUT:343536- ``group`` - a congruence subgroup.373839OUTPUT: a modular abelian variety attached4041EXAMPLES::4243sage: import sage.modular.abvar.abvar_ambient_jacobian as abvar_ambient_jacobian44sage: A = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))45sage: A46Abelian variety J0(11) of dimension 147sage: B = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))48sage: A is B49True5051You can get access to and/or clear the cache as follows::5253sage: abvar_ambient_jacobian._cache = {}54sage: B = abvar_ambient_jacobian.ModAbVar_ambient_jacobian(Gamma0(11))55sage: A is B56False57"""58try:59X = _cache[group]()60if not X is None:61return X62except KeyError:63pass64X = ModAbVar_ambient_jacobian_class(group)65_cache[group] = weakref.ref(X)66return X6768class ModAbVar_ambient_jacobian_class(ModularAbelianVariety_modsym_abstract):69"""70An ambient Jacobian modular abelian variety attached to a71congruence subgroup.72"""73def __init__(self, group):74"""75Create an ambient Jacobian modular abelian variety.7677EXAMPLES::7879sage: A = J0(37); A80Abelian variety J0(37) of dimension 281sage: type(A)82<class 'sage.modular.abvar.abvar_ambient_jacobian.ModAbVar_ambient_jacobian_class_with_category'>83sage: A.group()84Congruence Subgroup Gamma0(37)85"""86ModularAbelianVariety_modsym_abstract.__init__(self, (group,), QQ)87self.__group = group88self._is_hecke_stable = True8990def _modular_symbols(self):91"""92Return the modular symbols space associated to this ambient93Jacobian.9495OUTPUT: modular symbols space9697EXAMPLES::9899sage: M = J0(33)._modular_symbols(); M100Modular Symbols subspace of dimension 6 of Modular Symbols space of dimension 9 for Gamma_0(33) of weight 2 with sign 0 over Rational Field101sage: J0(33)._modular_symbols() is M102True103"""104try:105return self.__modsym106except AttributeError:107self.__modsym = ModularSymbols(self.__group, weight=2).cuspidal_submodule()108return self.__modsym109110def _repr_(self):111"""112Return string representation of this Jacobian modular abelian113variety.114115EXAMPLES::116117sage: A = J0(11); A118Abelian variety J0(11) of dimension 1119sage: A._repr_()120'Abelian variety J0(11) of dimension 1'121sage: A.rename("J_0(11)")122sage: A123J_0(11)124125We now clear the cache to get rid of our renamed126`J_0(11)`.127128::129130sage: import sage.modular.abvar.abvar_ambient_jacobian as abvar_ambient_jacobian131sage: abvar_ambient_jacobian._cache = {}132"""133return 'Abelian variety %s of dimension %s%s'%(self._ambient_repr(), self.dimension(),134'' if self.base_field() == QQ else ' over %s'%self.base_field())135136def _latex_(self):137"""138Return Latex representation of self.139140EXAMPLES::141142sage: latex(J0(37))143J_0(37)144sage: J1(13)._latex_()145'J_1(13)'146sage: latex(JH(389,[16]))147J_H(389,[16])148"""149return self._ambient_latex_repr()150151def ambient_variety(self):152"""153Return the ambient modular abelian variety that contains self.154Since self is a Jacobian modular abelian variety, this is just155self.156157OUTPUT: abelian variety158159EXAMPLES::160161sage: A = J0(17)162sage: A.ambient_variety()163Abelian variety J0(17) of dimension 1164sage: A is A.ambient_variety()165True166"""167return self168169def group(self):170"""171Return the group that this Jacobian modular abelian variety is172attached to.173174EXAMPLES::175176sage: J1(37).group()177Congruence Subgroup Gamma1(37)178sage: J0(5077).group()179Congruence Subgroup Gamma0(5077)180sage: J = GammaH(11,[3]).modular_abelian_variety(); J181Abelian variety JH(11,[3]) of dimension 1182sage: J.group()183Congruence Subgroup Gamma_H(11) with H generated by [3]184"""185return self.__group186187def groups(self):188"""189Return the tuple of congruence subgroups attached to this ambient190Jacobian. This is always a tuple of length 1.191192OUTPUT: tuple193194EXAMPLES::195196sage: J0(37).groups()197(Congruence Subgroup Gamma0(37),)198"""199return (self.__group,)200201def _calculate_endomorphism_generators(self):202"""203Calculate generators for the endomorphism ring of self.204205EXAMPLES::206207sage: J0(11)._calculate_endomorphism_generators()208[Abelian variety endomorphism of Abelian variety J0(11) of dimension 1]209sage: ls = J0(46)._calculate_endomorphism_generators() ; ls210[Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,211Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,212Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,213Abelian variety endomorphism of Abelian variety J0(46) of dimension 5,214Abelian variety endomorphism of Abelian variety J0(46) of dimension 5]215sage: len(ls) == J0(46).dimension()216True217"""218D = self.decomposition()219phi = self._isogeny_to_product_of_simples()220psi = phi.complementary_isogeny()221222m1 = phi.matrix()223m2 = psi.matrix()224225H = self.Hom(self)226M = H.matrix_space()227228ls = []229ind = 0230for d in D:231to_newform = d._isogeny_to_newform_abelian_variety()232n1 = to_newform.matrix()233n2 = to_newform.complementary_isogeny().matrix()234f_gens = to_newform.codomain()._calculate_endomorphism_generators()235small_space = to_newform.parent().matrix_space()236f_gens = [ small_space(x.list()) for x in f_gens ]237for m in f_gens:238mat = H.matrix_space()(0)239mat.set_block(ind, ind, n1 * m * n2 )240ls.append((m1 * mat * m2).list())241ind += 2*d.dimension()242243return [ H( morphism.Morphism(H, M(x)) ) for x in ls ]244245def degeneracy_map(self, level, t=1, check=True):246"""247Return the t-th degeneracy map from self to J(level). Here t must248be a divisor of either level/self.level() or self.level()/level.249250INPUT:251252253- ``level`` - integer (multiple or divisor of level of254self)255256- ``t`` - divisor of quotient of level of self and257level258259- ``check`` - bool (default: True); if True do some260checks on the input261262263OUTPUT: a morphism264265EXAMPLES::266267sage: J0(11).degeneracy_map(33)268Degeneracy map from Abelian variety J0(11) of dimension 1 to Abelian variety J0(33) of dimension 3 defined by [1]269sage: J0(11).degeneracy_map(33).matrix()270[ 0 -3 2 1 -2 0]271[ 1 -2 0 1 0 -1]272sage: J0(11).degeneracy_map(33,3).matrix()273[-1 0 0 0 1 -2]274[-1 -1 1 -1 1 0]275sage: J0(33).degeneracy_map(11,1).matrix()276[ 0 1]277[ 0 -1]278[ 1 -1]279[ 0 1]280[-1 1]281[ 0 0]282sage: J0(11).degeneracy_map(33,1).matrix() * J0(33).degeneracy_map(11,1).matrix()283[4 0]284[0 4]285"""286if check:287if (level % self.level()) and (self.level() % level):288raise ValueError, "level must be divisible by level of self"289if (max(level,self.level()) // min(self.level(),level)) % t:290raise ValueError, "t must divide the quotient of the two levels"291292Mself = self.modular_symbols()293#Jdest = Mself.ambient_module().modular_symbols_of_level(level).cuspidal_subspace().abelian_variety()294Jdest = (type(Mself.group()))(level).modular_abelian_variety()295Mdest = Jdest.modular_symbols()296297symbol_map = Mself.degeneracy_map(level, t).restrict_codomain(Mdest)298H = self.Hom(Jdest)299300return H(morphism.DegeneracyMap(H, symbol_map.matrix(), [t]))301302def dimension(self):303"""304Return the dimension of this modular abelian variety.305306EXAMPLES::307308sage: J0(2007).dimension()309221310sage: J1(13).dimension()3112312sage: J1(997).dimension()31340920314sage: J0(389).dimension()31532316sage: JH(389,[4]).dimension()31764318sage: J1(389).dimension()3196112320"""321try:322return self._dimension323except AttributeError:324d = self.group().genus()325self._dimension = d326return d327328def decomposition(self, simple=True, bound=None):329"""330Decompose this ambient Jacobian as a product of abelian331subvarieties, up to isogeny.332333EXAMPLES::334335sage: J0(33).decomposition(simple=False)336[337Abelian subvariety of dimension 2 of J0(33),338Abelian subvariety of dimension 1 of J0(33)339]340sage: J0(33).decomposition(simple=False)[1].is_simple()341True342sage: J0(33).decomposition(simple=False)[0].is_simple()343False344sage: J0(33).decomposition(simple=False)345[346Abelian subvariety of dimension 2 of J0(33),347Simple abelian subvariety 33a(None,33) of dimension 1 of J0(33)348]349sage: J0(33).decomposition(simple=True)350[351Simple abelian subvariety 11a(1,33) of dimension 1 of J0(33),352Simple abelian subvariety 11a(3,33) of dimension 1 of J0(33),353Simple abelian subvariety 33a(1,33) of dimension 1 of J0(33)354]355"""356try:357return self.__decomposition[simple]358except KeyError:359pass360except AttributeError:361self.__decomposition = {}362363M = self.modular_symbols().ambient_module()364level = M.level()365group = M.group()366factors = simple_factorization_of_modsym_space(M, simple=simple)367factors = modsym_lattices(M, factors)368369D = []370for newform_level, isogeny_number, number, modsym, lattice in factors:371if simple:372is_simple = True373else:374is_simple = None375A = ModularAbelianVariety_modsym(modsym, lattice=lattice,376newform_level = (newform_level, group), is_simple=is_simple,377isogeny_number=isogeny_number, number=(number, level), check=False)378D.append(A)379380# This line below could be safely deleted. It basically creates a circular381# reference so that say J0(389)[0] + J0(389)[1] doesn't do two separate382# decompositions. Memory will be freed though, at least if you do383# import gc; gc.collect().384A._ambient = self385386387D.sort()388D = Sequence(D, immutable=True, cr=True, universe=self.category())389self.__decomposition[simple] = D390return D391392393394395396397