# Base class for old-style parent objects with generators¶

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)
sage: M
Ambient free module of rank 4 over the principal ideal domain Integer Ring
sage: M.ngens()
4
sage: M.gen(0)
(1, 0, 0, 0)
sage: M.gens()
((1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1))


EXAMPLES:

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')

generator_orders()
class sage.structure.parent_gens.ParentWithGens

EXAMPLES:

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, check=True)

Return the unique homomorphism from self to codomain that sends self.gens() to the entries of im_gens. 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 homomorphism
• codomain - the codomain of the homomorphism
• check - 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.

EXAMPLE: 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))
Traceback (most recent call last):
...
TypeError: images do not define a valid homomorphism

sage: R.<x> = PolynomialRing(GF(7))
sage: f = R.hom([3], GF(49,'a'))
sage: f
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)
2
sage: f(x^2+1)
3


EXAMPLE: Natural morphism

sage: f = ZZ.hom(GF(5))
sage: f(7)
2
sage: f
Ring Coercion 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.

ngens()
class sage.structure.parent_gens.ParentWithMultiplicativeAbelianGens

EXAMPLES:

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')

generator_orders()

Return True if x is a parent object with additive abelian generators, i.e., derives from sage.structure.parent_gens.ParentWithAdditiveAbelianGens and False otherwise.

EXAMPLES:

sage: from sage.structure.parent_gens import is_ParentWithAdditiveAbelianGens
False
True

sage.structure.parent_gens.is_ParentWithGens(x)

Return True if x is a parent object with generators, i.e., derives from sage.structure.parent_gens.ParentWithGens and False otherwise.

EXAMPLES:

sage: from sage.structure.parent_gens import is_ParentWithGens
sage: is_ParentWithGens(QQ['x'])
True
sage: is_ParentWithGens(CC)
True
sage: is_ParentWithGens(Primes())
False

sage.structure.parent_gens.is_ParentWithMultiplicativeAbelianGens(x)

Return True if x is a parent object with additive abelian generators, i.e., derives from sage.structure.parent_gens.ParentWithMultiplicativeAbelianGens and False otherwise.

EXAMPLES:

sage: from sage.structure.parent_gens import is_ParentWithMultiplicativeAbelianGens
sage: is_ParentWithMultiplicativeAbelianGens(QQ)
False
sage: is_ParentWithMultiplicativeAbelianGens(DirichletGroup(11))
True

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)
sage.structure.parent_gens.normalize_names(ngens, names=None)

Return a tuple of strings of variable names of length ngens given the input names.

INPUT:

• ngens - integer
• names
• tuple or list of strings, such as (‘x’, ‘y’)
• a string prefix, such as ‘alpha’
• string of single character names, such as ‘xyz’

EXAMPLES:

sage: from sage.structure.parent_gens import normalize_names as nn
sage: nn(1, 'a')
('a',)
sage: nn(2, 'zzz')
('zzz0', 'zzz1')
sage: nn(2, 'ab')
('a', 'b')
sage: nn(3, ('a', 'bb', 'ccc'))
('a', 'bb', 'ccc')
sage: nn(4, ['a1', 'a2', 'b1', 'b11'])
('a1', 'a2', 'b1', 'b11')


TESTS:

sage: nn(2, 'z1')
('z10', 'z11')
sage: PolynomialRing(QQ, 2, 'alpha0')
Multivariate Polynomial Ring in alpha00, alpha01 over Rational Field


#### Previous topic

Base class for old-style parent objects with a base ring

#### Next topic

Containers for storing coercion data