28.1 Univariate Polynomial Rings

Module: sage.rings.polynomial.polynomial_ring

Univariate Polynomial Rings

SAGE implements sparse and dense polynomials over commutative and non-commutative rings. In the non-commutative case, the polynomial variable commutes with the elements of the base ring.

Author Log:

Creating a polynomial ring injects the variable into the interpreter namespace:

sage: z = QQ['z'].0
sage: (z^3 + z - 1)^3
z^9 + 3*z^7 - 3*z^6 + 3*z^5 - 6*z^4 + 4*z^3 - 3*z^2 + 3*z - 1

Saving and loading of polynomial rings works:

sage: loads(dumps(QQ['x'])) == QQ['x']
True
sage: k = PolynomialRing(QQ['x'],'y'); loads(dumps(k))==k
True    
sage: k = PolynomialRing(ZZ,'y'); loads(dumps(k)) == k
True
sage: k = PolynomialRing(ZZ,'y', sparse=True); loads(dumps(k))
Sparse Univariate Polynomial Ring in y over Integer Ring

The rings of sparse and dense polynomials in the same variable are canonically isomorphic:

sage: PolynomialRing(ZZ,'y', sparse=True) == PolynomialRing(ZZ,'y')
True

sage: QQ['y'] < QQ['x']
False
sage: QQ['y'] < QQ['z']
True

We create a polynomial ring over a quaternion algebra:

sage: A.<i,j,k> = QuaternionAlgebra(QQ, -1,-1)
sage: R.<w> = PolynomialRing(A,sparse=True)
sage: f = w^3 + (i+j)*w + 1
sage: f
w^3 + (i + j)*w + 1
sage: f^2
w^6 + (2*i + 2*j)*w^4 + 2*w^3 + (-2)*w^2 + (2*i + 2*j)*w + 1
sage: f = w + i ; g = w + j
sage: f * g
w^2 + (i + j)*w + k
sage: g * f
w^2 + (i + j)*w + -k

TESTS:

sage: K.<x>=FractionField(QQ['x'])
sage: V.<z> = K[]
sage: x+z
z + x

Module-level Functions

is_PolynomialRing( x)

Return True if x is a *univariate* polynomial ring (and not a sparse multivariate polynomial ring in one variable).

sage: is_PolynomialRing(2)
False

This polynomial ring is not univariate.

sage: is_PolynomialRing(ZZ['x,y,z'])
False
sage: is_MPolynomialRing(ZZ['x,y,z']) 
True

sage: is_PolynomialRing(ZZ['w']) 
True

Univariate means not only in one variable, but is a specific data type. There is a multivariate (sparse) polynomial ring data type, which supports a single variable as a special case.

sage: is_PolynomialRing(PolynomialRing(ZZ,1,'w'))
False
sage: R = PolynomialRing(ZZ,1,'w'); R
Multivariate Polynomial Ring in w over Integer Ring
sage: is_PolynomialRing(R)
False    
sage: type(R)
<class 'sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydic
t_domain'>

polygen( ring_or_element, [name=x])

Return a polynomial indeterminate.

Input: * polygen(base_ring, name="x") * polygen(ring_element, name="x")

If the first input is a ring, return a polynomial generator over that ring. If it is a ring element, return a polynomial generator over the parent of the element.

sage: z = polygen(QQ,'z')
sage: z^3 + z +1
z^3 + z + 1
sage: parent(z)
Univariate Polynomial Ring in z over Rational Field

NOTE: If you give a list or comma separated string to polygen, you'll get a tuple of indeterminates, exactly as if you called polygens.

polygens( base_ring, [names=x])

Return indeterminates over the given base ring with the given names.

sage: x,y,z = polygens(QQ,'x,y,z')
sage: (x+y+z)^2
x^2 + 2*x*y + y^2 + 2*x*z + 2*y*z + z^2
sage: parent(x)
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: t = polygens(QQ,['x','yz','abc'])
sage: t
(x, yz, abc)

Class: PolynomialRing_commutative

class PolynomialRing_commutative
Univariate polynomial ring over a commutative ring.
PolynomialRing_commutative( self, base_ring, [name=None], [sparse=False], [implementation=None])

Functions: quotient_by_principal_ideal

quotient_by_principal_ideal( self, f, [names=None])

Return the quotient of this polynomial ring by the principal ideal generated by $ f$ .

Special Functions: __init__

