Functors

AUTHORS:

  • David Kohel and William Stein

  • David Joyner (2005-12-17): examples

  • Robert Bradshaw (2007-06-23): Pyrexify

  • Simon King (2010-04-30): more examples, several bug fixes, re-implementation of the default call method, making functors applicable to morphisms (not only to objects)

  • Simon King (2010-12): Pickling of functors without losing domain and codomain

sage.categories.functor.ForgetfulFunctor(domain, codomain)[source]

Construct the forgetful function from one category to another.

INPUT:

  • C, D – two categories

OUTPUT:

A functor that returns the corresponding object of D for any element of C, by forgetting the extra structure.

ASSUMPTION:

The category C must be a sub-category of D.

EXAMPLES:

sage: rings = Rings()
sage: abgrps = CommutativeAdditiveGroups()
sage: F = ForgetfulFunctor(rings, abgrps)
sage: F
The forgetful functor
 from Category of rings
   to Category of commutative additive groups
>>> from sage.all import *
>>> rings = Rings()
>>> abgrps = CommutativeAdditiveGroups()
>>> F = ForgetfulFunctor(rings, abgrps)
>>> F
The forgetful functor
 from Category of rings
   to Category of commutative additive groups

It would be a mistake to call it in opposite order:

sage: F = ForgetfulFunctor(abgrps, rings)
Traceback (most recent call last):
...
ValueError: Forgetful functor not supported for domain
Category of commutative additive groups
>>> from sage.all import *
>>> F = ForgetfulFunctor(abgrps, rings)
Traceback (most recent call last):
...
ValueError: Forgetful functor not supported for domain
Category of commutative additive groups

If both categories are equal, the forgetful functor is the same as the identity functor:

sage: ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps)
True
>>> from sage.all import *
>>> ForgetfulFunctor(abgrps, abgrps) == IdentityFunctor(abgrps)
True
class sage.categories.functor.ForgetfulFunctor_generic[source]

Bases: Functor

The forgetful functor, i.e., embedding of a subcategory.

NOTE:

Forgetful functors should be created using ForgetfulFunctor(), since the init method of this class does not check whether the domain is a subcategory of the codomain.

EXAMPLES:

sage: F = ForgetfulFunctor(FiniteFields(), Fields())  # indirect doctest
sage: F
The forgetful functor
 from Category of finite enumerated fields
   to Category of fields
sage: F(GF(3))
Finite Field of size 3
>>> from sage.all import *
>>> F = ForgetfulFunctor(FiniteFields(), Fields())  # indirect doctest
>>> F
The forgetful functor
 from Category of finite enumerated fields
   to Category of fields
>>> F(GF(Integer(3)))
Finite Field of size 3
class sage.categories.functor.Functor[source]

Bases: SageObject

A class for functors between two categories.

NOTE:

  • In the first place, a functor is given by its domain and codomain, which are both categories.

  • When defining a sub-class, the user should not implement a call method. Instead, one should implement three methods, which are composed in the default call method:

    • _coerce_into_domain(self, x) – return an object of self’s domain, corresponding to x, or raise a TypeError. - Default: Raise TypeError if x is not in self’s domain.

    • _apply_functor(self, x) – apply self to an object x of self’s domain. - Default: Conversion into self’s codomain.

    • _apply_functor_to_morphism(self, f) – apply self to a morphism f in self’s domain. - Default: Return self(f.domain()).hom(f,self(f.codomain())).

EXAMPLES:

sage: rings  = Rings()
sage: abgrps = CommutativeAdditiveGroups()
sage: F = ForgetfulFunctor(rings, abgrps)
sage: F.domain()
Category of rings
sage: F.codomain()
Category of commutative additive groups
sage: from sage.categories.functor import Functor
sage: isinstance(F, Functor)
True
sage: I = IdentityFunctor(abgrps)
sage: I
The identity functor on Category of commutative additive groups
sage: I.domain()
Category of commutative additive groups
sage: isinstance(I, Functor)
True
>>> from sage.all import *
>>> rings  = Rings()
>>> abgrps = CommutativeAdditiveGroups()
>>> F = ForgetfulFunctor(rings, abgrps)
>>> F.domain()
Category of rings
>>> F.codomain()
Category of commutative additive groups
>>> from sage.categories.functor import Functor
>>> isinstance(F, Functor)
True
>>> I = IdentityFunctor(abgrps)
>>> I
The identity functor on Category of commutative additive groups
>>> I.domain()
Category of commutative additive groups
>>> isinstance(I, Functor)
True

Note that by default, an instance of the class Functor is coercion from the domain into the codomain. The above subclasses overloaded this behaviour. Here we illustrate the default:

sage: from sage.categories.functor import Functor
sage: F = Functor(Rings(), Fields())
sage: F
Functor from Category of rings to Category of fields
sage: F(ZZ)
Rational Field
sage: F(GF(2))
Finite Field of size 2
>>> from sage.all import *
>>> from sage.categories.functor import Functor
>>> F = Functor(Rings(), Fields())
>>> F
Functor from Category of rings to Category of fields
>>> F(ZZ)
Rational Field
>>> F(GF(Integer(2)))
Finite Field of size 2

Functors are not only about the objects of a category, but also about their morphisms. We illustrate it, again, with the coercion functor from rings to fields.

sage: R1.<x> = ZZ[]
sage: R2.<a,b> = QQ[]
sage: f = R1.hom([a + b], R2)
sage: f
Ring morphism:
  From: Univariate Polynomial Ring in x over Integer Ring
  To:   Multivariate Polynomial Ring in a, b over Rational Field
  Defn: x |--> a + b
sage: F(f)
Ring morphism:
  From: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
  To:   Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field
  Defn: x |--> a + b
