Constructors for polynomial rings

This module provides the function PolynomialRing(), which constructs rings of univariate and multivariate polynomials, and implements caching to prevent the same ring being created in memory multiple times (which is wasteful and breaks the general assumption in Sage that parents are unique).

There is also a function BooleanPolynomialRing_constructor(), used for constructing Boolean polynomial rings, which are not technically polynomial rings but rather quotients of them (see module sage.rings.polynomial.pbori for more details).

sage.rings.polynomial.polynomial_ring_constructor.BooleanPolynomialRing_constructor(n=None, names=None, order='lex')[source]

Construct a boolean polynomial ring with the following parameters:

INPUT:

  • n – number of variables (an integer > 1)

  • names – names of ring variables, may be a string or list/tuple of strings

  • order – term order (default: 'lex')

EXAMPLES:

sage: # needs sage.rings.polynomial.pbori
sage: R.<x, y, z> = BooleanPolynomialRing(); R  # indirect doctest
Boolean PolynomialRing in x, y, z
sage: p = x*y + x*z + y*z
sage: x*p
x*y*z + x*y + x*z
sage: R.term_order()
Lexicographic term order

sage: R = BooleanPolynomialRing(5, 'x', order='deglex(3),deglex(2)')            # needs sage.rings.polynomial.pbori
sage: R.term_order()                                                            # needs sage.rings.polynomial.pbori
Block term order with blocks:
(Degree lexicographic term order of length 3,
 Degree lexicographic term order of length 2)

sage: R = BooleanPolynomialRing(3, 'x', order='degneglex')                      # needs sage.rings.polynomial.pbori
sage: R.term_order()                                                            # needs sage.rings.polynomial.pbori
Degree negative lexicographic term order

sage: BooleanPolynomialRing(names=('x','y'))                                    # needs sage.rings.polynomial.pbori
Boolean PolynomialRing in x, y

sage: BooleanPolynomialRing(names='x,y')                                        # needs sage.rings.polynomial.pbori
Boolean PolynomialRing in x, y
>>> from sage.all import *
>>> # needs sage.rings.polynomial.pbori
>>> R = BooleanPolynomialRing(names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3); R  # indirect doctest
Boolean PolynomialRing in x, y, z
>>> p = x*y + x*z + y*z
>>> x*p
x*y*z + x*y + x*z
>>> R.term_order()
Lexicographic term order

>>> R = BooleanPolynomialRing(Integer(5), 'x', order='deglex(3),deglex(2)')            # needs sage.rings.polynomial.pbori
>>> R.term_order()                                                            # needs sage.rings.polynomial.pbori
Block term order with blocks:
(Degree lexicographic term order of length 3,
 Degree lexicographic term order of length 2)

>>> R = BooleanPolynomialRing(Integer(3), 'x', order='degneglex')                      # needs sage.rings.polynomial.pbori
>>> R.term_order()                                                            # needs sage.rings.polynomial.pbori
Degree negative lexicographic term order

>>> BooleanPolynomialRing(names=('x','y'))                                    # needs sage.rings.polynomial.pbori
Boolean PolynomialRing in x, y

>>> BooleanPolynomialRing(names='x,y')                                        # needs sage.rings.polynomial.pbori
Boolean PolynomialRing in x, y
# needs sage.rings.polynomial.pbori
R.<x, y, z> = BooleanPolynomialRing(); R  # indirect doctest
p = x*y + x*z + y*z
x*p
R.term_order()
R = BooleanPolynomialRing(5, 'x', order='deglex(3),deglex(2)')            # needs sage.rings.polynomial.pbori
R.term_order()                                                            # needs sage.rings.polynomial.pbori
R = BooleanPolynomialRing(3, 'x', order='degneglex')                      # needs sage.rings.polynomial.pbori
R.term_order()                                                            # needs sage.rings.polynomial.pbori
BooleanPolynomialRing(names=('x','y'))                                    # needs sage.rings.polynomial.pbori
BooleanPolynomialRing(names='x,y')                                        # needs sage.rings.polynomial.pbori
sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing(base_ring, *args, **kwds)[source]

Return the globally unique univariate or multivariate polynomial ring with given properties and variable name or names.