Class: PolynomialRing_dense_mod_n

class PolynomialRing_dense_mod_n
PolynomialRing_dense_mod_n( self, base_ring, [name=x])

Functions: modulus

Special Functions: __call__,$ \,$ __init__

Class: PolynomialRing_dense_mod_p

class PolynomialRing_dense_mod_p
PolynomialRing_dense_mod_p( self, base_ring, [name=x])

Special Functions: __call__,$ \,$ __init__

Class: PolynomialRing_dense_padic_field_capped_relative

class PolynomialRing_dense_padic_field_capped_relative

Class: PolynomialRing_dense_padic_field_generic

class PolynomialRing_dense_padic_field_generic
PolynomialRing_dense_padic_field_generic( self, base_ring, [name=None])

Special Functions: __init__

Class: PolynomialRing_dense_padic_field_lazy

class PolynomialRing_dense_padic_field_lazy

Class: PolynomialRing_dense_padic_ring_capped_absolute

class PolynomialRing_dense_padic_ring_capped_absolute

Class: PolynomialRing_dense_padic_ring_capped_relative

class PolynomialRing_dense_padic_ring_capped_relative

Class: PolynomialRing_dense_padic_ring_fixed_mod

class PolynomialRing_dense_padic_ring_fixed_mod

Class: PolynomialRing_dense_padic_ring_generic

class PolynomialRing_dense_padic_ring_generic
PolynomialRing_dense_padic_ring_generic( self, base_ring, [name=None])

Special Functions: __init__

Class: PolynomialRing_dense_padic_ring_lazy

class PolynomialRing_dense_padic_ring_lazy

Class: PolynomialRing_field

class PolynomialRing_field
PolynomialRing_field( self, base_ring, [name=x], [sparse=False])

Functions: lagrange_polynomial

lagrange_polynomial( self, points)

Return the Lagrange interpolation polynomial in self associated to the given list of points.

Given a list of points, i.e. tuples of elements of self's base ring, this function returns the interpolation polynomial in the Lagrange form.

Input:

points
- a list of tuples representing points through which the polynomial returned by this function must pass.

sage: R = PolynomialRing(QQ, 'x')
sage: f = R.lagrange_polynomial([(0,1),(2,2),(3,-2),(-4,9)]);f
-23/84*x^3 - 11/84*x^2 + 13/7*x + 1
sage: f(0)
1
sage: f(2)
2
sage: f(3)
-2
sage: f(-4)
9
sage: R = PolynomialRing(GF(2**3,'a'), 'x')
sage: a = R.base_ring().gen()
sage: f = R.lagrange_polynomial([(a^2+a,a),(a,1),(a^2,a^2+a+1)]); f
a^2*x^2 + a^2*x + a^2
sage: f(a^2+a)
a
sage: f(a)
1
sage: f(a^2)
a^2 + a + 1

NOTE: This is a straight forward Lagrange construction and no measures were taken to optimize it. (If you need something that is highly optimized, consider implementing it and including it with SAGE.)

Special Functions: __init__

Class: PolynomialRing_general

class PolynomialRing_general
Univariate polynomial ring over a ring.
PolynomialRing_general( self, base_ring, [name=None], [sparse=False], [implementation=None])

sage: R.<x> = QQ['x']
sage: R(-1) + R(1)
0
sage: (x - 2/3)*(x^2 - 8*x + 16)
x^3 - 26/3*x^2 + 64/3*x - 32/3

Functions: base_extend,$ \,$ change_ring,$ \,$ change_var,$ \,$ characteristic,$ \,$ completion,$ \,$ construction,$ \,$ cyclotomic_polynomial,$ \,$ extend_variables,$ \,$ gen,$ \,$ is_exact,$ \,$ is_field,$ \,$ is_finite,$ \,$ is_integral_domain,$ \,$ is_noetherian,$ \,$ is_sparse,$ \,$ krull_dimension,$ \,$ monics,$ \,$ ngens,$ \,$ parameter,$ \,$ polynomials,$ \,$ random_element,$ \,$ variable_names_recursive

base_extend( self, R)

Return the base extension of this polynomial ring to R.

sage: R.<x> = RR[]; R
Univariate Polynomial Ring in x over Real Field with 53 bits of precision
sage: R.base_extend(CC)
Univariate Polynomial Ring in x over Complex Field with 53 bits of
precision
sage: R.base_extend(QQ)
Traceback (most recent call last):
...
TypeError: no such base extension
sage: R.change_ring(QQ)
Univariate Polynomial Ring in x over Rational Field

