code / alex / psage / psage / modform / fourier_expansion_framework / modularforms / modularform_ambient.py
241852 viewsr"""1Rings of orthogonal modular forms.23AUTHOR :4-- Martin Raum (2009 - 07 - 30) Initial version5"""67#===============================================================================8#9# Copyright (C) 2009 Martin Raum10#11# This program is free software; you can redistribute it and/or12# modify it under the terms of the GNU General Public License13# as published by the Free Software Foundation; either version 314# of the License, or (at your option) any later version.15#16# This program is distributed in the hope that it will be useful,17# but WITHOUT ANY WARRANTY; without even the implied warranty of18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU19# General Public License for more details.20#21# You should have received a copy of the GNU General Public License22# along with this program; if not, see <http://www.gnu.org/licenses/>.23#24#===============================================================================2526from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_module import GradedExpansionModule_class27from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import GradedExpansionRing_class28from psage.modform.fourier_expansion_framework.modularforms.modularform_element import ModularForm_generic29from psage.modform.fourier_expansion_framework.modularforms.modularform_functor import ModularFormsFunctor30from psage.modform.fourier_expansion_framework.modularforms.modularform_interfaces import ModularFormsAmbientWithHeckeAction_abstract31from psage.modform.fourier_expansion_framework.modularforms.modularform_submodule import ModularFormsWeightSubmodule32from sage.rings.integer import Integer33from sage.rings.integer_ring import ZZ34from sage.structure.element import Element3536#===============================================================================37# ModularFormsAmbient38#===============================================================================3940def ModularFormsAmbient( A, type, precision, *args, **kwds) :41"""42Create a ring or module of modular forms of given type. The underlying Fourier43expansions are calculated up to ``precision``.4445INPUT:46- `A` -- A ring; The base ring for the modular forms.47- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.48- ``precision`` -- A precision class.49- ``*arg`` -- Will be forwarded to the type's construction function.50- ``**kwds`` -- Will be forwarded to the type's construction function.5152OUTPUT:53An instance of :class:~`ModularFormsAmbient_abstract`.5455TESTS::56sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *57sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *58sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *59sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )60sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_vectorvalued(), NNFilter(5), reduce_before_evaluating = False )61"""62if not 'reduce_before_evaluating' in kwds :63kwds['reduce_before_evaluating'] = type.reduce_before_evaluating(A)6465return type._ambient_construction_function()(A, type, precision, *args, **kwds)6667#===============================================================================68# ModularFormsAmbient_abstract69#===============================================================================7071class ModularFormsAmbient_abstract :72"""73An abstract implementation of a graded expansion ambient, that deduced its structure from74data stored by a type of modular forms.75"""7677def __init__(self, type, precision) :78"""79INPUT:80- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.81- ``precision`` -- A precision class.8283NOTE:84- The attribute ``_extended_base_ring`` must be set before calling the constructor or85will be ignored.86- The attribute ``_submodule_classes`` will be overwritten and has to be populated after calling the87constructor. See :meth:~`._submodule` for its description.88- The attribute ``_element_class`` may not be set if it has to be adopted from the type.8990TESTS::91sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *92sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *93sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *94sage: ma = ModularFormsAmbient_abstract( ModularFormTestType_scalar(), NNFilter(5) )95"""96self.__type = type97self.__precision = precision9899if not hasattr(self, '_element_class') :100try :101self._element_class = type._ambient_element_class()102except NotImplementedError :103self._element_class = ModularForm_generic104105single_weight_pred = lambda basis, **kwds: "grading_indices" in kwds and len(kwds["grading_indices"]) == 1106def single_weight_function(basis, **kwds) :107try :108return self.__type._weight_submodule_class()(self, basis, kwds["grading_indices"][0], **kwds)109except NotImplementedError :110return ModularFormsWeightSubmodule(self, basis, kwds["grading_indices"][0])111112self._submodule_classes = [( single_weight_pred, single_weight_function ),113( lambda _, **kwds : True,114lambda basis, **kwds : self._graded_ambient_class._submodule(self, basis, **kwds) ) ]115116# This couldn't be refactored completely and will most likely cause problems in the117# the concrete implementations. A complete replacement has taken place and this is118# probably no issue.119# def precision(self) :120def fourier_expansion_precision(self) :121"""122The common precision of the underlying Fourier expansions.123124OUTPUT:125A filter for the Fourier expansion ambient's monoid or action.126127TESTS::128sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *129sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *130sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *131sage: ma = ModularFormsAmbient_abstract( ModularFormTestType_scalar(), NNFilter(5) )132sage: ma.fourier_expansion_precision()133Filtered NN with action up to 5134"""135return self.__precision136137def type(self) :138"""139The type of modular forms this ambient contains.140141OUTPUT:142An instance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.143144TESTS::145sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *146sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *147sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *148sage: ma = ModularFormsAmbient_abstract( ModularFormTestType_scalar(), NNFilter(5) )149sage: ma.type()150Test type of modular forms with 5 generators151"""152return self.__type153154def group(self) :155"""156The modular group the modular forms in this ambient are attached to.157158OUTPUT:159An arbitrary type.160161TESTS::162sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *163sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *164sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *165sage: ma = ModularFormsAmbient_abstract( ModularFormTestType_scalar(), NNFilter(5) )166sage: ma.group()167'1'168"""169return self.__type.group()170171def weights(self) :172"""173The generators' weights.174175OUTPUT:176A tuple of (generalized) weights.177178TESTS::179sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *180sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *181sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *182sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )183sage: ma.weights()184(1, 2, 3, 4, 5)185"""186return self.__type.weights(self.relations().base_ring())187188def graded_submodules_are_free(self) :189"""190Whether the modules of elements of fixed grading are free.191192OUTPUT:193A boolean.194195TESTS::196sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *197sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *198sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *199sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )200sage: ma.graded_submodules_are_free()201True202"""203return self.__type.graded_submodules_are_free(self.relations().base_ring())204205def _submodule(self, basis, **kwds) :206"""207A submodule with given basis.208209INPUT:210- ``basis`` -- A list of elements of ``self``.211- ``**kwds`` -- Will be forwarded to the submodule construction function.212213OUTPUT:214A submodule of graded expansions.215216TESTS::217sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *218sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *219sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *220sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )221sage: sm = ma._submodule([ma.0], grading_indices = [1])222"""223for pred, fcn in self._submodule_classes :224if pred(basis, **kwds) : return fcn(basis, **kwds)225226raise RuntimeError, "submodule classes do not match %s, %s" % (basis, kwds)227228def construction(self) :229"""230TESTS::231sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *232sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *233sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *234sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )235sage: (F, A) = ma.construction()236sage: F(A) == ma237True238"""239return ModularFormsFunctor(self.__type, self.__precision), self.relations().base_ring()240241def _coerce_map_from_(self, other) :242"""243TESTS::244sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *245sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *246sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *247sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )248sage: ma2 = ModularFormsAmbient( ZZ, ModularFormTestType_scalar(), NNFilter(5) )249sage: ma._coerce_map_from_(ma2)250Conversion via _element_constructor_ map:251From: Graded expansion ring with generators g1, g2, g3, g4, g5252To: Graded expansion ring with generators g1, g2, g3, g4, g5253"""254from sage.structure.coerce_maps import CallableConvertMap255256if isinstance(other, ModularFormsAmbient_abstract) and \257self.relations().base_ring().has_coerce_map_from(other.relations().base_ring()) and \258self.type() == other.type() :259return CallableConvertMap(other, self, self._element_constructor_)260261return self._graded_ambient_class._coerce_map_from_(self, other)262263def _element_constructor_(self, x) :264"""265TESTS::266sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *267sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *268sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *269sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )270sage: ma2 = ModularFormsAmbient( ZZ, ModularFormTestType_scalar(), NNFilter(5) )271sage: ma(ma2.0)272Graded expansion g1273"""274if isinstance(x, (int, Integer)) and x == 0 :275return self._element_class(self, self.relations().ring().zero())276277if isinstance(x, Element) :278P = x.parent()279if isinstance(P, ModularFormsAmbient_abstract) :280if P.type() == self.type() and \281self.relations().base_ring().has_coerce_map_from(P.relations().base_ring()) :282return self._element_class( self,283self.relations().ring()( x.polynomial(). \284subs(self.type()._hom_base_extension(P.relations().base_ring(), self.relations().base_ring())) )285)286287return self._graded_ambient_class._element_constructor_(self, x)288289def __cmp__(self, other) :290"""291TESTS::292sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *293sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *294sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *295sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )296sage: ma == ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )297True298sage: ma == ModularFormsAmbient( ZZ, ModularFormTestType_scalar(), NNFilter(5) )299False300sage: ma == ModularFormsAmbient( QQ, ModularFormTestType_vectorvalued(), NNFilter(5) )301False302"""303c = cmp(type(self), type(other))304305if c == 0 :306c = cmp(self.type(), other.type())307if c == 0 :308c = cmp(self.relations().base_ring(), other.relations().base_ring())309310return c311312#===============================================================================313# ModularFormsRing_generic314#===============================================================================315316class ModularFormsRing_generic ( ModularFormsAmbient_abstract, GradedExpansionRing_class ) :317def __init__(self, K, type, precision, **kwds) :318"""319INPUT:320- `K` -- A ring.321- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.322- ``precision`` -- A precision class.323- ``**kwds`` -- Will be forwardd to :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_ring.GradedExpansionRing_class`.324325NOTE:326- The attribute ``_extended_base_ring`` must be set before calling the constructor or327will be ignored.328- The attribute ``_graded_ambient_class`` may not be set.329- The attribute ``_submodule_classes`` will be overwritten and has to be populated after calling the330constructor. See :meth:~`fourier_expansion_framework.modularforms.modularform_ambient._submodule` for its description.331- The attribute ``_element_class`` may not be set if it has to be adopted from the type.332333TESTS::334sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *335sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *336sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *337sage: ma = ModularFormsRing_generic( QQ, ModularFormTestType_scalar(), NNFilter(5) )338sage: ma.has_coerce_map_from(QQ)339True340"""341if not hasattr(self, '_extended_base_ring') :342try :343if type.is_vector_valued() :344nvv_type = type.non_vector_valued()345self._extended_base_ring = ModularFormsAmbient(K, nvv_type, precision)346except NotImplementedError :347del self._extended_base_ring348349if not hasattr(self, '_graded_ambient_class') :350self._graded_ambient_class = GradedExpansionRing_class351352if not 'all_relations' in kwds :353kwds['all_relations'] = True354355ModularFormsAmbient_abstract.__init__(self, type, precision)356GradedExpansionRing_class.__init__(self, type.base_ring_generators(K, precision),357type.generators(K, precision), type.generator_relations(K), type.grading(K), **kwds)358359#=======================================================================360# self._populate_coercion_lists_(361# coerce_list = [GradedExpansionBaseringInjection(self.base_ring(), self)],362# convert_list = [self.relations().ring()],363# convert_method_name = "_graded_expansion_submodule_to_graded_ambient_" )364#=======================================================================365366def _coerce_map_from_(self, other):367"""368TESTS::369sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *370sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *371sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *372sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )373sage: ma._coerce_map_from_(ma)374Conversion via _element_constructor_ map:375From: Graded expansion ring with generators g1, g2, g3, g4, g5376To: Graded expansion ring with generators g1, g2, g3, g4, g5377"""378from sage.structure.coerce_maps import CallableConvertMap379380if isinstance(other, ModularFormsRing_generic) and \381self.base_ring().has_coerce_map_from(other.base_ring()) and \382self.type().is_vector_valued() and \383self.type().non_vector_valued() == other.type() :384return CallableConvertMap(other, self, self._element_constructor_)385386return ModularFormsAmbient_abstract._coerce_map_from_(self, other)387388def _element_constructor_(self, x) :389"""390TESTS::391sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *392sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *393sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *394sage: ma = ModularFormsAmbient( QQ, ModularFormTestType_scalar(), NNFilter(5) )395sage: ma2 = ModularFormsAmbient( ZZ, ModularFormTestType_scalar(), NNFilter(5) )396sage: ma(ma2.0)397Graded expansion g1398"""399if isinstance(x, Element) :400P = x.parent()401if isinstance(P, ModularFormsRing_generic) :402try :403if self.type().is_vector_valued() and \404self.type().non_vector_values() == P.type() and \405self.base_ring().has_coerce_map_from(P.base_ring()) :406if self.base_ring() != P.base_ring() :407from sage.categories.pushout import pushout408x = pushout(P, self.base_ring())(x)409410return self._element_class( self,411self.relations().ring()( x.polynomial(). \412subs(self.type()._hom_to_vector_valued(self.base_ring())) )413)414except NotImplementedError :415pass416417return ModularFormsAmbient_abstract._element_constructor_(self, x)418419#===============================================================================420# ModularFormsModule_generic421#===============================================================================422423class ModularFormsModule_generic ( ModularFormsAmbient_abstract, GradedExpansionModule_class ) :424def __init__(self, K, type, precision, **kwds) :425"""426INPUT:427- `K` -- A ring.428- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.429- ``precision`` -- A precision class.430- ``**kwds`` -- Will be forwardd to :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_ring.GradedExpansionRing_class`.431432NOTE:433- The attribute ``_extended_base_ring`` must be set before calling the constructor or434will be ignored.435- The attribute ``_graded_ambient_class`` may not be set.436- The attribute ``_submodule_classes`` will be overwritten and has to be populated after calling the437constructor. See :meth:~`fourier_expansion_framework.modularforms.modularform_ambient._submodule` for its description.438- The attribute ``_element_class`` may not be set if it has to be adopted from the type.439440TESTS::441sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *442sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *443sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *444sage: ma = ModularFormsModule_generic( QQ, ModularFormTestType_vectorvalued(), NNFilter(5) )445"""446if not hasattr(self, '_extended_base_ring') :447try :448if type.is_vector_valued() :449nvv_type = type.non_vector_valued()450self._extended_base_ring = ModularFormsAmbient(K, nvv_type, precision)451except NotImplementedError :452del self._extended_base_ring453454if not hasattr(self, '_graded_ambient_class') :455self._graded_ambient_class = GradedExpansionModule_class456457if not 'all_relations' in kwds :458kwds['all_relations'] = True459460ModularFormsAmbient_abstract.__init__(self, type, precision)461GradedExpansionModule_class.__init__(self, type.base_ring_generators(K, precision),462type.generators(K, precision), type.generator_relations(K), type.grading(K), **kwds)463464#=======================================================================465# self._populate_coercion_lists_(466# convert_list = [self.relations().ring()],467# convert_method_name = "_graded_expansion_submodule_to_graded_ambient_" )468#=======================================================================469470#===============================================================================471# ModularFormsRing_withheckeaction472#===============================================================================473474class ModularFormsRing_withheckeaction(ModularFormsAmbientWithHeckeAction_abstract, ModularFormsRing_generic ) :475def __init__(self, K, type, precision, **kwds) :476"""477INPUT:478- `K` -- A ring.479- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.480- ``precision`` -- A precision class.481- ``**kwds`` -- Will be forwardd to :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_ring.GradedExpansionRing_class`.482483NOTE:484- The attribute ``_extended_base_ring`` must be set before calling the constructor or485will be ignored.486- The attribute ``_graded_ambient_class`` may not be set.487- The attribute ``_submodule_classes`` will be overwritten and has to be populated after calling the488constructor. See :meth:~`fourier_expansion_framework.modularforms.modularform_ambient._submodule` for its description.489- The attribute ``_element_class`` may not be set if it has to be adopted from the type.490491TESTS::492sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *493sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *494sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *495sage: ma = ModularFormsRing_generic( QQ, ModularFormTestType_scalar(), NNFilter(5) )496"""497ModularFormsRing_generic.__init__(self, K, type, precision, **kwds)498ModularFormsAmbientWithHeckeAction_abstract.__init__(self, type)499500#===============================================================================501# ModularFormsModule_withheckeaction502#===============================================================================503504class ModularFormsModule_withheckeaction(ModularFormsAmbientWithHeckeAction_abstract, ModularFormsModule_generic ) :505def __init__(self, K, type, precision, **kwds) :506"""507INPUT:508- `K` -- A ring.509- ``type`` -- An inystance of :class:~`fourier_expansion_framework.modularforms.modularform_types.ModularFormType_abstract`.510- ``precision`` -- A precision class.511- ``**kwds`` -- Will be forwardd to :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_ring.GradedExpansionRing_class`.512513NOTE:514- The attribute ``_extended_base_ring`` must be set before calling the constructor or515will be ignored.516- The attribute ``_graded_ambient_class`` may not be set.517- The attribute ``_submodule_classes`` will be overwritten and has to be populated after calling the518constructor. See :meth:~`fourier_expansion_framework.modularforms.modularform_ambient._submodule` for its description.519- The attribute ``_element_class`` may not be set if it has to be adopted from the type.520521TESTS::522sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_ambient import *523sage: from psage.modform.fourier_expansion_framework.modularforms.modularform_testtype import *524sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *525sage: ma = ModularFormsModule_withheckeaction( QQ, ModularFormTestType_vectorvalued(), NNFilter(5) )526"""527ModularFormsModule_generic.__init__(self, K, type, precision, **kwds)528ModularFormsAmbientWithHeckeAction_abstract.__init__(self, type)529530531