code / alex / psage / psage / modform / fourier_expansion_framework / monoidpowerseries / monoidpowerseries_basicmonoids.py
241852 viewsr"""1Implementation of base classes used as parameters for a ring of monoid2power series.34AUTHOR :5- Martin Raum (2009 - 07 - 25) Initial version6"""78#===============================================================================9#10# Copyright (C) 2009 Martin Raum11#12# This program is free software; you can redistribute it and/or13# modify it under the terms of the GNU General Public License14# as published by the Free Software Foundation; either version 315# of the License, or (at your option) any later version.16#17# This program is distributed in the hope that it will be useful,18# but WITHOUT ANY WARRANTY; without even the implied warranty of19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU20# General Public License for more details.21#22# You should have received a copy of the GNU General Public License23# along with this program; if not, see <http://www.gnu.org/licenses/>.24#25#===============================================================================2627from operator import xor28from sage.misc.latex import latex29from sage.categories.all import Rings30from sage.rings.infinity import infinity31from sage.rings.integer import Integer32from sage.rings.integer_ring import ZZ33from sage.structure.sage_object import SageObject3435#===============================================================================36# CharacterMonoid_class37#===============================================================================3839class CharacterMonoid_class ( SageObject ) :40r"""41The characters for an equivariant monoid power series must42form a monoid. A basic implementation is given here.43"""4445def __init__(self, G, C, codomain, eval, C_multiplicative = True) :46r"""47INPUT:4849- `G` -- Every type accepted; Representative of a group which50the characters can be evaluated on.51- `C` -- A class implementing all functions of :class:`~.TrivialMonoid_class`;52A monoid whose elements represent one character each.53- ``codomain`` -- A ring; A common codomain for all characters.54- ``eval`` -- A function; It accepts a group element and a character,55returning the evaluation of this character at the56group element.57- ``C_multiplicative`` -- A boolean; If true the monoid `C` is assumed58to be multiplicative. Otherwise it is assumed to be additive.5960NOTE:61The interface may change in the future, enforcing `G` to be a group.6263EXAMPLES::64sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid65sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)6667TESTS::68sage: cm = CharacterMonoid_class(None, TrivialMonoid(), AbelianGroup([3,3]), lambda g, c: 1)69sage: cm = CharacterMonoid_class("ZZ", ZZ, AbelianGroup([3,3]), lambda g, c: 1, True)70"""71self.__G = G72self.__C = C73self.__codomain = codomain74self.__eval = eval75self.__C_multiplicative = C_multiplicative7677def ngens(self) :78r"""79OUTPUT:80An integer.8182TESTS::83sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid84sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)85sage: cm.ngens()86187sage: cm = CharacterMonoid_class("ZZ", AbelianGroup([3, 3]), ZZ, lambda g, c: 1)88sage: cm.ngens()89290"""91return self.__C.ngens()9293def gen(self, i = 0) :94r"""95OUTPUT:96An instance of :class:`~.CharacterMonoidElement_class`.9798TESTS::99sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid100sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)101sage: cm.gen()1021103"""104return CharacterMonoidElement_class(self, self.__C.gen(i))105106def gens(self) :107r"""108OUTPUT:109A tuple of instances of :class:`~.CharacterMonoidElement_class`.110111TESTS::112sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid113sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)114sage: cm.gens()115(1,)116"""117return tuple(map(lambda c: CharacterMonoidElement_class(self, c), self.__C.gens()))118119def group(self) :120r"""121Return the group, which is the common domain of all characters122of this monoid of characters.123124OUTPUT:125Of arbitrary type.126127TESTS::128sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid129sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)130sage: cm.group()131'ZZ'132"""133return self.__G134135def codomain(self) :136r"""137Return the common codomain of all characters of this monoid of characters.138139OUTPUT:140A ring.141142EXAMPLES::143sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid144sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)145sage: cm.codomain()146Rational Field147"""148return self.__codomain149150def monoid(self) :151r"""152Return the abstract monoid underlying this monoid of characters.153154OUTPUT:155A monoid.156157EXAMPLES::158sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid159sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)160sage: cm.monoid()161Trivial monoid162sage: cm = CharacterMonoid_class("ZZ", AbelianGroup([3, 3]), ZZ, lambda g, c: 1)163sage: cm.monoid()164Multiplicative Abelian Group isomorphic to C3 x C3165"""166return self.__C167168def extends(self, other) :169r"""170Decide whether ``self`` extends ``other``. Namely, whether there is a is an embedding of ``other``171into ``self`` that is compatible with a common codomain. A negative answer does not mean172that there is no such embedding.173174INPUT:175- other -- An instance of :class:.`~CharacterMonoid_class`.176177OUTPUT:178A boolean.179180EXAMPLES::181sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid182sage: cm1 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)183sage: cm2 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)184sage: cm1 == cm2185False186"""187return self == other188189def _is_C_multiplicative(self) :190r"""191Return whether the underlying monoid is multiplicative.192193OUTPUT:194A boolean.195196TESTS::197sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid198sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)199sage: cm._is_C_multiplicative()200True201"""202return self.__C_multiplicative203204def _eval_function(self) :205r"""206Return the evaluation function, mapping an element of the associated group and an element of ``self``207to an element of the codomain.208209OUTPUT:210A function with signature `g, c \mapsto e`.211212TESTS::213sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid214sage: e = lambda g, c: 1215sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, e)216sage: e == cm._eval_function()217True218"""219return self.__eval220221def _apply(self, g, c, b) :222r"""223Apply `c(g)` to some element `b` by multiplication.224225INPUT:226- g -- Arbitrary type; A representative of the group.227- c -- An element of self; A character.228- b -- An element of a ring with embedding from the codomain. An element to229apply `c(g)` to.230231OUTPUT:232An element of a ring.233234EXAMPLES::235sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid236sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)237sage: cm._apply(1, 1, 2)2382239"""240return self.__eval(g, c) * b241242def __cmp__(self, other) :243r"""244TESTS::245sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid246sage: cm1 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)247sage: cm2 = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)248sage: cm1 == cm2249False250"""251c = cmp(type(self), type(other))252if c == 0 :253c = cmp(self.__G, other.__G)254if c == 0 :255c = cmp(self.__codomain, other.__codomain)256if c == 0 :257c = cmp(self.__C, other.__C)258if c == 0 and not self.__eval is other.__eval :259return -1260261return c262263def __iter__(self) :264r"""265TEST::266sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid267sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)268sage: list(cm)269[1]270"""271for c in self.__C :272yield CharacterMonoidElement_class(self, c)273274raise StopIteration275276def one_element(self) :277r"""278TESTS::279sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid280sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)281sage: cm.one_element()2821283"""284return CharacterMonoidElement_class(self, self.__C.one_element())285286def __call__(self, x) :287r"""288Convert an element to ``self``.289290INPUT:291- `x` -- An element that is convertible to :meth:~`.monoid()`.292293OUTPUT:294An element of ``self``.295296TESTS::297sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid298sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)299sage: cm(1)3001301"""302return CharacterMonoidElement_class(self, self.__C(x))303304def __hash__(self) :305r"""306TESTS::307sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid308sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)309sage: d = dict([(cm.one_element, 0)]) # indirect doctest310"""311return xor(hash(self.__C), hash(self.__G))312313def _repr_(self) :314r"""315TESTS::316sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid317sage: CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)318Character monoid over Trivial monoid319"""320return "Character monoid over %s" % self.__C321322def _latex_(self) :323r"""324TESTS::325sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, TrivialMonoid326sage: latex(CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1))327\text{Character monoid over } \text{Trivial monoid}328"""329return r"\text{Character monoid over }" + latex(self.__C)330331#===============================================================================332# CharacterMonoidElement_class333#===============================================================================334335class CharacterMonoidElement_class ( SageObject ) :336"""337The element class of :class:`~.CharacterMonoid_class`.338"""339340def __init__(self, parent, c) :341r"""342INPUT:343- ``parent`` -- An instance of :class:`~.CharacterMonoid_class`; The parent of ``self``.344- `c` -- An element of a monoid; The element in the underlying monoid of ``parent``345associated to ``self``.346347TESTS::348sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid349sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)350sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())351"""352self.__parent = parent353self.__c = c354355def parent(self) :356r"""357OUTPUT:358An instance of :class:`~.CharacterMonoid_class`.359360TESTS::361sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid362sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)363sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())364sage: c.parent() is cm365True366"""367return self.__parent368369def _monoid_element(self) :370r"""371The underlying element of the monoid.372373OUTPUT:374An element of a character.375376TESTS::377sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid378sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)379sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())380sage: c._monoid_element() == cm.monoid().one_element()381True382"""383return self.__c384385def __call__(self, g) :386r"""387OUTPUT:388An element of the codomain of the parent.389390TESTS::391sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid392sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)393sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())394sage: c(2)3951396397Test old bug, where elements of the underlying monoid were passed to the eval function::398sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1 if isinstance(c, CharacterMonoidElement_class) else -1)399sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())400sage: c(2)4011402"""403return self.parent()._eval_function()(g, self)404405def __mul__(left, right) :406r"""407NOTE:408If the underlying monoid is additive the character are nevertheless multiplied.409410OUTPUT:411An instance of :class:`~.CharacterMonoidElement_class`.412413TESTS::414sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid415sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)416sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())417sage: c * c # indirect doctest4181419sage: cm = CharacterMonoid_class("ZZ", ZZ, QQ, lambda g, c: 1, False)420sage: c = CharacterMonoidElement_class(cm, cm.monoid().one_element())421sage: c * c # indirect doctest4222423"""424if not isinstance(right, CharacterMonoidElement_class) or \425not left.parent() == right.parent() :426raise TypeError( "Right factor should be an element of the monoid." )427428if left.parent()._is_C_multiplicative() :429return CharacterMonoidElement_class(left.parent(), left.__c * right.__c)430else :431return CharacterMonoidElement_class(left.parent(), left.__c + right.__c)432433def __cmp__(self, other) :434r"""435TESTS::436sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid437sage: cm = CharacterMonoid_class("ZZ", ZZ, QQ, lambda g, c: 1, False)438sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())439sage: c2 = CharacterMonoidElement_class(cm, cm.monoid().one_element())440sage: c1 == c2 # indirect doctest441True442sage: c1 * c1 == c1 # indirect doctest443False444"""445c = cmp(type(self), type(other))446if c == 0 :447c = cmp(self.__parent, other.__parent)448if c == 0 :449c = cmp(self.__c, other.__c)450451return c452453def __hash__(self) :454r"""455OUTPUT:456An integer.457458TESTS::459sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid460sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)461sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())462sage: hash(c1) # indirect doctest463-582796950 # 32-bit464-3589969894075844246 # 64-bit465"""466return xor(hash(self.__parent), hash(self.__c))467468def _repr_(self) :469r"""470OUTPUT:471A string.472473TESTS::474sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid475sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)476sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())477sage: repr(c1) # indirect doctest478'1'479"""480return repr(self.__c)481482def _latex_(self) :483r"""484OUTPUT:485A string.486487TESTS::488sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import CharacterMonoid_class, CharacterMonoidElement_class, TrivialMonoid489sage: cm = CharacterMonoid_class("ZZ", TrivialMonoid(), QQ, lambda g, c: 1)490sage: c1 = CharacterMonoidElement_class(cm, cm.monoid().one_element())491sage: latex(c1) # indirect doctest4921493"""494return latex(self.__c)495496#===============================================================================497# TrivialMonoid498#===============================================================================499500class TrivialMonoid ( SageObject ) :501r"""502A monoid with one element, which implements only functions that are necessary for503being an arguemnt of :meth:`~.CharacterMonoid_class.__init__`.504"""505506def __init__(self) :507r"""508TESTS::509sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid510sage: m = TrivialMonoid()511"""512SageObject.__init__(self)513514def ngens(self) :515r"""516OUTPUT:517An integer.518519TESTS::520sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid521sage: m = TrivialMonoid()522sage: m.ngens()5231524"""525return 1526527def gen(self, i = 0) :528r"""529OUTPUT:530An integer.531532TESTS::533sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid534sage: m = TrivialMonoid()535sage: m.gen()5361537sage: m.gen(1)538Traceback (most recent call last):539...540ValueError: Generator not defined.541"""542if i == 0 :543return Integer(1)544545raise ValueError, "Generator not defined."546547def gens(self) :548r"""549OUTPUT:550A tuple of integers.551552TESTS::553sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid554sage: m = TrivialMonoid()555sage: m.gens()556(1,)557"""558return (Integer(1), )559560def one_element(self) :561r"""562OUTPUT:563An integer.564565TESTS::566sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid567sage: m = TrivialMonoid()568sage: m.one_element()5691570"""571return Integer(1)572573def __call__(self, x) :574r"""575INPUT:576- `x` -- An integer.577578OUTPUT:579An integer.580581TESTS::582sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid583sage: m = TrivialMonoid()584sage: m(1)5851586sage: m(2)587Traceback (most recent call last):588...589TypeError: Cannot convert 2 into Trivial monoid.590"""591if x == 1 :592return 1593594raise TypeError( "Cannot convert %s into Trivial monoid." % (x,) )595596def __cmp__(self, other) :597r"""598TESTS::599sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid600sage: TrivialMonoid() == TrivialMonoid() # indirect doctest601True602"""603return cmp(type(self), type(other))604605def __iter__(self) :606r"""607OUTPUT:608A generator over integers.609610TESTS::611sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid612sage: m = TrivialMonoid()613sage: list(m) # indirect doctest614[1]615"""616yield Integer(1)617618raise StopIteration619620def _repr_(self) :621r"""622OUTPUT:623A string.624625TESTS::626sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid627sage: m = TrivialMonoid()628sage: repr(m) # indirect doctest629'Trivial monoid'630"""631return "Trivial monoid"632633def _latex_(self) :634r"""635OUTPUT:636A string.637638TESTS::639sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialMonoid640sage: m = TrivialMonoid()641sage: latex(m) # indirect doctest642\text{Trivial monoid}643"""644return r"\text{Trivial monoid}"645646#===============================================================================647# TrivialCharacterMonoid648#===============================================================================649650_trivial_evaluations = dict()651652def TrivialCharacterMonoid(G, K) :653r"""654Return the monoid of characters with codomain `K` with one element.655656INPUT:657- `K` -- A ring; The codomain for the characters.658659OUTPUT:660An instance of :class:`~.CharacterMonoid_class`.661662TESTS::663sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialCharacterMonoid664sage: h = TrivialCharacterMonoid("ZZ", QQ)665sage: h666Character monoid over Trivial monoid667sage: h == TrivialCharacterMonoid("ZZ", QQ)668True669"""670global _trivial_evaluations671672try :673eval = _trivial_evaluations[K]674except KeyError :675eval = lambda g, c : K.one_element()676_trivial_evaluations[K] = eval677678return CharacterMonoid_class(G, TrivialMonoid(), K, eval)679680#===============================================================================681# TrivialRepresentation682#===============================================================================683684class TrivialRepresentation ( SageObject ) :685r"""686A trivial representation over a group `G` with codomain `K` occurring as a representation for687:class:`~fourier_expansion_framework.monoidpowerseries.EquivariantMonoidPowerSeriesAmbient_abstract`.688"""689690def __init__(self, G, K) :691r"""692INPUT:693- `G` -- Arbitrary type; A group or representative of a group.694- `K` -- A module or ring; The codomain of the representation.695696OUTPUT:697An instance of :class:`~.TrivialRepresentation`.698699NOTE:700The interface may change late, enforcing `G` to be an actual group.701702TESTS::703sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation704sage: rep = TrivialRepresentation("ZZ", QQ) # indirect doctest705"""706self.__G = G707self.__K = K708709def base_ring(self) :710r"""711The base ring of the representation, commuting with the action.712713OUTPUT:714A ring.715716TESTS::717sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation718sage: rep = TrivialRepresentation("ZZ", QQ)719sage: rep.base_ring()720Rational Field721sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))722sage: rep.base_ring()723Integer Ring724"""725if self.__K in Rings() :726return self.__K727else :728return self.__K.base_ring()729730def codomain(self) :731r"""732The codomain of the representation.733734OUTPUT:735A ring or a module.736737TESTS::738sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation739sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))740sage: rep.codomain()741Ambient free module of rank 3 over the principal ideal domain Integer Ring742"""743return self.__K744745def from_module(self, R) :746r"""747Construct a representation of the same type with codomain `R`.748749INPUT:750751- `R` -- A module that the representation can be restricted or752extended to.753754OUTPUT:755756- An instance of :class:`~.TrivialRepresentation`.757758EXAMPLES::759760sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation761sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))762sage: rep2 = rep.from_module(FreeModule(QQ, 2))763sage: rep2.codomain()764Vector space of dimension 2 over Rational Field765"""766return TrivialRepresentation( self.__G, R )767768def base_extend(self, L) :769r"""770Extend the representation's codomain by `L`.771772INPUT:773- `L` -- A ring; A new base ring.774775OUTPUT:776An instance of :class:`~.TrivialRepresentation`.777778EXAMPLES::779sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation780sage: rep = TrivialRepresentation("ZZ", FreeModule(ZZ, 3))781sage: repQQ = rep.base_extend(QQ)782sage: repQQ.codomain()783Vector space of dimension 3 over Rational Field784sage: repQQ.base_extend(GF(3))785Traceback (most recent call last):786...787TypeError: Base extension of self (over 'Rational Field') to ring 'Finite Field of size 3' not defined.788sage: rep = TrivialRepresentation("ZZ", ZZ)789sage: repQQ = rep.base_extend(QQ)790sage: repQQ.codomain()791Rational Field792sage: repQQ.base_extend(GF(3))793Traceback (most recent call last):794...795AssertionError796"""797if self.__K in Rings() :798assert L.has_coerce_map_from(self.__K)799return TrivialRepresentation( self.__G, L )800else :801return TrivialRepresentation( self.__G, self.__K.base_extend(L) )802803def extends(self, other) :804r"""805Wheter ``self`` is an extension of ``other``.806807INPUT:808- ``other`` -- A representation.809810OUTPUT:811A boolean.812813NOTE:814This does not necessarily mean that ``self`` ocurres as a base extension of815``other``.816817EXAMPLES::818sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation819sage: rep1 = TrivialRepresentation("ZZ", ZZ)820sage: rep2 = TrivialRepresentation("ZZ", QQ)821sage: rep1.extends(rep2)822False823sage: rep2.extends(rep1)824True825"""826if type(self) != type(other) :827return False828829return self.__K.has_coerce_map_from(other.__K)830831def group(self) :832r"""833The group that acts.834835OUTPUT:836Arbitrary type.837838EXAMPLES::839sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation840sage: rep = TrivialRepresentation("ZZ", QQ)841sage: rep.group()842'ZZ'843"""844return self.__G845846def _apply_function(self) :847r"""848A function that maps a group element and an element of the codomain to its image.849850OUTPUT:851A function with signature `(g,a) \mapsto g.a`.852853TESTS::854sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation855sage: rep = TrivialRepresentation("ZZ", QQ)856sage: rep._apply_function() == rep.apply857True858"""859return self.apply860861def apply(self, g, a) :862r"""863Return the image of `a` under the transformation `g`.864865INPUT:866- `g` -- Arbitrary type; A group element.867- `a` -- An element of a ring of module; An elemento the codomain.868869OUTPUT:870A element of the codomain.871872TESTS::873sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation874sage: rep = TrivialRepresentation("ZZ", QQ)875sage: rep.apply(2, 1/2)8761/2877"""878return a879880def __cmp__(self, other) :881r"""882TESTS::883sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation884sage: rep1 = TrivialRepresentation("ZZ", QQ)885sage: rep2 = TrivialRepresentation("ZZ", FreeModule(QQ, 1))886sage: rep1 == rep1 # indirect doctest887True888sage: rep1 == rep2 # indirect doctest889False890"""891c = cmp(type(self), type(other))892893if c == 0 :894c = cmp(self.__G, self.__G)895if c == 0 :896c = cmp(self.__K, other.__K)897898return c899900def __hash__(self) :901r"""902TESTS::903sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation904sage: rep = TrivialRepresentation("ZZ", QQ)905sage: hash(rep) # indirect doctest906-564657610 # 32-bit907-11520069220171210 # 64-bit908"""909return xor(hash(self.__G), hash(self.__K))910911def _repr_(self) :912r"""913TESTS::914sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation915sage: rep = TrivialRepresentation("ZZ", QQ)916sage: repr(rep)917'Trivial representation of ZZ on Rational Field'918"""919return "Trivial representation of %s on %s" % (self.__G, self.__K)920921def _latex_(self) :922r"""923TESTS::924sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import TrivialRepresentation925sage: rep = TrivialRepresentation("ZZ", QQ)926sage: latex(rep)927\text{Trivial representation of $\verb|ZZ|$ on $\Bold{Q}$}928"""929return r"\text{Trivial representation of $%s$ on $%s$}" % (latex(self.__G), latex(self.__K))930931#===============================================================================932# NNMonoid933#===============================================================================934935class NNMonoid( SageObject ) :936r"""937Monoid of all natural numbers with zero as is can occure as an arguement of938:class:`~fourier_expansion_framework.monoidpowerseries.MonoidPowerSeriesAmbient_abstract`.939"""940941def __init__(self, reduced = True) :942r"""943INPUT:944- ``reduce`` -- A boolean (default: True); Wheter ``self`` is equipped with an action945or not.946947OUTPUT:948An instance of :class:`~.NNmonoid`.949950TESTS::951sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid952sage: m = NNMonoid()953"""954self.__reduced = reduced955956def ngens(self) :957r"""958OUTPUT:959An integer.960961TESTS::962sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid963sage: m = NNMonoid()964sage: m.ngens()9651966"""967return 1968969def gen(self, i = 0) :970r"""971OUTPUT:972An integer.973974TESTS::975sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid976sage: m = NNMonoid()977sage: m.gen()9781979sage: m.gen(1)980Traceback (most recent call last):981...982ValueError: Generator not defined.983"""984985if i == 0 :986return 1987988raise ValueError( "Generator not defined." )989990def gens(self) :991r"""992OUTPUT:993A tuple of integers.994995TESTS::996sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid997sage: m = NNMonoid()998sage: m.gens()999(1,)1000"""1001return tuple([self.gen(i) for i in xrange(self.ngens())])10021003def is_commutative(self) :1004r"""1005Whether the monoid is commutative or not.10061007OUTPUT:1008A boolean.10091010TESTS::1011sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1012sage: m = NNMonoid()1013sage: m.is_commutative()1014True1015"""1016return True10171018def monoid(self) :1019r"""1020If ``self`` respects the action of the trivial group return the underlying1021monoid without this action. Otherwise return a copy of ``self``.10221023OUTPUT:1024An instance of :class:`~.NNMonoid`.10251026TESTS::1027sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1028sage: m_a = NNMonoid()1029sage: m_woa = NNMonoid(False)1030sage: m_a.monoid() == m_woa1031True1032sage: m_woa.monoid() == m_woa1033True1034sage: m_woa.monoid() is m_woa1035False1036"""1037return NNMonoid(False)10381039def group(self) :1040r"""1041If ``self`` respects the action of a group return representative.10421043OUTPUT:1044Arbitrary type.10451046TESTS::1047sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1048sage: m_a = NNMonoid()1049sage: m_woa = NNMonoid(False)1050sage: m_a.group()1051'1'1052sage: m_woa.group()1053Traceback (most recent call last):1054...1055ArithmeticError: Monoid is not equipped with a group action.1056"""1057if self.__reduced :1058return "1"1059else :1060raise ArithmeticError( "Monoid is not equipped with a group action.")10611062def is_monoid_action(self) :1063r"""1064In case ``self`` respects the action of a group, decide whether this action is a monoid action1065on the underlying monoid.10661067OUTPUT:1068A boolean.10691070TESTS::1071sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1072sage: m_a = NNMonoid()1073sage: m_woa = NNMonoid(False)1074sage: m_a.is_monoid_action()107511076sage: m_woa.is_monoid_action()1077Traceback (most recent call last):1078...1079ArithmeticError: Monoid is not equipped with a group action.1080"""1081if self.__reduced :1082return True1083else :1084raise ArithmeticError( "Monoid is not equipped with a group action.")10851086def filter(self, bound) :1087r"""1088Return a filter with given bound associated to this monoid.10891090INPUT:1091- ``bound`` -- An integer; An upper bound for natural numbers.10921093OUTPUT:1094An instance of :class:`~.NNFilter`.10951096TESTS::1097sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1098sage: m_a = NNMonoid()1099sage: m_woa = NNMonoid(False)1100sage: f = m_a.filter(5)1101sage: f.index()110251103sage: f.is_reduced()1104True1105sage: f = m_woa.filter(7)1106sage: f.is_reduced()1107False1108"""1109return NNFilter(bound, self.__reduced)11101111def filter_all(self) :1112r"""1113Return the filter associated to this monoid which contains all elements.11141115OUTPUT:1116An instance of :class:`~.NNFilter`.11171118TESTS::1119sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1120sage: m_a = NNMonoid()1121sage: m_woa = NNMonoid(False)1122sage: f = m_a.filter_all()1123sage: f.index()1124+Infinity1125sage: f.is_reduced()1126True1127sage: m_woa.filter_all().is_reduced()1128False1129"""1130return NNFilter(infinity, self.__reduced)11311132def zero_filter(self) :1133r"""1134Return the filter associated to this monoid which contains no elements.11351136OUTPUT:1137An instance of :class:`~.NNFilter`.11381139TESTS::1140sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1141sage: m_a = NNMonoid()1142sage: m_woa = NNMonoid(False)1143sage: f = m_a.zero_filter()1144sage: f.index()114501146sage: f.is_reduced()1147True1148sage: m_woa.zero_filter().is_reduced()1149False1150"""1151return NNFilter(0, self.__reduced)11521153def minimal_composition_filter(self, ls, rs) :1154r"""1155Given two lists `ls` and `rs` of natural numbers return a filter that contains1156all the sums `l + r` of elements `l \in ls,\, r \in rs`.11571158INPUT:1159- `ls` -- A list of integers.1160- `rs` -- A list of integers.11611162OUTPUT:1163An instance of :class:`~.NNFilter`.11641165TESTS::1166sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1167sage: m = NNMonoid()1168sage: m.minimal_composition_filter([], []).is_reduced()1169True1170sage: m = NNMonoid(False)1171sage: m.minimal_composition_filter([], []).is_reduced()1172False1173sage: m = NNMonoid()1174sage: m.minimal_composition_filter([], []).index()117501176sage: m.minimal_composition_filter([], [1]).index()117701178sage: m.minimal_composition_filter([1], []).index()117901180sage: m.minimal_composition_filter([1], [1]).index()118131182sage: m.minimal_composition_filter([1,2,4], [1,5]).index()1183101184"""1185if len(ls) == 0 or len(rs) == 0 :1186return NNFilter(0, self.__reduced)11871188return NNFilter(max(0, max(ls) + max(rs) + 1), self.__reduced)11891190def _reduction_function(self) :1191r"""1192In case ``self`` respects the action of a group, return the1193reduction funtion for elements of this monoid.11941195SEE::1196:meth:`~.reduce`11971198OUTPUT:1199A function accepting one argument.12001201TESTS::1202sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1203sage: m = NNMonoid()1204sage: m._reduction_function() == m.reduce1205True1206sage: m = NNMonoid(False)1207sage: m._reduction_function()1208Traceback (most recent call last):1209...1210ArithmeticError: Monoid is not equipped with a group action.1211"""1212if self.__reduced :1213return self.reduce1214else :1215raise ArithmeticError( "Monoid is not equipped with a group action." )12161217def reduce(self, s) :1218r"""1219Reduce a natural number with respect to the trivial groups.12201221INPUT:1222- `s` -- An integer.12231224OUTPUT:1225The pair `(s, 1)`.12261227TESTS::1228sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1229sage: m = NNMonoid()1230sage: m.reduce(7)1231(7, 1)1232"""1233return (s, 1)12341235def decompositions(self, s) :1236r"""1237Decompose a natural number `s` in to a sum of two.12381239INPUT:1240- `s` -- An integer.12411242OUTPUT:1243A generator of pairs of integers.12441245EXAMPLES::1246sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1247sage: m = NNMonoid()1248sage: list(m.decompositions(4))1249[(0, 4), (1, 3), (2, 2), (3, 1), (4, 0)]1250"""1251for n in xrange(s+1) :1252yield (n, s-n)12531254raise StopIteration12551256def zero_element(self) :1257r"""1258The zero element of this monoid.12591260OUTPUT:1261An integer.12621263TESTS:1264sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1265sage: m = NNMonoid()1266sage: m.zero_element()126701268"""1269return 012701271def __contains__(self, x) :1272r"""1273TESTS::1274sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1275sage: m = NNMonoid()1276sage: 2 in m1277True1278sage: 'a' in m1279False1280sage: -1 in m1281False1282"""1283return isinstance(x, (int, Integer)) and x >= 012841285def __cmp__(self, other) :1286r"""1287TESTS::1288sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1289sage: m = NNMonoid()1290sage: m == NNMonoid()1291True1292sage: m == NNMonoid(False)1293False1294"""1295c = cmp(type(self), type(other))1296if c == 0 :1297c = cmp(self.__reduced, other.__reduced)12981299return c13001301def __hash__(self) :1302r"""1303TESTS::1304sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1305sage: hash(NNMonoid())130611307sage: hash(NNMonoid(False))130801309"""1310return hash(self.__reduced)13111312def _repr_(self) :1313r"""1314TESTS::1315sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1316sage: repr(NNMonoid())1317'NN with action'1318sage: repr(NNMonoid(False))1319'NN'1320"""1321if not self.__reduced :1322return "NN"1323else :1324return "NN with action"13251326def _latex_(self) :1327r"""1328TESTS::1329sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNMonoid1330sage: latex(NNMonoid())1331\Bold{N}\text{ with action}1332sage: latex(NNMonoid(False))1333\Bold{N}1334"""1335if not self.__reduced :1336return r"\Bold{N}"1337else :1338return r"\Bold{N}\text{ with action}"13391340#===============================================================================1341# NNFilter1342#===============================================================================13431344class NNFilter ( SageObject ) :1345r"""1346A filter for the monoid of natrual numbers bounding elements by their value.1347"""13481349def __init__(self, bound, reduced = True) :1350r"""1351INPUT:1352- ``bound`` -- An integer; A bound for the natural numbers.1353- ``reduced`` -- A boolean (default: True); If True the action of the trivial1354group is respected by the filter.13551356OUTPUT:1357An instance of :class:`~.NNFilter`.13581359TESTS::1360sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1361sage: f = NNFilter(3) # indirect doctest1362sage: f = NNFilter(7, False) # indirect doctest1363"""1364if isinstance(bound, NNFilter) :1365bound = bound.index()13661367self.__bound = bound1368self.__reduced = reduced13691370def is_infinite(self) :1371r"""1372Whether the filter contains infinitely many elements.13731374OUTPUT:1375A boolean.13761377TESTS::1378sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1379sage: NNFilter(3).is_infinite()1380False1381sage: NNFilter(infinity).is_infinite()1382True1383"""1384return self.__bound is infinity13851386def is_all(self) :1387r"""1388Whether the filter contains all elements of the associated monoid.13891390OUTPUT:1391A boolean.13921393TESTS::1394sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1395sage: NNFilter(3).is_all()1396False1397sage: NNFilter(infinity).is_all()1398True1399"""1400return self.is_infinite()14011402def index(self) :1403r"""1404Return the bound for this filter.14051406OUTPUT:1407An integer.14081409TESTS::1410sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1411sage: NNFilter(3).index()141231413"""1414return self.__bound14151416def is_reduced(self) :1417r"""1418Whether the filter respects the action of a group.14191420OUTPUT:1421A boolean.14221423TESTS::1424sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1425sage: NNFilter(3).is_reduced()1426True1427sage: NNFilter(7, False).is_reduced()1428False1429"""1430return self.__reduced14311432def __contains__(self, n) :1433r"""1434TESTS::1435sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1436sage: f = NNFilter(10)1437sage: 3 in f # indirect doctest1438True1439sage: 10 in f # indirect doctest1440False1441sage: 78 in NNFilter(infinity) # indirect doctest1442True1443"""1444if self.__bound is infinity :1445return True14461447return n < self.__bound14481449def __iter__(self) :1450r"""1451OUTPUT:1452A generator over integers.14531454TESTS::1455sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1456sage: list(NNFilter(4)) == range(4) # indirect doctest1457True1458sage: list(NNFilter(infinity))1459Traceback (most recent call last):1460...1461ArithmeticError: Cannot iterate over infinite filters.1462"""1463if self.__bound is infinity :1464raise ArithmeticError( "Cannot iterate over infinite filters." )14651466for n in xrange(self.__bound) :1467yield n14681469raise StopIteration14701471def __cmp__(self, other) :1472r"""1473TESTS::1474sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1475sage: NNFilter(4) == NNFilter(4) # indirect doctest1476True1477sage: NNFilter(4) == NNFilter(5) # indirect doctest1478False1479sage: NNFilter(4) == NNFilter(4, False) # indirect doctest1480False1481"""1482c = cmp(type(self), type(other))1483if c == 0 :1484c = cmp(self.__reduced, other.__reduced)1485if c == 0 :1486c = cmp(self.__bound, other.__bound)14871488return c14891490def __hash__(self) :1491r"""1492TESTS::1493sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1494sage: hash(NNFilter(4)) # indirect doctest1495211496sage: hash(NNFilter(7, False)) # indirect doctest149771498"""1499return hash(self.__bound) + 17 * hash(self.__reduced)15001501def _repr_(self) :1502r"""1503TESTS::1504sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1505sage: repr(NNFilter(3))1506'Filtered NN with action up to 3'1507sage: repr(NNFilter(4, False))1508'Filtered NN up to 4'1509"""1510if self.__reduced :1511return "Filtered NN with action up to %s" % self.__bound1512else :1513return "Filtered NN up to %s" % self.__bound15141515def _latex_(self) :1516r"""1517TESTS::1518sage: from psage.modform.fourier_expansion_framework.monoidpowerseries.monoidpowerseries_basicmonoids import NNFilter1519sage: latex(NNFilter(3))1520\text{Filtered $\Bold{N}$ with action up to $3$}1521sage: latex(NNFilter(4, False))1522\text{Filtered $\Bold{N}$ up to $4$}1523"""1524if self.__reduced :1525return r"\text{Filtered $\Bold{N}$ with action up to $%s$}" % latex(self.__bound)1526else :1527return r"\text{Filtered $\Bold{N}$ up to $%s$}" % latex(self.__bound)152815291530