There are many ways to specify the variables for the polynomial ring:

  1. PolynomialRing(base_ring, name, ...)

  2. PolynomialRing(base_ring, names, ...)

  3. PolynomialRing(base_ring, n, names, ...)

  4. PolynomialRing(base_ring, n, ..., var_array=var_array, ...)

The ... at the end of these commands stands for additional keywords, like sparse or order.

INPUT:

  • base_ring – a ring

  • n – integer

  • name – string

  • names – list or tuple of names (strings), or a comma separated string

  • var_array – list or tuple of names, or a comma separated string

  • sparse – boolean; whether or not elements are sparse. The default is a dense representation (sparse=False) for univariate rings and a sparse representation (sparse=True) for multivariate rings.

  • order – string or TermOrder object, e.g.,

    • 'degrevlex' – default; degree reverse lexicographic

    • 'lex' – lexicographic

    • 'deglex' – degree lexicographic

    • TermOrder('deglex',3) + TermOrder('deglex',3) – block ordering

  • implementation – string or None; selects an implementation in cases where Sage includes multiple choices (currently \(\ZZ[x]\) can be implemented with 'NTL' or 'FLINT'; default is 'FLINT'). For many base rings, the 'singular' implementation is available. One can always specify implementation="generic" for a generic Sage implementation which does not use any specialized library.

Note

If the given implementation does not exist for rings with the given number of generators and the given sparsity, then an error results.

OUTPUT:

PolynomialRing(base_ring, name, sparse=False) returns a univariate polynomial ring; also, PolynomialRing(base_ring, names, sparse=False) yields a univariate polynomial ring, if names is a list or tuple providing exactly one name. All other input formats return a multivariate polynomial ring.

UNIQUENESS and IMMUTABILITY: In Sage there is exactly one single-variate polynomial ring over each base ring in each choice of variable, sparseness, and implementation. There is also exactly one multivariate polynomial ring over each base ring for each choice of names of variables and term order. The names of the generators can only be temporarily changed after the ring has been created. Do this using the localvars() context.

EXAMPLES:

1. PolynomialRing(base_ring, name, …)

sage: PolynomialRing(QQ, 'w')
Univariate Polynomial Ring in w over Rational Field
sage: PolynomialRing(QQ, name='w')
Univariate Polynomial Ring in w over Rational Field
>>> from sage.all import *
>>> PolynomialRing(QQ, 'w')
Univariate Polynomial Ring in w over Rational Field
>>> PolynomialRing(QQ, name='w')
Univariate Polynomial Ring in w over Rational Field
PolynomialRing(QQ, 'w')
PolynomialRing(QQ, name='w')

Use the diamond brackets notation to make the variable ready for use after you define the ring:

sage: R.<w> = PolynomialRing(QQ)
sage: (1 + w)^3
w^3 + 3*w^2 + 3*w + 1
>>> from sage.all import *
>>> R = PolynomialRing(QQ, names=('w',)); (w,) = R._first_ngens(1)
>>> (Integer(1) + w)**Integer(3)
w^3 + 3*w^2 + 3*w + 1
R.<w> = PolynomialRing(QQ)
(1 + w)^3

You must specify a name:

sage: PolynomialRing(QQ)
Traceback (most recent call last):
...
TypeError: you must specify the names of the variables

sage: R.<abc> = PolynomialRing(QQ, sparse=True); R
Sparse Univariate Polynomial Ring in abc over Rational Field

sage: R.<w> = PolynomialRing(PolynomialRing(GF(7),'k')); R
Univariate Polynomial Ring in w over
 Univariate Polynomial Ring in k over Finite Field of size 7
>>> from sage.all import *
>>> PolynomialRing(QQ)
Traceback (most recent call last):
...
TypeError: you must specify the names of the variables

>>> R = PolynomialRing(QQ, sparse=True, names=('abc',)); (abc,) = R._first_ngens(1); R
Sparse Univariate Polynomial Ring in abc over Rational Field

>>> R = PolynomialRing(PolynomialRing(GF(Integer(7)),'k'), names=('w',)); (w,) = R._first_ngens(1); R
Univariate Polynomial Ring in w over
 Univariate Polynomial Ring in k over Finite Field of size 7
