Base class for objects of a category

CLASS HIERARCHY:

Many category objects in Sage are equipped with generators, which are usually 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.

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))
class sage.structure.category_object.CategoryObject

Bases: sage.structure.sage_object.SageObject

An object in some category.

Hom(codomain, cat=None)

Return the homspace Hom(self, codomain, cat) of all homomorphisms from self to codomain in the category cat.

The default category is determined by self.category() and codomain.category().

EXAMPLES:

sage: R.<x,y> = PolynomialRing(QQ, 2)
sage: R.Hom(QQ)
Set of Homomorphisms from Multivariate Polynomial Ring in x, y over Rational Field to Rational Field

Homspaces are defined for very general Sage objects, even elements of familiar rings.

sage: n = 5; Hom(n,7)
Set of Morphisms from 5 to 7 in Category of elements of Integer Ring
sage: z=(2/3); Hom(z,8/1)
Set of Morphisms from 2/3 to 8 in Category of elements of Rational Field

This example illustrates the optional third argument:

sage: QQ.Hom(ZZ, Sets())
Set of Morphisms from Rational Field to Integer Ring in Category of sets
base()
base_ring()

Return the base ring of self.

INPUT:

  • self – an object over a base ring; typically a module

EXAMPLES:

sage: from sage.modules.module import Module
sage: Module(ZZ).base_ring()
Integer Ring

sage: F = FreeModule(ZZ,3)
sage: F.base_ring()
Integer Ring
sage: F.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>

Note that the coordinates of the elements of a module can lie in a bigger ring, the coordinate_ring:

sage: M = (ZZ^2) * (1/2)
sage: v = M([1/2, 0])
sage: v.base_ring()
Integer Ring
sage: parent(v[0])
Rational Field
sage: v.coordinate_ring()
Rational Field

More examples:

sage: F = FreeAlgebra(QQ, 'x')
sage: F.base_ring()
Rational Field
sage: F.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>

sage: E = CombinatorialFreeModule(ZZ, [1,2,3])
sage: F = CombinatorialFreeModule(ZZ, [2,3,4])
sage: H = Hom(E, F)
sage: H.base_ring()
Integer Ring
sage: H.__class__.base_ring
<method 'base_ring' of 'sage.structure.category_object.CategoryObject' objects>

Todo

Move this method elsewhere (typically in the Modules category) so as not to pollute the namespace of all category objects.

categories()

Return the categories of self.

EXAMPLES:

sage: ZZ.categories()
[Join of Category of euclidean domains
     and Category of infinite enumerated sets
     and Category of metric spaces,
 Category of euclidean domains,
 Category of principal ideal domains,
 Category of unique factorization domains,
 Category of gcd domains,
 Category of integral domains,
 Category of domains,
 Category of commutative rings, ...
 Category of monoids, ...,
 Category of commutative additive groups, ...,
 Category of sets, ...,
 Category of objects]
category()
gens_dict(copy=True)

Return a dictionary whose entries are {name:variable,...}, where name stands for the variable names of this object (as strings) and variable stands for the corresponding defining generators (as elements of this object).

EXAMPLES:

sage: B.<a,b,c,d> = BooleanPolynomialRing()
sage: B.gens_dict()
{'a': a, 'b': b, 'c': c, 'd': d}
gens_dict_recursive()

Return the dictionary of generators of self and its base rings.

OUTPUT:

  • a dictionary with string names of generators as keys and generators of self and its base rings as values.

EXAMPLES:

sage: R = QQ['x,y']['z,w']
sage: sorted(R.gens_dict_recursive().items())
[('w', w), ('x', x), ('y', y), ('z', z)]
inject_variables(scope=None, verbose=True)

Inject the generators of self with their names into the namespace of the Python code from which this function is called.

Thus, e.g., if the generators of self are labeled ‘a’, ‘b’, and ‘c’, then after calling this method the variables a, b, and c in the current scope will be set equal to the generators of self.

NOTE: If Foo is a constructor for a Sage object with generators, and Foo is defined in Cython, then it would typically call inject_variables() on the object it creates. E.g., PolynomialRing(QQ, 'y') does this so that the variable y is the generator of the polynomial ring.

latex_name()
latex_variable_names()

Returns the list of variable names suitable for latex output.

All _SOMETHING substrings are replaced by _{SOMETHING} recursively so that subscripts of subscripts work.

EXAMPLES:

sage: R, x = PolynomialRing(QQ, 'x', 12).objgens()
sage: x
(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11)
sage: R.latex_variable_names ()
['x_{0}', 'x_{1}', 'x_{2}', 'x_{3}', 'x_{4}', 'x_{5}', 'x_{6}', 'x_{7}', 'x_{8}', 'x_{9}', 'x_{10}', 'x_{11}']
sage: f = x[0]^3 + 15/3 * x[1]^10
sage: print(latex(f))
5 x_{1}^{10} + x_{0}^{3}
objgen()

