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()]
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()]
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
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
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()]
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()]
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())
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(), )
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)
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)
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