PolynomialRing(QQ)
R.<abc> = PolynomialRing(QQ, sparse=True); R
R.<w> = PolynomialRing(PolynomialRing(GF(7),'k')); R

The square bracket notation:

sage: R.<y> = QQ['y']; R
Univariate Polynomial Ring in y over Rational Field
sage: y^2 + y
y^2 + y
>>> from sage.all import *
>>> R = QQ['y']; (y,) = R._first_ngens(1); R
Univariate Polynomial Ring in y over Rational Field
>>> y**Integer(2) + y
y^2 + y
R.<y> = QQ['y']; R
y^2 + y

In fact, since the diamond brackets on the left determine the variable name, you can omit the variable from the square brackets:

sage: R.<zz> = QQ[]; R
Univariate Polynomial Ring in zz over Rational Field
sage: (zz + 1)^2
zz^2 + 2*zz + 1
>>> from sage.all import *
>>> R = QQ['zz']; (zz,) = R._first_ngens(1); R
Univariate Polynomial Ring in zz over Rational Field
>>> (zz + Integer(1))**Integer(2)
zz^2 + 2*zz + 1
R.<zz> = QQ[]; R
(zz + 1)^2

This is exactly the same ring as what PolynomialRing returns:

sage: R is PolynomialRing(QQ, 'zz')
True
>>> from sage.all import *
>>> R is PolynomialRing(QQ, 'zz')
True
R is PolynomialRing(QQ, 'zz')

However, rings with different variables are different:

sage: QQ['x'] == QQ['y']
False
>>> from sage.all import *
>>> QQ['x'] == QQ['y']
False
QQ['x'] == QQ['y']

Sage has two implementations of univariate polynomials over the integers, one based on NTL and one based on FLINT. The default is FLINT. Note that FLINT uses a “more dense” representation for its polynomials than NTL, so in particular, creating a polynomial like 2^1000000 * x^1000000 in FLINT may be unwise.

sage: ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL              # needs sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring (using NTL)
sage: ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT        # needs sage.libs.flint
Univariate Polynomial Ring in x over Integer Ring
sage: ZxFLINT is ZZ['x']                                                        # needs sage.libs.flint
True
sage: ZxFLINT is PolynomialRing(ZZ, 'x')                                        # needs sage.libs.flint
True
sage: xNTL = ZxNTL.gen()                                                        # needs sage.libs.ntl
sage: xFLINT = ZxFLINT.gen()                                                    # needs sage.libs.flint
sage: xNTL.parent()                                                             # needs sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring (using NTL)
sage: xFLINT.parent()                                                           # needs sage.libs.flint
Univariate Polynomial Ring in x over Integer Ring
>>> from sage.all import *
>>> ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL              # needs sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring (using NTL)
>>> ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT        # needs sage.libs.flint
Univariate Polynomial Ring in x over Integer Ring
>>> ZxFLINT is ZZ['x']                                                        # needs sage.libs.flint
True
>>> ZxFLINT is PolynomialRing(ZZ, 'x')                                        # needs sage.libs.flint
True
>>> xNTL = ZxNTL.gen()                                                        # needs sage.libs.ntl
>>> xFLINT = ZxFLINT.gen()                                                    # needs sage.libs.flint
>>> xNTL.parent()                                                             # needs sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring (using NTL)
>>> xFLINT.parent()                                                           # needs sage.libs.flint
Univariate Polynomial Ring in x over Integer Ring
ZxNTL = PolynomialRing(ZZ, 'x', implementation='NTL'); ZxNTL              # needs sage.libs.ntl
ZxFLINT = PolynomialRing(ZZ, 'x', implementation='FLINT'); ZxFLINT        # needs sage.libs.flint
ZxFLINT is ZZ['x']                                                        # needs sage.libs.flint
ZxFLINT is PolynomialRing(ZZ, 'x')                                        # needs sage.libs.flint
xNTL = ZxNTL.gen()                                                        # needs sage.libs.ntl
xFLINT = ZxFLINT.gen()                                                    # needs sage.libs.flint
xNTL.parent()                                                             # needs sage.libs.ntl
xFLINT.parent()                                                           # needs sage.libs.flint

