With Realizations Covariant Functorial Construction#
See also
Sets().WithRealizations
for an introduction to realizations and with realizations.sage.categories.covariant_functorial_construction
for an introduction to covariant functorial constructions.
- sage.categories.with_realizations.WithRealizations(self)[source]#
Return the category of parents in
self
endowed with multiple realizations.INPUT:
self
– a category
See also
The documentation and code (
sage.categories.examples.with_realizations
) ofSets().WithRealizations().example()
for more on how to use and implement a parent with several realizations.Various use cases:
algebras.Moebius
ExtendedAffineWeylGroup
The Implementing Algebraic Structures thematic tutorial.
Note
this function is actually inserted as a method in the class
Category
(seeWithRealizations()
). It is defined here for code locality reasons.EXAMPLES:
sage: Sets().WithRealizations() Category of sets with realizations
>>> from sage.all import * >>> Sets().WithRealizations() Category of sets with realizations
Parent with realizations
Let us now explain the concept of realizations. A parent with realizations is a facade parent (see
Sets.Facade
) admitting multiple concrete realizations where its elements are represented. Consider for example an algebra \(A\) which admits several natural bases:sage: A = Sets().WithRealizations().example(); A # needs sage.modules The subset algebra of {1, 2, 3} over Rational Field
>>> from sage.all import * >>> A = Sets().WithRealizations().example(); A # needs sage.modules The subset algebra of {1, 2, 3} over Rational Field
For each such basis \(B\) one implements a parent \(P_B\) which realizes \(A\) with its elements represented by expanding them on the basis \(B\):
sage: # needs sage.modules sage: A.F() The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis sage: A.Out() The subset algebra of {1, 2, 3} over Rational Field in the Out basis sage: A.In() The subset algebra of {1, 2, 3} over Rational Field in the In basis sage: A.an_element() F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}]
>>> from sage.all import * >>> # needs sage.modules >>> A.F() The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis >>> A.Out() The subset algebra of {1, 2, 3} over Rational Field in the Out basis >>> A.In() The subset algebra of {1, 2, 3} over Rational Field in the In basis >>> A.an_element() F[{}] + 2*F[{1}] + 3*F[{2}] + F[{1, 2}]
If \(B\) and \(B'\) are two bases, then the change of basis from \(B\) to \(B'\) is implemented by a canonical coercion between \(P_B\) and \(P_{B'}\):
sage: # needs sage.modules sage: F = A.F(); In = A.In(); Out = A.Out() sage: i = In.an_element(); i In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] sage: F(i) 7*F[{}] + 3*F[{1}] + 4*F[{2}] + F[{1, 2}] sage: F.coerce_map_from(Out) Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field in the Out basis To: The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis
>>> from sage.all import * >>> # needs sage.modules >>> F = A.F(); In = A.In(); Out = A.Out() >>> i = In.an_element(); i In[{}] + 2*In[{1}] + 3*In[{2}] + In[{1, 2}] >>> F(i) 7*F[{}] + 3*F[{1}] + 4*F[{2}] + F[{1, 2}] >>> F.coerce_map_from(Out) Generic morphism: From: The subset algebra of {1, 2, 3} over Rational Field in the Out basis To: The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis
allowing for mixed arithmetic:
sage: (1 + Out.from_set(1)) * In.from_set(2,3) # needs sage.modules Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}]
>>> from sage.all import * >>> (Integer(1) + Out.from_set(Integer(1))) * In.from_set(Integer(2),Integer(3)) # needs sage.modules Out[{}] + 2*Out[{1}] + 2*Out[{2}] + 2*Out[{3}] + 2*Out[{1, 2}] + 2*Out[{1, 3}] + 4*Out[{2, 3}] + 4*Out[{1, 2, 3}]
In our example, there are three realizations:
sage: A.realizations() # needs sage.modules [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis]
>>> from sage.all import * >>> A.realizations() # needs sage.modules [The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis, The subset algebra of {1, 2, 3} over Rational Field in the In basis, The subset algebra of {1, 2, 3} over Rational Field in the Out basis]
Instead of manually defining the shorthands
F
,In
, andOut
, as above one can just do:sage: A.inject_shorthands() # needs sage.modules Defining F as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis Defining In as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the In basis Defining Out as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Out basis
>>> from sage.all import * >>> A.inject_shorthands() # needs sage.modules Defining F as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Fundamental basis Defining In as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the In basis Defining Out as shorthand for The subset algebra of {1, 2, 3} over Rational Field in the Out basis
Rationale
Besides some goodies described below, the role of \(A\) is threefold:
To provide, as illustrated above, a single entry point for the algebra as a whole: documentation, access to its properties and different realizations, etc.
To provide a natural location for the initialization of the bases and the coercions between, and other methods that are common to all bases.
To let other objects refer to \(A\) while allowing elements to be represented in any of the realizations.
We now illustrate this second point by defining the polynomial ring with coefficients in \(A\):
sage: P = A['x']; P # needs sage.modules Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field sage: x = P.gen() # needs sage.modules
>>> from sage.all import * >>> P = A['x']; P # needs sage.modules Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field >>> x = P.gen() # needs sage.modules
In the following examples, the coefficients turn out to be all represented in the \(F\) basis:
sage: P.one() # needs sage.modules F[{}] sage: (P.an_element() + 1)^2 # needs sage.modules F[{}]*x^2 + 2*F[{}]*x + F[{}]
>>> from sage.all import * >>> P.one() # needs sage.modules F[{}] >>> (P.an_element() + Integer(1))**Integer(2) # needs sage.modules F[{}]*x^2 + 2*F[{}]*x + F[{}]
However we can create a polynomial with mixed coefficients, and compute with it:
sage: p = P([1, In[{1}], Out[{2}] ]); p # needs sage.modules Out[{2}]*x^2 + In[{1}]*x + F[{}] sage: p^2 # needs sage.modules Out[{2}]*x^4 + (-8*In[{}] + 4*In[{1}] + 8*In[{2}] + 4*In[{3}] - 4*In[{1, 2}] - 2*In[{1, 3}] - 4*In[{2, 3}] + 2*In[{1, 2, 3}])*x^3 + (F[{}] + 3*F[{1}] + 2*F[{2}] - 2*F[{1, 2}] - 2*F[{2, 3}] + 2*F[{1, 2, 3}])*x^2 + (2*F[{}] + 2*F[{1}])*x + F[{}]
>>> from sage.all import * >>> p = P([Integer(1), In[{Integer(1)}], Out[{Integer(2)}] ]); p # needs sage.modules Out[{2}]*x^2 + In[{1}]*x + F[{}] >>> p**Integer(2) # needs sage.modules Out[{2}]*x^4 + (-8*In[{}] + 4*In[{1}] + 8*In[{2}] + 4*In[{3}] - 4*In[{1, 2}] - 2*In[{1, 3}] - 4*In[{2, 3}] + 2*In[{1, 2, 3}])*x^3 + (F[{}] + 3*F[{1}] + 2*F[{2}] - 2*F[{1, 2}] - 2*F[{2, 3}] + 2*F[{1, 2, 3}])*x^2 + (2*F[{}] + 2*F[{1}])*x + F[{}]
Note how each coefficient involves a single basis which need not be that of the other coefficients. Which basis is used depends on how coercion happened during mixed arithmetic and needs not be deterministic.
One can easily coerce all coefficient to a given basis with:
sage: p.map_coefficients(In) # needs sage.modules (-4*In[{}] + 2*In[{1}] + 4*In[{2}] + 2*In[{3}] - 2*In[{1, 2}] - In[{1, 3}] - 2*In[{2, 3}] + In[{1, 2, 3}])*x^2 + In[{1}]*x + In[{}]
>>> from sage.all import * >>> p.map_coefficients(In) # needs sage.modules (-4*In[{}] + 2*In[{1}] + 4*In[{2}] + 2*In[{3}] - 2*In[{1, 2}] - In[{1, 3}] - 2*In[{2, 3}] + In[{1, 2, 3}])*x^2 + In[{1}]*x + In[{}]
Alas, the natural notation for constructing such polynomials does not yet work:
sage: In[{1}] * x # needs sage.modules Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'The subset algebra of {1, 2, 3} over Rational Field in the In basis' and 'Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field'
>>> from sage.all import * >>> In[{Integer(1)}] * x # needs sage.modules Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for *: 'The subset algebra of {1, 2, 3} over Rational Field in the In basis' and 'Univariate Polynomial Ring in x over The subset algebra of {1, 2, 3} over Rational Field'
The category of realizations of \(A\)
The set of all realizations of \(A\), together with the coercion morphisms is a category (whose class inherits from
Category_realization_of_parent
):sage: A.Realizations() # needs sage.modules Category of realizations of The subset algebra of {1, 2, 3} over Rational Field
>>> from sage.all import * >>> A.Realizations() # needs sage.modules Category of realizations of The subset algebra of {1, 2, 3} over Rational Field
The various parent realizing \(A\) belong to this category:
sage: A.F() in A.Realizations() # needs sage.modules True
>>> from sage.all import * >>> A.F() in A.Realizations() # needs sage.modules True
\(A\) itself is in the category of algebras with realizations:
sage: A in Algebras(QQ).WithRealizations() # needs sage.modules True
>>> from sage.all import * >>> A in Algebras(QQ).WithRealizations() # needs sage.modules True
The (mostly technical)
WithRealizations
categories are the analogs of the*WithSeveralBases
categories in MuPAD-Combinat. They provide support tools for handling the different realizations and the morphisms between them.Typically,
VectorSpaces(QQ).FiniteDimensional().WithRealizations()
will eventually be in charge, whenever a coercion \(\phi: A\mapsto B\) is registered, to register \(\phi^{-1}\) as coercion \(B \mapsto A\) if there is none defined yet. To achieve this,FiniteDimensionalVectorSpaces
would provide a nested classWithRealizations
implementing the appropriate logic.WithRealizations
is aregressive covariant functorial construction
. On our example, this simply means that \(A\) is automatically in the category of rings with realizations (covariance):sage: A in Rings().WithRealizations() # needs sage.modules True
>>> from sage.all import * >>> A in Rings().WithRealizations() # needs sage.modules True
and in the category of algebras (regressiveness):
sage: A in Algebras(QQ) # needs sage.modules True
>>> from sage.all import * >>> A in Algebras(QQ) # needs sage.modules True
Note
For
C
a category,C.WithRealizations()
in fact callssage.categories.with_realizations.WithRealizations(C)
. The later is responsible for building the hierarchy of the categories with realizations in parallel to that of their base categories, optimizing away those categories that do not provide aWithRealizations
nested class. Seesage.categories.covariant_functorial_construction
for the technical details.Note
Design question: currently
WithRealizations
is a regressive construction. That isself.WithRealizations()
is a subcategory ofself
by default:sage: Algebras(QQ).WithRealizations().super_categories() [Category of algebras over Rational Field, Category of monoids with realizations, Category of additive unital additive magmas with realizations]
>>> from sage.all import * >>> Algebras(QQ).WithRealizations().super_categories() [Category of algebras over Rational Field, Category of monoids with realizations, Category of additive unital additive magmas with realizations]
Is this always desirable? For example,
AlgebrasWithBasis(QQ).WithRealizations()
should certainly be a subcategory ofAlgebras(QQ)
, but not ofAlgebrasWithBasis(QQ)
. This is becauseAlgebrasWithBasis(QQ)
is specifying something about the concrete realization.
- class sage.categories.with_realizations.WithRealizationsCategory(category, *args)[source]#
Bases:
RegressiveCovariantConstructionCategory
An abstract base class for all categories of parents with multiple realizations.
See also
The role of this base class is to implement some technical goodies, such as the name for that category.