change_ring( self, R)

Return the polynomial ring in the same variable as self over R.

sage: R.<ZZZ> = RealIntervalField() []; R
Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of
precision
sage: R.change_ring(GF(19^2,'b'))
Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2

change_var( self, var)

Return the polynomial ring in variable var over the same base ring.

sage: R.<x> = ZZ[]; R
Univariate Polynomial Ring in x over Integer Ring
sage: R.change_var('y')
Univariate Polynomial Ring in y over Integer Ring

characteristic( self)

Return the characteristic of this polynomial ring, which is the same as that of its base ring.

sage: R.<ZZZ> = RealIntervalField() []; R
Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of
precision
sage: R.characteristic()
0
sage: S = R.change_ring(GF(19^2,'b')); S
Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2
sage: S.characteristic()
19

completion( self, p, [prec=20], [extras=None])

Return the completion of self with respect to the irreducible polynomial p. Currently only implemented for p=self.gen(), i.e. you can only cimplete R[x] with respect to x, the result being a rings of power series in x. The prec variable controls the precision used in the power series ring.

sage: P.<x>=PolynomialRing(QQ)
sage: P
Univariate Polynomial Ring in x over Rational Field
sage: PP=P.completion(x)
sage: PP
Power Series Ring in x over Rational Field
sage: f=1-x
sage: PP(f)
1 - x
sage: 1/f
1/(-x + 1)
sage: 1/PP(f)
1 + x + x^2 + x^3 + x^4 + x^5 + x^6 + x^7 + x^8 + x^9 + x^10 + x^11 + x^12
+ x^13 + x^14 + x^15 + x^16 + x^17 + x^18 + x^19 + O(x^20)

cyclotomic_polynomial( self, n)

Return the nth cyclotomic polynomial as a polynomial in this polynomial ring.

sage: R = ZZ['x']
sage: R.cyclotomic_polynomial(8)
x^4 + 1
sage: R.cyclotomic_polynomial(12)
x^4 - x^2 + 1
sage: S = PolynomialRing(FiniteField(7), 'x')
sage: S.cyclotomic_polynomial(12)
x^4 + 6*x^2 + 1
sage: S.cyclotomic_polynomial(1)
x + 6

TESTS:

Make sure it agrees with other systems for the trivial case:

sage: ZZ['x'].cyclotomic_polynomial(1)
x - 1
sage: gp('polcyclo(1)')
x - 1

extend_variables( self, added_names, [order=degrevlex])

Returns a multivariate polynomial ring with the same base ring but with added_names as additional variables.

sage: R.<x> = ZZ[]; R
Univariate Polynomial Ring in x over Integer Ring
sage: R.extend_variables('y, z')
Multivariate Polynomial Ring in x, y, z over Integer Ring
sage: R.extend_variables(('y', 'z'))
Multivariate Polynomial Ring in x, y, z over Integer Ring

gen( self, [n=0])

Return the indeterminate generator of this polynomial ring.

sage: R.<abc> = Integers(8)[]; R
Univariate Polynomial Ring in abc over Ring of integers modulo 8
sage: t = R.gen(); t
abc
sage: t.is_gen()
True

An identical generator is always returned.

sage: t is R.gen()
True

is_field( self)

Return False, since polynomial rings are never fields.

sage: R.<z> = Integers(2)[]; R
Univariate Polynomial Ring in z over Ring of integers modulo 2
sage: R.is_field()
False

is_finite( self)

Return False since polynomial rings are not finite (unless the base ring is 0.)

sage: R = Integers(1)['x']
sage: R.is_finite()
True
sage: R = GF(7)['x']
sage: R.is_finite()
False
sage: R['x']['y'].is_finite()
False

is_integral_domain( self)

sage: ZZ['x'].is_integral_domain()
True
sage: Integers(8)['x'].is_integral_domain()
False

is_sparse( self)

Return true if elements of this polynomial ring have a sparse representation.

sage: R.<z> = Integers(8)[]; R
Univariate Polynomial Ring in z over Ring of integers modulo 8
sage: R.is_sparse()
False
sage: R.<W> = PolynomialRing(QQ, sparse=True); R
Sparse Univariate Polynomial Ring in W over Rational Field
sage: R.is_sparse()
True

