Base class for old-style parent objects with generators#
Note
This class is being deprecated, see
sage.structure.parent.Parent
and
sage.structure.category_object.CategoryObject
for the new
model.
Many parent objects in Sage are equipped with generators, which are
special elements of the object. For example, the polynomial ring
\(\ZZ[x,y,z]\) is generated by \(x\), \(y\), and \(z\). In Sage the \(i^{th}\)
generator of an object X
is obtained using the notation
X.gen(i)
. From the Sage interactive prompt, the shorthand
notation X.i
is also allowed.
REQUIRED: A class that derives from ParentWithGens must define the ngens() and gen(i) methods.
OPTIONAL: It is also good if they define gens() to return all gens, but this is not necessary.
The gens
function returns a tuple of all generators, the
ngens
function returns the number of generators.
The _assign_names
functions is for internal use only, and is
called when objects are created to set the generator names. It can
only be called once.
The following examples illustrate these functions in the context of multivariate polynomial rings and free modules.
EXAMPLES:
sage: R = PolynomialRing(ZZ, 3, 'x')
sage: R.ngens()
3
sage: R.gen(0)
x0
sage: R.gens()
(x0, x1, x2)
sage: R.variable_names()
('x0', 'x1', 'x2')
This example illustrates generators for a free module over \(\ZZ\).
sage: M = FreeModule(ZZ, 4) # optional - sage.modules
sage: M # optional - sage.modules
Ambient free module of rank 4 over the principal ideal domain Integer Ring
sage: M.ngens() # optional - sage.modules
4
sage: M.gen(0) # optional - sage.modules
(1, 0, 0, 0)
sage: M.gens() # optional - sage.modules
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))
- class sage.structure.parent_gens.ParentWithGens#
Bases:
ParentWithBase
EXAMPLES:
sage: from sage.structure.parent_gens import ParentWithGens sage: class MyParent(ParentWithGens): ....: def ngens(self): return 3 sage: P = MyParent(base=QQ, names='a,b,c', normalize=True, category=Groups()) sage: P.category() Category of groups sage: P._names ('a', 'b', 'c')
- gen(i=0)#
- gens()#
Return a tuple whose entries are the generators for this object, in order.
- hom(im_gens, codomain=None, base_map=None, category=None, check=True)#
Return the unique homomorphism from self to codomain that sends
self.gens()
to the entries ofim_gens
and induces the mapbase_map
on the base ring. Raises a TypeError if there is no such homomorphism.INPUT:
im_gens
– the images in the codomain of the generators of this object under the homomorphismcodomain
– the codomain of the homomorphismbase_map
– a map from the base ring of the domain into something that coerces into the codomaincategory
– the category of the resulting morphismcheck
– whether to verify that the images of generators extend to define a map (using only canonical coercions)
OUTPUT:
a homomorphism self –> codomain
Note
As a shortcut, one can also give an object X instead of
im_gens
, in which case return the (if it exists) natural map to X.EXAMPLES: Polynomial Ring We first illustrate construction of a few homomorphisms involving a polynomial ring.
sage: R.<x> = PolynomialRing(ZZ) sage: f = R.hom([5], QQ) sage: f(x^2 - 19) 6 sage: R.<x> = PolynomialRing(QQ) sage: f = R.hom([5], GF(7)) # optional - sage.rings.finite_rings Traceback (most recent call last): ... ValueError: relations do not all (canonically) map to 0 under map determined by images of generators sage: R.<x> = PolynomialRing(GF(7)) # optional - sage.rings.finite_rings sage: f = R.hom([3], GF(49, 'a')) # optional - sage.rings.finite_rings sage: f # optional - sage.rings.finite_rings Ring morphism: From: Univariate Polynomial Ring in x over Finite Field of size 7 To: Finite Field in a of size 7^2 Defn: x |--> 3 sage: f(x + 6) # optional - sage.rings.finite_rings 2 sage: f(x^2 + 1) # optional - sage.rings.finite_rings 3
EXAMPLES: Natural morphism
sage: f = ZZ.hom(GF(5)) # optional - sage.rings.finite_rings sage: f(7) # optional - sage.rings.finite_rings 2 sage: f # optional - sage.rings.finite_rings Natural morphism: From: Integer Ring To: Finite Field of size 5
There might not be a natural morphism, in which case a TypeError exception is raised.
sage: QQ.hom(ZZ) Traceback (most recent call last): ... TypeError: natural coercion morphism from Rational Field to Integer Ring not defined
You can specify a map on the base ring:
sage: k = GF(2) # optional - sage.rings.finite_rings sage: R.<a> = k[] # optional - sage.rings.finite_rings sage: l.<a> = k.extension(a^3 + a^2 + 1) # optional - sage.rings.finite_rings sage: R.<b> = l[] # optional - sage.rings.finite_rings sage: m.<b> = l.extension(b^2 + b + a) # optional - sage.rings.finite_rings sage: n.<z> = GF(2^6) # optional - sage.rings.finite_rings sage: m.hom([z^4 + z^3 + 1], base_map=l.hom([z^5 + z^4 + z^2])) # optional - sage.rings.finite_rings Ring morphism: From: Univariate Quotient Polynomial Ring in b over Finite Field in a of size 2^3 with modulus b^2 + b + a To: Finite Field in z of size 2^6 Defn: b |--> z^4 + z^3 + 1 with map of base ring
- ngens()#
- class sage.structure.parent_gens.localvars#
Bases:
object
Context manager for safely temporarily changing the variables names of an object with generators.
Objects with named generators are globally unique in Sage. Sometimes, though, it is very useful to be able to temporarily display the generators differently. The new Python
with
statement and the localvars context manager make this easy and safe (and fun!)Suppose X is any object with generators. Write
with localvars(X, names[, latex_names] [,normalize=False]): some code ...
and the indented code will be run as if the names in X are changed to the new names. If you give normalize=True, then the names are assumed to be a tuple of the correct number of strings.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2) sage: with localvars(R, 'z,w'): ....: print(x^3 + y^3 - x*y) z^3 + w^3 - z*w
Note
I wrote this because it was needed to print elements of the quotient of a ring R by an ideal I using the print function for elements of R. See the code in
quotient_ring_element.pyx
.AUTHOR:
William Stein (2006-10-31)