Return the tuple (self, self.gen()).

EXAMPLES:

sage: R, x = PolynomialRing(QQ,'x').objgen()
sage: R
Univariate Polynomial Ring in x over Rational Field
sage: x
x
objgens()

Return the tuple (self, self.gens()).

EXAMPLES:

sage: R = PolynomialRing(QQ, 3, 'x'); R
Multivariate Polynomial Ring in x0, x1, x2 over Rational Field
sage: R.objgens()
(Multivariate Polynomial Ring in x0, x1, x2 over Rational Field, (x0, x1, x2))
variable_name()

Return the first variable name.

OUTPUT: a string

EXAMPLES:

sage: R.<z,y,a42> = ZZ[]
sage: R.variable_name()
'z'
sage: R.<x> = InfinitePolynomialRing(ZZ)
sage: R.variable_name()
'x'
variable_names()

Return the list of variable names corresponding to the generators.

OUTPUT: a tuple of strings

EXAMPLES:

sage: R.<z,y,a42> = QQ[]
sage: R.variable_names()
('z', 'y', 'a42')
sage: S = R.quotient_ring(z+y)
sage: S.variable_names()
('zbar', 'ybar', 'a42bar')
sage: T.<x> = InfinitePolynomialRing(ZZ)
sage: T.variable_names()
('x',)
sage.structure.category_object.certify_names(names)

Check that names are valid variable names.

INPUT:

  • names – an iterable with strings representing variable names

OUTPUT: True (for efficiency of the Cython call)

EXAMPLES:

sage: from sage.structure.category_object import certify_names as cn
sage: cn(["a", "b", "c"])
1
sage: cn("abc")
1
sage: cn([])
1
sage: cn([""])
Traceback (most recent call last):
...
ValueError: variable name must be nonempty
sage: cn(["_foo"])
Traceback (most recent call last):
...
ValueError: variable name '_foo' does not start with a letter
sage: cn(["x'"])
Traceback (most recent call last):
...
ValueError: variable name "x'" is not alphanumeric
sage: cn(["a", "b", "b"])
Traceback (most recent call last):
...
ValueError: variable name 'b' appears more than once
sage.structure.category_object.check_default_category(default_category, category)
sage.structure.category_object.normalize_names(ngens, names)

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

INPUT:

  • ngens – integer: number of generators. The value ngens=-1 means that the number of generators is unknown a priori.
  • names – any of the following:
    • a tuple or list of strings, such as ('x', 'y')
    • a comma-separated string, such as x,y
    • a string prefix, such as ‘alpha’
    • a string of single character names, such as ‘xyz’

OUTPUT: a tuple of ngens strings to be used as variable names.

EXAMPLES:

sage: from sage.structure.category_object import normalize_names as nn
sage: nn(0, "")
()
sage: nn(0, [])
()
sage: nn(0, None)
()
sage: nn(1, 'a')
('a',)
sage: nn(2, 'z_z')
('z_z0', 'z_z1')
sage: nn(3, 'x, y, z')
('x', 'y', 'z')
sage: nn(2, 'ab')
('a', 'b')
sage: nn(2, 'x0')
('x00', 'x01')
sage: nn(3, (' a ', ' bb ', ' ccc '))
('a', 'bb', 'ccc')
sage: nn(4, ['a1', 'a2', 'b1', 'b11'])
('a1', 'a2', 'b1', 'b11')

Arguments are converted to strings:

sage: nn(1, u'a')
('a',)
sage: var('alpha')
alpha
sage: nn(2, alpha)
('alpha0', 'alpha1')
sage: nn(1, [alpha])
('alpha',)

With an unknown number of generators:

sage: nn(-1, 'a')
('a',)
sage: nn(-1, 'x, y, z')
('x', 'y', 'z')

Test errors:

sage: nn(3, ["x", "y"])
Traceback (most recent call last):
...
IndexError: the number of names must equal the number of generators
sage: nn(None, "a")  # py2
Traceback (most recent call last):
...
TypeError: 'NoneType' object cannot be interpreted as an index
sage: nn(None, "a")  # py3
Traceback (most recent call last):
...
TypeError: 'NoneType' object cannot be interpreted as an integer
sage: nn(1, "")
Traceback (most recent call last):
...
ValueError: variable name must be nonempty
sage: nn(1, "foo@")
Traceback (most recent call last):
...
ValueError: variable name 'foo@' is not alphanumeric
sage: nn(2, "_foo")
Traceback (most recent call last):
...
ValueError: variable name '_foo0' does not start with a letter
sage: nn(1, 3/2)
Traceback (most recent call last):
...
ValueError: variable name '3/2' is not alphanumeric