code / alex / psage / psage / modform / fourier_expansion_framework / gradedexpansions / gradedexpansion_grading.py
241849 viewsr"""1Gradings of a polynomial quotient ring.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 operator import mul27from operator import xor28from sage.misc.latex import latex29from sage.modules.free_module import FreeModule30from sage.rings.infinity import infinity31from sage.rings.integer import Integer32from sage.rings.integer_ring import ZZ33from sage.rings.polynomial.all import is_Polynomial, is_MPolynomial34from sage.structure.all import Sequence35from sage.structure.sage_object import SageObject3637class Grading_abstract ( SageObject ) :38r"""39A common interface for monomial gradings of polynomial rings40`R[x_1, .., x_n]`.41"""4243def ngens(self) :44r"""45The number of generators of the polynomial ring.4647OUTPUT:48An integer.4950TESTS::51sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *52sage: Grading_abstract().ngens()53Traceback (most recent call last):54...55NotImplementedError56"""57raise NotImplementedError5859def gen(self, i) :60r"""61The grading associated to the `i`-th generator of the polynomial ring.6263INPUT:64- `i` -- An integer.6566OUTPUT:67A grading index.6869TESTS::70sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *71sage: Grading_abstract().gen(1)72Traceback (most recent call last):73...74NotImplementedError75"""76raise NotImplementedError7778def gens(self) :79r"""80The gradings of the generators of the polynomial ring.8182OUTPUT:83A tuple of grading indices.8485TESTS::86sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *87sage: Grading_abstract().gens()88Traceback (most recent call last):89...90NotImplementedError91"""92raise NotImplementedError9394def index(self, x) :95r"""96The grading value of `x` with respect to this grading.9798INPUT:99- `x` -- A tuple of length `n`.100101OUTPUT:102A grading index.103104TESTS::105sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *106sage: Grading_abstract().index((1))107Traceback (most recent call last):108...109NotImplementedError110"""111raise NotImplementedError112113def basis(self, index, vars = None) :114r"""115All monomials that are have given grading index involving only the116given variables.117118INPUT:119- ``index`` -- A grading index.120- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``121(default: ``None``); If ``None`` all variables122will be considered.123124OUTPUT:125A list of tuples of integers, each of which has length `n`.126127TESTS::128sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *129sage: Grading_abstract().basis(1)130Traceback (most recent call last):131...132NotImplementedError133"""134raise NotImplementedError135136def subgrading(self, gens) :137r"""138The grading of same type for the ring with only the variables given by139``gens``.140141INPUT:142- ``gens`` - A list of integers.143144OUTPUT:145An instance of :class:~`.Grading_abstract`.146147TESTS::148sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *149sage: Grading_abstract().subgrading([1,2])150Traceback (most recent call last):151...152NotImplementedError153"""154raise NotImplementedError155156def __contains__(self, x) :157r"""158TESTS::159sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *160sage: 1 in Grading_abstract()161Traceback (most recent call last):162...163NotImplementedError164"""165raise NotImplementedError166167def _repr_(self) :168r"""169TESTS::170sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *171sage: Grading_abstract()172A grading173"""174return "A grading"175176def _latex_(self) :177r"""178TESTS::179sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *180sage: latex( Grading_abstract() )181\text{A grading}182"""183return r"\text{A grading}"184185#===============================================================================186# DegreeGrading187#===============================================================================188189class DegreeGrading( Grading_abstract ) :190r"""191This class implements a monomial grading for a polynomial ring192`R[x_1, .., x_n]`.193"""194195def __init__( self, degrees ) :196r"""197INPUT:198- ``degrees`` -- A list or tuple of `n` positive integers.199200TESTS::201sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *202sage: g = DegreeGrading((1,2))203sage: g = DegreeGrading([5,2,3])204"""205206self.__degrees = tuple(degrees)207self.__module = FreeModule(ZZ, len(degrees))208self.__module_basis = self.__module.basis()209210def ngens(self) :211r"""212The number of generators of the polynomial ring.213214OUTPUT:215An integer.216217TESTS::218sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *219sage: DegreeGrading((1,2)).ngens()2202221sage: DegreeGrading([5,2,3]).ngens()2223223"""224return len(self.__degrees)225226def gen(self, i) :227r"""228The number of generators of the polynomial ring.229230OUTPUT:231An integer.232233TESTS::234sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *235sage: DegreeGrading([5,2,3]).gen(0)2365237sage: DegreeGrading([5,2,3]).gen(3)238Traceback (most recent call last):239...240ValueError: Generator 3 does not exist.241"""242if i < len(self.__degrees) :243return self.__degrees[i]244245raise ValueError("Generator %s does not exist." % (i,))246247def gens(self) :248r"""249The gradings of the generators of the polynomial ring.250251OUTPUT:252A tuple of integers.253254TESTS::255sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *256sage: DegreeGrading((1,2)).gens()257(1, 2)258sage: DegreeGrading([5,2,3]).gens()259(5, 2, 3)260"""261return self.__degrees262263def index(self, x) :264r"""265The grading value of `x` with respect to this grading.266267INPUT:268- `x` -- A tuple of length `n`.269270OUTPUT:271An integer.272273TESTS::274sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *275sage: g = DegreeGrading([5,2,3])276sage: g.index((2,4,5))27733278sage: g.index((2,3))279Traceback (most recent call last):280...281ValueError: Tuple must have length 3.282"""283## TODO: We shouldn't need this.284#if len(x) == 0 : return infinity285286if len(x) != len(self.__degrees) :287raise ValueError( "Tuple must have length %s." % (len(self.__degrees),))288289return sum( map(mul, x, self.__degrees) )290291def basis(self, index, vars = None) :292r"""293All monomials that are have given grading index involving only the294given variables.295296INPUT:297- ``index`` -- A grading index.298- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``299(default: ``None``); If ``None`` all variables300will be considered.301302OUTPUT:303A list of elements in `\Z^n`.304305TESTS::306sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *307sage: g = DegreeGrading([5,2,3])308sage: g.basis(2)309[(0, 1, 0)]310sage: g.basis(10, vars = [0])311[(2, 0, 0)]312sage: g.basis(20, vars = [1,2])313[(0, 10, 0), (0, 7, 2), (0, 4, 4), (0, 1, 6)]314sage: g.basis(-1)315[]316sage: g.basis(0)317[(0, 0, 0)]318"""319if index < 0 :320return []321elif index == 0 :322return [self.__module.zero_vector()]323324if vars == None :325vars = [m for (m,d) in enumerate(self.__degrees) if d <= index]326if len(vars) == 0 :327return []328329res = [ self.__module_basis[vars[0]] + m330for m in self.basis(index - self.__degrees[vars[0]], vars) ]331res += self.basis(index, vars[1:])332333return res334335def subgrading(self, gens) :336r"""337The grading of same type for the ring with only the variables given by338``gens``.339340INPUT:341- ``gens`` - A list of integers.342343OUTPUT:344An instance of :class:~`.DegreeGrading`.345346TESTS::347sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *348sage: g = DegreeGrading([5,2,3])349sage: g.subgrading([2])350Degree grading (3,)351sage: g.subgrading([])352Degree grading ()353"""354return DegreeGrading([self.__degrees[i] for i in gens])355356def __contains__(self, x) :357r"""358TESTS::359sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *360sage: g = DegreeGrading([5,2,3])361sage: 5 in g362True363sage: "t" in g364False365"""366return isinstance(x, (int, Integer))367368def __cmp__(self, other) :369r"""370TESTS::371sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *372sage: g = DegreeGrading([5,2,3])373sage: g == DegreeGrading([5,2,3])374True375sage: g == DegreeGrading((2,4))376False377"""378c = cmp(type(self), type(other))379380if c == 0 :381c = cmp(self.__degrees, other.__degrees)382383return c384385def __hash__(self) :386r"""387TESTS::388sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *389sage: hash( DegreeGrading([5,2,3]) )390-1302562269 # 32-bit3917573306103633312291 # 64-bit392"""393return hash(self.__degrees)394395def _repr_(self) :396r"""397TESTS::398sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *399sage: DegreeGrading([5,2,3])400Degree grading (5, 2, 3)401"""402return "Degree grading %s" % str(self.__degrees)403404def _latex_(self) :405r"""406TESTS::407sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *408sage: latex( DegreeGrading([5,2,3]) )409\text{Degree grading } \left(5, 2, 3\right)410"""411return r"\text{Degree grading }" + latex(self.__degrees)412413class TrivialGrading ( Grading_abstract ) :414r"""415A grading for a polynomial ring `R[x_1, .., x_n]` assigning to every416element the same, arbitrary index.417"""418419def __init__(self, nmb_generators, index) :420r"""421INPUT:422- ``nmb_generators`` -- A positive integer; The number `n` of423variables of the graded polynomial ring.424- ``index`` -- An arbitrary object; The index assigned to425all monomials.426427TESTS::428sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *429sage: g = TrivialGrading( 3, "t" )430sage: g = TrivialGrading( 3, None )431"""432self.__ngens = nmb_generators433self.__index = index434435def ngens(self) :436r"""437The number of generators of the polynomial ring.438439OUTPUT:440An integer.441442TESTS::443sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *444sage: TrivialGrading( 3, "t" ).ngens()4453446"""447return self.__ngens448449def gen(self, i) :450r"""451The number of generators of the polynomial ring.452453OUTPUT:454An arbitrary object.455456TESTS::457sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *458sage: TrivialGrading( 3, "t" ).gen(2)459't'460sage: TrivialGrading( 3, "t" ).gen(3)461Traceback (most recent call last):462...463ValueError: Generator 3 does not exist.464"""465if i < self.__ngens :466return self.__index467468raise ValueError("Generator %s does not exist." % (i,))469470def gens(self) :471r"""472The gradings of the generators of the polynomial ring.473474OUTPUT:475A tuple of objects of arbitrary but equal type.476477TESTS::478sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *479sage: TrivialGrading( 3, "t" ).gens()480('t', 't', 't')481"""482return tuple(self.__ngens*[self.__index])483484def index(self, x) :485r"""486The grading value of `x` with respect to this grading.487488INPUT:489- `x` -- A tuple of length `n`.490491OUTPUT:492A grading index.493494TESTS::495sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *496sage: TrivialGrading( 3, "t" ).index((1,0,1))497't'498sage: TrivialGrading( 3, "t" ).index((1,0))499Traceback (most recent call last):500...501ValueError: Tuple must have length 3.502"""503if len(x) != self.__ngens :504raise ValueError( "Tuple must have length %s." % (self.__ngens,))505506return self.__index507508def basis(self, index, vars = None) :509r"""510All degree one monomials that are have given grading index involving only the511given variables.512513INPUT:514- ``index`` -- A grading index.515- ``vars`` -- A list of integers from `0` to `n - 1` or ``None``516(default: ``None``); If ``None`` all variables517will be considered.518519OUTPUT:520A list of tuples of integers, each of which has length `n`.521522TESTS::523sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *524sage: TrivialGrading( 3, "t" ).basis('t')525[(1, 0, 0), (0, 1, 0), (0, 0, 1)]526sage: TrivialGrading( 3, "t" ).basis( None )527[]528"""529if index == self.__index :530if vars is None :531vars = range(self.__ngens)532533return [ tuple(i*[0] + [1] + (self.__ngens - i - 1)*[0])534for i in vars ]535else :536return []537538def subgrading(self, gens) :539r"""540The grading of same type for the ring with only the variables given by541``gens``.542543INPUT:544- ``gens`` - A list of integers.545546OUTPUT:547An instance of :class:~`.TrivialGrading`.548549TESTS::550sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *551sage: TrivialGrading( 3, "t" ).subgrading([1,2])552Trivial grading on 2 generators with index 't'553sage: TrivialGrading( 3, "t" ).subgrading([])554Trivial grading on 0 generators with index 't'555"""556return TrivialGrading(len(gens), self.__index)557558def __contains__(self, x) :559r"""560TESTS::561sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *562sage: g = TrivialGrading( 3, "t" )563sage: "t" in g564True565sage: (1,2,1) in g566False567sage: None in g568False569"""570return x == self.__index571572def __cmp__(self, other) :573r"""574TESTS::575sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *576sage: g = TrivialGrading( 3, "t" )577sage: g == TrivialGrading( 3, "t" )578True579sage: g == TrivialGrading( 2, "t" )580False581sage: g == TrivialGrading( 3, None )582False583"""584c = cmp(type(self), type(other))585586if c == 0 :587c = cmp(self.__ngens, other.__ngens)588if c == 0 :589c = cmp(self.__index, other.__index)590591return c592593def __hash__(self) :594r"""595TESTS::596sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *597sage: hash( TrivialGrading( 3, "t" ) )5981963142774 # 32-bit59914848044662 # 64-bit600"""601return reduce(xor, map(hash, [self.__ngens, self.__index]))602603def _repr_(self) :604r"""605TESTS::606sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *607sage: TrivialGrading( 3, "t" )608Trivial grading on 3 generators with index 't'609"""610return "Trivial grading on %s generators with index %s" \611% (self.__ngens, repr(self.__index))612613def _latex_(self) :614r"""615TESTS::616sage: from psage.modform.fourier_expansion_framework.gradedexpansions.gradedexpansion_grading import *617sage: latex( TrivialGrading( 3, "t" ) )618\text{Trivial grading on $3$ generators with index $\verb|t|$}619"""620return r"\text{Trivial grading on $%s$ generators with index $%s$}" \621% (latex(self.__ngens), latex(self.__index))622623624