Ticket #9280: trac_9280-graded-algebras-example.patch

File trac_9280-graded-algebras-example.patch, 19.8 KB (added by jhpalmieri, 10 years ago)
  • doc/en/reference/categories.rst

    # HG changeset patch
    # User J. H. Palmieri <palmieri@math.washington.edu>
    # Date 1277423971 25200
    # Node ID b19c0fe552a6f20b4baa37182b333edfedee49f8
    # Parent  8dec8b43ccca5f104b1e280cb33c8f4c2c1b8f85
    #9280: an example of a graded algebra with basis
    
    diff -r 8dec8b43ccca -r b19c0fe552a6 doc/en/reference/categories.rst
    a b Examples of parents using categories 
    133133   sage/categories/examples/commutative_additive_monoids
    134134   sage/categories/examples/commutative_additive_semigroups
    135135   sage/categories/examples/coxeter_groups
     136   sage/categories/examples/graded_algebras_with_basis
    136137   sage/categories/examples/finite_coxeter_groups
    137138   sage/categories/examples/finite_enumerated_sets
    138139   sage/categories/examples/finite_monoids
  • sage/categories/algebras_with_basis.py

    diff -r 8dec8b43ccca -r b19c0fe552a6 sage/categories/algebras_with_basis.py
    a b class AlgebrasWithBasis(Category_over_ba 
    104104
    105105    def example(self, alphabet = ('a','b','c')):
    106106        """
    107         Returns an example of algebra with basis::
     107        Returns an example of algebra with basis as per
     108        :meth:`Category.example <sage.categories.category.Category.example>`.
     109
     110        ::
    108111
    109112            sage: AlgebrasWithBasis(QQ).example()
    110113            An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
  • new file sage/categories/examples/graded_algebras_with_basis.py

    diff -r 8dec8b43ccca -r b19c0fe552a6 sage/categories/examples/graded_algebras_with_basis.py
    - +  
     1r"""
     2Examples of graded algebras with basis
     3"""
     4#*****************************************************************************
     5#  Copyright (C) 2010 John H. Palmieri <palmieri@math.washington.edu>
     6#
     7#  Distributed under the terms of the GNU General Public License (GPL)
     8#                  http://www.gnu.org/licenses/
     9#*****************************************************************************
     10
     11from sage.misc.cachefunc import cached_method
     12from sage.categories.all import GradedAlgebrasWithBasis
     13from sage.combinat.free_module import CombinatorialFreeModule, CombinatorialFreeModuleElement
     14
     15def basis_function(d, degrees):
     16    """
     17    INPUT:
     18
     19    - ``d`` - non-negative integer, the degree in which you want the basis
     20    - ``degrees`` - list or tuple of positive integers, the degrees of
     21      the polynomial generators
     22
     23    OUTPUT: list of lists representing the basis in degree `d`.  Each
     24    list represents a monomial in a graded polynomial algebra with
     25    generators graded by ``degrees``: if the generators are `(x_1,
     26    ..., x_n)`, then a tuple `(e_1, ..., e_n)` in the output
     27    represents the monomial `x_1^{e_1} ... x_n^{e_n}`.
     28
     29    EXAMPLES::
     30
     31        sage: from sage.categories.examples.graded_algebras_with_basis import basis_function
     32        sage: basis_function(3, [1,2])
     33        [[1, 1], [3, 0]]
     34        sage: basis_function(3, [2,1])
     35        [[1, 1], [0, 3]]
     36        sage: basis_function(3, [1,1])
     37        [[0, 3], [1, 2], [2, 1], [3, 0]]
     38        sage: basis_function(3, [2,2])
     39        []
     40        sage: basis_function(-8, [1,2,3]) # always zero in negative degrees
     41        []
     42    """
     43    from sage.combinat.integer_vector_weighted import WeightedIntegerVectors
     44    # The following doesn't work: it leads to failures of the
     45    # TestSuite.  A bug somewhere, presumably...
     46    # return WeightedIntegerVectors(d, degrees)
     47    return WeightedIntegerVectors(d, degrees).list()
     48
     49class GradedPolynomialAlgebra(CombinatorialFreeModule):
     50    r"""
     51    This class illustrates an implementation of a graded algebra
     52    with basis: a polynomial algebra on several generators of varying
     53    degrees.
     54
     55    INPUT:
     56
     57    - ``R`` - base ring
     58
     59    - ``generators`` - list of strings defining the polynomial
     60      generators (optional, default ``("a", "b", "c")``)
     61
     62    - ``degrees`` - a positive integer or a list of positive integers
     63      (optional, default ``1``).  If it is a list of positive
     64      integers, then it must be of the same length as ``generators``,
     65      and its `i`-th entry specifies the degree of the `i`-th
     66      generator.  If it is an integer `d`, then every generator is
     67      given degree `d`.
     68
     69    .. note::
     70
     71        This is not a very full-featured implementation of a
     72        polynomial algebra; you can add and multiply elements and
     73        compute their degrees, but not much else.  For real
     74        calculations, use Sage's ``PolynomialRing`` construction.
     75
     76    The implementation involves the following:
     77
     78    - A choice of how to represent elements.  In this case, the basis
     79      elements are monomials in the generators, and each monomial is
     80      represented as a tuple corresponding to the exponents of the
     81      generators.  The algebra is constructed as a
     82      :class:`CombinatorialFreeModule
     83      <sage.combinat.free_module.CombinatorialFreeModule>` on the
     84      basis of monomials, so it inherits all of the methods for such
     85      objects, and has operations like addition already defined.
     86
     87    - A basis function - this algebra is graded by the non-negative
     88      integers, so there is a function defined in this module,
     89      creatively called :func:`basis_function`, which takes an integer
     90      `d` as input and returns a list of tuples representing a basis
     91      for the algebra in degree `d`.
     92
     93    - If the algebra is called ``A``, then its basis function is
     94      stored as ``A._basis_fcn``.  Thus the function can be used to
     95      find a basis for the degree `d` piece: essentially, just call
     96      ``A._basis_fcn(d)``.  More precisely, call ``A.monomial(x)`` for
     97      each ``x`` in ``A._basis_fcn(d)``.  See also the method
     98      :meth:`basis`.
     99
     100    - A :meth:`homogeneous_component` method, returning the degree `d`
     101      piece of `A`.
     102
     103    - For dealing with basis elements: :meth:`product_on_basis`,
     104      :meth:`degree_on_basis`, and :meth:`_repr_term`. The first of
     105      these defines the product by defining it on the tuples which
     106      define basis elements; the product on arbitrary elements is
     107      determined by linearity.  Similarly, the second of these defines
     108      the degree of any monomial, and then the :meth:`degree
     109      <GradedPolynomialAlgebra.Element.degree>` method for elements --
     110      see the next item -- uses it to compute the degree for a linear
     111      combination of monomials.  The last of these determines the
     112      print representation for monomials, which automatically produces
     113      the print representation for general elements.
     114
     115    - There is a class for elements, which inherits from
     116      :class:`CombinatorialFreeModuleElement
     117      <sage.combinat.free_module.CombinatorialFreeModuleElement>`.  An
     118      element is determined by a dictionary whose keys are tuples
     119      (representing monomials, as described above) and whose
     120      corresponding values are the coefficients.  The class implements
     121      two things: an :meth:`is_homogeneous
     122      <GradedPolynomialAlgebra.Element.is_homogeneous>` method and a
     123      :meth:`degree <GradedPolynomialAlgebra.Element.degree>` method.
     124    """
     125    def __init__(self, R, generators=("a", "b", "c"), degrees=1):
     126        """
     127        EXAMPLES::
     128
     129            sage: A = GradedAlgebrasWithBasis(QQ).example(); A
     130            An example of a graded algebra with basis: the polynomial algebra on generators ('a', 'b', 'c') of degrees (1, 1, 1) over Rational Field
     131            sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3)); A
     132            An example of a graded algebra with basis: the polynomial algebra on generators ('x', 'y') of degrees (2, 3) over Rational Field
     133            sage: TestSuite(A).run()
     134        """
     135        from sage.sets.all import Family, NonNegativeIntegers
     136        from sage.rings.all import Integer
     137        from functools import partial
     138        self._generators = generators
     139        try:
     140            Integer(degrees)
     141            if degrees <= 0:
     142                raise ValueError, "Degrees must be positive integers"
     143            degrees = [degrees] * len(generators)
     144        except TypeError:
     145            # assume degrees is a list or tuple already.
     146            if len(degrees) != len(generators):
     147                raise ValueError, "List of generators and degrees must have the same length"
     148            try:
     149                for d in degrees:
     150                    assert Integer(d) > 0
     151            except (TypeError, AssertionError):
     152                raise ValueError, "Degrees must be positive integers"
     153        self._degrees = tuple(degrees)
     154        NN = NonNegativeIntegers()
     155        # Use "partial" to make the basis function (with the degrees
     156        # argument specified) pickleable.  Otherwise, it seems to
     157        # cause problems...
     158        self._basis_fcn = partial(basis_function, degrees=degrees)
     159        CombinatorialFreeModule.__init__(self, R,
     160                                         Family(NN, self._basis_fcn),
     161                                         category=GradedAlgebrasWithBasis(R))
     162
     163    @cached_method
     164    def one_basis(self):
     165        """
     166        Returns a tuple of all zeroes, which indexes the one of this
     167        algebra, as per
     168        :meth:`AlgebrasWithBasis.ParentMethods.one_basis
     169        <sage.categories.algebras_with_basis.AlgebrasWithBasis.ParentMethods.one_basis`.
     170
     171        EXAMPLES::
     172
     173            sage: A = GradedAlgebrasWithBasis(QQ).example()
     174            sage: A.one_basis()
     175            (0, 0, 0)
     176            sage: A.one()
     177            1
     178        """
     179        return (0,) * len(self._generators)
     180
     181    def product_on_basis(self, t1, t2):
     182        r"""
     183        Product of basis elements, as per
     184        :meth:`AlgebrasWithBasis.ParentMethods.product_on_basis
     185        <sage.categories.algebras_with_basis.AlgebrasWithBasis.ParentMethods.product_on_basis`.
     186
     187        INPUT:
     188
     189        - ``t1``, ``t2`` - tuples determining monomials (as the
     190          exponents of the generators) in this algebra
     191
     192        OUTPUT: the product of the two corresponding monomials, as an
     193        element of self.
     194
     195        EXAMPLES::
     196
     197            sage: A = GradedAlgebrasWithBasis(QQ).example()
     198            sage: A.product_on_basis((1,0,1), (0,0,2))
     199            ac^{3}
     200            sage: (a,b,c) = A.algebra_generators()
     201            sage: a * (1-b)^2 * c
     202            ac - 2*abc + ab^{2}c
     203        """
     204        return self.monomial(tuple([a+b for a,b in zip(t1, t2)]))
     205
     206    def degree_on_basis(self, t):
     207        """
     208        The degree of the element determined by the tuple ``t`` in
     209        this graded polynomial algebra.
     210
     211        INPUT:
     212
     213        - ``t`` - a tuple determining a monomial (as the exponents of
     214          the generators) in this algebra
     215
     216        OUTPUT: int, the degree of the corresponding monomial
     217
     218        EXAMPLES::
     219
     220            sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3))
     221            sage: A.degree_on_basis((1,1)) # x^1 y^1
     222            5
     223            sage: A.degree_on_basis((0,3))
     224            9
     225        """
     226        return sum([exp*deg for exp,deg in zip(t, self._degrees)])
     227
     228    @cached_method
     229    def algebra_generators(self):
     230        r"""
     231        Returns the generators of this algebra, as per :meth:`Algebras.ParentMethods.algebra_generators`.
     232
     233        EXAMPLES::
     234
     235            sage: A = GradedAlgebrasWithBasis(QQ).example(); A
     236            An example of a graded algebra with basis: the polynomial algebra on generators ('a', 'b', 'c') of degrees (1, 1, 1) over Rational Field
     237            sage: A.algebra_generators()
     238            Family (a, b, c)
     239        """
     240        from sage.sets.family import Family
     241        L = len(self._generators)
     242        return Family([self.monomial((0,) * i + (1,) + (0,) * (L-i-1)) for i in range(L)])
     243
     244    def homogeneous_component(self, n):
     245        """
     246        Returns the degree `n` piece of this graded algebra.
     247
     248        EXAMPLES::
     249
     250            sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3))
     251            sage: A.homogeneous_component(1)  # zero
     252            Free module generated by () over Rational Field
     253            sage: A.homogeneous_component(6)
     254            Free module generated by (y^{2}, x^{3}) over Rational Field
     255
     256        For this algebra, you can also access the homogeneous
     257        components using square brackets::
     258
     259            sage: A[9]
     260            Free module generated by (y^{3}, x^{3}y) over Rational Field
     261        """
     262        basis = tuple([tuple(a) for a in self._basis_fcn(n)])
     263        M = CombinatorialFreeModule(self.base_ring(),
     264                                    basis,
     265                                    element_class=self.Element)
     266        M._name = "Free module generated by %s"%(tuple(self.monomial(a) for a in basis),)
     267        return M
     268
     269    # The following makes A[n] the same as
     270    # A.homogeneous_components(n).  While a homogeneous_components
     271    # method should be implemented for any graded object, whether
     272    # __getitem__ should be defined and whether it should be the same
     273    # as homogeneous_components (or return something else, e.g., an
     274    # element of the algebra as in the case of
     275    # SymmetricFunctions(QQ).schur()), should be decided on a
     276    # case-by-case basis.
     277    __getitem__ = homogeneous_component
     278
     279    def basis(self, d=None):
     280        """
     281        Returns the basis for this graded algebra, either the whole
     282        basis or the basis in degree `d`.
     283
     284        INPUT:
     285
     286        - `d` - integer or None, optional (default None)
     287
     288        If `d` is None, then return a basis of the algebra.
     289        Otherwise, return the basis in degree `d`.
     290
     291        EXAMPLES::
     292
     293            sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3))
     294            sage: A.basis(4)
     295            Family (x^{2},)
     296            sage: A.basis(6)
     297            Family (y^{2}, x^{3})
     298            sage: A.basis(-10)
     299            Family ()
     300            sage: A.basis() # no argument: return the whole basis
     301            Lazy family (Term map from Lazy family (<functools.partial object at ...>(i))_{i in Non negative integers} to An example of a graded algebra with basis: the polynomial algebra on generators ('x', 'y') of degrees (2, 3) over Rational Field(i))_{i in Lazy family (<functools.partial object at ...>(i))_{i in Non negative integers}}
     302        """
     303        from sage.sets.family import Family
     304        if d is None:
     305            return Family(self._basis_keys, self.monomial)
     306        else:
     307            return Family([self.monomial(tuple(a)) for a in self._basis_fcn(d)])
     308
     309    def _repr_(self):
     310        """
     311        Print representation
     312
     313        EXAMPLES::
     314
     315            sage: GradedAlgebrasWithBasis(QQ).example() # indirect doctest
     316            An example of a graded algebra with basis: the polynomial algebra on generators ('a', 'b', 'c') of degrees (1, 1, 1) over Rational Field
     317        """
     318        return "An example of a graded algebra with basis: the polynomial algebra on generators %s of degrees %s over %s"%(self._generators, self._degrees, self.base_ring())
     319
     320
     321    def _repr_term(self, t):
     322        """
     323        Print representation for the basis element represented by the
     324        tuple ``t``.  This governs the behavior of the print
     325        representation of all elements of the algebra.
     326
     327        EXAMPLES::
     328
     329            sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("B", "H", "d"))
     330            sage: A._repr_term((0,1,2))
     331            'Hd^{2}'
     332            sage: A._repr_term((2,3,1))
     333            'B^{2}H^{3}d'
     334        """
     335        if len(t) == 0:
     336            return "0"
     337        if max(t) == 0:
     338            return "1"
     339        s = ""
     340        for e,g in zip(t, self._generators):
     341            if e != 0:
     342                if e != 1:
     343                    s += "%s^{%s}" % (g,e)
     344                else:
     345                    s += "%s" % g
     346                s = s.strip()
     347        return s
     348
     349    class Element(CombinatorialFreeModuleElement):
     350        def is_homogeneous(self):
     351            """
     352            Return True iff this element is homogeneous.
     353
     354            EXAMPLES::
     355
     356                sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3))
     357                sage: (x, y) = A.algebra_generators()
     358                sage: (3*x).is_homogeneous()
     359                True
     360                sage: (x^3 - y^2).is_homogeneous()
     361                True
     362                sage: ((x + y)^2).is_homogeneous()
     363                False
     364            """
     365            monos = self.support()
     366            if len(monos) <= 1:
     367                return True
     368            degree = None
     369            deg = self.parent().degree_on_basis
     370            for mono in monos:
     371                if degree is None:
     372                    degree = deg(mono)
     373                elif deg(mono) != degree:
     374                    return False
     375            return True
     376
     377        def degree(self):
     378            """
     379            The degree of this element in the graded polynomial algebra.
     380
     381            .. note::
     382
     383               This raises an error if the element is not homogeneous.
     384               Another implementation option would be to return the
     385               maximum of the degrees of the homogeneous summands.
     386
     387            EXAMPLES::
     388
     389                sage: A = GradedAlgebrasWithBasis(QQ).example(generators=("x", "y"), degrees=(2, 3))
     390                sage: (x, y) = A.algebra_generators()
     391                sage: x.degree()
     392                2
     393                sage: (x^3 + 4*y^2).degree()
     394                6
     395                sage: ((1 + x)^3).degree()
     396                Traceback (most recent call last):
     397                ...
     398                ValueError: Element is not homogeneous.
     399            """
     400            if len(self.support()) == 0:
     401                raise ValueError, "The zero element does not have a well-defined degree."
     402            try:
     403                assert self.is_homogeneous()
     404                return self.parent().degree_on_basis(self.leading_support())
     405            except AssertionError:
     406                raise ValueError, "Element is not homogeneous."
     407
     408Example = GradedPolynomialAlgebra
  • sage/categories/examples/hopf_algebras_with_basis.py

    diff -r 8dec8b43ccca -r b19c0fe552a6 sage/categories/examples/hopf_algebras_with_basis.py
    a b  
    11r"""
    2 Examples of algebras with basis
     2Examples of Hopf algebras with basis
    33"""
    44#*****************************************************************************
    55#  Copyright (C) 2008-2009 Nicolas M. Thiery <nthiery at users.sf.net>
  • sage/categories/graded_algebras_with_basis.py

    diff -r 8dec8b43ccca -r b19c0fe552a6 sage/categories/graded_algebras_with_basis.py
    a b class GradedAlgebrasWithBasis(Category_o 
    3939        R = self.base_ring()
    4040        return [GradedModulesWithBasis(R),GradedAlgebras(R), AlgebrasWithBasis(R)]
    4141
     42    def example(self, generators = ('a','b','c'), degrees = 1):
     43        """
     44        Returns an example of a graded algebra with basis as per
     45        :meth:`Category.example <sage.categories.category.Category.example>`.
     46
     47        EXAMPLES::
     48
     49            sage: GradedAlgebrasWithBasis(QQ).example()
     50            An example of a graded algebra with basis: the polynomial algebra on generators ('a', 'b', 'c') of degrees (1, 1, 1) over Rational Field
     51
     52        Another set of generators, and their degrees, can be specified
     53        as optional arguments::
     54
     55            sage: GradedAlgebrasWithBasis(QQ).example(generators=("x", "z"), degrees=(3, 10))
     56            An example of a graded algebra with basis: the polynomial algebra on generators ('x', 'z') of degrees (3, 10) over Rational Field
     57        """
     58        from sage.categories.examples.graded_algebras_with_basis import Example
     59        return Example(self.base_ring(), generators, degrees)
     60
    4261    class ParentMethods:
    4362        pass
    4463