There is a coercion from the non-default to the default implementation, so the values can be mixed in a single expression:

sage: (xNTL + xFLINT^2)                                                         # needs sage.libs.flint sage.libs.ntl
x^2 + x
>>> from sage.all import *
>>> (xNTL + xFLINT**Integer(2))                                                         # needs sage.libs.flint sage.libs.ntl
x^2 + x
(xNTL + xFLINT^2)                                                         # needs sage.libs.flint sage.libs.ntl

The result of such an expression will use the default, i.e., the FLINT implementation:

sage: (xNTL + xFLINT^2).parent()                                                # needs sage.libs.flint sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring
>>> from sage.all import *
>>> (xNTL + xFLINT**Integer(2)).parent()                                                # needs sage.libs.flint sage.libs.ntl
Univariate Polynomial Ring in x over Integer Ring
(xNTL + xFLINT^2).parent()                                                # needs sage.libs.flint sage.libs.ntl

The generic implementation uses neither NTL nor FLINT:

sage: Zx = PolynomialRing(ZZ, 'x', implementation='generic'); Zx
Univariate Polynomial Ring in x over Integer Ring
sage: Zx.element_class
<... 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense'>
>>> from sage.all import *
>>> Zx = PolynomialRing(ZZ, 'x', implementation='generic'); Zx
Univariate Polynomial Ring in x over Integer Ring
>>> Zx.element_class
<... 'sage.rings.polynomial.polynomial_element.Polynomial_generic_dense'>
Zx = PolynomialRing(ZZ, 'x', implementation='generic'); Zx
Zx.element_class

2. PolynomialRing(base_ring, names, …)

sage: R = PolynomialRing(QQ, 'a,b,c'); R
Multivariate Polynomial Ring in a, b, c over Rational Field

sage: S = PolynomialRing(QQ, ['a','b','c']); S
Multivariate Polynomial Ring in a, b, c over Rational Field

sage: T = PolynomialRing(QQ, ('a','b','c')); T
Multivariate Polynomial Ring in a, b, c over Rational Field
>>> from sage.all import *
>>> R = PolynomialRing(QQ, 'a,b,c'); R
Multivariate Polynomial Ring in a, b, c over Rational Field

>>> S = PolynomialRing(QQ, ['a','b','c']); S
Multivariate Polynomial Ring in a, b, c over Rational Field

>>> T = PolynomialRing(QQ, ('a','b','c')); T
Multivariate Polynomial Ring in a, b, c over Rational Field
R = PolynomialRing(QQ, 'a,b,c'); R
S = PolynomialRing(QQ, ['a','b','c']); S
T = PolynomialRing(QQ, ('a','b','c')); T

All three rings are identical:

sage: R is S
True
sage: S is T
True
>>> from sage.all import *
>>> R is S
True
>>> S is T
True
R is S
S is T

There is a unique polynomial ring with each term order:

sage: R = PolynomialRing(QQ, 'x,y,z', order='degrevlex'); R
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: S = PolynomialRing(QQ, 'x,y,z', order='invlex'); S
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: S is PolynomialRing(QQ, 'x,y,z', order='invlex')
True
sage: R == S
False
>>> from sage.all import *
>>> R = PolynomialRing(QQ, 'x,y,z', order='degrevlex'); R
Multivariate Polynomial Ring in x, y, z over Rational Field
>>> S = PolynomialRing(QQ, 'x,y,z', order='invlex'); S
Multivariate Polynomial Ring in x, y, z over Rational Field
>>> S is PolynomialRing(QQ, 'x,y,z', order='invlex')
True
>>> R == S
False
R = PolynomialRing(QQ, 'x,y,z', order='degrevlex'); R
S = PolynomialRing(QQ, 'x,y,z', order='invlex'); S
S is PolynomialRing(QQ, 'x,y,z', order='invlex')
R == S

Note that a univariate polynomial ring is returned, if the list of names is of length one. If it is of length zero, a multivariate polynomial ring with no variables is returned.

