Base class for maps
Bases: sage.categories.map.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.
EXAMPLE:
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
The first map in the formal composition, where the composition is x|--> second(first(x)).
EXAMPLE:
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).first() is g
True
Tell whether self is injective.
It raises NotImplementedError if it can’t be determined.
EXAMPLE:
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)
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()),phi1,phi2)
sage: c1.is_injective()
True
If it can not be determined whether the composition is injective, an error is raised:
sage: psi1 = V2.hom(Matrix([[1,2],[3,4],[5,6]]),V1)
sage: c2 = FormalCompositeMap(Hom(V1,V1,phi2.category_for()),phi2,psi1)
sage: c2.is_injective()
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)
sage: c3 = FormalCompositeMap(Hom(V2,QQ^1,phi2.category_for()),psi2,psi1)
sage: c3.is_injective()
False
Tell whether self is surjective.
It raises NotImplementedError if it can’t be determined.
EXAMPLE:
sage: from sage.categories.map import FormalCompositeMap
sage: V3 = QQ^3
sage: V2 = QQ^2
sage: V1 = QQ^1
If both maps are surjective, the composition is surjective:
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
If the second map is not surjective, the composition is not surjective:
sage: FormalCompositeMap(Hom(V3,V1,phi32.category_for()),phi32,V2.hom(Matrix([[0],[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()),V2.hom(Matrix([[0],[0]]),V1),V1.hom(Matrix([[1]]),V1)).is_surjective()
False
Otherwise, surjectivity of the composition can not be determined:
sage: FormalCompositeMap(Hom(V2, V1, phi32.category_for()),
... 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.
The second map in the formal composition, where the composition is x|–> second(first(x)).
EXAMPLE:
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).second() is f
True
Bases: sage.structure.element.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
Returns 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 hom sets in Category of rings
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 commutative algebras over Rational Field
sage: f.category()
Join of Category of hom sets in Category of rings and Category of hom sets in Category of modules over Rational Field
FIXME: find a better name for this method
Return the codomain of self.
EXAMPLE:
sage: from sage.categories.map import Map
sage: f = Map(Hom(QQ, ZZ, Rings()))
sage: f.codomain()
Integer Ring
sage: R.<x,y> = QQ[]
sage: phi = R.hom([x+y,x-y],R)
sage: phi.codomain()
Multivariate Polynomial Ring in x, y over Rational Field
Return the domain of self.
EXAMPLE:
sage: from sage.categories.map import Map
sage: f = Map(Hom(QQ, ZZ, Rings()))
sage: f.domain()
Rational Field
sage: R.<x,y> = QQ[]
sage: phi = R.hom([x+y,x-y],R)
sage: phi.domain()
Multivariate Polynomial Ring in x, y over Rational Field
INPUT:
OUTPUT:
An element of Hom(X, Z) obtained by composing self with . If
no canonical
exists, a TypeError 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
INPUT:
OUTPUT:
An element of Hom(X, Z) obtained by composing self with . If
no canonical
exists, a TypeError is raised.
EXAMPLES:
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
Tells whether the map is injective (not implemented in the base class).
TEST:
sage: from sage.categories.map import Map
sage: f = Map(Hom(QQ, ZZ, Rings()))
sage: f.is_injective()
Traceback (most recent call last):
...
NotImplementedError: <type 'sage.categories.map.Map'>
Tells whether the map is surjective (not implemented in the base class).
TEST:
sage: from sage.categories.map import Map
sage: f = Map(Hom(QQ, ZZ, Rings()))
sage: f.is_surjective()
Traceback (most recent call last):
...
NotImplementedError: <type 'sage.categories.map.Map'>
INPUT:
Returns the composition of self followed by right as a morphism in Hom(X, Z, category) where category is the meet of category_left and category_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
INPUT:
Returns the composition of right followed by self as a morphism in Hom(X, Z, category) where category is the meet of category_left and category_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
Return a section of self.
NOTE:
By default, it returns None. You may override it in subclasses.
TEST:
sage: R.<x,y> = QQ[]
sage: f = R.hom([x+y,x-y],R)
sage: print f.section()
None
sage: f = QQ.coerce_map_from(ZZ); f
Natural morphism:
From: Integer Ring
To: Rational Field
sage: ff = f.section(); ff
Generic map:
From: Rational Field
To: Integer Ring
sage: ff(4/2)
2
sage: parent(ff(4/2)) is ZZ
True
sage: ff(1/2)
Traceback (most recent call last):
...
TypeError: no conversion of this rational to integer
Bases: sage.categories.map.Map
A formal section of a map.
NOTE:
Call methods are not implemented for the base class Section.
EXAMPLE:
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: <type 'sage.categories.map.Section'>
Auxiliary function: Is the argument a map?
EXAMPLE:
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)
True
Auxiliary function for unpickling a map.
TEST:
sage: R.<x,y> = QQ[]
sage: f = R.hom([x+y,x-y],R)
sage: f == loads(dumps(f)) # indirect doctest
True