sage: F(f)(1/x)
1/(a + b)
>>> from sage.all import *
>>> R1 = ZZ['x']; (x,) = R1._first_ngens(1)
>>> R2 = QQ['a, b']; (a, b,) = R2._first_ngens(2)
>>> f = R1.hom([a + b], R2)
>>> f
Ring morphism:
  From: Univariate Polynomial Ring in x over Integer Ring
  To:   Multivariate Polynomial Ring in a, b over Rational Field
  Defn: x |--> a + b
>>> F(f)
Ring morphism:
  From: Fraction Field of Univariate Polynomial Ring in x over Integer Ring
  To:   Fraction Field of Multivariate Polynomial Ring in a, b over Rational Field
  Defn: x |--> a + b
>>> F(f)(Integer(1)/x)
1/(a + b)

We can also apply a polynomial ring construction functor to our homomorphism. The result is a homomorphism that is defined on the base ring:

sage: F = QQ['t'].construction()[0]
sage: F
Poly[t]
sage: F(f)
Ring morphism:
  From: Univariate Polynomial Ring in t
         over Univariate Polynomial Ring in x over Integer Ring
  To:   Univariate Polynomial Ring in t
         over Multivariate Polynomial Ring in a, b over Rational Field
  Defn: Induced from base ring by
        Ring morphism:
          From: Univariate Polynomial Ring in x over Integer Ring
          To:   Multivariate Polynomial Ring in a, b over Rational Field
          Defn: x |--> a + b
sage: p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1')
sage: F(f)(p)
(-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t
- 4*a^2 - 8*a*b - 4*b^2 - a - b + 1
>>> from sage.all import *
>>> F = QQ['t'].construction()[Integer(0)]
>>> F
Poly[t]
>>> F(f)
Ring morphism:
  From: Univariate Polynomial Ring in t
         over Univariate Polynomial Ring in x over Integer Ring
  To:   Univariate Polynomial Ring in t
         over Multivariate Polynomial Ring in a, b over Rational Field
  Defn: Induced from base ring by
        Ring morphism:
          From: Univariate Polynomial Ring in x over Integer Ring
          To:   Multivariate Polynomial Ring in a, b over Rational Field
          Defn: x |--> a + b
>>> p = R1['t']('(-x^2 + x)*t^2 + (x^2 - x)*t - 4*x^2 - x + 1')
>>> F(f)(p)
(-a^2 - 2*a*b - b^2 + a + b)*t^2 + (a^2 + 2*a*b + b^2 - a - b)*t
- 4*a^2 - 8*a*b - 4*b^2 - a - b + 1
codomain()[source]

The codomain of self.

EXAMPLES:

sage: F = ForgetfulFunctor(FiniteFields(), Fields())
sage: F.codomain()
Category of fields
>>> from sage.all import *
>>> F = ForgetfulFunctor(FiniteFields(), Fields())
>>> F.codomain()
Category of fields
domain()[source]

The domain of self.

EXAMPLES:

sage: F = ForgetfulFunctor(FiniteFields(), Fields())
sage: F.domain()
Category of finite enumerated fields
>>> from sage.all import *
>>> F = ForgetfulFunctor(FiniteFields(), Fields())
>>> F.domain()
Category of finite enumerated fields
sage.categories.functor.IdentityFunctor(C)[source]

Construct the identity functor of the given category.

INPUT:

  • C – a category

OUTPUT: the identity functor in C

EXAMPLES:

sage: rings = Rings()
sage: F = IdentityFunctor(rings)
sage: F(ZZ['x','y']) is ZZ['x','y']
True
>>> from sage.all import *
>>> rings = Rings()
>>> F = IdentityFunctor(rings)
>>> F(ZZ['x','y']) is ZZ['x','y']
True
class sage.categories.functor.IdentityFunctor_generic(C)[source]

Bases: ForgetfulFunctor_generic

Generic identity functor on any category.

NOTE:

This usually is created using IdentityFunctor().

EXAMPLES:

sage: F = IdentityFunctor(Fields()) #indirect doctest
sage: F
The identity functor on Category of fields
sage: F(RR) is RR
True
sage: F(ZZ)
Traceback (most recent call last):
...
TypeError: x (=Integer Ring) is not in Category of fields
>>> from sage.all import *
>>> F = IdentityFunctor(Fields()) #indirect doctest
>>> F
The identity functor on Category of fields
>>> F(RR) is RR
True
>>> F(ZZ)
Traceback (most recent call last):
...
TypeError: x (=Integer Ring) is not in Category of fields
sage.categories.functor.is_Functor(x)[source]

Test whether the argument is a functor.

This function is deprecated.

EXAMPLES:

sage: from sage.categories.functor import is_Functor
sage: F1 = QQ.construction()[0]
sage: F1
FractionField
sage: is_Functor(F1)
doctest:warning...
DeprecationWarning: The function is_Functor is deprecated;
use 'isinstance(..., Functor)' instead.
See https://github.com/sagemath/sage/issues/38184 for details.
True
sage: is_Functor(FractionField)
False
sage: F2 = ForgetfulFunctor(Fields(), Rings())
sage: F2
The forgetful functor from Category of fields to Category of rings
sage: is_Functor(F2)
True
>>> from sage.all import *
>>> from sage.categories.functor import is_Functor
>>> F1 = QQ.construction()[Integer(0)]
>>> F1
FractionField
>>> is_Functor(F1)
doctest:warning...
DeprecationWarning: The function is_Functor is deprecated;
use 'isinstance(..., Functor)' instead.
See https://github.com/sagemath/sage/issues/38184 for details.
True
>>> is_Functor(FractionField)
False
>>> F2 = ForgetfulFunctor(Fields(), Rings())
>>> F2
The forgetful functor from Category of fields to Category of rings
>>> is_Functor(F2)
True