sage: PolynomialRing(QQ,["x"])
Univariate Polynomial Ring in x over Rational Field
sage: PolynomialRing(QQ,[])
Multivariate Polynomial Ring in no variables over Rational Field
>>> from sage.all import *
>>> PolynomialRing(QQ,["x"])
Univariate Polynomial Ring in x over Rational Field
>>> PolynomialRing(QQ,[])
Multivariate Polynomial Ring in no variables over Rational Field
PolynomialRing(QQ,["x"])
PolynomialRing(QQ,[])

The Singular implementation always returns a multivariate ring, even for 1 variable:

sage: PolynomialRing(QQ, "x", implementation='singular')                        # needs sage.libs.singular
Multivariate Polynomial Ring in x over Rational Field
sage: P.<x> = PolynomialRing(QQ, implementation='singular'); P                  # needs sage.libs.singular
Multivariate Polynomial Ring in x over Rational Field
>>> from sage.all import *
>>> PolynomialRing(QQ, "x", implementation='singular')                        # needs sage.libs.singular
Multivariate Polynomial Ring in x over Rational Field
>>> P = PolynomialRing(QQ, implementation='singular', names=('x',)); (x,) = P._first_ngens(1); P                  # needs sage.libs.singular
Multivariate Polynomial Ring in x over Rational Field
PolynomialRing(QQ, "x", implementation='singular')                        # needs sage.libs.singular
P.<x> = PolynomialRing(QQ, implementation='singular'); P                  # needs sage.libs.singular

3. PolynomialRing(base_ring, n, names, …) (where the arguments n and names may be reversed)

If you specify a single name as a string and a number of variables, then variables labeled with numbers are created.

sage: PolynomialRing(QQ, 'x', 10)
Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field

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

sage: PolynomialRing(GF(7), 'y', 5)
Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7

sage: PolynomialRing(QQ, 'y', 3, sparse=True)
Multivariate Polynomial Ring in y0, y1, y2 over Rational Field
>>> from sage.all import *
>>> PolynomialRing(QQ, 'x', Integer(10))
Multivariate Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9 over Rational Field

>>> PolynomialRing(QQ, Integer(2), 'alpha0')
Multivariate Polynomial Ring in alpha00, alpha01 over Rational Field

>>> PolynomialRing(GF(Integer(7)), 'y', Integer(5))
Multivariate Polynomial Ring in y0, y1, y2, y3, y4 over Finite Field of size 7

>>> PolynomialRing(QQ, 'y', Integer(3), sparse=True)
Multivariate Polynomial Ring in y0, y1, y2 over Rational Field
PolynomialRing(QQ, 'x', 10)
PolynomialRing(QQ, 2, 'alpha0')
PolynomialRing(GF(7), 'y', 5)
PolynomialRing(QQ, 'y', 3, sparse=True)

Note that a multivariate polynomial ring is returned when an explicit number is given.

sage: PolynomialRing(QQ,"x",1)
Multivariate Polynomial Ring in x over Rational Field
sage: PolynomialRing(QQ,"x",0)
Multivariate Polynomial Ring in no variables over Rational Field
>>> from sage.all import *
>>> PolynomialRing(QQ,"x",Integer(1))
Multivariate Polynomial Ring in x over Rational Field
>>> PolynomialRing(QQ,"x",Integer(0))
Multivariate Polynomial Ring in no variables over Rational Field
PolynomialRing(QQ,"x",1)
PolynomialRing(QQ,"x",0)

It is easy in Python to create fairly arbitrary variable names. For example, here is a ring with generators labeled by the primes less than 100:

sage: R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R                 # needs sage.libs.pari
Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29,
 x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97
 over Integer Ring
>>> from sage.all import *
>>> R = PolynomialRing(ZZ, ['x%s'%p for p in primes(Integer(100))]); R                 # needs sage.libs.pari
Multivariate Polynomial Ring in x2, x3, x5, x7, x11, x13, x17, x19, x23, x29,
 x31, x37, x41, x43, x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97
 over Integer Ring
R = PolynomialRing(ZZ, ['x%s'%p for p in primes(100)]); R                 # needs sage.libs.pari

By calling the inject_variables() method, all those variable names are available for interactive use:

