Example #1
0
    def super_categories(self):
        """
        EXAMPLES::

            sage: Semigroups().super_categories()
            [Category of magmas]
        """
        return [Magmas()]
    def super_categories(self):
        """
        EXAMPLES::

            sage: from sage.categories.magmas_and_additive_magmas import MagmasAndAdditiveMagmas
            sage: MagmasAndAdditiveMagmas().super_categories()
            [Category of magmas, Category of additive magmas]
        """
        return [Magmas(), AdditiveMagmas()]
Example #3
0
    def super_categories(self):
        """
        EXAMPLES::

            sage: PolyhedralSets(QQ).super_categories()
            [Category of commutative magmas, Category of additive monoids]
        """
        from sage.categories.magmas import Magmas
        from sage.categories.additive_monoids import AdditiveMonoids
        return [Magmas().Commutative(), AdditiveMonoids()]
    def extra_super_categories(self):
        """
        Any permutation group is assumed to be endowed with a finite set of generators.

        TESTS:

            sage: PermutationGroups().Finite().extra_super_categories()
            [Category of finitely generated magmas]
        """
        return [Magmas().FinitelyGenerated()]
Example #5
0
    def __init__(self, vars):
        """
        EXAMPLES::

            sage: F = sage.combinat.free_prelie_algebra.PreLieFunctor(['x','y'])
            sage: F
            PreLie[x,y]
            sage: F(ZZ)
            Free PreLie algebra on 2 generators ['x', 'y']  over Integer Ring
        """
        Functor.__init__(self, Rings(), Magmas())
        self.vars = vars
Example #6
0
    def __init__(self, vars):
        """
        EXAMPLES::

            sage: F = sage.algebras.free_zinbiel_algebra.ZinbielFunctor(['x','y'])
            sage: F
            Zinbiel[x,y]
            sage: F(ZZ)
            Free Zinbiel algebra on generators (Z[x], Z[y]) over Integer Ring
        """
        Functor.__init__(self, Rings(), Magmas())
        self.vars = vars
Example #7
0
            def extra_super_categories(self):
                """
                EXAMPLES::

                    sage: C = AdditiveMagmas().AdditiveUnital().Algebras(QQ)
                    sage: C.extra_super_categories()
                    [Category of unital magmas]

                    sage: C.super_categories()
                    [Category of unital algebras with basis over Rational Field, Category of additive magma algebras over Rational Field]
                """
                from sage.categories.magmas import Magmas
                return [Magmas().Unital()]
Example #8
0
            def extra_super_categories(self):
                """
                EXAMPLES::

                    sage: AdditiveMagmas().AdditiveCommutative().Algebras(QQ).extra_super_categories()
                    [Category of commutative magmas]

                    sage: AdditiveMagmas().AdditiveCommutative().Algebras(QQ).super_categories()
                    [Category of additive magma algebras over Rational Field,
                     Category of commutative magmas]
                """
                from sage.categories.magmas import Magmas
                return [Magmas().Commutative()]
Example #9
0
    def __init__(self, variables):
        """
        EXAMPLES::

            sage: functor = sage.algebras.free_zinbiel_algebra.ZinbielFunctor
            sage: F = functor(['x','y']); F
            Zinbiel[x,y]
            sage: F(ZZ)
            Free Zinbiel algebra on generators (Z[x], Z[y]) over Integer Ring
        """
        Functor.__init__(self, Rings(), Magmas())
        self.vars = variables
        self._finite_vars = bool(
            isinstance(variables, (list, tuple))
            or variables in Sets().Finite())
