Base class for maps¶
AUTHORS:
Robert Bradshaw: initial implementation
Sebastien Besnier (2014-05-5):
FormalCompositeMap
contains a list of Map instead of only two Map. See Issue #16291.Sebastian Oehms (2019-01-19):
section()
added toFormalCompositeMap
. See Issue #27081.
- class sage.categories.map.FormalCompositeMap[source]¶
Bases:
Map
Formal composite maps.
A formal composite map is formed by two maps, so that the codomain of the first map is contained in the domain of the second map.
Note
When calling a composite with additional arguments, these arguments are only passed to the second underlying map.
EXAMPLES:
sage: R.<x> = QQ[] sage: S.<a> = QQ[] sage: from sage.categories.morphism import SetMorphism sage: f = SetMorphism(Hom(R, S, Rings()), lambda p: p[0]*a^p.degree()) sage: g = S.hom([2*x]) sage: f*g Composite map: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in a over Rational Field Defn: Ring morphism: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: a |--> 2*x then Generic morphism: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in a over Rational Field sage: g*f Composite map: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in a over Rational Field then Ring morphism: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: a |--> 2*x sage: (f*g)(2*a^2+5) 5*a^2 sage: (g*f)(2*x^2+5) 20*x^2
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> S = QQ['a']; (a,) = S._first_ngens(1) >>> from sage.categories.morphism import SetMorphism >>> f = SetMorphism(Hom(R, S, Rings()), lambda p: p[Integer(0)]*a**p.degree()) >>> g = S.hom([Integer(2)*x]) >>> f*g Composite map: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in a over Rational Field Defn: Ring morphism: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: a |--> 2*x then Generic morphism: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in a over Rational Field >>> g*f Composite map: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Rational Field To: Univariate Polynomial Ring in a over Rational Field then Ring morphism: From: Univariate Polynomial Ring in a over Rational Field To: Univariate Polynomial Ring in x over Rational Field Defn: a |--> 2*x >>> (f*g)(Integer(2)*a**Integer(2)+Integer(5)) 5*a^2 >>> (g*f)(Integer(2)*x**Integer(2)+Integer(5)) 20*x^2
- domains()[source]¶
Iterate over the domains of the factors of this map.
(This is useful in particular to check for loops in coercion maps.)
See also
EXAMPLES:
sage: f = QQ.coerce_map_from(ZZ) sage: g = MatrixSpace(QQ, 2, 2).coerce_map_from(QQ) # needs sage.modules sage: list((g * f).domains()) # needs sage.modules [Integer Ring, Rational Field]
>>> from sage.all import * >>> f = QQ.coerce_map_from(ZZ) >>> g = MatrixSpace(QQ, Integer(2), Integer(2)).coerce_map_from(QQ) # needs sage.modules >>> list((g * f).domains()) # needs sage.modules [Integer Ring, Rational Field]
- first()[source]¶
Return the first map in the formal composition.
If
self
represents \(f_n \circ f_{n-1} \circ \cdots \circ f_1 \circ f_0\), thenself.first()
returns \(f_0\). We haveself == self.then() * self.first()
.EXAMPLES:
sage: R.<x> = QQ[] sage: S.<a> = QQ[] sage: from sage.categories.morphism import SetMorphism sage: f = SetMorphism(Hom(R, S, Rings()), lambda p: p[0]*a^p.degree()) sage: g = S.hom([2*x]) sage: fg = f * g sage: fg.first() == g True sage: fg == fg.then() * fg.first() True
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> S = QQ['a']; (a,) = S._first_ngens(1) >>> from sage.categories.morphism import SetMorphism >>> f = SetMorphism(Hom(R, S, Rings()), lambda p: p[Integer(0)]*a**p.degree()) >>> g = S.hom([Integer(2)*x]) >>> fg = f * g >>> fg.first() == g True >>> fg == fg.then() * fg.first() True
- is_injective()[source]¶
Tell whether
self
is injective.It raises
NotImplementedError
if it cannot be determined.EXAMPLES:
sage: # needs sage.modules sage: V1 = QQ^2 sage: V2 = QQ^3 sage: phi1 = (QQ^1).hom(Matrix([[1, 1]]), V1) sage: phi2 = V1.hom(Matrix([[1, 2, 3], [4, 5, 6]]), V2)
>>> from sage.all import * >>> # needs sage.modules >>> V1 = QQ**Integer(2) >>> V2 = QQ**Integer(3) >>> phi1 = (QQ**Integer(1)).hom(Matrix([[Integer(1), Integer(1)]]), V1) >>> phi2 = V1.hom(Matrix([[Integer(1), Integer(2), Integer(3)], [Integer(4), Integer(5), Integer(6)]]), V2)
If both constituents are injective, the composition is injective:
sage: from sage.categories.map import FormalCompositeMap sage: c1 = FormalCompositeMap(Hom(QQ^1, V2, phi1.category_for()), # needs sage.modules ....: phi1, phi2) sage: c1.is_injective() # needs sage.modules True
>>> from sage.all import * >>> from sage.categories.map import FormalCompositeMap >>> c1 = FormalCompositeMap(Hom(QQ**Integer(1), V2, phi1.category_for()), # needs sage.modules ... phi1, phi2) >>> c1.is_injective() # needs sage.modules True
If it cannot be determined whether the composition is injective, an error is raised:
sage: psi1 = V2.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V1) # needs sage.modules sage: c2 = FormalCompositeMap(Hom(V1, V1, phi2.category_for()), # needs sage.modules ....: phi2, psi1) sage: c2.is_injective() # needs sage.modules Traceback (most recent call last): ... NotImplementedError: not enough information to deduce injectivity
>>> from sage.all import * >>> psi1 = V2.hom(Matrix([[Integer(1), Integer(2)], [Integer(3), Integer(4)], [Integer(5), Integer(6)]]), V1) # needs sage.modules >>> c2 = FormalCompositeMap(Hom(V1, V1, phi2.category_for()), # needs sage.modules ... phi2, psi1) >>> c2.is_injective() # needs sage.modules Traceback (most recent call last): ... NotImplementedError: not enough information to deduce injectivity
If the first map is surjective and the second map is not injective, then the composition is not injective:
sage: psi2 = V1.hom([[1], [1]], QQ^1) # needs sage.modules sage: c3 = FormalCompositeMap(Hom(V2, QQ^1, phi2.category_for()), # needs sage.modules ....: psi2, psi1) sage: c3.is_injective() # needs sage.modules False
>>> from sage.all import * >>> psi2 = V1.hom([[Integer(1)], [Integer(1)]], QQ**Integer(1)) # needs sage.modules >>> c3 = FormalCompositeMap(Hom(V2, QQ**Integer(1), phi2.category_for()), # needs sage.modules ... psi2, psi1) >>> c3.is_injective() # needs sage.modules False
- is_surjective()[source]¶
Tell whether
self
is surjective.It raises
NotImplementedError
if it cannot be determined.EXAMPLES:
sage: from sage.categories.map import FormalCompositeMap sage: V3 = QQ^3 # needs sage.modules sage: V2 = QQ^2 # needs sage.modules sage: V1 = QQ^1 # needs sage.modules
>>> from sage.all import * >>> from sage.categories.map import FormalCompositeMap >>> V3 = QQ**Integer(3) # needs sage.modules >>> V2 = QQ**Integer(2) # needs sage.modules >>> V1 = QQ**Integer(1) # needs sage.modules
If both maps are surjective, the composition is surjective:
sage: # needs sage.modules sage: phi32 = V3.hom(Matrix([[1, 2], [3, 4], [5, 6]]), V2) sage: phi21 = V2.hom(Matrix([[1], [1]]), V1) sage: c_phi = FormalCompositeMap(Hom(V3, V1, phi32.category_for()), ....: phi32, phi21) sage: c_phi.is_surjective() True
>>> from sage.all import * >>> # needs sage.modules >>> phi32 = V3.hom(Matrix([[Integer(1), Integer(2)], [Integer(3), Integer(4)], [Integer(5), Integer(6)]]), V2) >>> phi21 = V2.hom(Matrix([[Integer(1)], [Integer(1)]]), V1) >>> c_phi = FormalCompositeMap(Hom(V3, V1, phi32.category_for()), ... phi32, phi21) >>> c_phi.is_surjective() True
If the second map is not surjective, the composition is not surjective:
sage: FormalCompositeMap(Hom(V3, V1, phi32.category_for()), # needs sage.modules ....: phi32, ....: V2.hom(Matrix([[0], [0]]), V1)).is_surjective() False
>>> from sage.all import * >>> FormalCompositeMap(Hom(V3, V1, phi32.category_for()), # needs sage.modules ... phi32, ... V2.hom(Matrix([[Integer(0)], [Integer(0)]]), V1)).is_surjective() False
If the second map is an isomorphism and the first map is not surjective, then the composition is not surjective:
sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # needs sage.modules ....: V2.hom(Matrix([[0], [0]]), V1), ....: V1.hom(Matrix([[1]]), V1)).is_surjective() False
>>> from sage.all import * >>> FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # needs sage.modules ... V2.hom(Matrix([[Integer(0)], [Integer(0)]]), V1), ... V1.hom(Matrix([[Integer(1)]]), V1)).is_surjective() False
Otherwise, surjectivity of the composition cannot be determined:
sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # needs sage.modules ....: V2.hom(Matrix([[1, 1], [1, 1]]), V2), ....: V2.hom(Matrix([[1], [1]]), V1)).is_surjective() Traceback (most recent call last): ... NotImplementedError: not enough information to deduce surjectivity
>>> from sage.all import * >>> FormalCompositeMap(Hom(V2, V1, phi32.category_for()), # needs sage.modules ... V2.hom(Matrix([[Integer(1), Integer(1)], [Integer(1), Integer(1)]]), V2), ... V2.hom(Matrix([[Integer(1)], [Integer(1)]]), V1)).is_surjective() Traceback (most recent call last): ... NotImplementedError: not enough information to deduce surjectivity
- section()[source]¶
Compute a section map from sections of the factors of
self
if they have been implemented.EXAMPLES:
sage: P.<x> = QQ[] sage: incl = P.coerce_map_from(ZZ) sage: sect = incl.section(); sect Composite map: From: Univariate Polynomial Ring in x over Rational Field To: Integer Ring Defn: Generic map: From: Univariate Polynomial Ring in x over Rational Field To: Rational Field then Generic map: From: Rational Field To: Integer Ring sage: p = x + 5; q = x + 2 sage: sect(p-q) 3
>>> from sage.all import * >>> P = QQ['x']; (x,) = P._first_ngens(1) >>> incl = P.coerce_map_from(ZZ) >>> sect = incl.section(); sect Composite map: From: Univariate Polynomial Ring in x over Rational Field To: Integer Ring Defn: Generic map: From: Univariate Polynomial Ring in x over Rational Field To: Rational Field then Generic map: From: Rational Field To: Integer Ring >>> p = x + Integer(5); q = x + Integer(2) >>> sect(p-q) 3
the following example has been attached to
_integer_()
ofsage.rings.polynomial.polynomial_element.Polynomial
before (see comment there):sage: k = GF(47) sage: R.<x> = PolynomialRing(k) sage: R.coerce_map_from(ZZ).section() Composite map: From: Univariate Polynomial Ring in x over Finite Field of size 47 To: Integer Ring Defn: Generic map: From: Univariate Polynomial Ring in x over Finite Field of size 47 To: Finite Field of size 47 then Lifting map: From: Finite Field of size 47 To: Integer Ring sage: ZZ(R(45)) # indirect doctest 45 sage: ZZ(3*x + 45) # indirect doctest Traceback (most recent call last): ... TypeError: 3*x + 45 is not a constant polynomial
>>> from sage.all import * >>> k = GF(Integer(47)) >>> R = PolynomialRing(k, names=('x',)); (x,) = R._first_ngens(1) >>> R.coerce_map_from(ZZ).section() Composite map: From: Univariate Polynomial Ring in x over Finite Field of size 47 To: Integer Ring Defn: Generic map: From: Univariate Polynomial Ring in x over Finite Field of size 47 To: Finite Field of size 47 then Lifting map: From: Finite Field of size 47 To: Integer Ring >>> ZZ(R(Integer(45))) # indirect doctest 45 >>> ZZ(Integer(3)*x + Integer(45)) # indirect doctest Traceback (most recent call last): ... TypeError: 3*x + 45 is not a constant polynomial
- then()[source]¶
Return the tail of the list of maps.
If
self
represents \(f_n \circ f_{n-1} \circ \cdots \circ f_1 \circ f_0\), thenself.first()
returns \(f_n \circ f_{n-1} \circ \cdots \circ f_1\). We haveself == self.then() * self.first()
.EXAMPLES:
sage: R.<x> = QQ[] sage: S.<a> = QQ[] sage: from sage.categories.morphism import SetMorphism sage: f = SetMorphism(Hom(R, S, Rings()), lambda p: p[0]*a^p.degree()) sage: g = S.hom([2*x]) sage: (f*g).then() == f True sage: f = QQ.coerce_map_from(ZZ) sage: f = f.extend_domain(ZZ).extend_codomain(QQ) sage: f.then() Composite map: From: Integer Ring To: Rational Field Defn: Natural morphism: From: Integer Ring To: Rational Field then Identity endomorphism of Rational Field
>>> from sage.all import * >>> R = QQ['x']; (x,) = R._first_ngens(1) >>> S = QQ['a']; (a,) = S._first_ngens(1) >>> from sage.categories.morphism import SetMorphism >>> f = SetMorphism(Hom(R, S, Rings()), lambda p: p[Integer(0)]*a**p.degree()) >>> g = S.hom([Integer(2)*x]) >>> (f*g).then() == f True >>> f = QQ.coerce_map_from(ZZ) >>> f = f.extend_domain(ZZ).extend_codomain(QQ) >>> f.then() Composite map: From: Integer Ring To: Rational Field Defn: Natural morphism: From: Integer Ring To: Rational Field then Identity endomorphism of Rational Field
- class sage.categories.map.Map[source]¶
Bases:
Element
Basic class for all maps.
Note
The call method is of course not implemented in this base class. This must be done in the sub classes, by overloading
_call_
and possibly also_call_with_args
.EXAMPLES:
Usually, instances of this class will not be constructed directly, but for example like this:
sage: from sage.categories.morphism import SetMorphism sage: X.<x> = ZZ[] sage: Y = ZZ sage: phi = SetMorphism(Hom(X, Y, Rings()), lambda p: p[0]) sage: phi(x^2+2*x-1) -1 sage: R.<x,y> = QQ[] sage: f = R.hom([x+y, x-y], R) sage: f(x^2+2*x-1) x^2 + 2*x*y + y^2 + 2*x + 2*y - 1
>>> from sage.all import * >>> from sage.categories.morphism import SetMorphism >>> X = ZZ['x']; (x,) = X._first_ngens(1) >>> Y = ZZ >>> phi = SetMorphism(Hom(X, Y, Rings()), lambda p: p[Integer(0)]) >>> phi(x**Integer(2)+Integer(2)*x-Integer(1)) -1 >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> f = R.hom([x+y, x-y], R) >>> f(x**Integer(2)+Integer(2)*x-Integer(1)) x^2 + 2*x*y + y^2 + 2*x + 2*y - 1
- category_for()[source]¶
Return the category
self
is a morphism for.Note
This is different from the category of maps to which this map belongs as an object.
EXAMPLES:
sage: from sage.categories.morphism import SetMorphism sage: X.<x> = ZZ[] sage: Y = ZZ sage: phi = SetMorphism(Hom(X, Y, Rings()), lambda p: p[0]) sage: phi.category_for() Category of rings sage: phi.category() Category of homsets of unital magmas and additive unital additive magmas sage: R.<x,y> = QQ[] sage: f = R.hom([x+y, x-y], R) sage: f.category_for() Join of Category of unique factorization domains and Category of algebras with basis over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets sage: f.category() Category of endsets of unital magmas and right modules over (number fields and quotient fields and metric spaces) and left modules over (number fields and quotient fields and metric spaces)
>>> from sage.all import * >>> from sage.categories.morphism import SetMorphism >>> X = ZZ['x']; (x,) = X._first_ngens(1) >>> Y = ZZ >>> phi = SetMorphism(Hom(X, Y, Rings()), lambda p: p[Integer(0)]) >>> phi.category_for() Category of rings >>> phi.category() Category of homsets of unital magmas and additive unital additive magmas >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> f = R.hom([x+y, x-y], R) >>> f.category_for() Join of Category of unique factorization domains and Category of algebras with basis over (number fields and quotient fields and metric spaces) and Category of commutative algebras over (number fields and quotient fields and metric spaces) and Category of infinite sets >>> f.category() Category of endsets of unital magmas and right modules over (number fields and quotient fields and metric spaces) and left modules over (number fields and quotient fields and metric spaces)
FIXME: find a better name for this method
- domains()[source]¶
Iterate over the domains of the factors of a (composite) map.
This default implementation simply yields the domain of this map.
See also
EXAMPLES:
sage: list(QQ.coerce_map_from(ZZ).domains()) [Integer Ring]
>>> from sage.all import * >>> list(QQ.coerce_map_from(ZZ).domains()) [Integer Ring]
- extend_codomain(new_codomain)[source]¶
INPUT:
self
– a member of Hom(X, Y)new_codomain
– an object Z such that there is a canonical coercion \(\phi\) in Hom(Y, Z)
OUTPUT:
An element of Hom(X, Z) obtained by composing
self
with \(\phi\). If no canonical \(\phi\) exists, aTypeError
is raised.EXAMPLES:
sage: mor = QQ.coerce_map_from(ZZ) sage: mor.extend_codomain(RDF) Composite map: From: Integer Ring To: Real Double Field Defn: Natural morphism: From: Integer Ring To: Rational Field then Native morphism: From: Rational Field To: Real Double Field sage: mor.extend_codomain(GF(7)) Traceback (most recent call last): ... TypeError: No coercion from Rational Field to Finite Field of size 7
>>> from sage.all import * >>> mor = QQ.coerce_map_from(ZZ) >>> mor.extend_codomain(RDF) Composite map: From: Integer Ring To: Real Double Field Defn: Natural morphism: From: Integer Ring To: Rational Field then Native morphism: From: Rational Field To: Real Double Field >>> mor.extend_codomain(GF(Integer(7))) Traceback (most recent call last): ... TypeError: No coercion from Rational Field to Finite Field of size 7
- extend_domain(new_domain)[source]¶
INPUT:
self
– a member of Hom(Y, Z)new_codomain
– an object X such that there is a canonical coercion \(\phi\) in Hom(X, Y)
OUTPUT:
An element of Hom(X, Z) obtained by composing self with \(\phi\). If no canonical \(\phi\) exists, a
TypeError
is raised.EXAMPLES:
sage: # needs sage.rings.complex_double sage: mor = CDF.coerce_map_from(RDF) sage: mor.extend_domain(QQ) Composite map: From: Rational Field To: Complex Double Field Defn: Native morphism: From: Rational Field To: Real Double Field then Native morphism: From: Real Double Field To: Complex Double Field sage: mor.extend_domain(ZZ['x']) Traceback (most recent call last): ... TypeError: No coercion from Univariate Polynomial Ring in x over Integer Ring to Real Double Field
>>> from sage.all import * >>> # needs sage.rings.complex_double >>> mor = CDF.coerce_map_from(RDF) >>> mor.extend_domain(QQ) Composite map: From: Rational Field To: Complex Double Field Defn: Native morphism: From: Rational Field To: Real Double Field then Native morphism: From: Real Double Field To: Complex Double Field >>> mor.extend_domain(ZZ['x']) Traceback (most recent call last): ... TypeError: No coercion from Univariate Polynomial Ring in x over Integer Ring to Real Double Field
- parent()[source]¶
Return the homset containing this map.
Note
The method
_make_weak_references()
, that is used for the maps found by the coercion system, needs to remove the usual strong reference from the coercion map to the homset containing it. As long as the user keeps strong references to domain and codomain of the map, we will be able to reconstruct the homset. However, a strong reference to the coercion map does not prevent the domain from garbage collection!EXAMPLES:
sage: Q = QuadraticField(-5) # needs sage.rings.number_field sage: phi = CDF._internal_convert_map_from(Q) # needs sage.rings.number_field sage: print(phi.parent()) # needs sage.rings.number_field Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field
>>> from sage.all import * >>> Q = QuadraticField(-Integer(5)) # needs sage.rings.number_field >>> phi = CDF._internal_convert_map_from(Q) # needs sage.rings.number_field >>> print(phi.parent()) # needs sage.rings.number_field Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field
We now demonstrate that the reference to the coercion map \(\phi\) does not prevent \(Q\) from being garbage collected:
sage: import gc sage: del Q # needs sage.rings.number_field sage: _ = gc.collect() sage: phi.parent() # needs sage.rings.number_field Traceback (most recent call last): ... ValueError: This map is in an invalid state, the domain has been garbage collected
>>> from sage.all import * >>> import gc >>> del Q # needs sage.rings.number_field >>> _ = gc.collect() >>> phi.parent() # needs sage.rings.number_field Traceback (most recent call last): ... ValueError: This map is in an invalid state, the domain has been garbage collected
You can still obtain copies of the maps used by the coercion system with strong references:
sage: # needs sage.rings.number_field sage: Q = QuadraticField(-5) sage: phi = CDF.convert_map_from(Q) sage: print(phi.parent()) Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field sage: import gc sage: del Q sage: _ = gc.collect() sage: phi.parent() Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field
>>> from sage.all import * >>> # needs sage.rings.number_field >>> Q = QuadraticField(-Integer(5)) >>> phi = CDF.convert_map_from(Q) >>> print(phi.parent()) Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field >>> import gc >>> del Q >>> _ = gc.collect() >>> phi.parent() Set of field embeddings from Number Field in a with defining polynomial x^2 + 5 with a = 2.236067977499790?*I to Complex Double Field
- post_compose(left)[source]¶
INPUT:
self
– a Map in someHom(X, Y, category_right)
left
– a Map in someHom(Y, Z, category_left)
Returns the composition of
self
followed byleft
as a morphism inHom(X, Z, category)
wherecategory
is the meet ofcategory_left
andcategory_right
.Caveat: see the current restrictions on
Category.meet()
EXAMPLES:
sage: from sage.categories.morphism import SetMorphism sage: X.<x> = ZZ[] sage: Y = ZZ sage: Z = QQ sage: phi_xy = SetMorphism(Hom(X, Y, Rings()), lambda p: p[0]) sage: phi_yz = SetMorphism(Hom(Y, Z, Monoids()), lambda y: QQ(y**2)) sage: phi_xz = phi_xy.post_compose(phi_yz); phi_xz Composite map: From: Univariate Polynomial Ring in x over Integer Ring To: Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Integer Ring then Generic morphism: From: Integer Ring To: Rational Field sage: phi_xz.category_for() Category of monoids
>>> from sage.all import * >>> from sage.categories.morphism import SetMorphism >>> X = ZZ['x']; (x,) = X._first_ngens(1) >>> Y = ZZ >>> Z = QQ >>> phi_xy = SetMorphism(Hom(X, Y, Rings()), lambda p: p[Integer(0)]) >>> phi_yz = SetMorphism(Hom(Y, Z, Monoids()), lambda y: QQ(y**Integer(2))) >>> phi_xz = phi_xy.post_compose(phi_yz); phi_xz Composite map: From: Univariate Polynomial Ring in x over Integer Ring To: Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Integer Ring then Generic morphism: From: Integer Ring To: Rational Field >>> phi_xz.category_for() Category of monoids
- pre_compose(right)[source]¶
INPUT:
self
– a Map in someHom(Y, Z, category_left)
left
– a Map in someHom(X, Y, category_right)
Returns the composition of
right
followed byself
as a morphism inHom(X, Z, category)
wherecategory
is the meet ofcategory_left
andcategory_right
.EXAMPLES:
sage: from sage.categories.morphism import SetMorphism sage: X.<x> = ZZ[] sage: Y = ZZ sage: Z = QQ sage: phi_xy = SetMorphism(Hom(X, Y, Rings()), lambda p: p[0]) sage: phi_yz = SetMorphism(Hom(Y, Z, Monoids()), lambda y: QQ(y**2)) sage: phi_xz = phi_yz.pre_compose(phi_xy); phi_xz Composite map: From: Univariate Polynomial Ring in x over Integer Ring To: Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Integer Ring then Generic morphism: From: Integer Ring To: Rational Field sage: phi_xz.category_for() Category of monoids
>>> from sage.all import * >>> from sage.categories.morphism import SetMorphism >>> X = ZZ['x']; (x,) = X._first_ngens(1) >>> Y = ZZ >>> Z = QQ >>> phi_xy = SetMorphism(Hom(X, Y, Rings()), lambda p: p[Integer(0)]) >>> phi_yz = SetMorphism(Hom(Y, Z, Monoids()), lambda y: QQ(y**Integer(2))) >>> phi_xz = phi_yz.pre_compose(phi_xy); phi_xz Composite map: From: Univariate Polynomial Ring in x over Integer Ring To: Rational Field Defn: Generic morphism: From: Univariate Polynomial Ring in x over Integer Ring To: Integer Ring then Generic morphism: From: Integer Ring To: Rational Field >>> phi_xz.category_for() Category of monoids
- class sage.categories.map.Section[source]¶
Bases:
Map
A formal section of a map.
Note
Call methods are not implemented for the base class
Section
.EXAMPLES:
sage: from sage.categories.map import Section sage: R.<x,y> = ZZ[] sage: S.<a,b> = QQ[] sage: f = R.hom([a+b, a-b]) sage: sf = Section(f); sf Section map: From: Multivariate Polynomial Ring in a, b over Rational Field To: Multivariate Polynomial Ring in x, y over Integer Ring sage: sf(a) Traceback (most recent call last): ... NotImplementedError: <class 'sage.categories.map.Section'>
>>> from sage.all import * >>> from sage.categories.map import Section >>> R = ZZ['x, y']; (x, y,) = R._first_ngens(2) >>> S = QQ['a, b']; (a, b,) = S._first_ngens(2) >>> f = R.hom([a+b, a-b]) >>> sf = Section(f); sf Section map: From: Multivariate Polynomial Ring in a, b over Rational Field To: Multivariate Polynomial Ring in x, y over Integer Ring >>> sf(a) Traceback (most recent call last): ... NotImplementedError: <class 'sage.categories.map.Section'>
- sage.categories.map.is_Map(x)[source]¶
Auxiliary function: Is the argument a map?
EXAMPLES:
sage: R.<x,y> = QQ[] sage: f = R.hom([x+y, x-y], R) sage: from sage.categories.map import is_Map sage: is_Map(f) doctest:warning... DeprecationWarning: The function is_Map is deprecated; use 'isinstance(..., Map)' instead. See https://github.com/sagemath/sage/issues/38103 for details. True
>>> from sage.all import * >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> f = R.hom([x+y, x-y], R) >>> from sage.categories.map import is_Map >>> is_Map(f) doctest:warning... DeprecationWarning: The function is_Map is deprecated; use 'isinstance(..., Map)' instead. See https://github.com/sagemath/sage/issues/38103 for details. True