sage: R.inject_variables()                                                      # needs sage.libs.pari
Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43,
x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97
sage: (x2 + x41 + x71)^2                                                        # needs sage.libs.pari
x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2
>>> from sage.all import *
>>> R.inject_variables()                                                      # needs sage.libs.pari
Defining x2, x3, x5, x7, x11, x13, x17, x19, x23, x29, x31, x37, x41, x43,
x47, x53, x59, x61, x67, x71, x73, x79, x83, x89, x97
>>> (x2 + x41 + x71)**Integer(2)                                                        # needs sage.libs.pari
x2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2
R.inject_variables()                                                      # needs sage.libs.pari
(x2 + x41 + x71)^2                                                        # needs sage.libs.pari

4. PolynomialRing(base_ring, n, …, var_array=var_array, …)

This creates an array of variables where each variables begins with an entry in var_array and is indexed from 0 to \(n-1\).

sage: PolynomialRing(ZZ, 3, var_array=['x','y'])
Multivariate Polynomial Ring in x0, y0, x1, y1, x2, y2 over Integer Ring
sage: PolynomialRing(ZZ, 3, var_array='a,b')
Multivariate Polynomial Ring in a0, b0, a1, b1, a2, b2 over Integer Ring
>>> from sage.all import *
>>> PolynomialRing(ZZ, Integer(3), var_array=['x','y'])
Multivariate Polynomial Ring in x0, y0, x1, y1, x2, y2 over Integer Ring
>>> PolynomialRing(ZZ, Integer(3), var_array='a,b')
Multivariate Polynomial Ring in a0, b0, a1, b1, a2, b2 over Integer Ring
PolynomialRing(ZZ, 3, var_array=['x','y'])
PolynomialRing(ZZ, 3, var_array='a,b')

It is possible to create higher-dimensional arrays:

sage: PolynomialRing(ZZ, 2, 3, var_array=('p', 'q'))
Multivariate Polynomial Ring
 in p00, q00, p01, q01, p02, q02, p10, q10, p11, q11, p12, q12
 over Integer Ring
sage: PolynomialRing(ZZ, 2, 3, 4, var_array='m')
Multivariate Polynomial Ring in m000, m001, m002, m003, m010, m011,
 m012, m013, m020, m021, m022, m023, m100, m101, m102, m103, m110,
 m111, m112, m113, m120, m121, m122, m123 over Integer Ring
>>> from sage.all import *
>>> PolynomialRing(ZZ, Integer(2), Integer(3), var_array=('p', 'q'))
Multivariate Polynomial Ring
 in p00, q00, p01, q01, p02, q02, p10, q10, p11, q11, p12, q12
 over Integer Ring
>>> PolynomialRing(ZZ, Integer(2), Integer(3), Integer(4), var_array='m')
Multivariate Polynomial Ring in m000, m001, m002, m003, m010, m011,
 m012, m013, m020, m021, m022, m023, m100, m101, m102, m103, m110,
 m111, m112, m113, m120, m121, m122, m123 over Integer Ring
PolynomialRing(ZZ, 2, 3, var_array=('p', 'q'))
PolynomialRing(ZZ, 2, 3, 4, var_array='m')

The array is always at least 2-dimensional. So, if var_array is a single string and only a single number \(n\) is given, this creates an \(n \times n\) array of variables:

sage: PolynomialRing(ZZ, 2, var_array='m')
Multivariate Polynomial Ring in m00, m01, m10, m11 over Integer Ring
>>> from sage.all import *
>>> PolynomialRing(ZZ, Integer(2), var_array='m')
Multivariate Polynomial Ring in m00, m01, m10, m11 over Integer Ring
PolynomialRing(ZZ, 2, var_array='m')

Square brackets notation

You can alternatively create a polynomial ring over a ring \(R\) with square brackets:

sage: # needs sage.rings.real_mpfr
sage: RR["x"]
Univariate Polynomial Ring in x over Real Field with 53 bits of precision
sage: RR["x,y"]
Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision
sage: P.<x,y> = RR[]; P
Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision
>>> from sage.all import *
>>> # needs sage.rings.real_mpfr
>>> RR["x"]
Univariate Polynomial Ring in x over Real Field with 53 bits of precision
>>> RR["x,y"]
Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision
>>> P = RR['x, y']; (x, y,) = P._first_ngens(2); P
Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision
# needs sage.rings.real_mpfr
RR["x"]
RR["x,y"]
P.<x,y> = RR[]; P