krull_dimension( self)

Return the Krull dimension of this polynomial ring, which is one more than the Krull dimension of the base ring.

sage: R.<x> = QQ[]
sage: R.krull_dimension()
1
sage: R.<z> = GF(9,'a')[]; R
Univariate Polynomial Ring in z over Finite Field in a of size 3^2
sage: R.krull_dimension()
1
sage: S.<t> = R[]
sage: S.krull_dimension()
2
sage: for n in range(10):
...    S = PolynomialRing(S,'w')
sage: S.krull_dimension()
12

monics( self, [of_degree=None], [max_degree=None])

Return an iterator over the monic polynomials of specified degree.

Input: Pass exactly one of:

max_degree
- an int; the iterator will generate all monic polynomials which have degree less than or equal to max_degree
of_degree
- an int; the iterator will generate all monic polynomials which have degree of_degree

Output: an iterator

sage: P = PolynomialRing(GF(4,'a'),'y')
sage: for p in P.monics( of_degree = 2 ): print p
y^2
y^2 + a
y^2 + a + 1
y^2 + 1
y^2 + a*y
y^2 + a*y + a
y^2 + a*y + a + 1
y^2 + a*y + 1
y^2 + (a + 1)*y
y^2 + (a + 1)*y + a
y^2 + (a + 1)*y + a + 1
y^2 + (a + 1)*y + 1
y^2 + y
y^2 + y + a
y^2 + y + a + 1
y^2 + y + 1
sage: for p in P.monics( max_degree = 1 ): print p
1
y
y + a
y + a + 1
y + 1
sage: for p in P.monics( max_degree = 1, of_degree = 3 ): print p
Traceback (most recent call last):
...
ValueError: you should pass exactly one of of_degree and max_degree

Author: Joel B. Mohler

ngens( self)

Return the number of generators of this polynomial ring, which is 1 since it is a univariate polynomial ring.

sage: R.<z> = Integers(8)[]; R
Univariate Polynomial Ring in z over Ring of integers modulo 8
sage: R.ngens()
1

parameter( self)

Return the generator of this polynomial ring.

This is the same as self.gen().

polynomials( self, [of_degree=None], [max_degree=None])

Return an iterator over the polynomials of specified degree.

Input: Pass exactly one of:

max_degree
- an int; the iterator will generate all polynomials which have degree less than or equal to max_degree
of_degree
- an int; the iterator will generate all polynomials which have degree of_degree

Output: an iterator

sage: P = PolynomialRing(GF(3),'y')
sage: for p in P.polynomials( of_degree = 2 ): print p
y^2
y^2 + 1
y^2 + 2
y^2 + y
y^2 + y + 1
y^2 + y + 2
y^2 + 2*y
y^2 + 2*y + 1
y^2 + 2*y + 2
2*y^2
2*y^2 + 1
2*y^2 + 2
2*y^2 + y
2*y^2 + y + 1
2*y^2 + y + 2
2*y^2 + 2*y
2*y^2 + 2*y + 1
2*y^2 + 2*y + 2
sage: for p in P.polynomials( max_degree = 1 ): print p
0
1
2
y
y + 1
y + 2
2*y
2*y + 1
2*y + 2
sage: for p in P.polynomials( max_degree = 1, of_degree = 3 ): print p
Traceback (most recent call last):
...
ValueError: you should pass exactly one of of_degree and max_degree

Author: Joel B. Mohler

random_element( self, [degree=2])

Return a random polynomial.

Input:

degree
- an integer
*args, **kwds
- passed onto the random_element method for the base ring.

Output:
Polynomial
- A polynomial such that the coefficient of $ x^i$ , for $ i$ up to degree, are coercions to the base ring of random integers between -bound and bound.

sage: R.<x> = ZZ[]
sage: R.random_element(10, 5,10)
9*x^10 + 8*x^9 + 6*x^8 + 8*x^7 + 8*x^6 + 9*x^5 + 8*x^4 + 8*x^3 + 6*x^2 +
8*x + 8
sage: R.random_element(6)
x^6 - 3*x^5 - x^4 + x^3 - x^2 + x + 1
sage: R.random_element(6)
-2*x^5 + 2*x^4 - 3*x^3 + 1
sage: R.random_element(6)
x^4 - x^3 + x - 2

variable_names_recursive( self, [depth=+Infinity])

Returns the list of variable names of this and its baserings, as if it were a single multi-variate polynomial.

