code / alex / psage / psage / modform / fourier_expansion_framework / gradedexpansions / gradedexpansion_ring.py
241849 viewsr"""1Rings of elements with Fourier expansion and partially known relations.23AUTHOR :4-- Martin Raum (2009 - 07 - 27) 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_ambient import GradedExpansionAmbient_abstract27from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_element import GradedExpansion_class28from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_functor import GradedExpansionBaseringInjection29from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_submodule import GradedExpansionSubmodule_abstract30from sage.algebras.algebra import Algebra31from sage.misc.flatten import flatten32from sage.misc.latex import latex33from sage.rings.all import Integer34from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing35from sage.structure.element import Element36import operator3738#===============================================================================39# GradedExpansionRing_class40#===============================================================================4142class GradedExpansionRing_class ( GradedExpansionAmbient_abstract, Algebra ) :43r"""44A class for a ring of graded expansions over an ambient of graded expansions,45that might also be trivial.46That is, a polynomial ring with relations and a mapping to an (equivariant)47monoid power series.48"""4950def __init__ ( self, base_ring_generators, generators,51relations, grading, all_relations = True, reduce_before_evaluating = True) :52r"""53The degree one part of the monomials that correspond to generators over the54base expansion ring will serve as the coordinates of the elements.5556INPUT:57- ``base_ring_generators`` -- A list of (equivariant) monoid power series with58coefficient domain the base ring of the coefficient59domain of the generators or ``None``.60- ``generators`` -- A list 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.7677TESTS::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(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)))85sage: ger.base_ring()86Graded expansion ring with generators a87"""88if not hasattr(self, '_element_class') :89self._element_class = GradedExpansion_class9091if hasattr(self, "_extended_base_ring") :92Algebra.__init__(self, self._extended_base_ring)93elif base_ring_generators is None or len(base_ring_generators) == 0 :94Algebra.__init__(self, relations.base_ring())95else :96gb = filter( lambda p: all( all(a == 0 for a in list(e)[len(base_ring_generators):])97for e in p.exponents() ),98relations.groebner_basis() )99P = PolynomialRing( relations.base_ring(),100list(relations.ring().variable_names())[:len(base_ring_generators)] )101base_relations = P.ideal(gb)102R = GradedExpansionRing_class(None, base_ring_generators, base_relations,103grading.subgrading(xrange(len(base_ring_generators))), all_relations, reduce_before_evaluating)104Algebra.__init__(self, R)105106GradedExpansionAmbient_abstract.__init__(self, base_ring_generators, generators, relations, grading, all_relations, reduce_before_evaluating)107108self._populate_coercion_lists_(109coerce_list = [GradedExpansionBaseringInjection(self.base_ring(), self)],110# This is deactivated since it leads to errors in the coercion system for Sage 4.8111# TODO: Find out why112# convert_list = [self.relations().ring()],113convert_list = [],114convert_method_name = "_graded_expansion_submodule_to_graded_ambient_" )115116def _graded_monoms(self, index) :117r"""118Return all monoms in the generators that have a given grading index.119120INPUT:121- ``index`` -- A grading values.122123OUTPUT:124A list of elements of ``self``.125126TESTS::127sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *128sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *129sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *130sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading131sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *132sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))133sage: 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)))134sage: ger._graded_monoms(3)135[Graded expansion a^3, Graded expansion a*b]136sage: ger = GradedExpansionRing_class(Sequence([MonoidPowerSeries(mps, {1 : 1}, 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,3)))137sage: ger._graded_monoms(3)138[Graded expansion a^3, Graded expansion a*b, Graded expansion c]139"""140module_gens = self.grading().basis(index)141module_gens = [ filter( lambda e: e != 1,142[ mon**ex if ex > 0 else 1143for mon,ex in zip(self.basegens(), g[:self.nbasegens()]) + zip(self.gens(), g[self.nbasegens():]) ] )144for g in module_gens ]145146return [ self(reduce(operator.mul, g)) if len(g) > 1 else g[0] for g in module_gens ]147148def _coerce_map_from_(self, other) :149r"""150TESTS::151sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *152sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *153sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *154sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading155sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *156sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))157sage: 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)))158sage: ger._coerce_map_from_(ZZ)159"""160if other is self.relations().ring() :161from sage.structure.coerce_maps import CallableConvertMap162163return CallableConvertMap(other, self, self._element_constructor_)164165if isinstance(other, GradedExpansionSubmodule_abstract) :166if other.graded_ambient() is self \167or self.has_coerce_map_from(other.graded_ambient()) :168from sage.structure.coerce_maps import CallableConvertMap169170return CallableConvertMap(other, self, other._graded_expansion_submodule_to_graded_ambient_)171172return Algebra._coerce_map_from_(self, other)173174def _element_constructor_(self, x) :175r"""176INPUT:177- `x` -- An integer, an element of the underlying polynomial ring or178an element in a submodule of graded expansions.179180OUTPUT:181An instance of the element class.182183TESTS::184sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *185sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_module import *186sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *187sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading188sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *189sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))190sage: 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)))191sage: h = ger(1)192"""193if isinstance(x, (int, Integer)) :194return self._element_class(self, self.relations().ring()(x))195196P = x.parent()197if P is self.relations().ring() :198return self._element_class(self, x)199elif self.relations().ring().has_coerce_map_from(P) :200return self._element_class(self, self.relations().ring()(x))201elif P is self.base_ring() and isinstance( self.base_ring(), GradedExpansionAmbient_abstract ) :202return self._element_class(self, self.relations().ring()(x.polynomial()))203204return GradedExpansionAmbient_abstract._element_constructor_(self, x)205206def _repr_(self) :207r"""208TESTS::209sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *210sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *211sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *212sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading213sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *214sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))215sage: 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)))216sage: ger217Graded expansion ring with generators b218"""219return "Graded expansion ring with generators "\220+ ''.join(map(lambda e: repr(e.polynomial()) + ", ", self.gens()))[:-2]221222def _latex_(self) :223r"""224TESTS::225sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import *226sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_ring import *227sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_element import *228sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import DegreeGrading229sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_ring import *230sage: mps = MonoidPowerSeriesRing(QQ, NNMonoid(False))231sage: 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)))232sage: latex(ger)233\text{Graded expansion ring with generators }b234"""235return r"\text{Graded expansion ring with generators }"\236+ ''.join(map(lambda e: latex(e.polynomial()) + ", ", self.gens()))[:-2]237238239