Example #10
0
    def Finite_extra_super_categories(self):
        r"""
        Return extraneous super categories for ``DivisionRings().Finite()``.

        EXAMPLES:

        Any field is a division ring::

            sage: Fields().is_subcategory(DivisionRings())
            True

        This methods specifies that, by Weddeburn theorem, the
        reciprocal holds in the finite case: a finite division ring is
        commutative and thus a field::

            sage: DivisionRings().Finite_extra_super_categories()
            (Category of commutative magmas,)
            sage: DivisionRings().Finite()
            Category of finite enumerated fields

        .. WARNING::

            This is not implemented in
            ``DivisionRings.Finite.extra_super_categories`` because
            the categories of finite division rings and of finite
            fields coincide. See the section
            :ref:`axioms-deduction-rules` in the documentation of
            axioms.

        TESTS::

            sage: DivisionRings().Finite() is Fields().Finite()
            True

        This works also for subcategories::

            sage: class Foo(Category):
            ....:     def super_categories(self): return [DivisionRings()]
            sage: Foo().Finite().is_subcategory(Fields())
            True
        """
        from sage.categories.magmas import Magmas
        return (Magmas().Commutative(), )
Example #11
0
    def super_categories(self):
        """
        EXAMPLES::

            sage: from sage.categories.magmatic_algebras import MagmaticAlgebras
            sage: MagmaticAlgebras(ZZ).super_categories()
            [Category of additive commutative additive associative additive unital distributive magmas and additive magmas, Category of modules over Integer Ring]

            sage: from sage.categories.additive_semigroups import AdditiveSemigroups
            sage: MagmaticAlgebras(ZZ).is_subcategory((AdditiveSemigroups() & Magmas()).Distributive())
            True

        """
        R = self.base_ring()
        # Note: The specifications impose `self` to be a subcategory
        # of the join of its super categories. Here the join is non
        # trivial, since some of the axioms of Modules (like the
        # commutativity of '+') are added to the left hand side.  We
        # might want the infrastructure to take this join for us.
        return Category.join([(Magmas() & AdditiveMagmas()).Distributive(), Modules(R)], as_list=True)
Example #12
0
def GroupAlgebra(G, R=IntegerRing()):
    """
    Return the group algebra of `G` over `R`.

    INPUT:

    - `G` -- a group
    - `R` -- (default: `\ZZ`) a ring

    EXAMPLES:

    The *group algebra* `A=RG` is the space of formal linear
    combinations of elements of `G` with coefficients in `R`::

        sage: G = DihedralGroup(3)
        sage: R = QQ
        sage: A = GroupAlgebra(G, R); A
        Algebra of Dihedral group of order 6 as a permutation group over Rational Field
        sage: a = A.an_element(); a
        () + 4*(1,2,3) + 2*(1,3)

    This space is endowed with an algebra structure, obtained by extending
    by bilinearity the multiplication of `G` to a multiplication on `RG`::

        sage: A in Algebras
        True
        sage: a * a
        5*() + 8*(2,3) + 8*(1,2) + 8*(1,2,3) + 16*(1,3,2) + 4*(1,3)

    :func:`GroupAlgebra` is just a short hand for a more general
    construction that covers, e.g., monoid algebras, additive group
    algebras and so on::

        sage: G.algebra(QQ)
        Algebra of Dihedral group of order 6 as a permutation group over Rational Field

        sage: GroupAlgebra(G,QQ) is G.algebra(QQ)
        True

        sage: M = Monoids().example(); M
        An example of a monoid:
        the free monoid generated by ('a', 'b', 'c', 'd')
        sage: M.algebra(QQ)
        Algebra of An example of a monoid: the free monoid generated by ('a', 'b', 'c', 'd')
                over Rational Field

    See the documentation of :mod:`sage.categories.algebra_functor`
    for details.

    TESTS::

        sage: GroupAlgebra(1)
        Traceback (most recent call last):
        ...
        ValueError: 1 is not a magma or additive magma

        sage: GroupAlgebra(GL(3, GF(7)))
        Algebra of General Linear Group of degree 3 over Finite Field of size 7
         over Integer Ring
        sage: GroupAlgebra(GL(3, GF(7)), QQ)
        Algebra of General Linear Group of degree 3 over Finite Field of size 7
         over Rational Field
    """
    if not (G in Magmas() or G in AdditiveMagmas()):
        raise ValueError("%s is not a magma or additive magma" % G)
    if not R in Rings():
        raise ValueError("%s is not a ring" % R)
    return G.algebra(R)