sage: R = QQ['x']['y']['z']
sage: R.variable_names_recursive()
('x', 'y', 'z')
sage: R.variable_names_recursive(2)
('y', 'z')

Special Functions: __call__,$ \,$ __cmp__,$ \,$ __init__,$ \,$ __reduce__,$ \,$ _coerce_impl,$ \,$ _gap_,$ \,$ _gap_init_,$ \,$ _is_valid_homomorphism_,$ \,$ _latex_,$ \,$ _magma_,$ \,$ _magma_init_,$ \,$ _monics_degree,$ \,$ _monics_max,$ \,$ _mpoly_base_ring,$ \,$ _PolynomialRing_general__set_polynomial_class,$ \,$ _polys_degree,$ \,$ _polys_max,$ \,$ _repr_

__call__( self, [x=None], [check=True], [is_gen=False], [construct=False], [absprec=None])

Coerce x into this univariate polynomial ring, possibly non-canonically.

Stacked polynomial rings coerce into constants if possible. First, the univariate case:

sage: R.<x> = QQ[]
sage: S.<u> = R[]
sage: S(u + 2)
u + 2
sage: S(x + 3)
x + 3
sage: S(x + 3).degree()
0

Second, the multivariate case:

sage: R.<x,y> = QQ[]
sage: S.<u> = R[]
sage: S(x + 2*y)
x + 2*y
sage: S(x + 2*y).degree()
0
sage: S(u + 2*x)
u + 2*x
sage: S(u + 2*x).degree()
1

Foreign polynomial rings coerce into the highest ring; the point here is that an element of T could coerce to an element of R or an element of S; it is anticipated that an element of T is more likely to be "the right thing" and is historically consistent.

sage: R.<x> = QQ[]
sage: S.<u> = R[]
sage: T.<a> = QQ[]
sage: S(a)
u

Coercing in pari elements:

sage: QQ['x'](pari('[1,2,3/5]'))
3/5*x^2 + 2*x + 1
sage: QQ['x'](pari('(-1/3)*x^10 + (2/3)*x - 1/5'))
-1/3*x^10 + 2/3*x - 1/5

Coercing strings:

sage: QQ['y']('-y')
-y

_coerce_impl( self, x)

Return the canonical coercion of x to this polynomial ring, if one is defined, or raise a TypeError.

The rings that canonically coerce to this polynomial ring are: * this ring itself * any ring that canonically coerces to the base ring of this ring. * polynomial rings in the same variable over any base ring that canonically coerces to the base ring of this ring

_gap_( self, [G=None])

Used in converting this ring to the corresponding ring in GAP.

sage: R.<z> = ZZ[]
sage: gap(R)
PolynomialRing( Integers, ["z"] )
sage: gap(z^2 + z)
z^2+z

_latex_( self)

sage: S.<alpha12>=ZZ[]
sage: latex(S)
\mathbf{Z}[\alpha_{12}]

_magma_( self, [G=None])

Used in converting this ring to the corresponding ring in MAGMA.

sage: R.<y> = PolynomialRing(QQ)
sage: S = magma(R) #optional
sage: print S #optional
Univariate Polynomial Ring in y over Rational Field
sage: S.1 #optional
y

sage: magma(PolynomialRing(GF(7), 'x')) #optional
Univariate Polynomial Ring in x over GF(7)

sage: magma(PolynomialRing(GF(49,'a'), 'x')) #optional
Univariate Polynomial Ring in x over GF(7^2)

sage: magma(PolynomialRing(PolynomialRing(ZZ,'w'), 'x')) #optional
Univariate Polynomial Ring in x over Univariate Polynomial Ring over
Integer Ring

_monics_degree( self, of_degree)

Refer to monics() for full documentation.

_monics_max( self, max_degree)

Refer to monics() for full documentation.

_mpoly_base_ring( self, [variables=None])

Returns the basering if this is viewed as a polynomial ring over variables. See also Polynomial._mpoly_dict_recursive

_polys_degree( self, of_degree)

Refer to polynomials() for full documentation.

_polys_max( self, max_degree)

Refer to polynomials() for full documentation.

Class: PolynomialRing_integral_domain

class PolynomialRing_integral_domain
PolynomialRing_integral_domain( self, base_ring, [name=x], [sparse=False], [implementation=None])

Special Functions: __init__

See About this document... for information on suggesting changes.