Morphisms#
This module defines the base classes of morphisms between objects of a given category.
EXAMPLES:
Typically, a morphism is defined by the images of the generators of the domain.
sage: X.<a, b> = ZZ[]
sage: Y.<c> = ZZ[]
sage: X.hom([c, c^2])
Ring morphism:
From: Multivariate Polynomial Ring in a, b over Integer Ring
To: Univariate Polynomial Ring in c over Integer Ring
Defn: a |--> c
b |--> c^2
>>> from sage.all import *
>>> X = ZZ['a, b']; (a, b,) = X._first_ngens(2)
>>> Y = ZZ['c']; (c,) = Y._first_ngens(1)
>>> X.hom([c, c**Integer(2)])
Ring morphism:
From: Multivariate Polynomial Ring in a, b over Integer Ring
To: Univariate Polynomial Ring in c over Integer Ring
Defn: a |--> c
b |--> c^2
AUTHORS:
William Stein (2005): initial version
David Joyner (2005-12-17): added examples
Robert Bradshaw (2007-06-25): Pyrexification
- class sage.categories.morphism.IdentityMorphism[source]#
Bases:
Morphism
- is_identity()[source]#
Return
True
if this morphism is the identity morphism.EXAMPLES:
sage: E = End(Partitions(5)) # needs sage.combinat sage: E.identity().is_identity() # needs sage.combinat True
>>> from sage.all import * >>> E = End(Partitions(Integer(5))) # needs sage.combinat >>> E.identity().is_identity() # needs sage.combinat True
Check that Issue #15478 is fixed:
sage: # needs sage.rings.finite_rings sage: K.<z> = GF(4) sage: phi = End(K)([z^2]) sage: R.<t> = K[] sage: psi = End(R)(phi) sage: psi.is_identity() False
>>> from sage.all import * >>> # needs sage.rings.finite_rings >>> K = GF(Integer(4), names=('z',)); (z,) = K._first_ngens(1) >>> phi = End(K)([z**Integer(2)]) >>> R = K['t']; (t,) = R._first_ngens(1) >>> psi = End(R)(phi) >>> psi.is_identity() False
- is_injective()[source]#
Return whether this morphism is injective.
EXAMPLES:
sage: Hom(ZZ, ZZ).identity().is_injective() True
>>> from sage.all import * >>> Hom(ZZ, ZZ).identity().is_injective() True
- class sage.categories.morphism.Morphism[source]#
Bases:
Map
- category()[source]#
Return the category of the parent of this morphism.
EXAMPLES:
sage: R.<t> = ZZ[] sage: f = R.hom([t**2]) sage: f.category() Category of endsets of unital magmas and right modules over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) and left modules over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) sage: # needs sage.rings.number_field sage: K = CyclotomicField(12) sage: L = CyclotomicField(132) sage: phi = L._internal_coerce_map_from(K) sage: phi.category() Category of homsets of number fields
>>> from sage.all import * >>> R = ZZ['t']; (t,) = R._first_ngens(1) >>> f = R.hom([t**Integer(2)]) >>> f.category() Category of endsets of unital magmas and right modules over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) and left modules over (Dedekind domains and euclidean domains and noetherian rings and infinite enumerated sets and metric spaces) >>> # needs sage.rings.number_field >>> K = CyclotomicField(Integer(12)) >>> L = CyclotomicField(Integer(132)) >>> phi = L._internal_coerce_map_from(K) >>> phi.category() Category of homsets of number fields
- is_endomorphism()[source]#
Return
True
if this morphism is an endomorphism.EXAMPLES:
sage: R.<t> = ZZ[] sage: f = R.hom([t]) sage: f.is_endomorphism() True sage: # needs sage.rings.number_field sage: K = CyclotomicField(12) sage: L = CyclotomicField(132) sage: phi = L._internal_coerce_map_from(K) sage: phi.is_endomorphism() False
>>> from sage.all import * >>> R = ZZ['t']; (t,) = R._first_ngens(1) >>> f = R.hom([t]) >>> f.is_endomorphism() True >>> # needs sage.rings.number_field >>> K = CyclotomicField(Integer(12)) >>> L = CyclotomicField(Integer(132)) >>> phi = L._internal_coerce_map_from(K) >>> phi.is_endomorphism() False
- is_identity()[source]#
Return
True
if this morphism is the identity morphism.Note
Implemented only when the domain has a method gens()
EXAMPLES:
sage: R.<t> = ZZ[] sage: f = R.hom([t]) sage: f.is_identity() True sage: g = R.hom([t + 1]) sage: g.is_identity() False
>>> from sage.all import * >>> R = ZZ['t']; (t,) = R._first_ngens(1) >>> f = R.hom([t]) >>> f.is_identity() True >>> g = R.hom([t + Integer(1)]) >>> g.is_identity() False
A morphism between two different spaces cannot be the identity:
sage: R2.<t2> = QQ[] sage: h = R.hom([t2]) sage: h.is_identity() False
>>> from sage.all import * >>> R2 = QQ['t2']; (t2,) = R2._first_ngens(1) >>> h = R.hom([t2]) >>> h.is_identity() False
- register_as_coercion()[source]#
Register this morphism as a coercion to Sage’s coercion model (see
sage.structure.coerce
).EXAMPLES:
By default, adding polynomials over different variables triggers an error:
sage: X.<x> = ZZ[] sage: Y.<y> = ZZ[] sage: x^2 + y Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: 'Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring'
>>> from sage.all import * >>> X = ZZ['x']; (x,) = X._first_ngens(1) >>> Y = ZZ['y']; (y,) = Y._first_ngens(1) >>> x**Integer(2) + y Traceback (most recent call last): ... TypeError: unsupported operand parent(s) for +: 'Univariate Polynomial Ring in x over Integer Ring' and 'Univariate Polynomial Ring in y over Integer Ring'
Let us declare a coercion from \(\ZZ[x]\) to \(\ZZ[z]\):
sage: Z.<z> = ZZ[] sage: phi = Hom(X, Z)(z) sage: phi(x^2+1) z^2 + 1 sage: phi.register_as_coercion()
>>> from sage.all import * >>> Z = ZZ['z']; (z,) = Z._first_ngens(1) >>> phi = Hom(X, Z)(z) >>> phi(x**Integer(2)+Integer(1)) z^2 + 1 >>> phi.register_as_coercion()
Now we can add elements from \(\ZZ[x]\) and \(\ZZ[z]\), because the elements of the former are allowed to be implicitly coerced into the later:
sage: x^2 + z z^2 + z
>>> from sage.all import * >>> x**Integer(2) + z z^2 + z
Caveat: the registration of the coercion must be done before any other coercion is registered or discovered:
sage: phi = Hom(X, Z)(z^2) sage: phi.register_as_coercion() Traceback (most recent call last): ... AssertionError: coercion from Univariate Polynomial Ring in x over Integer Ring to Univariate Polynomial Ring in z over Integer Ring already registered or discovered
>>> from sage.all import * >>> phi = Hom(X, Z)(z**Integer(2)) >>> phi.register_as_coercion() Traceback (most recent call last): ... AssertionError: coercion from Univariate Polynomial Ring in x over Integer Ring to Univariate Polynomial Ring in z over Integer Ring already registered or discovered
- register_as_conversion()[source]#
Register this morphism as a conversion to Sage’s coercion model
(see
sage.structure.coerce
).EXAMPLES:
Let us declare a conversion from the symmetric group to \(\ZZ\) through the sign map:
sage: # needs sage.groups sage: S = SymmetricGroup(4) sage: phi = Hom(S, ZZ)(lambda x: ZZ(x.sign())) sage: x = S.an_element(); x (2,3,4) sage: phi(x) 1 sage: phi.register_as_conversion() sage: ZZ(x) 1
>>> from sage.all import * >>> # needs sage.groups >>> S = SymmetricGroup(Integer(4)) >>> phi = Hom(S, ZZ)(lambda x: ZZ(x.sign())) >>> x = S.an_element(); x (2,3,4) >>> phi(x) 1 >>> phi.register_as_conversion() >>> ZZ(x) 1
- class sage.categories.morphism.SetIsomorphism[source]#
Bases:
SetMorphism
An isomorphism of sets.
INPUT:
parent
– a Homsetfunction
– a Python function that takes elements of the domain as input and returns elements of the codomain.
EXAMPLES:
sage: f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ....: operator.__neg__); f Generic endomorphism of Integer Ring sage: f._set_inverse(f) sage: ~f is f True
>>> from sage.all import * >>> f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ... operator.__neg__); f Generic endomorphism of Integer Ring >>> f._set_inverse(f) >>> ~f is f True
- is_injective()[source]#
Return whether this morphism is injective.
EXAMPLES:
sage: f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ....: operator.__neg__) sage: f.is_injective() True
>>> from sage.all import * >>> f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ... operator.__neg__) >>> f.is_injective() True
- is_surjective()[source]#
Return whether this morphism is surjective.
EXAMPLES:
sage: f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ....: operator.__neg__) sage: f.is_surjective() True
>>> from sage.all import * >>> f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ... operator.__neg__) >>> f.is_surjective() True
- section()[source]#
Return a section of this morphism.
EXAMPLES:
sage: f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ....: operator.__neg__) sage: f._set_inverse(f) sage: f.section() is f True
>>> from sage.all import * >>> f = sage.categories.morphism.SetIsomorphism(Hom(ZZ, ZZ, Sets()), ... operator.__neg__) >>> f._set_inverse(f) >>> f.section() is f True
- class sage.categories.morphism.SetMorphism[source]#
Bases:
Morphism
INPUT:
parent
– a Homsetfunction
– a Python function that takes elements of the domain as input and returns elements of the codomain.
EXAMPLES:
sage: from sage.categories.morphism import SetMorphism sage: f = SetMorphism(Hom(QQ, ZZ, Sets()), numerator) sage: f.parent() Set of Morphisms from Rational Field to Integer Ring in Category of sets sage: f.domain() Rational Field sage: f.codomain() Integer Ring sage: TestSuite(f).run()
>>> from sage.all import * >>> from sage.categories.morphism import SetMorphism >>> f = SetMorphism(Hom(QQ, ZZ, Sets()), numerator) >>> f.parent() Set of Morphisms from Rational Field to Integer Ring in Category of sets >>> f.domain() Rational Field >>> f.codomain() Integer Ring >>> TestSuite(f).run()