code / alex / psage / psage / modform / fourier_expansion_framework / gradedexpansions / gradedexpansion_ambient.py
241849 viewsr"""1Ambients of elements with Fourier expansion and partially known relations.23AUTHOR :4-- Martin Raum (2010 - 03 - 10) Initial version5"""67#===============================================================================8#9# Copyright (C) 2010 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_functor import \27GradedExpansionFunctor, GradedExpansionEvaluationHomomorphism28from operator import xor29from sage.misc.cachefunc import cached_method30from sage.misc.flatten import flatten31from sage.misc.misc import prod32from sage.rings.all import Integer33from sage.structure.element import Element34from sage.structure.parent import Parent35from sage.structure.sequence import Sequence3637## late import in GradedExpansionAmbient_abstract38GradedExpansionSubmodule = None39GradedExpansionSubmodule_abstract = None4041#===============================================================================42# GradedExpansionAmbient_abstract43#===============================================================================4445class GradedExpansionAmbient_abstract :46r"""47A ring of graded expansions. This is a polynomial ring with relations48and a mapping to an (equivariant) monoid power series. These should49respect the given relations, but there can me more relations of the50Fourier expansions that are stored for the polynomial ring.51"""5253def __init__ ( self, base_ring_generators, generators, relations,54grading, all_relations = True, reduce_before_evaluating = True) :55r"""56INPUT:57- ``base_ring_generators`` -- A sequence of (equivariant) monoid power series with58coefficient domain the base ring of the coefficient59domain of the generators or ``None``.60- ``generators`` -- A sequence of (equivariant) monoid power series; The generators61of the ambient over the ring generated by the base ring62generators.63- ``relations`` -- An ideal in a polynomial ring with ``len(base_ring_generators) + len(generators)``64variables.65- ``grading`` -- A grading deriving from :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_grading`;66A grading for the polynomial ring of the relations.67- ``all_relations`` -- A boolean (default: ``True``); If ``True`` the relations given68for the polynomial ring are all relations that the Fourier69expansion have.70- ``reduce_before_evaluating`` -- A boolean (default: ``True``); If ``True`` any monomial71will be Groebner reduced before the Fourier expansion72is calculated.7374NOTE:75The grading must respect the relations of the generators.7677EXAMPLES::78sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *79sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *80sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *81sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading82sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *83sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))84sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,))) # indirect doctest85sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2))) # indirect doctest86sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)), all_relations = False) # indirect doctest87sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)), reduce_before_evaluating = False) # indirect doctest88"""89global GradedExpansionSubmodule, GradedExpansionSubmodule_abstract90from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_submodule import GradedExpansionSubmodule91from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_submodule import GradedExpansionSubmodule_abstract9293self.__relations = relations94self.__all_relations = all_relations95self.__grading = grading9697if base_ring_generators is None :98base_ring_generators = []99base_ring_generators = Sequence([], universe = generators.universe().base_ring())100self.__base_gens = \101tuple([ self.base_ring()._element_class( self.base_ring(), self.base_ring().relations().ring()(g) )102for g in self.__relations.ring().gens()[:len(base_ring_generators)] ])103self.__gens = \104tuple([ self._element_class( self, g )105for g in self.__relations.ring().gens()[len(base_ring_generators):] ])106107# We expect the base ring generators to either admit coercion108# into the universe of the generators or to act on it from the left109self.__base_gen_expansions = base_ring_generators110self.__gen_expansions = generators111self.__evaluation_hom = GradedExpansionEvaluationHomomorphism( self.__relations, self.__base_gen_expansions,112self.__gen_expansions, self.__gen_expansions.universe(),113reduce_before_evaluating )114115self.__graded_submodules = dict()116117def ngens(self) :118r"""119The number of generators of ``self`` over the base expansion ring.120121OUTPUT:122An integer.123124EXAMPLES::125sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *126sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *127sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *128sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading129sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *130sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))131sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))132sage: ger.ngens()1331134"""135return len(self.__gens)136137def gen(self, i = 0) :138r"""139The `i`-th generator of ``self`` over the base expansion ring.140141INPUT:142- `i` -- An integer.143144OUTPUT:145An instance of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_element.GradedExpansion_abstract`.146147EXAMPLES::148sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *149sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *150sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *151sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading152sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *153sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))154sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))155sage: ger.gen(0)156Graded expansion a157"""158return self.__gens[i]159160def gens(self) :161r"""162The generators of ``self`` over the base expansion ring.163164OUTPUT:165A tuple of instances of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_element.GradedExpansion_abstract`.166167EXAMPLES::168sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *169sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *170sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *171sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading172sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *173sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))174sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))175sage: ger.gens()176(Graded expansion a,)177"""178return self.__gens179180def nbasegens(self) :181r"""182Number of generators of the base expansion ring.183184OUTPUT:185An integer.186187TESTS::188sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *189sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *190sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *191sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading192sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *193sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))194sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))195sage: ger.nbasegens()1960197sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))198sage: ger.nbasegens()1991200"""201return len(self.__base_gens)202203def basegen(self, i) :204r"""205The `i`-th generator of the base expansion ring.206207INPUT:208- `i` -- An integer.209210OUTPUT:211An instance of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_element.GradedExpansion_abstract`.212213TESTS::214sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *215sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *216sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *217sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading218sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *219sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))220sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))221sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))222sage: ger.basegen(0)223Graded expansion a224"""225return self.__base_gens[i]226227def basegens(self) :228r"""229The generators of the base expansion ring.230231OUTPUT:232A tuple of instances of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_element.GradedExpansion_abstract`.233234TESTS::235sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *236sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *237sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *238sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading239sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *240sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))241sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))242sage: ger.basegens()243(Graded expansion a,)244"""245return self.__base_gens246247def is_field(self) :248r"""249OUTPUT:250A boolean.251252TESTS::253sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *254sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *255sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *256sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading257sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *258sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))259sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))260sage: ger.is_field()261False262"""263## Never delete this. It is called during intialisation of deriving classes264## over number fields and and causes coercion to fail.265return False266267def grading(self) :268r"""269The grading imposed on this ring.270271OUTPUT:272An isntance of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_grading`.273274EXAMPLES::275sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *276sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *277sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *278sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading279sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *280sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))281sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))282sage: ger.grading() == DegreeGrading((1,2))283True284"""285return self.__grading286287def relations(self) :288r"""289The relation of the generators of this ring with in the underlying290polynomial ring.291292OUTPUT:293An ideal in a polynomial ring.294295SEE:296all_relations_known297298TESTS::299sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *300sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *301sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *302sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading303sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *304sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))305sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))306sage: ger.relations()307Principal ideal (0) of Univariate Polynomial Ring in a over Integer Ring308sage: P.<a,b,c> = PolynomialRing(ZZ)309sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), P.ideal(a*b - c), DegreeGrading((1,2)))310sage: ger.relations()311Ideal (a*b - c) of Multivariate Polynomial Ring in a, b, c over Integer Ring312"""313return self.__relations314315def all_relations_known(self) :316r"""317If ``True`` is returned any relation of the Fourier expansions associated318with elements of this ring - thought of as expansions with319infinite precision - implies that the relation is also contained320in ``self.relations()``.321322OUTPUT:323A boolean.324325TESTS::326sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *327sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *328sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *329sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading330sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *331sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))332sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))333sage: ger.all_relations_known()334True335sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)), all_relations = False)336sage: ger.all_relations_known()337False338"""339return self.__all_relations340341def has_relation_free_generators(self) :342r"""343If ``True`` is returned, there are no relations of the Fourier344expansions - thought of as expansions with infinite precision.345346OUTPUT:347A boolean.348349TESTS::350sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *351sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *352sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *353sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading354sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *355sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))356sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,))) # indirect doctest357sage: ger.has_relation_free_generators()358True359sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)), all_relations = False)360sage: ger.has_relation_free_generators()361False362sage: P.<a,b,c> = PolynomialRing(ZZ)363sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), P.ideal(a*b - c), DegreeGrading((1,2)))364sage: ger.has_relation_free_generators()365False366"""367return self.__all_relations and self.__relations.is_zero()368369def _generator_expansions(self) :370r"""371The generators' Fourier expansion within a common parent.372373OUTPUT:374A sequence of of (equivariant) monoid power series.375376TESTS::377sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *378sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *379sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *380sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading381sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *382sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))383sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))384sage: ger._generator_expansions().universe()385Ring of monoid power series over NN386sage: ger._generator_expansions()[0].coefficients()387{0: 1}388"""389return self.__gen_expansions390391def _base_generator_expansions(self) :392r"""393The Fourier expansions of the generators of the base expansion ring.394395OUTPUT:396A sequence of of (equivariant) monoid power series.397398TESTS::399sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *400sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *401sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *402sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading403sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *404sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))405sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))406sage: ger._base_generator_expansions().universe()407Rational Field408sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))409sage: ger._base_generator_expansions()410[Monoid power series in Ring of monoid power series over NN]411"""412return self.__base_gen_expansions413414@cached_method415def fourier_expansion_precision(self) :416r"""417A precision which is obtained by all expansions of any element.418419OUTPUT:420A filter for the Fourier expansion ambient's monoid or action.421422TESTS::423sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *424sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *425sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *426sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading427sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *428sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))429sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))430sage: ger.fourier_expansion_precision()431Filtered NN up to +Infinity432sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))433sage: ger.fourier_expansion_precision()434Filtered NN up to 2435"""436return min([ g.precision() for g in self.__gen_expansions + self.__base_gen_expansions])437438@cached_method439def fourier_ring(self) :440r"""441The ring that Fourier expansions of all elements of this442ring will be contained in.443444OUTPUT:445An ambient of (equivariant) monoid power series.446447TESTS::448sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *449sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *450sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *451sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading452sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *453sage: mps = MonoidPowerSeriesRing(ZZ, NNMonoid(False))454sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(QQ, 'a').ideal(0), DegreeGrading((1,)))455sage: ger.fourier_ring()456Ring of monoid power series over NN457sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))458sage: ger.fourier_ring()459Ring of monoid power series over NN460"""461if self.__gen_expansions.universe().base_ring() == self.base_ring() :462return self.__gen_expansions.universe()463else :464from sage.categories.pushout import pushout465466if self.nbasegens() == 0 :467scalar_ring = self.base_ring()468else :469scalar_ring = self.base_ring().base_ring()470471return pushout(self.__gen_expansions.universe(), scalar_ring)472473#===========================================================================474# def precision(self) :475# r"""476# Return the minimal precision of any fourier expansion in this ring.477# """478# return min([g.precision() for g in self._generator_expansions()])479#===========================================================================480481def _set_evaluation_hom(self, hom) :482r"""483Set the homomorphism that maps every polynomial in the underlying484polynomial ring to its expansion.485486INPUT:487- ``hom`` -- A morphism with domain a polynomial ring and488domain an ambient of (equivariant) monoid power series.489490OUTPUT:491``None``.492493TESTS::494sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *495sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *496sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *497sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading498sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *499sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))500sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))501sage: ger2 = GradedExpansionRing_class(None, Sequence([mps(2)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))502sage: ger2._set_evaluation_hom(ger._GradedExpansionAmbient_abstract__evaluation_hom)503sage: ger2.0.fourier_expansion().coefficients()504{0: 1}505"""506self.__evaluation_hom = hom507508def _fourier_expansion_of_element(self, e) :509r"""510The Fourier expansion of an element `e`.511512INPUT:513- `e` -- An element of the ``self``.514515OUTPUT:516A (equivariant) monoid power series.517518SEE:519:class:~`.fourier_expansion_framework.gradedexpansions.fourierexpansionwrapper.FourierExpansionWrapper`.520521TESTS::522sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *523sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *524sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *525sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading526sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *527sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))528sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, mps.monoid().filter(2))]), Sequence([MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))529sage: ger.0.fourier_expansion() # indirect doctest530Monoid power series in Ring of monoid power series over NN531sage: (ger.basegens()[0]^2 * 2*ger.0).fourier_expansion() # indirect doctest532Monoid power series in Ring of monoid power series over NN533sage: (ger.basegens()[0] + 5*ger.0).fourier_expansion() # indirect doctest534Monoid power series in Ring of monoid power series over NN535"""536return self.__evaluation_hom(e.polynomial())537538#===============================================================================539# def graded_submodules_are_free(self) :540# r"""541# If ``True`` is returned, there are no relations within the module542# formed by the Fourier expansions - thought of as expansions with543# infinite precision - for a fixed grading value.544#545# OUTPUT:546# A boolean.547#548# TESTS::549# sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *550# sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *551# sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *552# sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading553# sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *554# sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))555# sage: ger = GradedExpansionRing_class(None, Sequence([mps(1)]), PolynomialRing(ZZ, 'a').ideal(0), DegreeGrading((1,)))556# sage: ger.graded_submodules_are_free()557# False558# """559# return False560#===============================================================================561562def _graded_monoms(self, index) :563r"""564Return all monoms in the generators that have a given grading index.565566INPUT:567- ``index`` -- A grading values.568569OUTPUT:570A list of elements of ``self``.571572TESTS::573sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *574sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *575sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *576sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading577sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *578sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))579sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))580sage: GradedExpansionAmbient_abstract._graded_monoms(ger, 3)581Traceback (most recent call last):582...583NotImplementedError584"""585raise NotImplementedError586587def graded_submodule(self, indices, **kwds) :588r"""589The submodule which contains all elements of given590grading values.591592INPUT:593- ``indices`` -- A list or tuple of grading values or a single grading value.594- ``**kwds`` -- A dictionary of keywords; They will be passed to the595submodule constructor.596597OUTPUT:598An instance of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_submodule.GradedExpansionSubmodule_abstract`.599600TESTS::601sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *602sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *603sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *604sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *605sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading606sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *607sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_module import *608sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))609sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))610sage: sm = ger.graded_submodule(2)611sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter_all()), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter_all())]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))612sage: sm = ger.graded_submodule(3)613sage: P.<a,b,c> = PolynomialRing(QQ)614sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter_all()), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter_all()), MonoidPowerSeries(mps, {2 : 1, 3: 6, 4 : 9}, mps.monoid().filter_all())]), P.ideal(b^2 - c), DegreeGrading((1,2)))615sage: sm = ger.graded_submodule(4)616sage: m = FreeModule(QQ, 3)617sage: mpsm = MonoidPowerSeriesModule(m, NNMonoid(False))618sage: mps = mpsm.base_ring()619sage: ger = GradedExpansionModule_class(None, Sequence([MonoidPowerSeries(mpsm, {1 : m([1,2,3]), 2 : m([3,-3,2])}, mpsm.monoid().filter(4)), MonoidPowerSeries(mpsm, {1 : m([2,-1,-1]), 2 : m([1,0,0])}, mpsm.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))620sage: ger.graded_submodule(4).rank()6210622"""623#=======================================================================624# if not self.graded_submodules_are_free() :625# raise ValueError( "Graded submodules of must be free." )626#=======================================================================627628if indices in self.grading() :629indices = tuple([indices])630elif isinstance(indices, list) :631indices = tuple(indices)632elif not isinstance(indices, tuple) :633raise TypeError( "Wrong type of indices." )634635try :636return self.__graded_submodules[indices]637except KeyError :638pass639640module_gens = flatten(map(self._graded_monoms, indices), max_level = 1)641642if self.has_relation_free_generators() :643basis = module_gens644else :645module_gens_poly = map(lambda g: g.polynomial(), module_gens)646basis = list()647648I = self.relations().ring().zero_ideal()649for i,g in enumerate(module_gens_poly) :650rg = I.reduce(g)651652if not rg.is_zero() :653I = I.ring().ideal([rg] + list(I.gens_reduced()))654basis.append(module_gens[i])655656self.__graded_submodules[indices] = self._submodule(basis, grading_indices = indices, **kwds)657658return self.__graded_submodules[indices]659660def _submodule(self, arg, *args, **kwds) :661r"""662Return a submodule of ``self``.663664INPUT:665- `arg` -- A list of elements of ``self``.666667OUTPUT:668An instance of :class:~`fourier_expansion_framework.gradedexpansions.gradedexpansion_submodule.GradedExpansionSubmodule_abstract`.669670TESTS::671sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *672sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *673sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *674sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading675sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *676sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))677sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(ZZ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))678sage: sm = ger.graded_submodule(2) # indirect doctest679"""680if isinstance(arg, list) :681return GradedExpansionSubmodule(self, arg)682else :683raise NotImplementedError684685def __cmp__(self, other) :686r"""687TESTS::688sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *689sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *690sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *691sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading692sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *693sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))694sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))695sage: ger == GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))696True697sage: ger == GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,3)))698False699sage: P.<a,b> = PolynomialRing(QQ)700sage: ger == GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), P.ideal(a^2 - b), DegreeGrading((1,2)))701False702sage: ger == GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 4}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))703False704sage: ger == GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 4}, mps.monoid().filter(4))]), Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b', 'c']).ideal(0), DegreeGrading((1,2,2)))705False706"""707c = cmp(type(self), type(other))708if c == 0 :709c = cmp(self.__relations, other.__relations)710if c == 0 :711c = cmp(self.__all_relations, other.__all_relations)712if c == 0 :713c = cmp(self.__grading, other.__grading)714if c == 0 :715c = cmp(self.__base_gen_expansions, other.__base_gen_expansions)716if c == 0 :717c = cmp(self.__gen_expansions, other.__gen_expansions)718719return c720721def construction(self) :722r"""723TESTS::724sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *725sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *726sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *727sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading728sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *729sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))730sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))731sage: (F, A) = ger.construction()732sage: ger == F(A)733True734"""735return ( GradedExpansionFunctor(self.__base_gen_expansions, self.__gen_expansions,736self.__relations, self.__grading, self.__all_relations ), \737self.base_ring() )738739def _element_constructor_(self, x) :740r"""741INPUT:742- `x` -- An element of the underlying polynomial ring or743an element in a submodule of graded expansions.744745OUTPUT:746An instance of the element class.747748TESTS::749sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *750sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *751sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *752sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading753sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *754sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_module import *755sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))756sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1: 1}, mps.monoid().filter(4))]), Sequence([MonoidPowerSeries(mps, {1: 1, 2: 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))757sage: h = ger(PolynomialRing(QQ, ['a', 'b']).gen(0))758sage: sm = ger.graded_submodule(3)759sage: h = ger(sm.0)760sage: m = FreeModule(QQ, 3)761sage: mpsm = MonoidPowerSeriesModule(m, NNMonoid(False))762sage: mps = mpsm.base_ring()763sage: ger = GradedExpansionModule_class(Sequence([MonoidPowerSeries(mps, {1: 1}, mps.monoid().filter(4))]), Sequence([MonoidPowerSeries(mpsm, {1: m([1,1,1]), 2: m([1,3,-3])}, mpsm.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))764sage: h = ger(PolynomialRing(QQ, ['a', 'b']).gen(1))765sage: sm = ger.graded_submodule(3)766sage: h = ger(sm.0)767"""768if isinstance(x, Element) :769P = x.parent()770if P is self.relations().ring() :771return self._element_class(self, x)772elif isinstance(P, GradedExpansionSubmodule_abstract) :773if self is P.graded_ambient() :774return P._graded_expansion_submodule_to_graded_ambient_(x)775elif self.has_coerce_map_from(P.graded_ambient()) :776return self(P.graded_ambient()(x))777## We cannot handle base extensions here, because we don't know anything778## about additional relations which may occur. So deriving classes have779## to care about this.780781raise TypeError( "The element %s cannot be converted into %s," % (x, self) )782783def __hash__(self) :784r"""785TESTS::786sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *787sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *788sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *789sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading790sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *791sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))792sage: ger = GradedExpansionRing_class(None, Sequence([MonoidPowerSeries(mps, {1 : 4, 2 : 3}, mps.monoid().filter(4)), MonoidPowerSeries(mps, {1 : 1, 2 : 3}, mps.monoid().filter(4))]), PolynomialRing(QQ, ['a', 'b']).ideal(0), DegreeGrading((1,2)))793sage: hash(ger)794921050467 # 32-bit7953906772531912514915 # 64-bit796"""797return reduce(xor, map(hash, [self.__grading, self.__relations,798self.__all_relations, self.__base_gens, self.__gens]) )799800801