This notation does not allow to set any of the optional arguments.

Changing variable names

Consider

sage: R.<x,y> = PolynomialRing(QQ, 2); R
Multivariate Polynomial Ring in x, y over Rational Field
sage: f = x^2 - 2*y^2
>>> from sage.all import *
>>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2); R
Multivariate Polynomial Ring in x, y over Rational Field
>>> f = x**Integer(2) - Integer(2)*y**Integer(2)
R.<x,y> = PolynomialRing(QQ, 2); R
f = x^2 - 2*y^2

You can’t just globally change the names of those variables. This is because objects all over Sage could have pointers to that polynomial ring.

sage: R._assign_names(['z','w'])
Traceback (most recent call last):
...
ValueError: variable names cannot be changed after object creation.
>>> from sage.all import *
>>> R._assign_names(['z','w'])
Traceback (most recent call last):
...
ValueError: variable names cannot be changed after object creation.
R._assign_names(['z','w'])

However, you can very easily change the names within a with block:

sage: with localvars(R, ['z','w']):
....:     print(f)
z^2 - 2*w^2
>>> from sage.all import *
>>> with localvars(R, ['z','w']):
...     print(f)
z^2 - 2*w^2
with localvars(R, ['z','w']):
    print(f)

After the with block the names revert to what they were before:

sage: print(f)
x^2 - 2*y^2
>>> from sage.all import *
>>> print(f)
x^2 - 2*y^2
print(f)
sage.rings.polynomial.polynomial_ring_constructor.polynomial_default_category(n_variables)[source]

Choose an appropriate category for a polynomial ring.

It is assumed that the corresponding base ring is nonzero.

INPUT:

  • base_ring_category – the category of ring over which the polynomial ring shall be defined

  • n_variables – number of variables

EXAMPLES:

sage: from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category
sage: polynomial_default_category(Rings(), 1)
Category of infinite algebras with basis over rings
sage: polynomial_default_category(Rings().Commutative(), 1)
Category of infinite commutative algebras with basis
    over commutative rings
sage: polynomial_default_category(Fields(), 1)
Join of Category of euclidean domains
    and Category of algebras with basis over fields
    and Category of commutative algebras over fields
    and Category of infinite sets
sage: polynomial_default_category(Fields(), 2)
Join of Category of unique factorization domains
    and Category of algebras with basis over fields
    and Category of commutative algebras over fields
    and Category of infinite sets

sage: QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
True
sage: QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
True
sage: QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).WithBasis().Infinite()
True
>>> from sage.all import *
>>> from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category
>>> polynomial_default_category(Rings(), Integer(1))
Category of infinite algebras with basis over rings
>>> polynomial_default_category(Rings().Commutative(), Integer(1))
Category of infinite commutative algebras with basis
    over commutative rings
>>> polynomial_default_category(Fields(), Integer(1))
Join of Category of euclidean domains
    and Category of algebras with basis over fields
    and Category of commutative algebras over fields
    and Category of infinite sets
>>> polynomial_default_category(Fields(), Integer(2))
Join of Category of unique factorization domains
    and Category of algebras with basis over fields
    and Category of commutative algebras over fields
    and Category of infinite sets

>>> QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
True
>>> QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
True
>>> QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).WithBasis().Infinite()
True
from sage.rings.polynomial.polynomial_ring_constructor import polynomial_default_category
polynomial_default_category(Rings(), 1)
polynomial_default_category(Rings().Commutative(), 1)
polynomial_default_category(Fields(), 1)
polynomial_default_category(Fields(), 2)
QQ['t'].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
QQ['s','t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ.category()).WithBasis().Infinite()
QQ['s']['t'].category() is UniqueFactorizationDomains() & CommutativeAlgebras(QQ['s'].category()).WithBasis().Infinite()
sage.rings.polynomial.polynomial_ring_constructor.unpickle_PolynomialRing(base_ring, arg1=None, arg2=None, sparse=False)[source]

Custom unpickling function for polynomial rings.

This has the same positional arguments as the old PolynomialRing constructor before Issue #23338.