Example #13
0
        def __init_extra__(self):
            """
            Declare the canonical coercion from ``self.base_ring()``
            to ``self``, if there has been none before.

            EXAMPLES::

                sage: A = AlgebrasWithBasis(QQ).example(); A
                An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field
                sage: coercion_model = sage.structure.element.get_coercion_model()
                sage: coercion_model.discover_coercion(QQ, A)
                (Generic morphism:
                  From: Rational Field
                  To:   An example of an algebra with basis: the free algebra on the generators ('a', 'b', 'c') over Rational Field, None)
                sage: A(1)          # indirect doctest
                B[word: ]

            TESTS:

            Ensure that :trac:`28328` is fixed and that non-associative
            algebras are supported::

                sage: class Foo(CombinatorialFreeModule):
                ....:     def one(self):
                ....:         return self.monomial(0)
                sage: from sage.categories.magmatic_algebras \
                ....:   import MagmaticAlgebras
                sage: C = MagmaticAlgebras(QQ).WithBasis().Unital()
                sage: F = Foo(QQ,(1,),category=C)
                sage: F(0)
                0
                sage: F(3)
                3*B[0]

            """
            # If self has an attribute _no_generic_basering_coercion
            # set to True, then this declaration is skipped.
            # This trick, introduced in #11900, is used in
            # sage.matrix.matrix_space.py and
            # sage.rings.polynomial.polynomial_ring.
            # It will hopefully be refactored into something more
            # conceptual later on.
            if getattr(self, '_no_generic_basering_coercion', False):
                return

            base_ring = self.base_ring()
            if base_ring is self:
                # There are rings that are their own base rings. No need to register that.
                return
            if self._is_coercion_cached(base_ring):
                # We will not use any generic stuff, since a (presumably) better conversion
                # has already been registered.
                return

            # Pick a homset for the morphism to live in...
            if self in Rings():
                # The algebra is associative, and thus a ring. The
                # base ring is also a ring. Everything is OK.
                H = Hom(base_ring, self, Rings())
            else:
                # If the algebra isn't associative, we would like to
                # use the category of unital magmatic algebras (which
                # are not necessarily associative) instead. But,
                # unfortunately, certain important rings like QQ
                # aren't in that category. As a result, we have to use
                # something weaker.
                cat = Magmas().Unital()
                cat = Category.join([cat, CommutativeAdditiveGroups()])
                cat = cat.Distributive()
                H = Hom(base_ring, self, cat)

            # We need to register a coercion from the base ring to self.
            #
            # There is a generic method from_base_ring(), that just does
            # multiplication with the multiplicative unit. However, the
            # unit is constructed repeatedly, which is slow.
            # So, if the unit is available *now*, then we can create a
            # faster coercion map.
            #
            # This only applies for the generic from_base_ring() method.
            # If there is a specialised from_base_ring(), then it should
            # be used unconditionally.
            generic_from_base_ring = self.category(
            ).parent_class.from_base_ring
            if type(self).from_base_ring != generic_from_base_ring:
                # Custom from_base_ring()
                use_from_base_ring = True
            if isinstance(generic_from_base_ring, lazy_attribute):
                # If the category implements from_base_ring() as lazy
                # attribute, then we always use it.
                # This is for backwards compatibility, see Trac #25181
                use_from_base_ring = True
            else:
                try:
                    one = self.one()
                    use_from_base_ring = False
                except (NotImplementedError, AttributeError, TypeError):
                    # The unit is not available, yet. But there are cases
                    # in which it will be available later. So, we use
                    # the generic from_base_ring() after all.
                    use_from_base_ring = True

            mor = None
            if use_from_base_ring:
                mor = SetMorphism(function=self.from_base_ring, parent=H)
            else:
                # We have the multiplicative unit, so implement the
                # coercion from the base ring as multiplying with that.
                #
                # But first we check that it actually works. If not,
                # then the generic implementation of from_base_ring()
                # would fail as well so we don't use it.
                try:
                    if one._lmul_(base_ring.an_element()) is not None:
                        # There are cases in which lmul returns None,
                        # which means that it's not implemented.
                        # One example: Hecke algebras.
                        mor = SetMorphism(function=one._lmul_, parent=H)
                except (NotImplementedError, AttributeError, TypeError):
                    pass
            if mor is not None:
                try:
                    self.register_coercion(mor)
                except AssertionError:
                    pass
        def _coerce_map_from_base_ring(self):
            """
            Return a suitable coercion map from the base ring of ``self``.

            TESTS::

                sage: A = cartesian_product((QQ['z'],)); A
                The Cartesian product of (Univariate Polynomial Ring in z over Rational Field,)
                sage: A.base_ring()
                Rational Field
                sage: A._coerce_map_from_base_ring()
                Generic morphism:
                From: Rational Field
                To:   The Cartesian product of (Univariate Polynomial Ring in z over Rational Field,)

            Check that :trac:`29312` is fixed::

                sage: F.<x,y,z> = FreeAlgebra(QQ, implementation='letterplace')
                sage: F._coerce_map_from_base_ring()
                Generic morphism:
                  From: Rational Field
                  To:   Free Associative Unital Algebra on 3 generators (x, y, z) over Rational Field
            """
            base_ring = self.base_ring()

            # Pick a homset for the morphism to live in...
            if self in Rings():
                # The algebra is associative, and thus a ring. The
                # base ring is also a ring. Everything is OK.
                H = Hom(base_ring, self, Rings())
            else:
                # If the algebra isn't associative, we would like to
                # use the category of unital magmatic algebras (which
                # are not necessarily associative) instead. But,
                # unfortunately, certain important rings like QQ
                # aren't in that category. As a result, we have to use
                # something weaker.
                cat = Magmas().Unital()
                cat = Category.join([cat, CommutativeAdditiveGroups()])
                cat = cat.Distributive()
                H = Hom(base_ring, self, cat)

            # We need to construct a coercion from the base ring to self.
            #
            # There is a generic method from_base_ring(), that just does
            # multiplication with the multiplicative unit. However, the
            # unit is constructed repeatedly, which is slow.
            # So, if the unit is available *now*, then we can create a
            # faster coercion map.
            #
            # This only applies for the generic from_base_ring() method.
            # If there is a specialised from_base_ring(), then it should
            # be used unconditionally.
            generic_from_base_ring = self.category(
            ).parent_class.from_base_ring
            from_base_ring = self.from_base_ring  # bound method
            if from_base_ring.__func__ != generic_from_base_ring:
                # Custom from_base_ring()
                use_from_base_ring = True
            elif isinstance(generic_from_base_ring, lazy_attribute):
                # If the category implements from_base_ring() as lazy
                # attribute, then we always use it.
                # This is for backwards compatibility, see Trac #25181
                use_from_base_ring = True
            else:
                try:
                    one = self.one()
                    use_from_base_ring = False
                except (NotImplementedError, AttributeError, TypeError):
                    # The unit is not available, yet. But there are cases
                    # in which it will be available later. So, we use
                    # the generic from_base_ring() after all.
                    use_from_base_ring = True

            mor = None
            if use_from_base_ring:
                mor = SetMorphism(function=from_base_ring, parent=H)
            else:
                # We have the multiplicative unit, so implement the
                # coercion from the base ring as multiplying with that.
                #
                # But first we check that it actually works. If not,
                # then the generic implementation of from_base_ring()
                # would fail as well so we don't use it.
                try:
                    if one._lmul_(base_ring.an_element()) is not None:
                        # There are cases in which lmul returns None,
                        # which means that it's not implemented.
                        # One example: Hecke algebras.
                        mor = SetMorphism(function=one._lmul_, parent=H)
                except (NotImplementedError, AttributeError, TypeError):
                    pass
            return mor