Polynomials
Release 10.4

The Sage Development TeamJul 23, 2024

CONTENTS

1

Polynomial Rings

1

2

Univariate Polynomials

15

3

Multivariate Polynomials

457

4

Rational Functions

913

5

Laurent Polynomials

945

6

Infinite Polynomial Rings

989

7

Boolean Polynomials

1047

8

Indices and Tables

1049

Python Module Index

1051

Index

1053

i

ii

CHAPTERONEPOLYNOMIAL RINGS

1.1 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 andbreaks 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=Noorder='lex')
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
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# indirect doctest

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 )

#␣
#␣

#␣
(continues on next page)1

Polynomials, Release 10.4

(continued from previous page)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 ,˓→ngens(3); R# indirect doctest
Boolean PolynomialRing in x, y, z>>> p = x*y + x*z + y*z>>> x*px*y*z + x*y + x*z>>> R.term_order()
Lexicographic term ordery ,z ,)); (x, y, z,) = R._first_>>> 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#␣sage.rings.polynomial.polynomial_ring_constructor.PolynomialRing(base_ring, *args,**kwds)Return the globally unique univariate or multivariate polynomial ring with given properties and variable name ornames.
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, ...)
2

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

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 – an integer• name – a string• names – a list or tuple of names (strings), or a comma separated string• var_array – a list or tuple of names, or a comma separated string• sparse – bool: 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 Z[𝑥] 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 basering 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 canonly 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

1.1. Constructors for polynomial rings3Polynomials, Release 10.4

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)^3w^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

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

The square bracket notation:
sage: R.<y> = QQ[ y ]; R
Univariate Polynomial Ring in y over Rational Field
sage: y^2 + yy^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) + yy^2 + yIn fact, since the diamond brackets on the left determine the variable name, you can omit the variable from thesquare brackets:

4

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

sage: R.<zz> = QQ[]; R
Univariate Polynomial Ring in zz over Rational Field
sage: (zz + 1)^2zz^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

This is exactly the same ring as what PolynomialRing returns:
sage: R is PolynomialRing(QQ,
True>>> from sage.all import *>>> R is PolynomialRing(QQ,
True

zz )

zz )

However, rings with different variables are different:
sage: QQ[ x ] == QQ[ y ]False>>> from sage.all import *>>> QQ[ x ] == QQ[ y ]FalseSage 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 Ringsage: 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

1.1. Constructors for polynomial rings

#␣

#␣

#␣

#␣

#␣
#␣
#␣

#␣

5

Polynomials, Release 10.4>>> 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

#␣

#␣

#␣

#␣

#␣
#␣
#␣

#␣

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␣

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␣

The generic implementation uses neither NTL nor FLINT:
sage: Zx = PolynomialRing(ZZ, x , implementation= generic ); Zx
Univariate Polynomial Ring in x over Integer Ringsage: Zx.element_class<... sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >>>> from sage.all import *>>> Zx = PolynomialRing(ZZ,x , implementation= generic ); Zx(continues on next page)

6

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

Univariate Polynomial Ring in x over Integer Ring>>> Zx.element_class<... sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >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

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

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 )Truesage: 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 )(continues on next page)

1.1. Constructors for polynomial rings

7

Polynomials, Release 10.4

(continued from previous page)True>>> R == S
False

Note that a univariate polynomial ring is returned, if the list of names is of length one. If it is of length zero, amultivariate 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

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

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(continues on next page)

8

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> 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

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

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␣

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.parix2^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)

#␣

#␣

#␣

␣

(continues on next page)

1.1. Constructors for polynomial rings

9

Polynomials, Release 10.4

(continued from previous page)# needs sage.libs.parix2^2 + 2*x2*x41 + x41^2 + 2*x2*x71 + 2*x41*x71 + x71^2
˓→

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 from0 to 𝑛 − 1.
sage: PolynomialRing(ZZ, 3, var_array=[ x , y ])Multivariate Polynomial Ring in x0, y0, x1, y1, x2, y2 over Integer Ringsage: 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

It is possible to create higher-dimensional arrays:
sage: PolynomialRing(ZZ, 2, 3, var_array=( p , q ))Multivariate Polynomial Ringin p00, q00, p01, q01, p02, q02, p10, q10, p11, q11, p12, q12
over Integer Ringsage: 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 Ringin 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

The array is always at least 2-dimensional. So, if var_array is a single string and only a single number 𝑛 isgiven, this creates an 𝑛 × 𝑛 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

Square brackets notation
You can alternatively create a polynomial ring over a ring 𝑅 with square brackets:sage: # needs sage.rings.real_mpfr
sage: RR["x"](continues on next page)10

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

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 precisionThis notation does not allow to set any of the optional arguments.
Changing variable names
Considersage: 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)You can’t just globally change the names of those variables. This is because objects all over Sage could have pointersto 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.

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

1.1. Constructors for polynomial rings

11

Polynomials, Release 10.4

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^2sage.rings.polynomial.polynomial_ring_constructor.polynomial_default_category(n_variables)
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) is Algebras(Rings()).Infinite()True
sage: polynomial_default_category(Rings().Commutative(),1) is Algebras(Rings().
˓→Commutative()).Commutative().Infinite()True
sage: polynomial_default_category(Fields(),1) is EuclideanDomains() &␣˓→Algebras(Fields()).Infinite()True
sage: polynomial_default_category(Fields(),2) is UniqueFactorizationDomains() &␣˓→CommutativeAlgebras(Fields()).Infinite()True
sage: QQ[ t ].category() is EuclideanDomains() & CommutativeAlgebras(QQ.
˓→category()).Infinite()True
sage: QQ[ s , t ].category() is UniqueFactorizationDomains() &␣˓→CommutativeAlgebras(QQ.category()).Infinite()True
sage: QQ[ s ][ t ].category() is UniqueFactorizationDomains() &␣˓→CommutativeAlgebras(QQ[ s ].category()).Infinite()True>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_ring_constructor import polynomial_
˓→default_category>>> polynomial_default_category(Rings(),Integer(1)) is Algebras(Rings()).
˓→Infinite()True>>> polynomial_default_category(Rings().Commutative(),Integer(1)) is␣
˓→Algebras(Rings().Commutative()).Commutative().Infinite()True>>> polynomial_default_category(Fields(),Integer(1)) is EuclideanDomains() &␣˓→Algebras(Fields()).Infinite()(continues on next page)

12

Chapter 1. Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)True>>> polynomial_default_category(Fields(),Integer(2)) is␣
˓→UniqueFactorizationDomains() & CommutativeAlgebras(Fields()).Infinite()
True>>> QQ[ t ].category() is EuclideanDomains() & CommutativeAlgebras(QQ.category()).
˓→Infinite()
True>>> QQ[ s , t ].category() is UniqueFactorizationDomains() &␣˓→CommutativeAlgebras(QQ.category()).Infinite()
True>>> QQ[ s ][ t ].category() is UniqueFactorizationDomains() &␣˓→CommutativeAlgebras(QQ[ s ].category()).Infinite()True

sage.rings.polynomial.polynomial_ring_constructor.unpickle_PolynomialRing(base_ring,arg1=None,arg2=None,sparse=False)
Custom unpickling function for polynomial rings.
This has the same positional arguments as the old PolynomialRing constructor before Issue #23338.

1.1. Constructors for polynomial rings

13

Polynomials, Release 10.4

14Chapter 1. Polynomial Rings

CHAPTERTWOUNIVARIATE POLYNOMIALS

2.1 Univariate Polynomials and Polynomial Rings
Sage’s architecture for polynomials ‘under the hood’ is complex, interfacing to a variety of C/C++ libraries for polynomials
over specific rings. In practice, the user rarely has to worry about which backend is being used.
The hierarchy of class inheritance is somewhat confusing, since most of the polynomial element classes are implemented
as Cython extension types rather than pure Python classes and thus can only inherit from a single base class, whereas
others have multiple bases.

2.1.1 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:• William Stein• Kiran Kedlaya (2006-02-13): added macaulay2 option• Martin Albrecht (2006-08-25): removed it again as it isn’t needed anymore• Simon King (2011-05): Dense and sparse polynomial rings must not be equal.
• Simon King (2011-10): Choice of categories for polynomial rings.
EXAMPLES:
sage: z = QQ[ z ].0
sage: (z^3 + z - 1)^3z^9 + 3*z^7 - 3*z^6 + 3*z^5 - 6*z^4 + 4*z^3 - 3*z^2 + 3*z - 1>>> from sage.all import *>>> z = QQ[ z ].gen(0)>>> (z**Integer(3) + z - Integer(1))**Integer(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 ]Truesage: k = PolynomialRing(QQ[ x ], y ); loads(dumps(k))==k
True(continues on next page)

15

Polynomials, Release 10.4

(continued from previous page)

sage: k = PolynomialRing(ZZ, y ); loads(dumps(k)) == kTruesage: k = PolynomialRing(ZZ, y , sparse=True); loads(dumps(k))
Sparse Univariate Polynomial Ring in y over Integer Ring>>> from sage.all import *>>> loads(dumps(QQ[ x ])) == QQ[ x ]True>>> k = PolynomialRing(QQ[ x ], y ); loads(dumps(k))==k
True>>> k = PolynomialRing(ZZ, y ); loads(dumps(k)) == k
True>>> k = PolynomialRing(ZZ, y , sparse=True); loads(dumps(k))
Sparse Univariate Polynomial Ring in y over Integer Ring

Rings with different variable names are not equal; in fact, by Issue #9944, polynomial rings are equal if and only if they
are identical (which should be the case for all parent structures in Sage):sage: QQ[ y ] != QQ[ x ]Truesage: QQ[ y ] != QQ[ z ]True>>> from sage.all import *>>> QQ[ y ] != QQ[ x ]True>>> QQ[ y ] != QQ[ z ]TrueWe create a polynomial ring over a quaternion algebra:
sage: # needs sage.combinat sage.modules
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: fw^3 + (i + j)*w + 1
sage: f^2w^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 * gw^2 + (i + j)*w + k
sage: g * fw^2 + (i + j)*w - k>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = QuaternionAlgebra(QQ, -Integer(1),-Integer(1), names=( i , j , k ,)); (i, j,
˓→ k,) = A._first_ngens(3)>>> R = PolynomialRing(A, sparse=True, names=( w ,)); (w,) = R._first_ngens(1)>>> f = w**Integer(3) + (i+j)*w + Integer(1)>>> fw^3 + (i + j)*w + 1>>> f**Integer(2)w^6 + (2*i + 2*j)*w^4 + 2*w^3 - 2*w^2 + (2*i + 2*j)*w + 1(continues on next page)

16

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = w + i ; g = w + j>>> f * gw^2 + (i + j)*w + k>>> g * fw^2 + (i + j)*w - k

Issue #9944 introduced some changes related with coercion. Previously, a dense and a sparse polynomial ring with thesame variable name over the same base ring evaluated equal, but of course they were not identical. Coercion maps arecached - but if a coercion to a dense ring is requested and a coercion to a sparse ring is returned instead (since the cachekeys are equal!), all hell breaks loose.
Therefore, the coercion between rings of sparse and dense polynomials works as follows:
sage: R.<x> = PolynomialRing(QQ, sparse=True)
sage: S.<x> = QQ[]
sage: S == R
False
sage: S.has_coerce_map_from(R)Truesage: R.has_coerce_map_from(S)False
sage: (R.0 + S.0).parent()
Univariate Polynomial Ring in x over Rational Field
sage: (S.0 + R.0).parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, sparse=True, names=( x ,)); (x,) = R._first_ngens(1)>>> S = QQ[ x ]; (x,) = S._first_ngens(1)>>> S == R
False>>> S.has_coerce_map_from(R)
True>>> R.has_coerce_map_from(S)False>>> (R.gen(0) + S.gen(0)).parent()
Univariate Polynomial Ring in x over Rational Field>>> (S.gen(0) + R.gen(0)).parent()
Univariate Polynomial Ring in x over Rational Field

It may be that one has rings of dense or sparse polynomials over different base rings. In that situation, coercion works bymeans of the pushout() formalism:
sage: R.<x> = PolynomialRing(GF(5), sparse=True)
sage: S.<x> = PolynomialRing(ZZ)
sage: R.has_coerce_map_from(S)False
sage: S.has_coerce_map_from(R)False
sage: S.0 + R.0
2*x
sage: (S.0 + R.0).parent()
Univariate Polynomial Ring in x over Finite Field of size 5
sage: (S.0 + R.0).parent().is_sparse()
False

2.1. Univariate Polynomials and Polynomial Rings

17

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(5)), sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> S = PolynomialRing(ZZ, names=( x ,)); (x,) = S._first_ngens(1)>>> R.has_coerce_map_from(S)False>>> S.has_coerce_map_from(R)False>>> S.gen(0) + R.gen(0)2*x>>> (S.gen(0) + R.gen(0)).parent()
Univariate Polynomial Ring in x over Finite Field of size 5>>> (S.gen(0) + R.gen(0)).parent().is_sparse()
False

Similarly, there is a coercion from the (non-default) NTL implementation for univariate polynomials over the integers to
the default FLINT implementation, but not vice versa:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )˓→needs sage.libs.ntl
sage: S.<x> = PolynomialRing(ZZ, implementation= FLINT )sage: (S.0 + R.0).parent() is S
˓→needs sage.libs.flint sage.libs.ntl
True
sage: (R.0 + S.0).parent() is S
˓→needs sage.libs.flint sage.libs.ntl
True

#␣

#␣

#␣

>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._first_
˓→ngens(1)# needs sage.libs.ntl>>> S = PolynomialRing(ZZ, implementation= FLINT , names=( x ,)); (x,) = S._first_
˓→ngens(1)>>> (S.gen(0) + R.gen(0)).parent() is S˓→# needs sage.libs.flint sage.libs.ntl
True>>> (R.gen(0) + S.gen(0)).parent() is S˓→# needs sage.libs.flint sage.libs.ntl
True

␣

␣

class sage.rings.polynomial.polynomial_ring.PolynomialRing_cdvf(base_ring,
name=None,sparse=False, implementation=None,element_class=None,
category=None)
Bases: PolynomialRing_cdvr, PolynomialRing_fieldA class for polynomial ring over complete discrete valuation fields
class sage.rings.polynomial.polynomial_ring.PolynomialRing_cdvr(base_ring,
name=None,sparse=False, implementation=None,element_class=None,
category=None)
Bases: PolynomialRing_integral_domain
18

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

A class for polynomial ring over complete discrete valuation rings
class sage.rings.polynomial.polynomial_ring.PolynomialRing_commutative(base_ring,
name=None,sparse=False,
implementation=None,element_class=None,
category=None)
Bases: PolynomialRing_general
Univariate polynomial ring over a commutative ring.
quotient_by_principal_ideal(f, names=None, **kwds)
Return the quotient of this polynomial ring by the principal ideal (generated by) 𝑓 .
INPUT:• f – either a polynomial in self, or a principal ideal of self.
• further named arguments that are passed to the quotient constructor.
EXAMPLES:
sage: R.<x> = QQ[]
sage: I = (x^2 - 1) * R
sage: R.quotient_by_principal_ideal(I)˓→needs sage.libs.pari
Univariate Quotient Polynomial Ring in xbar
over Rational Field with modulus x^2 - 1>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> I = (x**Integer(2) - Integer(1)) * R>>> R.quotient_by_principal_ideal(I)˓→needs sage.libs.pari
Univariate Quotient Polynomial Ring in xbar
over Rational Field with modulus x^2 - 1#␣#␣The same example, using the polynomial instead of the ideal, and customizing the variable name:sage: R.<x> = QQ[]
sage: R.quotient_by_principal_ideal(x^2 - 1, names=( foo ,))˓→needs sage.libs.pari
Univariate Quotient Polynomial Ring in foo
over Rational Field with modulus x^2 - 1#␣>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.quotient_by_principal_ideal(x**Integer(2) - Integer(1), names=( foo ,))␣˓→
# needs sage.libs.pari
Univariate Quotient Polynomial Ring in foo
over Rational Field with modulus x^2 - 1

2.1. Univariate Polynomials and Polynomial Rings

19

Polynomials, Release 10.4

weyl_algebra()
Return the Weyl algebra generated from self.
EXAMPLES:
sage: R = QQ[ x ]sage: W = R.weyl_algebra(); W˓→needs sage.modules
Differential Weyl algebra of polynomials in x over Rational Field
sage: W.polynomial_ring() == R
˓→needs sage.modules
True>>> from sage.all import *>>> R = QQ[ x ]>>> W = R.weyl_algebra(); W˓→needs sage.modules
Differential Weyl algebra of polynomials in x over Rational Field>>> W.polynomial_ring() == R
˓→needs sage.modules
True

#␣

#␣

#␣

#␣

class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field(base_ring,
name='x',element_class=None,
implementation=None)
Bases: PolynomialRing_field
Univariate polynomial ring over a finite field.
EXAMPLES:
sage: R = PolynomialRing(GF(27, a ), x )#␣˓→needs sage.rings.finite_rings
sage: type(R)#␣˓→needs sage.rings.finite_rings<class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field_
˓→with_category >>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(27), a ), x )␣˓→# needs sage.rings.finite_rings>>> type(R)#␣˓→needs sage.rings.finite_rings<class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field_
˓→with_category >irreducible_element(n, algorithm=None)
Construct a monic irreducible polynomial of degree 𝑛.
INPUT:

20

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• n – integer: degree of the polynomial to construct• algorithm – string: algorithm to use, or None–random or None: try random polynomials until an irreducible one is found.

–first_lexicographic : try polynomials in lexicographic order until an irreducible one isfound.

OUTPUT:
A monic irreducible polynomial of degree 𝑛 in self.
EXAMPLES:
sage: # needs sage.modules sage.rings.finite_rings
sage: f = GF(5^3, a )[ x ].irreducible_element(2)sage: f.degree()2
sage: f.is_irreducible()True
sage: R = GF(19)[ x ]sage: R.irreducible_element(21, algorithm="first_lexicographic")x^21 + x + 5
sage: R = GF(5**2, a )[ x ]sage: R.irreducible_element(17, algorithm="first_lexicographic")x^17 + a*x + 4*a + 3>>> from sage.all import *>>> # needs sage.modules sage.rings.finite_rings>>> f = GF(Integer(5)**Integer(3), a )[ x ].irreducible_element(Integer(2))>>> f.degree()2>>> f.is_irreducible()
True>>> R = GF(Integer(19))[ x ]>>> R.irreducible_element(Integer(21), algorithm="first_lexicographic")x^21 + x + 5>>> R = GF(Integer(5)**Integer(2), a )[ x ]>>> R.irreducible_element(Integer(17), algorithm="first_lexicographic")x^17 + a*x + 4*a + 3

AUTHORS:• Peter Bruin (June 2013)• Jean-Pierre Flori (May 2014)class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_n(base_ring,
name=None,element_class=None,
implementation=None,
category=None)
Bases: PolynomialRing_commutative

2.1. Univariate Polynomials and Polynomial Rings

21

Polynomials, Release 10.4

modulus()
EXAMPLES:
sage: R.<x> = Zmod(15)[]
sage: R.modulus()
15>>> from sage.all import *>>> R = Zmod(Integer(15))[ x ]; (x,) = R._first_ngens(1)>>> R.modulus()
15

residue_field(ideal, names=None)
Return the residue finite field at the given ideal.
EXAMPLES:
sage: # needs sage.libs.ntl
sage: R.<t> = GF(2)[]sage: k.<a> = R.residue_field(t^3 + t + 1); k
Residue field in aof Principal ideal (t^3 + t + 1) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)
sage: k.list()[0, a, a^2, a + 1, a^2 + a, a^2 + a + 1, a^2 + 1, 1]
sage: R.residue_field(t)Residue field of Principal ideal (t) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)
sage: P = R.irreducible_element(8) * R
sage: P
Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)
sage: k.<a> = R.residue_field(P); k
Residue field in aof Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring␣˓→in tover Finite Field of size 2 (using GF2X)
sage: k.cardinality()256>>> from sage.all import *>>> # needs sage.libs.ntl>>> R = GF(Integer(2))[ t ]; (t,) = R._first_ngens(1)>>> k = R.residue_field(t**Integer(3) + t + Integer(1), names=( a ,)); (a,) =␣
˓→k._first_ngens(1); k
Residue field in aof Principal ideal (t^3 + t + 1) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)>>> k.list()[0, a, a^2, a + 1, a^2 + a, a^2 + a + 1, a^2 + 1, 1]>>> R.residue_field(t)Residue field of Principal ideal (t) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)>>> P = R.irreducible_element(Integer(8)) * R>>> P
Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring in t
over Finite Field of size 2 (using GF2X)(continues on next page)

22

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> k = R.residue_field(P, names=( a ,)); (a,) = k._first_ngens(1); k
Residue field in aof Principal ideal (t^8 + t^4 + t^3 + t^2 + 1) of Univariate Polynomial Ring␣˓→in tover Finite Field of size 2 (using GF2X)>>> k.cardinality()256

Non-maximal ideals are not accepted:
sage: # needs sage.libs.ntl
sage: R.residue_field(t^2 + 1)
Traceback (most recent call last):...
ArithmeticError: ideal is not maximal
sage: R.residue_field(0)Traceback (most recent call last):...
ArithmeticError: ideal is not maximal
sage: R.residue_field(1)Traceback (most recent call last):...
ArithmeticError: ideal is not maximal>>> from sage.all import *>>> # needs sage.libs.ntl>>> R.residue_field(t**Integer(2) + Integer(1))
Traceback (most recent call last):...
ArithmeticError: ideal is not maximal>>> R.residue_field(Integer(0))
Traceback (most recent call last):...
ArithmeticError: ideal is not maximal>>> R.residue_field(Integer(1))
Traceback (most recent call last):...
ArithmeticError: ideal is not maximalclass sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_p(base_ring,
name='x',
implementation=None,element_class=None,
category=None)
Bases: PolynomialRing_dense_finite_field, PolynomialRing_dense_mod_n, PolynomialRing_singular_repr
fraction_field()
Return the fraction field of self.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

23

Polynomials, Release 10.4

sage: R.<t> = GF(5)[]sage: R.fraction_field()
Fraction Field of Univariate Polynomial Ring in t
over Finite Field of size 5>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> R.fraction_field()
Fraction Field of Univariate Polynomial Ring in t
over Finite Field of size 5

irreducible_element(n, algorithm=None)
Construct a monic irreducible polynomial of degree 𝑛.
INPUT:• n – integer: the degree of the polynomial to construct• algorithm – string: algorithm to use, or None. Currently available options are:–adleman-lenstra : a variant of the Adleman–Lenstra algorithm as implemented in PARI.

–

conway : look up the Conway polynomial of degree 𝑛 over the field of 𝑝 elements in the database;raise a RuntimeError if it is not found.

–

ffprimroot : use the pari:ffprimroot function from PARI.

–

first_lexicographic : return the lexicographically smallest irreducible polynomial of degree 𝑛.

–minimal_weight : return an irreducible polynomial of degree 𝑛 with minimal number of
non-zero coefficients. Only implemented for 𝑝 = 2.

–

primitive : return a polynomial 𝑓 such that a root of 𝑓 generates the multiplicative group of
the finite field extension defined by 𝑓 . This uses the Conway polynomial if possible, otherwise it
uses ffprimroot .

–random : try random polynomials until an irreducible one is found.

If algorithm is None, use 𝑥 − 1 in degree 1. In degree > 1, the Conway polynomial is used if it isfound in the database. Otherwise, the algorithm minimal_weight is used if 𝑝 = 2, and the algorithm
adleman-lenstra if 𝑝 > 2.
OUTPUT:
A monic irreducible polynomial of degree 𝑛 in self.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: GF(5)[ x ].irreducible_element(2)x^2 + 4*x + 2
sage: GF(5)[ x ].irreducible_element(2, algorithm="adleman-lenstra")x^2 + x + 1
sage: GF(5)[ x ].irreducible_element(2, algorithm="primitive")x^2 + 4*x + 2
sage: GF(5)[ x ].irreducible_element(32, algorithm="first_lexicographic")x^32 + 2
sage: GF(5)[ x ].irreducible_element(32, algorithm="conway")
Traceback (most recent call last):...
(continues on next page)

24

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

RuntimeError: requested Conway polynomial not in database.
sage: GF(5)[ x ].irreducible_element(32, algorithm="primitive")x^32 + ...
>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> GF(Integer(5))[ x ].irreducible_element(Integer(2))
x^2 + 4*x + 2>>> GF(Integer(5))[ x ].irreducible_element(Integer(2), algorithm="adleman˓→lenstra")x^2 + x + 1>>> GF(Integer(5))[ x ].irreducible_element(Integer(2), algorithm="primitive")x^2 + 4*x + 2>>> GF(Integer(5))[ x ].irreducible_element(Integer(32), algorithm="first_
˓→lexicographic")x^32 + 2>>> GF(Integer(5))[ x ].irreducible_element(Integer(32), algorithm="conway")
Traceback (most recent call last):...
RuntimeError: requested Conway polynomial not in database.
>>> GF(Integer(5))[ x ].irreducible_element(Integer(32), algorithm="primitive˓→")x^32 + ...

In characteristic 2:
sage: GF(2)[ x ].irreducible_element(33)˓→needs sage.rings.finite_ringsx^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1
sage: GF(2)[ x ].irreducible_element(33, algorithm="minimal_weight")
˓→needs sage.rings.finite_ringsx^33 + x^10 + 1#␣#␣>>> from sage.all import *>>> GF(Integer(2))[ x ].irreducible_element(Integer(33))␣˓→# needs sage.rings.finite_ringsx^33 + x^13 + x^12 + x^11 + x^10 + x^8 + x^6 + x^3 + 1>>> GF(Integer(2))[ x ].irreducible_element(Integer(33), algorithm="minimal_
˓→weight")# needs sage.rings.finite_ringsx^33 + x^10 + 1

In degree 1:
sage: GF(97)[ x ].irreducible_element(1)˓→needs sage.rings.finite_rings
x + 96sage: GF(97)[ x ].irreducible_element(1, algorithm="conway")˓→needs sage.rings.finite_rings
x + 92sage: GF(97)[ x ].irreducible_element(1, algorithm="adleman-lenstra")˓→needs sage.rings.finite_ringsx>>> from sage.all import *>>> GF(Integer(97))[ x ].irreducible_element(Integer(1))

#␣

#␣

#␣

␣
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

25

Polynomials, Release 10.4

(continued from previous page)˓→# needs sage.rings.finite_rings

x + 96>>> GF(Integer(97))[ x ].irreducible_element(Integer(1), algorithm="conway") ␣˓→# needs sage.rings.finite_rings
x + 92>>> GF(Integer(97))[ x ].irreducible_element(Integer(1), algorithm="adleman˓→lenstra")# needs sage.rings.finite_ringsx

AUTHORS:• Peter Bruin (June 2013)• Jeroen Demeyer (September 2014): add “ffprimroot” algorithm, see Issue #8373.

class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_field_capped_relativ

Bases: PolynomialRing_dense_padic_field_genericclass sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_field_generic(base_rin
name=N
implementation=No
element_cla
category=No
Bases: PolynomialRing_cdvf
A class for dense polynomial ring over p-adic fields

26

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_capped_absolute

Bases: PolynomialRing_dense_padic_ring_genericclass sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_capped_relative

Bases: PolynomialRing_dense_padic_ring_genericclass sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_fixed_mod(base_ri
name=implementation=N
element_c
category=N
Bases: PolynomialRing_dense_padic_ring_generic2.1. Univariate Polynomials and Polynomial Rings

27

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_padic_ring_generic(base_ring,
name=No
implementation=Noneelement_clas
category=Non
Bases: PolynomialRing_cdvr
A class for dense polynomial ring over p-adic rings
class sage.rings.polynomial.polynomial_ring.PolynomialRing_field(base_ring,
name='x',sparse=False, implementation=None,element_class=None,
category=None)
Bases: PolynomialRing_integral_domain, PrincipalIdealDomain
divided_difference(points, full_table=False)
Return the Newton divided-difference coefficients of the Lagrange interpolation polynomial throughpoints.
INPUT:• points – a list of pairs (𝑥0 , 𝑦0 ), (𝑥1 , 𝑦1 ), . . . , (𝑥𝑛 , 𝑦𝑛 ) of elements of the base ring of self, where𝑥𝑖 − 𝑥𝑗 is invertible for 𝑖 ̸= 𝑗. This method converts the 𝑥𝑖 and 𝑦𝑖 into the base ring of self.
• full_table – boolean (default: False): If True, return the full divided-difference table. If
False, only return entries along the main diagonal; these are the Newton divided-difference coefficients
𝐹𝑖,𝑖 .
OUTPUT:
The Newton divided-difference coefficients of the 𝑛-th Lagrange interpolation polynomial 𝑃𝑛 (𝑥) thatpasses through the points in points (see lagrange_polynomial()). These are the coefficients
𝐹0,0 , 𝐹1,1 , . . . , 𝐹𝑛,𝑛 in the base ring of self such that𝑃𝑛 (𝑥) =

𝑛
∑︁
𝑖=0

𝐹𝑖,𝑖

𝑖−1
∏︁

(𝑥 − 𝑥𝑗 )𝑗=0

EXAMPLES:
Only return the divided-difference coefficients 𝐹𝑖,𝑖 . This example is taken from Example 1, page 121 of[BF2005]:
sage: # needs sage.rings.real_mpfr
sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022),....:(1.9, 0.2818186), (2.2, 0.1103623)]
sage: R = PolynomialRing(RR, "x")(continues on next page)

28

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: R.divided_difference(points)[0.765197700000000,-0.483705666666666,-0.108733888888889,
0.0658783950617283,
0.00182510288066044]>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> points = [(RealNumber( 1.0 ), RealNumber( 0.7651977 )), (RealNumber( 1.3
˓→ ), RealNumber( 0.6200860 )), (RealNumber( 1.6 ), RealNumber( 0.4554022 )),...
(RealNumber( 1.9 ), RealNumber( 0.2818186 )), (RealNumber( 2.2
˓→ ), RealNumber( 0.1103623 ))]>>> R = PolynomialRing(RR, "x")>>> R.divided_difference(points)[0.765197700000000,-0.483705666666666,-0.108733888888889,
0.0658783950617283,
0.00182510288066044]

Now return the full divided-difference table:
sage: # needs sage.rings.real_mpfr
sage: points = [(1.0, 0.7651977), (1.3, 0.6200860), (1.6, 0.4554022),....:(1.9, 0.2818186), (2.2, 0.1103623)]
sage: R = PolynomialRing(RR, "x")sage: R.divided_difference(points, full_table=True)[[0.765197700000000],[0.620086000000000, -0.483705666666666],[0.455402200000000, -0.548946000000000, -0.108733888888889],[0.281818600000000, -0.578612000000000,-0.0494433333333339, 0.0658783950617283],[0.110362300000000, -0.571520999999999, 0.0118183333333349,
0.0680685185185209, 0.00182510288066044]]>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> points = [(RealNumber( 1.0 ), RealNumber( 0.7651977 )), (RealNumber( 1.3
˓→ ), RealNumber( 0.6200860 )), (RealNumber( 1.6 ), RealNumber( 0.4554022 )),...
(RealNumber( 1.9 ), RealNumber( 0.2818186 )), (RealNumber( 2.2
˓→ ), RealNumber( 0.1103623 ))]>>> R = PolynomialRing(RR, "x")>>> R.divided_difference(points, full_table=True)[[0.765197700000000],[0.620086000000000, -0.483705666666666],[0.455402200000000, -0.548946000000000, -0.108733888888889],[0.281818600000000, -0.578612000000000,-0.0494433333333339, 0.0658783950617283],[0.110362300000000, -0.571520999999999, 0.0118183333333349,
0.0680685185185209, 0.00182510288066044]]

The following example is taken from Example 4.12, page 225 of [MF1999]:
sage: points = [(1, -3), (2, 0), (3, 15), (4, 48), (5, 105), (6, 192)]
sage: R = PolynomialRing(QQ, "x")(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

29

Polynomials, Release 10.4

(continued from previous page)

sage: R.divided_difference(points)[-3, 3, 6, 1, 0, 0]
sage: R.divided_difference(points, full_table=True)[[-3],[0, 3],[15, 15, 6],[48, 33, 9, 1],[105, 57, 12, 1, 0],[192, 87, 15, 1, 0, 0]]>>> from sage.all import *>>> points = [(Integer(1), -Integer(3)), (Integer(2), Integer(0)),␣
˓→(Integer(3), Integer(15)), (Integer(4), Integer(48)), (Integer(5),␣
˓→Integer(105)), (Integer(6), Integer(192))]>>> R = PolynomialRing(QQ, "x")>>> R.divided_difference(points)[-3, 3, 6, 1, 0, 0]>>> R.divided_difference(points, full_table=True)[[-3],[0, 3],[15, 15, 6],[48, 33, 9, 1],[105, 57, 12, 1, 0],[192, 87, 15, 1, 0, 0]]

fraction_field()
Return the fraction field of self.
EXAMPLES:
sage: QQbar[ x ].fraction_field()
Fraction Field of Univariate Polynomial Ring in x over Algebraic
Field>>> from sage.all import *>>> QQbar[ x ].fraction_field()
Fraction Field of Univariate Polynomial Ring in x over Algebraic
Field

lagrange_polynomial(points, algorithm='divided_difference', previous_row=None)
Return the Lagrange interpolation polynomial through the given points.
INPUT:• points – a list of pairs (𝑥0 , 𝑦0 ), (𝑥1 , 𝑦1 ), . . . , (𝑥𝑛 , 𝑦𝑛 ) of elements of the base ring of self, where𝑥𝑖 − 𝑥𝑗 is invertible for 𝑖 ̸= 𝑗. This method converts the 𝑥𝑖 and 𝑦𝑖 into the base ring of self.
• algorithm – (default: divided_difference ): one of the following:

30–

divided_difference : use the method of divided differences.

–neville : adapt Neville’s method as described on page 144 of [BF2005] to recursively generate the Lagrange interpolation polynomial. Neville’s method generates a table of approximating
polynomials, where the last row of that table contains the 𝑛-th Lagrange interpolation polynomial.
The adaptation implemented by this method is to only generate the last row of this table, instead of
the full table itself. Generating the full table can be memory inefficient.

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• previous_row – (default:None):
This option is only relevant if used withalgorithm= neville . If provided, this should be the last row of the table resulting froma previous use of Neville’s method. If such a row is passed, then points should consist of bothprevious and new interpolating points. Neville’s method will then use that last row and the interpolating
points to generate a new row containing an interpolation polynomial for the new points.
OUTPUT:
The Lagrange interpolation polynomial through the points (𝑥0 , 𝑦0 ), (𝑥1 , 𝑦1 ), . . . , (𝑥𝑛 , 𝑦𝑛 ). This is the uniquepolynomial 𝑃𝑛 of degree at most 𝑛 in self satisfying 𝑃𝑛 (𝑥𝑖 ) = 𝑦𝑖 for 0 ≤ 𝑖 ≤ 𝑛.
EXAMPLES:
By default, we use the method of divided differences:
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)1sage: f(2)2sage: f(3)-2sage: f(-4)
9sage: # needs sage.rings.finite_rings
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)]); fa^2*x^2 + a^2*x + a^2
sage: f(a^2 + a)asage: f(a)1sage: f(a^2)
a^2 + a + 1>>> from sage.all import *>>> R = PolynomialRing(QQ, x )>>> f = R.lagrange_polynomial([(Integer(0),Integer(1)), (Integer(2),˓→Integer(2)), (Integer(3),-Integer(2)), (-Integer(4),Integer(9))]); f-23/84*x^3 - 11/84*x^2 + 13/7*x + 1>>> f(Integer(0))
1>>> f(Integer(2))
2>>> f(Integer(3))-2>>> f(-Integer(4))
9>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(2)**Integer(3), a ), x )>>> a = R.base_ring().gen()>>> f = R.lagrange_polynomial([(a**Integer(2)+a, a), (a, Integer(1)),␣
˓→(a**Integer(2), a**Integer(2)+a+Integer(1))]); fa^2*x^2 + a^2*x + a^2(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

31

Polynomials, Release 10.4

(continued from previous page)>>> f(a**Integer(2) + a)a>>> f(a)1>>> f(a**Integer(2))
a^2 + a + 1

Now use a memory efficient version of Neville’s method:
sage: R = PolynomialRing(QQ, x )sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)],....:algorithm="neville")[9,-11/7*x + 19/7,-17/42*x^2 - 83/42*x + 53/7,-23/84*x^3 - 11/84*x^2 + 13/7*x + 1]
sage: # needs sage.rings.finite_rings
sage: R = PolynomialRing(GF(2**3, a ), x )sage: a = R.base_ring().gen()sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)],....:
algorithm="neville")[a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2]>>> from sage.all import *>>> R = PolynomialRing(QQ, x )>>> R.lagrange_polynomial([(Integer(0),Integer(1)), (Integer(2),Integer(2)),␣
˓→(Integer(3),-Integer(2)), (-Integer(4),Integer(9))],...
algorithm="neville")[9,-11/7*x + 19/7,-17/42*x^2 - 83/42*x + 53/7,-23/84*x^3 - 11/84*x^2 + 13/7*x + 1]>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(2)**Integer(3), a ), x )>>> a = R.base_ring().gen()>>> R.lagrange_polynomial([(a**Integer(2)+a, a), (a, Integer(1)),␣
˓→(a**Integer(2), a**Integer(2)+a+Integer(1))],...
algorithm="neville")[a^2 + a + 1, x + a + 1, a^2*x^2 + a^2*x + a^2]

Repeated use of Neville’s method to get better Lagrange interpolation polynomials:
sage: R = PolynomialRing(QQ, x )sage: p = R.lagrange_polynomial([(0,1), (2,2)], algorithm="neville")
sage: R.lagrange_polynomial([(0,1), (2,2), (3,-2), (-4,9)],....:algorithm="neville", previous_row=p)[-1]-23/84*x^3 - 11/84*x^2 + 13/7*x + 1
sage: # needs sage.rings.finite_rings
sage: R = PolynomialRing(GF(2**3, a ), x )sage: a = R.base_ring().gen()sage: p = R.lagrange_polynomial([(a^2+a, a), (a, 1)], algorithm="neville")
sage: R.lagrange_polynomial([(a^2+a, a), (a, 1), (a^2, a^2+a+1)],....:
algorithm="neville", previous_row=p)[-1]a^2*x^2 + a^2*x + a^232

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, x )>>> p = R.lagrange_polynomial([(Integer(0),Integer(1)), (Integer(2),˓→Integer(2))], algorithm="neville")>>> R.lagrange_polynomial([(Integer(0),Integer(1)), (Integer(2),Integer(2)),␣
˓→(Integer(3),-Integer(2)), (-Integer(4),Integer(9))],...
algorithm="neville", previous_row=p)[-Integer(1)]-23/84*x^3 - 11/84*x^2 + 13/7*x + 1>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(2)**Integer(3), a ), x )>>> a = R.base_ring().gen()>>> p = R.lagrange_polynomial([(a**Integer(2)+a, a), (a, Integer(1))],␣
˓→algorithm="neville")>>> R.lagrange_polynomial([(a**Integer(2)+a, a), (a, Integer(1)),␣
˓→(a**Integer(2), a**Integer(2)+a+Integer(1))],...
algorithm="neville", previous_row=p)[-Integer(1)]a^2*x^2 + a^2*x + a^2

class sage.rings.polynomial.polynomial_ring.PolynomialRing_general(base_ring,
name=None,sparse=False,
implementation=None,element_class=None,
category=None)
Bases: Ring
Univariate polynomial ring over a ring.
base_extend(R)Return the base extension of this polynomial ring to 𝑅.
EXAMPLES:
sage: # needs sage.rings.real_mpfr
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>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ x ]; (x,) = R._first_ngens(1); R
Univariate Polynomial Ring in x over Real Field with 53 bits of precision>>> R.base_extend(CC)Univariate Polynomial Ring in x over Complex Field with 53 bits of precision>>> R.base_extend(QQ)
Traceback (most recent call last):...
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

33

Polynomials, Release 10.4

(continued from previous page)

TypeError: no such base extension>>> R.change_ring(QQ)
Univariate Polynomial Ring in x over Rational Fieldchange_ring(R)Return the polynomial ring in the same variable as self over 𝑅.
EXAMPLES:
sage: # needs sage.rings.finite_rings sage.rings.real_interval_fieldsage: 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>>> from sage.all import *>>> # needs sage.rings.finite_rings sage.rings.real_interval_field>>> R = RealIntervalField()[ ZZZ ]; (ZZZ,) = R._first_ngens(1); R
Univariate Polynomial Ring in ZZZ over
Real Interval Field with 53 bits of precision>>> R.change_ring(GF(Integer(19)**Integer(2), b ))Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2change_var(var)
Return the polynomial ring in variable var over the same base ring.
EXAMPLES:
sage: R.<x> = ZZ[]; R
Univariate Polynomial Ring in x over Integer Ringsage: R.change_var( y )Univariate Polynomial Ring in y over Integer Ring>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1); R
Univariate Polynomial Ring in x over Integer Ring>>> R.change_var( y )Univariate Polynomial Ring in y over Integer Ring

characteristic()
Return the characteristic of this polynomial ring, which is the same as that of its base ring.
EXAMPLES:
sage: # needs sage.rings.real_interval_fieldsage: 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#␣˓→needs sage.rings.finite_rings
Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2
sage: S.characteristic()#␣(continues on next page)

34

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.finite_rings

˓→19>>> from sage.all import *>>> # needs sage.rings.real_interval_field>>> R = RealIntervalField()[ ZZZ ]; (ZZZ,) = R._first_ngens(1); R
Univariate Polynomial Ring in ZZZ over Real Interval Field with 53 bits of␣˓→precision>>> R.characteristic()
0>>> S = R.change_ring(GF(Integer(19)**Integer(2), b )); S␣˓→# needs sage.rings.finite_rings
Univariate Polynomial Ring in ZZZ over Finite Field in b of size 19^2>>> S.characteristic()#␣˓→needs sage.rings.finite_rings
19

completion(p=None, prec=20, extras=None)
Return the completion of self with respect to the irreducible polynomial p.
Currently only implemented for p=self.gen() (the default), i.e. you can only complete 𝑅[𝑥] with respect
to 𝑥, the result being a ring of power series in 𝑥. The prec variable controls the precision used in the power
series ring. If prec is ∞, then this returns a LazyPowerSeriesRing.
EXAMPLES:
sage: P.<x> = PolynomialRing(QQ)
sage: P
Univariate Polynomial Ring in x over Rational Field
sage: PP = P.completion(x)sage: PPPower Series Ring in x over Rational Field
sage: f = 1 - x
sage: PP(f)1 - x
sage: 1 / f-1/(x - 1)sage: g = 1 / PP(f); g
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)
sage: 1 / g
1 - x + O(x^20)
sage: # needs sage.combinat
sage: PP = P.completion(x, prec=oo); PP
Lazy Taylor Series Ring in x over Rational Field
sage: g = 1 / PP(f); g
1 + x + x^2 + O(x^3)
sage: 1 / g == f
True>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x ,)); (x,) = P._first_ngens(1)>>> P
Univariate Polynomial Ring in x over Rational Field>>> PP = P.completion(x)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

35

Polynomials, Release 10.4

(continued from previous page)>>> PPPower Series Ring in x over Rational Field>>> f = Integer(1) - x>>> PP(f)1 - x>>> Integer(1) / f-1/(x - 1)>>> g = Integer(1) / PP(f); g
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)>>> Integer(1) / g
1 - x + O(x^20)>>> # needs sage.combinat>>> PP = P.completion(x, prec=oo); PP
Lazy Taylor Series Ring in x over Rational Field>>> g = Integer(1) / PP(f); g
1 + x + x^2 + O(x^3)>>> Integer(1) / g == f
Trueconstruction()
Return the construction functor.
cyclotomic_polynomial(n)Return the nth cyclotomic polynomial as a polynomial in this polynomial ring.
For detailsof the implementation, see the documentation for sage.rings.polynomial.cyclotomic.
cyclotomic_coeffs().
EXAMPLES:
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),sage: S.cyclotomic_polynomial(12)x^4 + 6*x^2 + 1
sage: S.cyclotomic_polynomial(1)
x + 6

x )

>>> from sage.all import *>>> R = ZZ[ x ]>>> R.cyclotomic_polynomial(Integer(8))
x^4 + 1>>> R.cyclotomic_polynomial(Integer(12))
x^4 - x^2 + 1>>> S = PolynomialRing(FiniteField(Integer(7)),>>> S.cyclotomic_polynomial(Integer(12))
x^4 + 6*x^2 + 1>>> S.cyclotomic_polynomial(Integer(1))
x + 6

x )

extend_variables(added_names, order='degrevlex')
36

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Return a multivariate polynomial ring with the same base ring but with added_names as additional variables.
EXAMPLES:
sage: R.<x> = ZZ[]; R
Univariate Polynomial Ring in x over Integer Ringsage: R.extend_variables( y, z )Multivariate Polynomial Ring in x, y, z over Integer Ringsage: R.extend_variables(( y , z ))Multivariate Polynomial Ring in x, y, z over Integer Ring>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1); R
Univariate Polynomial Ring in x over Integer Ring>>> R.extend_variables( y, z )Multivariate Polynomial Ring in x, y, z over Integer Ring>>> R.extend_variables(( y , z ))Multivariate Polynomial Ring in x, y, z over Integer Ring

flattening_morphism()
Return the flattening morphism of this polynomial ring
EXAMPLES:
sage: QQ[ a , b ][ x ].flattening_morphism()
Flattening morphism:
From: Univariate Polynomial Ring in x overMultivariate Polynomial Ring in a, b over Rational Field
To:
Multivariate Polynomial Ring in a, b, x over Rational Field
sage: QQ[ x ].flattening_morphism()
Identity endomorphism of Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> QQ[ a , b ][ x ].flattening_morphism()
Flattening morphism:
From: Univariate Polynomial Ring in x overMultivariate Polynomial Ring in a, b over Rational Field
To:
Multivariate Polynomial Ring in a, b, x over Rational Field>>> QQ[ x ].flattening_morphism()
Identity endomorphism of Univariate Polynomial Ring in x over Rational Fieldgen(n=0)
Return the indeterminate generator of this polynomial ring.
EXAMPLES:
sage: R.<abc> = Integers(8)[]; R
Univariate Polynomial Ring in abc over Ring of integers modulo 8
sage: t = R.gen(); tabc
sage: t.is_gen()True

2.1. Univariate Polynomials and Polynomial Rings

37

Polynomials, Release 10.4>>> from sage.all import *>>> R = Integers(Integer(8))[ abc ]; (abc,) = R._first_ngens(1); R
Univariate Polynomial Ring in abc over Ring of integers modulo 8>>> t = R.gen(); tabc>>> t.is_gen()True

An identical generator is always returned.
sage: t is R.gen()True>>> from sage.all import *>>> t is R.gen()True

gens_dict()
Return a dictionary whose entries are {name:variable,...}, where name stands for the variablenames of this object (as strings) and variable stands for the corresponding generators (as elements ofthis object).
EXAMPLES:
sage: R.<y,x,a42> = RR[]
sage: R.gens_dict(){ a42 : a42, x : x, y : y}>>> from sage.all import *>>> R = RR[ y, x, a42 ]; (y, x, a42,) = R._first_ngens(3)>>> R.gens_dict(){ a42 : a42, x : x, y : y}is_exact()
EXAMPLES:
sage: class Foo:....:def __init__(self, x):....:
self._x = x....:@cached_method....:
def f(self):....:
return self._x^2
sage: a = Foo(2)sage: print(a.f.cache)Nonesage: a.f()4
sage: a.f.cache4>>> from sage.all import *>>> class Foo:...
def __init__(self, x):...
self._x = x...
@cached_method...
def f(self):(continues on next page)

38

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)...
return self._x**Integer(2)>>> a = Foo(Integer(2))>>> print(a.f.cache)None>>> a.f()4>>> a.f.cache4

is_field(proof=True)
Return False, since polynomial rings are never fields.
EXAMPLES:
sage: # needs sage.libs.ntl
sage: R.<z> = Integers(2)[]; R
Univariate Polynomial Ring in z over Ring of integers modulo 2 (using GF2X)
sage: R.is_field()
False>>> from sage.all import *>>> # needs sage.libs.ntl>>> R = Integers(Integer(2))[ z ]; (z,) = R._first_ngens(1); R
Univariate Polynomial Ring in z over Ring of integers modulo 2 (using GF2X)>>> R.is_field()
False

is_integral_domain(proof=True)
EXAMPLES:
sage: ZZ[ x ].is_integral_domain()Truesage: Integers(8)[ x ].is_integral_domain()False>>> from sage.all import *>>> ZZ[ x ].is_integral_domain()
True>>> Integers(Integer(8))[ x ].is_integral_domain()
False

is_noetherian()
is_sparse()
Return True if elements of this polynomial ring have a sparse representation.
EXAMPLES:
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

2.1. Univariate Polynomials and Polynomial Rings

39

Polynomials, Release 10.4>>> from sage.all import *>>> R = Integers(Integer(8))[ z ]; (z,) = R._first_ngens(1); R
Univariate Polynomial Ring in z over Ring of integers modulo 8>>> R.is_sparse()
False>>> R = PolynomialRing(QQ, sparse=True, names=( W ,)); (W,) = R._first_
˓→ngens(1); R
Sparse Univariate Polynomial Ring in W over Rational Field>>> R.is_sparse()
True

is_unique_factorization_domain(proof=True)
EXAMPLES:
sage: ZZ[ x ].is_unique_factorization_domain()Truesage: Integers(8)[ x ].is_unique_factorization_domain()False>>> from sage.all import *>>> ZZ[ x ].is_unique_factorization_domain()
True>>> Integers(Integer(8))[ x ].is_unique_factorization_domain()False

karatsuba_threshold()
Return the Karatsuba threshold used for this ring by the method _mul_karatsuba() to fall back to theschoolbook algorithm.
EXAMPLES:
sage: K = QQ[ x ]sage: K.karatsuba_threshold()8
sage: K = QQ[ x ][ y ]sage: K.karatsuba_threshold()0>>> from sage.all import *>>> K = QQ[ x ]>>> K.karatsuba_threshold()8>>> K = QQ[ x ][ y ]>>> K.karatsuba_threshold()0

krull_dimension()
Return the Krull dimension of this polynomial ring, which is one more than the Krull dimension of the basering.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R.krull_dimension()1(continues on next page)

40

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: # needs sage.rings.finite_rings
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>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.krull_dimension()1>>> # needs sage.rings.finite_rings>>> R = GF(Integer(9), a )[ z ]; (z,) = R._first_ngens(1); R
Univariate Polynomial Ring in z over Finite Field in a of size 3^2>>> R.krull_dimension()1>>> S = R[ t ]; (t,) = S._first_ngens(1)>>> S.krull_dimension()2>>> for n in range(Integer(10)):...
S = PolynomialRing(S, w )>>> S.krull_dimension()
12

monics(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 orequal to max_degree• of_degree – an int; the iterator will generate all monic polynomials which have degree of_degree
OUTPUT: an iterator
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: P = PolynomialRing(GF(4, a ), y )sage: for p in P.monics(of_degree=2): print(p)y^2y^2 + ay^2 + a + 1
y^2 + 1y^2 + a*yy^2 + a*y + ay^2 + a*y + a + 1
y^2 + a*y + 1
y^2 + (a + 1)*yy^2 + (a + 1)*y + a(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

41

Polynomials, Release 10.4

(continued from previous page)y^2 + (a + 1)*y + a + 1
y^2 + (a + 1)*y + 1
y^2 + yy^2 + y + ay^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>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> P = PolynomialRing(GF(Integer(4), a ), y )>>> for p in P.monics(of_degree=Integer(2)): print(p)y^2y^2 + ay^2 + a + 1
y^2 + 1y^2 + a*yy^2 + a*y + ay^2 + a*y + a + 1
y^2 + a*y + 1
y^2 + (a + 1)*yy^2 + (a + 1)*y + ay^2 + (a + 1)*y + a + 1
y^2 + (a + 1)*y + 1
y^2 + yy^2 + y + ay^2 + y + a + 1
y^2 + y + 1>>> for p in P.monics(max_degree=Integer(1)): print(p)
1
y
y + a
y + a + 1
y + 1>>> for p in P.monics(max_degree=Integer(1), of_degree=Integer(3)): print(p)Traceback (most recent call last):...
ValueError: you should pass exactly one of of_degree and max_degree

AUTHORS:• Joel B. Mohlermonomial(exponent)
Return the monomial with the exponent.
INPUT:• exponent – nonnegative integer
42

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: R.monomial(5)x^5sage: e=(10,)
sage: R.monomial(*e)
x^10sage: m = R.monomial(100)sage: R.monomial(m.degree()) == mTrue>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> R.monomial(Integer(5))
x^5>>> e=(Integer(10),)>>> R.monomial(*e)
x^10>>> m = R.monomial(Integer(100))>>> R.monomial(m.degree()) == mTruengens()
Return the number of generators of this polynomial ring, which is 1 since it is a univariate polynomial ring.
EXAMPLES:
sage: R.<z> = Integers(8)[]; R
Univariate Polynomial Ring in z over Ring of integers modulo 8
sage: R.ngens()
1>>> from sage.all import *>>> R = Integers(Integer(8))[ z ]; (z,) = R._first_ngens(1); R
Univariate Polynomial Ring in z over Ring of integers modulo 8>>> R.ngens()
1

parameter()
Return the generator of this polynomial ring.
This is the same as self.gen().
polynomials(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
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

43

Polynomials, Release 10.4

sage: P = PolynomialRing(GF(3), y )sage: for p in P.polynomials(of_degree=2): print(p)y^2y^2 + 1y^2 + 2y^2 + yy^2 + y + 1
y^2 + y + 2
y^2 + 2*yy^2 + 2*y + 1
y^2 + 2*y + 2
2*y^2
2*y^2 + 1
2*y^2 + 2
2*y^2 + y2*y^2 + y + 1
2*y^2 + y + 2
2*y^2 + 2*y2*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 + 12*y + 2sage: 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>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(3)), y )>>> for p in P.polynomials(of_degree=Integer(2)): print(p)y^2y^2 + 1y^2 + 2y^2 + yy^2 + y + 1
y^2 + y + 2
y^2 + 2*yy^2 + 2*y + 1
y^2 + 2*y + 2
2*y^2
2*y^2 + 1
2*y^2 + 2
2*y^2 + y2*y^2 + y + 1
2*y^2 + y + 2
2*y^2 + 2*y2*y^2 + 2*y + 1
2*y^2 + 2*y + 2>>> for p in P.polynomials(max_degree=Integer(1)): print(p)(continues on next page)

44

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

0
1
2
y
y + 1
y + 2
2*y
2*y + 12*y + 2>>> for p in P.polynomials(max_degree=Integer(1), of_degree=Integer(3)):␣
˓→print(p)Traceback (most recent call last):...
ValueError: you should pass exactly one of of_degree and max_degree

AUTHORS:• Joel B. Mohler
random_element(degree=(-1, 2), monic=False, *args, **kwds)
Return a random polynomial of given degree (bounds).
INPUT:• degree – (default: (-1, 2)) integer for fixing the degree or a tuple of minimum and maximum
degrees• monic – boolean (optional); indicate whether the sampled polynomial should be monic• *args, **kwds – additional keyword parameters passed on to the random_element method forthe base ring
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = R.random_element(10, x=5, y=10)
sage: f.degree()10
sage: f.parent() is R
True
sage: all(a in range(5, 10) for a in f.coefficients())
Truesage: R.random_element(6).degree()6>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = R.random_element(Integer(10), x=Integer(5), y=Integer(10))>>> f.degree()10>>> f.parent() is R
True>>> all(a in range(Integer(5), Integer(10)) for a in f.coefficients())
True>>> R.random_element(Integer(6)).degree()6

If a tuple of two integers is given for the degree argument, a polynomial is chosen among all polynomials with degree between them. If the base ring can be sampled uniformly, then this method also samples
2.1. Univariate Polynomials and Polynomial Rings

45

Polynomials, Release 10.4

uniformly:
sage: R.random_element(degree=(0, 4)).degree() in range(0, 5)
True
sage: found = [False]*5
sage: while not all(found):....:found[R.random_element(degree=(0, 4)).degree()] = True>>> from sage.all import *>>> R.random_element(degree=(Integer(0), Integer(4))).degree() in␣
˓→range(Integer(0), Integer(5))
True>>> found = [False]*Integer(5)>>> while not all(found):...
found[R.random_element(degree=(Integer(0), Integer(4))).degree()] =␣
˓→TrueNote that the zero polynomial has degree −1, so if you want to consider it set the minimum degree to −1:
sage: while R.random_element(degree=(-1,2), x=-1, y=1) != R.zero():
....:
pass
>>> from sage.all import *>>> while R.random_element(degree=(-Integer(1),Integer(2)), x=-Integer(1),␣
˓→y=Integer(1)) != R.zero():
...
pass

Monic polynomials are chosen among all monic polynomials with degree between the given degree argument:
sage: all(R.random_element(degree=(-1, 1), monic=True).is_monic() for _ in␣˓→range(10^3))
True
sage: all(R.random_element(degree=(0, 1), monic=True).is_monic() for _ in␣˓→range(10^3))
True>>> from sage.all import *>>> all(R.random_element(degree=(-Integer(1), Integer(1)), monic=True).is_˓→monic() for _ in range(Integer(10)**Integer(3)))
True>>> all(R.random_element(degree=(Integer(0), Integer(1)), monic=True).is_˓→monic() for _ in range(Integer(10)**Integer(3)))
True

set_karatsuba_threshold(Karatsuba_threshold)
Changes the default threshold for this ring in the method _mul_karatsuba() to fall back to the schoolbook algorithm.
Warning: This method may have a negative performance impact in polynomial arithmetic. So use it atyour own risk.
EXAMPLES:

46

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: K = QQ[ x ]sage: K.karatsuba_threshold()8
sage: K.set_karatsuba_threshold(0)sage: K.karatsuba_threshold()0>>> from sage.all import *>>> K = QQ[ x ]>>> K.karatsuba_threshold()8>>> K.set_karatsuba_threshold(Integer(0))>>> K.karatsuba_threshold()0

some_elements()
Return a list of polynomials.
This is typically used for running generic tests.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R.some_elements()[x, 0, 1, 1/2, x^2 + 2*x + 1, x^3, x^2 - 1, x^2 + 1, 2*x^2 + 2]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.some_elements()[x, 0, 1, 1/2, x^2 + 2*x + 1, x^3, x^2 - 1, x^2 + 1, 2*x^2 + 2]

variable_names_recursive(depth=+Infinity)
Return the list of variable names of this ring and its base rings, as if it were a single multi-variate polynomial.
INPUT:• depth – an integer or Infinity.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: R = QQ[ x ][ y ][ z ]sage: R.variable_names_recursive()( x , y , z )sage: R.variable_names_recursive(2)( y , z )>>> from sage.all import *>>> R = QQ[ x ][ y ][ z ]>>> R.variable_names_recursive()( x , y , z )>>> R.variable_names_recursive(Integer(2))( y , z )2.1. Univariate Polynomials and Polynomial Rings

47

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain(base_ring,
name='x',sparse=False,
implementation=None,element_class=None,
category=None)
Bases:
main

PolynomialRing_commutative, PolynomialRing_singular_repr, IntegralDo-

construction()
Return the construction functor.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_ring import PolynomialRing_
˓→integral_domain as PRingsage: R = PRing(ZZ, x ); R
Univariate Polynomial Ring in x over Integer Ringsage: functor, arg = R.construction(); functor, arg(Poly[x], Integer Ring)sage: functor.implementation is None
True
sage: # needs sage.libs.ntl
sage: R = PRing(ZZ, x , implementation= NTL ); R
Univariate Polynomial Ring in x over Integer Ring (using NTL)
sage: functor, arg = R.construction(); functor, arg(Poly[x], Integer Ring)sage: functor.implementation
NTL>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_ring import PolynomialRing_integral_
˓→domain as PRing>>> R = PRing(ZZ, x ); R
Univariate Polynomial Ring in x over Integer Ring>>> functor, arg = R.construction(); functor, arg(Poly[x], Integer Ring)>>> functor.implementation is None
True>>> # needs sage.libs.ntl>>> R = PRing(ZZ, x , implementation= NTL ); R
Univariate Polynomial Ring in x over Integer Ring (using NTL)>>> functor, arg = R.construction(); functor, arg(Poly[x], Integer Ring)>>> functor.implementation
NTL

weil_polynomials(d, q, sign=1, lead=1)
Return all integer polynomials whose complex roots all have a specified absolute value.
48

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Such polynomials 𝑓 satisfy a functional equation
𝑇 𝑑 𝑓 (𝑞/𝑇 ) = 𝑠𝑞 𝑑/2 𝑓 (𝑇 )where 𝑑 is the degree of 𝑓 , 𝑠 is a sign and 𝑞 1/2 is the absolute value of the roots of 𝑓 .
INPUT:• d – integer, the degree of the polynomials• q – integer, the square of the complex absolute value of the roots• sign – integer (default 1), the sign 𝑠 of the functional equation• lead – integer, list of integers or list of pairs of integers (default 1), constraints on the leading few
coefficients of the generated polynomials. If pairs (𝑎, 𝑏) of integers are given, they are treated as aconstraint of the form ≡ 𝑎 (mod 𝑏); the moduli must be in decreasing order by divisibility, and themodulus of the leading coefficient must be 0.
See also:
More documentation and additional options are available using the iterator sage.rings.polynomial.
weil.weil_polynomials.WeilPolynomials directly. In addition, polynomials have a method
is_weil_polynomial() to test whether or not the given polynomial is a Weil polynomial.
EXAMPLES:
sage: # needs sage.libs.flint
sage: R.<T> = ZZ[]
sage: L = R.weil_polynomials(4, 2)
sage: len(L)35
sage: L[9]T^4 + T^3 + 2*T^2 + 2*T + 4
sage: all(p.is_weil_polynomial() for p in L)
True>>> from sage.all import *>>> # needs sage.libs.flint>>> R = ZZ[ T ]; (T,) = R._first_ngens(1)>>> L = R.weil_polynomials(Integer(4), Integer(2))>>> len(L)35>>> L[Integer(9)]T^4 + T^3 + 2*T^2 + 2*T + 4>>> all(p.is_weil_polynomial() for p in L)
True

Setting multiple leading coefficients:
sage: R.<T> = QQ[]
sage: l = R.weil_polynomials(4, 2, lead=((1,0), (2,4), (1,2))); l˓→needs sage.libs.flint[T^4 + 2*T^3 + 5*T^2 + 4*T + 4,T^4 + 2*T^3 + 3*T^2 + 4*T + 4,T^4 - 2*T^3 + 5*T^2 - 4*T + 4,T^4 - 2*T^3 + 3*T^2 - 4*T + 4]

2.1. Univariate Polynomials and Polynomial Rings#␣

49

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ T ]; (T,) = R._first_ngens(1)>>> l = R.weil_polynomials(Integer(4), Integer(2), lead=((Integer(1),˓→Integer(0)), (Integer(2),Integer(4)), (Integer(1),Integer(2)))); l˓→ # needs sage.libs.flint[T^4 + 2*T^3 + 5*T^2 + 4*T + 4,T^4 + 2*T^3 + 3*T^2 + 4*T + 4,T^4 - 2*T^3 + 5*T^2 - 4*T + 4,T^4 - 2*T^3 + 3*T^2 - 4*T + 4]

␣

We do not require Weil polynomials to be monic. This example generates Weil polynomials associated to K3
surfaces over F2 of Picard number at least 12:
sage: R.<T> = QQ[]
sage: l = R.weil_polynomials(10, 1, lead=2)
˓→needs sage.libs.flint
sage: len(l)˓→needs sage.libs.flint
4865
sage: l[len(l)//2]
˓→needs sage.libs.flint
2*T^10 + T^8 + T^6 + T^4 + T^2 + 2

#␣
#␣

#␣

>>> from sage.all import *>>> R = QQ[ T ]; (T,) = R._first_ngens(1)>>> l = R.weil_polynomials(Integer(10), Integer(1), lead=Integer(2))˓→# needs sage.libs.flint>>> len(l)˓→needs sage.libs.flint
4865>>> l[len(l)//Integer(2)]˓→# needs sage.libs.flint
2*T^10 + T^8 + T^6 + T^4 + T^2 + 2

␣
#␣

␣

sage.rings.polynomial.polynomial_ring.is_PolynomialRing(x)Return True if x is a univariate polynomial ring (and not a sparse multivariate polynomial ring in one variable).
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_ring import is_PolynomialRing
sage: from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing
sage: is_PolynomialRing(2)False>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_ring import is_PolynomialRing>>> from sage.rings.polynomial.multi_polynomial_ring import is_MPolynomialRing>>> is_PolynomialRing(Integer(2))
FalseThis polynomial ring is not univariate.
sage: is_PolynomialRing(ZZ[ x,y,z ])False
sage: is_MPolynomialRing(ZZ[ x,y,z ])
True

50

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> is_PolynomialRing(ZZ[ x,y,z ])False>>> is_MPolynomialRing(ZZ[ x,y,z ])Truesage: is_PolynomialRing(ZZ[ w ])True>>> from sage.all import *>>> 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: # needs sage.libs.singularsage: R.<w> = PolynomialRing(ZZ, implementation="singular"); R
Multivariate Polynomial Ring in w over Integer Ringsage: is_PolynomialRing(R)False
sage: type(R)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_
˓→libsingular >>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(ZZ, implementation="singular", names=( w ,)); (w,) = R._
˓→first_ngens(1); R
Multivariate Polynomial Ring in w over Integer Ring>>> is_PolynomialRing(R)False>>> type(R)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_
˓→libsingular >sage.rings.polynomial.polynomial_ring.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.
EXAMPLES:
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

2.1. Univariate Polynomials and Polynomial Rings

51

Polynomials, Release 10.4>>> from sage.all import *>>> z = polygen(QQ, z )>>> z**Integer(3) + z +Integer(1)z^3 + z + 1>>> 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().
sage.rings.polynomial.polynomial_ring.polygens(base_ring, names='x', *args)
Return indeterminates over the given base ring with the given names.
EXAMPLES:
sage: x,y,z = polygens(QQ, x,y,z )sage: (x+y+z)^2x^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)>>> from sage.all import *>>> x,y,z = polygens(QQ, x,y,z )>>> (x+y+z)**Integer(2)x^2 + 2*x*y + y^2 + 2*x*z + 2*y*z + z^2>>> parent(x)Multivariate Polynomial Ring in x, y, z over Rational Field>>> t = polygens(QQ, [ x , yz , abc ])>>> t(x, yz, abc)

The number of generators can be passed as a third argument:
sage: polygens(QQ,(x0, x1, x2, x3)

x , 4)>>> from sage.all import *>>> polygens(QQ, x , Integer(4))(x0, x1, x2, x3)

2.1.2 Ring homomorphisms from a polynomial ring to another ringThis module currently implements the canonical ring homomorphism from 𝐴[𝑥] to 𝐵[𝑥] induced by a ring homomorphismfrom 𝐴 to 𝐵.
Todo: Implement homomorphisms from 𝐴[𝑥] to an arbitrary ring 𝑅, given by a ring homomorphism from 𝐴 to 𝑅 and
the image of 𝑥 in 𝑅.
AUTHORS:
52

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• Peter Bruin (March 2014): initial version
class sage.rings.polynomial.polynomial_ring_homomorphism.
PolynomialRingHomomorphism_from_base
Bases: RingHomomorphism_from_base
The canonical ring homomorphism from 𝑅[𝑥] to 𝑆[𝑥] induced by a ring homomorphism from 𝑅 to 𝑆.
EXAMPLES:
sage: QQ[ x ].coerce_map_from(ZZ[ x ])Ring morphism:
From: Univariate Polynomial Ring in x over Integer RingTo:
Univariate Polynomial Ring in x over Rational Field
Defn: Induced from base ring by
Natural morphism:
From: Integer RingTo:
Rational Field>>> from sage.all import *>>> QQ[ x ].coerce_map_from(ZZ[ x ])Ring morphism:
From: Univariate Polynomial Ring in x over Integer RingTo:
Univariate Polynomial Ring in x over Rational Field
Defn: Induced from base ring by
Natural morphism:
From: Integer RingTo:
Rational Field

is_injective()
Return whether this morphism is injective.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: S.<x> = QQ[]
sage: R.hom(S).is_injective()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = QQ[ x ]; (x,) = S._first_ngens(1)>>> R.hom(S).is_injective()
True

is_surjective()
Return whether this morphism is surjective.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: S.<x> = Zmod(2)[]sage: R.hom(S).is_surjective()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

53

Polynomials, Release 10.4

(continued from previous page)>>> S = Zmod(Integer(2))[ x ]; (x,) = S._first_ngens(1)>>> R.hom(S).is_surjective()
True

2.1.3 Univariate polynomial base class
AUTHORS:• William Stein: first version• Martin Albrecht: added singular coercion• Robert Bradshaw: moved Polynomial_generic_dense to Cython• Miguel Marco: implemented resultant in the case where PARI fails• Simon King: used a faster way of conversion from the base ring
• Kwankyu Lee (2013-06-02): enhanced quo_rem()• Julian Rueth (2012-05-25,2014-05-09): fixed is_squarefree() for imperfect fields, fixed division without remainderover QQbar; added _cache_key for polynomials with unhashable coefficients• Simon King (2013-10): implemented copying of PolynomialBaseringInjection• Bruno Grenet (2014-07-13): enhanced quo_rem()• Kiran Kedlaya (2016-03): added root counting• Edgar Costa (2017-07): added rational reconstruction• Kiran Kedlaya (2017-09): added reciprocal transform, trace polynomial• David Zureick-Brown (2017-09): added is_weil_polynomial• Sebastian Oehms (2018-10): made roots() and factor() work over more cases of proper integral domains(see Issue #26421)
class sage.rings.polynomial.polynomial_element.ConstantPolynomialSection
Bases: Map
This class is used for conversion from a polynomial ring to its base ring.
Since Issue #9944, it calls the constant_coefficient() method, which can be optimized for a particularpolynomial type.
EXAMPLES:
sage: P0.<y_1> = GF(3)[]sage: P1.<y_2,y_1,y_0> = GF(3)[]sage: P0(-y_1)
2*y_1
sage: phi = GF(3).convert_map_from(P0); phi
Generic map:
From: Univariate Polynomial Ring in y_1 over Finite Field of size 3
To:
Finite Field of size 3
sage: type(phi)<class sage.rings.polynomial.polynomial_element.ConstantPolynomialSection >sage: phi(P0.one())
1(continues on next page)

54

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: phi(y_1)
Traceback (most recent call last):...
TypeError: y_1 is not a constant polynomial>>> from sage.all import *>>> P0 = GF(Integer(3))[ y_1 ]; (y_1,) = P0._first_ngens(1)>>> P1 = GF(Integer(3))[ y_2, y_1, y_0 ]; (y_2, y_1, y_0,) = P1._first_ngens(3)>>> P0(-y_1)
2*y_1>>> phi = GF(Integer(3)).convert_map_from(P0); phi
Generic map:
From: Univariate Polynomial Ring in y_1 over Finite Field of size 3
To:
Finite Field of size 3>>> type(phi)<class sage.rings.polynomial.polynomial_element.ConstantPolynomialSection >>>> phi(P0.one())
1>>> phi(y_1)
Traceback (most recent call last):...
TypeError: y_1 is not a constant polynomialclass sage.rings.polynomial.polynomial_element.Polynomial
Bases: CommutativePolynomial
A polynomial.
EXAMPLES:
sage: R.<y> = QQ[ y ]sage: S.<x> = R[ x ]sage: S
Univariate Polynomial Ring in x over Univariate Polynomial Ring in yover Rational Field
sage: f = x*y; fy*x
sage: type(f)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >sage: p = (y+1)^10; p(1)1024>>> from sage.all import *>>> R = QQ[ y ]; (y,) = R._first_ngens(1)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> S
Univariate Polynomial Ring in x over Univariate Polynomial Ring in yover Rational Field>>> f = x*y; fy*x>>> type(f)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >>>> p = (y+Integer(1))**Integer(10); p(Integer(1))
1024_add_(right)
2.1. Univariate Polynomials and Polynomial Rings

55

Polynomials, Release 10.4

Add two polynomials.
EXAMPLES:
sage: R = ZZ[ x ]sage: p = R([1,2,3,4])
sage: q = R([4,-3,2,-1])
sage: p + q# indirect doctest
3*x^3 + 5*x^2 - x + 5>>> from sage.all import *>>> R = ZZ[ x ]>>> p = R([Integer(1),Integer(2),Integer(3),Integer(4)])>>> q = R([Integer(4),-Integer(3),Integer(2),-Integer(1)])>>> p + q
# indirect doctest
3*x^3 + 5*x^2 - x + 5_sub_(other)
Default implementation of subtraction using addition and negation.
_lmul_(left)
Multiply self on the left by a scalar.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = (x^3 + x + 5)
sage: f._lmul_(7)7*x^3 + 7*x + 35
sage: 7*f
7*x^3 + 7*x + 35>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = (x**Integer(3) + x + Integer(5))>>> f._lmul_(Integer(7))
7*x^3 + 7*x + 35>>> Integer(7)*f7*x^3 + 7*x + 35

_rmul_(right)
Multiply self on the right by a scalar.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = (x^3 + x + 5)
sage: f._rmul_(7)7*x^3 + 7*x + 35
sage: f*7
7*x^3 + 7*x + 35>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = (x**Integer(3) + x + Integer(5))>>> f._rmul_(Integer(7))(continues on next page)

56

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

7*x^3 + 7*x + 35>>> f*Integer(7)7*x^3 + 7*x + 35

_mul_(right)
EXAMPLES:
sage: R.<x> = ZZ[]
sage: (x - 4) * (x^2 - 8*x + 16)
x^3 - 12*x^2 + 48*x - 64
sage: C.<t> = PowerSeriesRing(ZZ)
sage: D.
 = PolynomialRing(C)sage: z = (1 + O(t)) + t*s^2
sage: z*zt^2*s^4 + (2*t + O(t^2))*s^2 + 1 + O(t)## More examples from trac 2943, added by Kiran S. Kedlaya 2 Dec 09
sage: C.<t> = PowerSeriesRing(Integers())
sage: D.
 = PolynomialRing(C)sage: z = 1 + (t + O(t^2))*s + (t^2 + O(t^3))*s^2
sage: z*z(t^4 + O(t^5))*s^4 + (2*t^3 + O(t^4))*s^3 + (3*t^2 + O(t^3))*s^2 + (2*t + O(t^˓→2))*s + 1>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (x - Integer(4)) * (x**Integer(2) - Integer(8)*x + Integer(16))
x^3 - 12*x^2 + 48*x - 64>>> C = PowerSeriesRing(ZZ, names=( t ,)); (t,) = C._first_ngens(1)>>> D = PolynomialRing(C, names=( s ,)); (s,) = D._first_ngens(1)>>> z = (Integer(1) + O(t)) + t*s**Integer(2)>>> z*zt^2*s^4 + (2*t + O(t^2))*s^2 + 1 + O(t)## More examples from trac 2943, added by Kiran S. Kedlaya 2 Dec 09>>> C = PowerSeriesRing(Integers(), names=( t ,)); (t,) = C._first_ngens(1)>>> D = PolynomialRing(C, names=( s ,)); (s,) = D._first_ngens(1)>>> z = Integer(1) + (t + O(t**Integer(2)))*s + (t**Integer(2) +␣˓→O(t**Integer(3)))*s**Integer(2)>>> z*z(t^4 + O(t^5))*s^4 + (2*t^3 + O(t^4))*s^3 + (3*t^2 + O(t^3))*s^2 + (2*t + O(t^˓→2))*s + 1_mul_trunc_(right, n)
Return the truncated multiplication of two polynomials up to n.
This is the default implementation that does the multiplication and then truncate! There are custom implementations in several subclasses:• on dense polynomial over integers (via FLINT)• on dense polynomial over Z/nZ (via FLINT)• on dense rational polynomial (via FLINT)• on dense polynomial on Z/nZ (via NTL)
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

57

Polynomials, Release 10.4

sage: R = QQ[ x ][ y ]sage: y = R.gen()sage: x = R.base_ring().gen()sage: p1 = 1 - x*y + 2*y**3
sage: p2 = -1/3 + y**5
sage: p1._mul_trunc_(p2, 5)-2/3*y^3 + 1/3*x*y - 1/3>>> from sage.all import *>>> R = QQ[ x ][ y ]>>> y = R.gen()>>> x = R.base_ring().gen()>>> p1 = Integer(1) - x*y + Integer(2)*y**Integer(3)>>> p2 = -Integer(1)/Integer(3) + y**Integer(5)>>> p1._mul_trunc_(p2, Integer(5))-2/3*y^3 + 1/3*x*y - 1/3

Todo: implement a generic truncated Karatsuba and use it here.
adams_operator(*args, **kwds)
Deprecated: Use adams_operator_on_roots() instead. See Issue #36396 for details.
adams_operator_on_roots(n, monic=False)
Return the polynomial whose roots are the 𝑛-th powers of the roots of self.
INPUT:• 𝑛 – an integer• monic – boolean (default False) if set to True, force the output to be monic
EXAMPLES:
sage: # needs sage.libs.pari sage.libs.singularsage: f = cyclotomic_polynomial(30)sage: f.adams_operator_on_roots(7) == f
True
sage: f.adams_operator_on_roots(6) == cyclotomic_polynomial(5)**2
True
sage: f.adams_operator_on_roots(10) == cyclotomic_polynomial(3)**4
True
sage: f.adams_operator_on_roots(15) == cyclotomic_polynomial(2)**8
True
sage: f.adams_operator_on_roots(30) == cyclotomic_polynomial(1)**8
True
sage: x = polygen(QQ)
sage: f = x^2 - 2*x + 2
sage: f.adams_operator_on_roots(10)˓→# needs sage.libs.singularx^2 + 1024␣>>> from sage.all import *>>> # needs sage.libs.pari sage.libs.singular>>> f = cyclotomic_polynomial(Integer(30))>>> f.adams_operator_on_roots(Integer(7)) == f(continues on next page)

58

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True>>> f.adams_operator_on_roots(Integer(6)) == cyclotomic_
˓→polynomial(Integer(5))**Integer(2)True>>> f.adams_operator_on_roots(Integer(10)) == cyclotomic_
˓→polynomial(Integer(3))**Integer(4)True>>> f.adams_operator_on_roots(Integer(15)) == cyclotomic_
˓→polynomial(Integer(2))**Integer(8)True>>> f.adams_operator_on_roots(Integer(30)) == cyclotomic_
˓→polynomial(Integer(1))**Integer(8)True>>> x = polygen(QQ)>>> f = x**Integer(2) - Integer(2)*x + Integer(2)>>> f.adams_operator_on_roots(Integer(10))˓→# needs sage.libs.singularx^2 + 1024

␣When self is monic, the output will have leading coefficient ±1 depending on the degree, but we can force
it to be monic:
sage: R.<a,b,c> = ZZ[]
sage: x = polygen(R)sage: f = (x - a) * (x - b) * (x - c)sage: f.adams_operator_on_roots(3).factor()˓→# needs sage.libs.singular(-1) * (x - c^3) * (x - b^3) * (x - a^3)
sage: f.adams_operator_on_roots(3, monic=True).factor()˓→# needs sage.libs.singular(x - c^3) * (x - b^3) * (x - a^3)>>> from sage.all import *>>> R = ZZ[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> x = polygen(R)>>> f = (x - a) * (x - b) * (x - c)>>> f.adams_operator_on_roots(Integer(3)).factor()˓→# needs sage.libs.singular(-1) * (x - c^3) * (x - b^3) * (x - a^3)>>> f.adams_operator_on_roots(Integer(3), monic=True).factor()˓→# needs sage.libs.singular(x - c^3) * (x - b^3) * (x - a^3)

␣

␣

␣

␣

add_bigoh(prec)
Return the power series of precision at most prec got by adding 𝑂(𝑞 prec ) to self, where 𝑞 is its variable.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = 1 + 4*x + x^3
sage: f.add_bigoh(7)1 + 4*x + x^3 + O(x^7)
sage: f.add_bigoh(2)1 + 4*x + O(x^2)
sage: f.add_bigoh(2).parent()
Power Series Ring in x over Integer Ring

2.1. Univariate Polynomials and Polynomial Rings

59

Polynomials, Release 10.4>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(1) + Integer(4)*x + x**Integer(3)>>> f.add_bigoh(Integer(7))
1 + 4*x + x^3 + O(x^7)>>> f.add_bigoh(Integer(2))
1 + 4*x + O(x^2)>>> f.add_bigoh(Integer(2)).parent()
Power Series Ring in x over Integer Ring

all_roots_in_interval(a=None, b=None)
Return True if the roots of this polynomial are all real and contained in the given interval.
EXAMPLES:
sage: # needs sage.libs.pari
sage: R.<x> = PolynomialRing(ZZ)
sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3)sage: pol.all_roots_in_interval(1, 3)
True
sage: pol.all_roots_in_interval(1.01, 3)
False
sage: pol = chebyshev_T(5, x)
sage: pol.all_roots_in_interval(-1, 1)
True
sage: pol = chebyshev_T(5, x/2)
sage: pol.all_roots_in_interval(-1, 1)
False
sage: pol.all_roots_in_interval()
True>>> from sage.all import *>>> # needs sage.libs.pari>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = (x - Integer(1))**Integer(2) * (x - Integer(2))**Integer(2) * (x -␣˓→Integer(3))>>> pol.all_roots_in_interval(Integer(1), Integer(3))
True>>> pol.all_roots_in_interval(RealNumber( 1.01 ), Integer(3))
False>>> pol = chebyshev_T(Integer(5), x)>>> pol.all_roots_in_interval(-Integer(1), Integer(1))
True>>> pol = chebyshev_T(Integer(5), x/Integer(2))>>> pol.all_roots_in_interval(-Integer(1), Integer(1))
False>>> pol.all_roots_in_interval()
True

any_irreducible_factor(degree=None, assume_squarefree=False, assume_equal_deg=False,
ext_degree=None)
Return an irreducible factor of this polynomial.
INPUT:• degree (None or positive integer) – (default: None). Used for polynomials over finite fields. If None,
returns the the first factor found (usually the smallest). Otherwise, attempts to return an irreducible factor
of self of chosen degree degree.
60

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• assume_squarefree (boolean) – (default: False). Used for polynomials over finite fields. If
True, this polynomial is assumed to be squarefree.
• assume_equal_deg (boolean) – (default: False). Used for polynomials over finite fields. If True,
this polynomial is assumed to be the product of irreducible polynomials of degree equal to degree.
• ext_degree – positive integer or None (default); used for polynomials over finite fields. If not None
only returns irreducible factors of self whose degree divides ext_degree.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: F = GF(163)
sage: R.<x> = F[]sage: f = (x + 40)^3 * (x^5 + 76*x^4 + 93*x^3 + 112*x^2 + 22*x + 27)^2 * (x^6␣˓→+ 50*x^5 + 143*x^4 + 162*x^2 + 109*x + 140)
sage: f.any_irreducible_factor()x + 40sage: f.any_irreducible_factor(degree=5)x^5 + 76*x^4 + 93*x^3 + 112*x^2 + 22*x + 27>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(163))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> f = (x + Integer(40))**Integer(3) * (x**Integer(5) +␣˓→Integer(76)*x**Integer(4) + Integer(93)*x**Integer(3) +␣˓→Integer(112)*x**Integer(2) + Integer(22)*x + Integer(27))**Integer(2) *␣˓→(x**Integer(6) + Integer(50)*x**Integer(5) + Integer(143)*x**Integer(4) +␣˓→Integer(162)*x**Integer(2) + Integer(109)*x + Integer(140))>>> f.any_irreducible_factor()x + 40>>> f.any_irreducible_factor(degree=Integer(5))
x^5 + 76*x^4 + 93*x^3 + 112*x^2 + 22*x + 27

When the polynomial is known to be squarefree we can optimise the call by setting assume_squarefree
to be True:
sage: # needs sage.rings.finite_rings
sage: F = GF(163)
sage: R.<x> = F[]sage: g = (x - 1) * (x^3 + 7*x + 161)
sage: g.any_irreducible_factor(assume_squarefree=True)x + 162
sage: g.any_irreducible_factor(degree=3, assume_squarefree=True)x^3 + 7*x + 161>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(163))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = (x - Integer(1)) * (x**Integer(3) + Integer(7)*x + Integer(161))>>> g.any_irreducible_factor(assume_squarefree=True)x + 162>>> g.any_irreducible_factor(degree=Integer(3), assume_squarefree=True)x^3 + 7*x + 161

If we ask for an irreducible factor which does not exist, the function will throw a ValueError:

2.1. Univariate Polynomials and Polynomial Rings

61

Polynomials, Release 10.4

sage: # needs sage.rings.finite_rings
sage: F = GF(163)
sage: R.<x> = F[]sage: g = (x - 1) * (x^3 + 7*x + 161)
sage: g.any_irreducible_factor(degree=2, assume_squarefree=True)
Traceback (most recent call last):...
ValueError: no irreducible factor of degree 2 could be computed from x^4 +␣
˓→162*x^3 + 7*x^2 + 154*x + 2>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(163))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> g = (x - Integer(1)) * (x**Integer(3) + Integer(7)*x + Integer(161))>>> g.any_irreducible_factor(degree=Integer(2), assume_squarefree=True)
Traceback (most recent call last):...
ValueError: no irreducible factor of degree 2 could be computed from x^4 +␣
˓→162*x^3 + 7*x^2 + 154*x + 2

If we assume that the polynomial is product of irreducible polynomials of the same degree, we must also
supply the degree:
sage: # needs sage.rings.finite_rings
sage: F = GF(163)
sage: R.<x> = F[]sage: h = (x + 57) * (x + 98) * (x + 117) * (x + 145)
sage: h.any_irreducible_factor(degree=1, assume_equal_deg=True)# randomx + 98sage: h.any_irreducible_factor(assume_equal_deg=True)
Traceback (most recent call last):...
ValueError: degree must be known if distinct degree factorisation is assumed>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(163))>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> h = (x + Integer(57)) * (x + Integer(98)) * (x + Integer(117)) * (x +␣˓→Integer(145))>>> h.any_irreducible_factor(degree=Integer(1), assume_equal_deg=True)#␣˓→randomx + 98>>> h.any_irreducible_factor(assume_equal_deg=True)
Traceback (most recent call last):...
ValueError: degree must be known if distinct degree factorisation is assumed

Also works for extension fields and even characteristic:
sage: F.<z4> = GF(2^4)
sage: R.<x> = F[]sage: f = (x + z4^3 + z4^2)^4 * (x^2 + z4*x + z4) * (x^2 + (z4^3 + z4^2 +␣˓→z4)*x + z4^2 + z4 + 1)
sage: f.any_irreducible_factor()x + z4^3 + z4^2(continues on next page)

62

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.any_irreducible_factor(degree=2) # randomx^2 + (z4^3 + z4^2 + z4)*x + z4^2 + z4 + 1>>> from sage.all import *>>> F = GF(Integer(2)**Integer(4), names=( z4 ,)); (z4,) = F._first_ngens(1)>>> R = F[ x ]; (x,) = R._first_ngens(1)>>> f = (x + z4**Integer(3) + z4**Integer(2))**Integer(4) * (x**Integer(2) +␣˓→z4*x + z4) * (x**Integer(2) + (z4**Integer(3) + z4**Integer(2) + z4)*x +␣
˓→z4**Integer(2) + z4 + Integer(1))>>> f.any_irreducible_factor()x + z4^3 + z4^2>>> f.any_irreducible_factor(degree=Integer(2)) # randomx^2 + (z4^3 + z4^2 + z4)*x + z4^2 + z4 + 1

We can also use this function for polynomials which are not defined over finite fields, but this simply fallsback to a slow method of factorisation:
sage: R.<x> = ZZ[]
sage: f = 3*x^4 + 2*x^3sage: f.any_irreducible_factor()
3*x + 2>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(3)*x**Integer(4) + Integer(2)*x**Integer(3)>>> f.any_irreducible_factor()
3*x + 2

any_root(ring=None, degree=None, assume_squarefree=False, assume_equal_deg=False)
Return a root of this polynomial in the given ring.
INPUT:• ring – The ring in which a root is sought. By default this is the coefficient ring.
• degree (None or nonzero integer) – Used for polynomials over finite fields. Return a root of degreeabs(degree) over the ground field. If negative, also assumes that all factors of this polynomial areof degree abs(degree). If None, returns a root of minimal degree contained within the given ring.
• assume_squarefree (bool) – Used for polynomials over finite fields. If True, this polynomial is
assumed to be squarefree.
• assume_equal_deg (bool) – Used for polynomials over finite fields. If True, all factors of thispolynomial are assumed to have degree degree. Note that degree must be set.
Warning: Negative degree input will be deprecated. Instead use assume_equal_deg.

Note: For finite fields, any_root() is non-deterministic when finding linear roots of a polynomial overthe base ring. However, if degree is greater than one, or ring is an extension of the base ring, then the root
computed is found by attempting to return a root after factorisation. Roots found in this way are deterministic.
This may change in the future. For all other rings or fields, roots are found by first fully-factoring self andthe output is deterministic.
EXAMPLES:
2.1. Univariate Polynomials and Polynomial Rings

63

Polynomials, Release 10.4

sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(11)[]sage: f = 7*x^7 + 8*x^6 + 4*x^5 + x^4 + 6*x^3 + 10*x^2 + 8*x + 5
sage: f.any_root()2
sage: f.factor()(7) * (x + 9) * (x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2)
sage: f = x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2
sage: root = f.any_root(GF(11^6, a ))sage: roots = sorted(f.roots(GF(11^6, a ), multiplicities=False))
sage: roots[10*a^5 + 2*a^4 + 8*a^3 + 9*a^2 + a,a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a,
9*a^5 + 5*a^4 + 10*a^3 + 8*a^2 + 3*a + 1,
2*a^5 + 8*a^4 + 3*a^3 + 6*a + 2,a^5 + 3*a^4 + 8*a^3 + 2*a^2 + 3*a + 4,
10*a^5 + 3*a^4 + 8*a^3 + a^2 + 10*a + 4]
sage: root in roots
Truesage: # needs sage.rings.finite_rings
sage: g = (x-1) * (x^2 + 3*x + 9) * (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5)
sage: g.any_root(ring=GF(11^10, b ), degree=1)
1
sage: root = g.any_root(ring=GF(11^10, b ), degree=2)
sage: roots = (x^2 + 3*x + 9).roots(ring=GF(11^10, b ), multiplicities=False)
sage: root in roots
Truesage: root = g.any_root(ring=GF(11^10, b ), degree=5)
sage: roots = (x^5 + 5*x^4 + 8*x^3 + 5*x^2 + 3*x + 5).roots(ring=GF(11^10, b
˓→ ), multiplicities=False)
sage: root in rootsTrue>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(11))[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(7)*x**Integer(7) + Integer(8)*x**Integer(6) +␣˓→Integer(4)*x**Integer(5) + x**Integer(4) + Integer(6)*x**Integer(3) +␣˓→Integer(10)*x**Integer(2) + Integer(8)*x + Integer(5)>>> f.any_root()2>>> f.factor()(7) * (x + 9) * (x^6 + 10*x^4 + 6*x^3 + 5*x^2 + 2*x + 2)>>> f = x**Integer(6) + Integer(10)*x**Integer(4) + Integer(6)*x**Integer(3)␣
˓→+ Integer(5)*x**Integer(2) + Integer(2)*x + Integer(2)>>> root = f.any_root(GF(Integer(11)**Integer(6), a ))>>> roots = sorted(f.roots(GF(Integer(11)**Integer(6), a ),␣˓→multiplicities=False))>>> roots[10*a^5 + 2*a^4 + 8*a^3 + 9*a^2 + a,a^5 + a^4 + 7*a^3 + 2*a^2 + 10*a,
9*a^5 + 5*a^4 + 10*a^3 + 8*a^2 + 3*a + 1,
2*a^5 + 8*a^4 + 3*a^3 + 6*a + 2,a^5 + 3*a^4 + 8*a^3 + 2*a^2 + 3*a + 4,
10*a^5 + 3*a^4 + 8*a^3 + a^2 + 10*a + 4]>>> root in roots(continues on next page)

64

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True>>> # needs sage.rings.finite_rings>>> g = (x-Integer(1)) * (x**Integer(2) + Integer(3)*x + Integer(9)) *␣
˓→(x**Integer(5) + Integer(5)*x**Integer(4) + Integer(8)*x**Integer(3) +␣˓→Integer(5)*x**Integer(2) + Integer(3)*x + Integer(5))>>> g.any_root(ring=GF(Integer(11)**Integer(10), b ), degree=Integer(1))
1>>> root = g.any_root(ring=GF(Integer(11)**Integer(10), b ),␣
˓→degree=Integer(2))>>> roots = (x**Integer(2) + Integer(3)*x + Integer(9)).
˓→roots(ring=GF(Integer(11)**Integer(10),b ), multiplicities=False)>>> root in roots
True>>> root = g.any_root(ring=GF(Integer(11)**Integer(10), b ),␣
˓→degree=Integer(5))>>> roots = (x**Integer(5) + Integer(5)*x**Integer(4) +␣˓→Integer(8)*x**Integer(3) + Integer(5)*x**Integer(2) + Integer(3)*x +␣˓→Integer(5)).roots(ring=GF(Integer(11)**Integer(10),b ),␣
˓→multiplicities=False)>>> root in rootsTrue

args()
Return the generator of this polynomial ring, which is the (only) argument used when calling self.
EXAMPLES:
sage: R.<x> = QQ[]
sage: x.args()(x,)>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> x.args()(x,)

A constant polynomial has no variables, but still takes a single argument.
sage: R(2).args()(x,)>>> from sage.all import *>>> R(Integer(2)).args()(x,)

base_extend(R)Return a copy of this polynomial but with coefficients in R, if there is a natural map from the coefficient ringof self to R.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^3 - 17*x + 3
sage: f.base_extend(GF(7))
Traceback (most recent call last):(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

65

Polynomials, Release 10.4

(continued from previous page)...
TypeError: no such base extension
sage: f.change_ring(GF(7))
x^3 + 4*x + 3>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) - Integer(17)*x + Integer(3)>>> f.base_extend(GF(Integer(7)))
Traceback (most recent call last):...
TypeError: no such base extension>>> f.change_ring(GF(Integer(7)))
x^3 + 4*x + 3

base_ring()
Return the base ring of the parent of self.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: x.base_ring()
Integer Ringsage: (2*x + 3).base_ring()
Integer Ring>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> x.base_ring()
Integer Ring>>> (Integer(2)*x + Integer(3)).base_ring()
Integer Ringchange_ring(R)Return a copy of this polynomial but with coefficients in R, if at all possible.
INPUT:• R – a ring or morphism.
EXAMPLES:
sage: K.<z> = CyclotomicField(3)˓→needs sage.rings.number_fieldsage: f = K.defining_polynomial()
˓→needs sage.rings.number_fieldsage: f.change_ring(GF(7))˓→needs sage.rings.finite_rings sage.rings.number_fieldx^2 + x + 1

#␣
#␣
#␣

>>> from sage.all import *>>> K = CyclotomicField(Integer(3), names=( z ,)); (z,) = K._first_ngens(1)#␣
˓→needs sage.rings.number_field>>> f = K.defining_polynomial()#␣˓→needs sage.rings.number_field>>> f.change_ring(GF(Integer(7)))␣(continues on next page)

66

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)# needs sage.rings.finite_rings sage.rings.number_fieldx^2 + x + 1
˓→sage: # needs sage.rings.number_fieldsage: K.<z> = CyclotomicField(3)sage: R.<x> = K[]
sage: f = x^2 + z
sage: f.change_ring(K.embeddings(CC)[1])˓→needs sage.rings.real_mpfrx^2 - 0.500000000000000 - 0.866025403784438*I>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(3), names=( z ,)); (z,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + z>>> f.change_ring(K.embeddings(CC)[Integer(1)])˓→# needs sage.rings.real_mpfrx^2 - 0.500000000000000 - 0.866025403784438*I
sage: R.<x> = QQ[]
sage: f = x^2 + 1
sage: f.change_ring(QQ.embeddings(CC)[0])˓→needs sage.rings.real_mpfr
x^2 + 1.00000000000000>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> f.change_ring(QQ.embeddings(CC)[Integer(0)])˓→# needs sage.rings.real_mpfr
x^2 + 1.00000000000000

#␣

␣

#␣

␣

change_variable_name(var)
Return a new polynomial over the same base ring but in a different variable.
EXAMPLES:
sage: x = polygen(QQ, x )sage: f = -2/7*x^3 + (2/3)*x - 19/993; f-2/7*x^3 + 2/3*x - 19/993
sage: f.change_variable_name( theta )-2/7*theta^3 + 2/3*theta - 19/993>>> from sage.all import *>>> x = polygen(QQ, x )>>> f = -Integer(2)/Integer(7)*x**Integer(3) + (Integer(2)/Integer(3))*x -␣
˓→Integer(19)/Integer(993); f-2/7*x^3 + 2/3*x - 19/993>>> f.change_variable_name( theta )-2/7*theta^3 + 2/3*theta - 19/993

coefficients(sparse=True)
Return the coefficients of the monomials appearing in self.

2.1. Univariate Polynomials and Polynomial Rings

67

Polynomials, Release 10.4

If sparse=True (the default), it returns only the non-zero coefficients. Otherwise, it returns the same value
as self.list(). (In this case, it may be slightly faster to invoke self.list() directly.) In either case,the coefficients are ordered by increasing degree.
EXAMPLES:
sage: _.<x> = PolynomialRing(ZZ)
sage: f = 3*x^4 + 2*x^2 + 1
sage: f.coefficients()[1, 2, 3]
sage: f.coefficients(sparse=False)[1, 0, 2, 0, 3]>>> from sage.all import *>>> _ = PolynomialRing(ZZ, names=( x ,)); (x,) = _._first_ngens(1)>>> f = Integer(3)*x**Integer(4) + Integer(2)*x**Integer(2) + Integer(1)>>> f.coefficients()[1, 2, 3]>>> f.coefficients(sparse=False)[1, 0, 2, 0, 3]

complex_roots()
Return the complex roots of this polynomial, without multiplicities.
Calls self.roots(ring=CC), unless this is a polynomial with floating-point coefficients, in which case
it is uses the appropriate precision from the input coefficients.
EXAMPLES:
sage: # needs sage.libs.pari sage.rings.real_mpfr
sage: x = polygen(ZZ)
sage: (x^3 - 1).complex_roots()# note: low order bits slightly different␣˓→on ppc.
[1.00000000000000,-0.500000000000000 - 0.86602540378443...*I,-0.500000000000000 + 0.86602540378443...*I]>>> from sage.all import *>>> # needs sage.libs.pari sage.rings.real_mpfr>>> x = polygen(ZZ)>>> (x**Integer(3) - Integer(1)).complex_roots()
˓→slightly different on ppc.
[1.00000000000000,-0.500000000000000 - 0.86602540378443...*I,-0.500000000000000 + 0.86602540378443...*I]# note: low order bits␣

compose_power(k, algorithm=None, monic=False)
Return the 𝑘-th iterate of the composed product of this polynomial with itself.
INPUT:• 𝑘 – a non-negative integer• algorithm – None (default), "resultant" or "BFSS". See composed_op()• monic – False (default) or True. See composed_op()
OUTPUT:

68

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

The polynomial of degree 𝑑𝑘 where 𝑑 is the degree, whose roots are all 𝑘-fold products of roots of thispolynomial. That is, 𝑓 * 𝑓 * · · · * 𝑓 where this is 𝑓 and 𝑓 * 𝑓 = f.composed_op(f, operator.mul).
EXAMPLES:
sage: R.<a,b,c> = ZZ[]
sage: x = polygen(R)sage: f = (x - a) * (x - b) * (x - c)sage: f.compose_power(2).factor()#␣˓→needs sage.libs.singular sage.modules(x - c^2) * (x - b^2) * (x - a^2) * (x - b*c)^2 * (x - a*c)^2 * (x - a*b)^2
sage: # needs sage.libs.singular sage.modules
sage: x = polygen(QQ)
sage: f = x^2 - 2*x + 2
sage: f2 = f.compose_power(2); f2x^4 - 4*x^3 + 8*x^2 - 16*x + 16
sage: f2 == f.composed_op(f, operator.mul)
True
sage: f3 = f.compose_power(3); f3x^8 - 8*x^7 + 32*x^6 - 64*x^5 + 128*x^4 - 512*x^3 + 2048*x^2 - 4096*x + 4096
sage: f3 == f2.composed_op(f, operator.mul)
True
sage: f4 = f.compose_power(4)sage: f4 == f3.composed_op(f, operator.mul)
True>>> from sage.all import *>>> R = ZZ[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> x = polygen(R)>>> f = (x - a) * (x - b) * (x - c)>>> f.compose_power(Integer(2)).factor()˓→# needs sage.libs.singular sage.modules(x - c^2) * (x - b^2) * (x - a^2) * (x - b*c)^2 * (x - a*c)^2 * (x - a*b)^2␣>>> # needs sage.libs.singular sage.modules>>> x = polygen(QQ)>>> f = x**Integer(2) - Integer(2)*x + Integer(2)>>> f2 = f.compose_power(Integer(2)); f2x^4 - 4*x^3 + 8*x^2 - 16*x + 16>>> f2 == f.composed_op(f, operator.mul)
True>>> f3 = f.compose_power(Integer(3)); f3x^8 - 8*x^7 + 32*x^6 - 64*x^5 + 128*x^4 - 512*x^3 + 2048*x^2 - 4096*x + 4096>>> f3 == f2.composed_op(f, operator.mul)
True>>> f4 = f.compose_power(Integer(4))>>> f4 == f3.composed_op(f, operator.mul)
True

compose_trunc(other, n)
Return the composition of self and other, truncated to 𝑂(𝑥𝑛 ).
This method currently works for some specific coefficient rings only.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

69

Polynomials, Release 10.4

sage: Pol.<x> = CBF[]
˓→needs sage.libs.flint
sage: (1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120).compose_trunc(1 + x, 2)
˓→needs sage.libs.flint([2.708333333333333 +/- ...e-16])*x + [2.71666666666667 +/- ...e-15]#␣#␣

sage: Pol.<x> = QQ[ y ][]sage: (1 + x + x^2/2 + x^3/6 + x^4/24 + x^5/120).compose_trunc(1 + x, 2)Traceback (most recent call last):...
NotImplementedError: truncated composition is not implemented
for this subclass of polynomials>>> from sage.all import *>>> Pol = CBF[ x ]; (x,) = Pol._first_ngens(1)# needs sage.libs.flint>>> (Integer(1) + x + x**Integer(2)/Integer(2) + x**Integer(3)/Integer(6) +␣˓→x**Integer(4)/Integer(24) + x**Integer(5)/Integer(120)).compose_
˓→trunc(Integer(1) + x, Integer(2))# needs sage.libs.flint([2.708333333333333 +/- ...e-16])*x + [2.71666666666667 +/- ...e-15]>>> Pol = QQ[ y ][ x ]; (x,) = Pol._first_ngens(1)>>> (Integer(1) + x + x**Integer(2)/Integer(2) + x**Integer(3)/Integer(6) +␣˓→x**Integer(4)/Integer(24) + x**Integer(5)/Integer(120)).compose_
˓→trunc(Integer(1) + x, Integer(2))
Traceback (most recent call last):...
NotImplementedError: truncated composition is not implemented
for this subclass of polynomials

composed_op(p1, p2, op, algorithm=None, monic=False)
Return the composed sum, difference, product or quotient of this polynomial with another one.
In the case of two monic polynomials 𝑝1 and 𝑝2 over an integral domain, the composed sum, difference, etc.
are given by∏︁(𝑥 − (𝑎 * 𝑏)),* {+, −, , /}𝑝1 (𝑎)=𝑝2 (𝑏)=0

where the roots 𝑎 and 𝑏 are to be considered in the algebraic closure of the fraction field of the coefficients anddeg(𝑝 ) deg(𝑝 )counted with multiplicities. If the polynomials are not monic this quantity is multiplied by 𝛼1 2 𝛼2 1
where 𝛼1 and 𝛼2 are the leading coefficients of 𝑝1 and 𝑝2 respectively.
INPUT:• p2 – univariate polynomial belonging to the same polynomial ring as this polynomial• op – operator.OP where OP=add or sub or mul or truediv.
• algorithm – can be "resultant" or "BFSS"; by default the former is used when the polynomials
have few nonzero coefficients and small degrees or if the base ring is not Z or . Otherwise the latter isused.
• monic – whether to return a monic polynomial. If True the coefficients of the result belong to thefraction field of the coefficients.
ALGORITHM:
The computation is straightforward using resultants. Indeed for the composed sum it would be 𝑅𝑒𝑠𝑦 (𝑝1 (𝑥 −𝑦), 𝑝2 (𝑦)). However, the method from [BFSS2006] using series expansions is asymptotically much faster.

70

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Note that the algorithm BFSS with polynomials with coefficients in Z needs to perform operations over

.

Todo:
• The [BFSS2006] algorithm has been implemented here only in the case of polynomials over rationals.
For other rings of zero characteristic (or if the characteristic is larger than the product of the degrees), one
needs to implement a generic method _exp_series. In the general case of non-zero characteristic
there is an alternative algorithm in the same paper.
• The Newton series computation can be done much more efficiently! See [BFSS2006].
EXAMPLES:
sage: x = polygen(ZZ)
sage: p1 = x^2 - 1
sage: p2 = x^4 - 1
sage: p1.composed_op(p2, operator.add)
˓→needs sage.libs.singularx^8 - 4*x^6 + 4*x^4 - 16*x^2
sage: p1.composed_op(p2, operator.mul)
˓→needs sage.libs.singularx^8 - 2*x^4 + 1
sage: p1.composed_op(p2, operator.truediv)
˓→needs sage.libs.singularx^8 - 2*x^4 + 1

#␣

#␣

#␣

>>> from sage.all import *>>> x = polygen(ZZ)>>> p1 = x**Integer(2) - Integer(1)>>> p2 = x**Integer(4) - Integer(1)>>> p1.composed_op(p2, operator.add)
˓→needs sage.libs.singularx^8 - 4*x^6 + 4*x^4 - 16*x^2>>> p1.composed_op(p2, operator.mul)
˓→needs sage.libs.singularx^8 - 2*x^4 + 1>>> p1.composed_op(p2, operator.truediv)
˓→needs sage.libs.singularx^8 - 2*x^4 + 1

This function works over any field. However for base rings other than Z andavailable:

#␣

#␣

#␣

only the resultant algorithm issage: # needs sage.rings.number_fieldsage: x = polygen(QQbar)
sage: p1 = x**2 - AA(2).sqrt()
sage: p2 = x**3 - AA(3).sqrt()
sage: r1 = p1.roots(multiplicities=False)
sage: r2 = p2.roots(multiplicities=False)
sage: p = p1.composed_op(p2, operator.add); px^6 - 4.242640687119285?*x^4 - 3.464101615137755?*x^3 + 6*x^2- 14.69693845669907?*x + 0.1715728752538099?
sage: all(p(x+y).is_zero() for x in r1 for y in r2)
True
sage: x = polygen(GF(2))
sage: p1 = x**2 + x - 1(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

71

Polynomials, Release 10.4

(continued from previous page)

sage: p2 = x**3 + x - 1
sage: p_add = p1.composed_op(p2, operator.add); p_add
˓→needs sage.libs.singularx^6 + x^5 + x^3 + x^2 + 1
sage: p_mul = p1.composed_op(p2, operator.mul); p_mul
˓→needs sage.libs.singularx^6 + x^4 + x^2 + x + 1
sage: p_div = p1.composed_op(p2, operator.truediv); p_div
˓→needs sage.libs.singularx^6 + x^5 + x^4 + x^2 + 1

#␣

#␣

#␣

sage: # needs sage.rings.finite_rings
sage: K = GF(2**6, a )sage: r1 = p1.roots(K, multiplicities=False)
sage: r2 = p2.roots(K, multiplicities=False)
sage: all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2)
˓→needs sage.libs.singularTrue
sage: all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2)
˓→needs sage.libs.singularTrue
sage: all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2)
˓→needs sage.libs.singular
True

#␣

#␣

#␣

>>> from sage.all import *>>> # needs sage.rings.number_field>>> x = polygen(QQbar)>>> p1 = x**Integer(2) - AA(Integer(2)).sqrt()>>> p2 = x**Integer(3) - AA(Integer(3)).sqrt()>>> r1 = p1.roots(multiplicities=False)>>> r2 = p2.roots(multiplicities=False)>>> p = p1.composed_op(p2, operator.add); px^6 - 4.242640687119285?*x^4 - 3.464101615137755?*x^3 + 6*x^2- 14.69693845669907?*x + 0.1715728752538099?
>>> all(p(x+y).is_zero() for x in r1 for y in r2)
True>>> x = polygen(GF(Integer(2)))>>> p1 = x**Integer(2) + x - Integer(1)>>> p2 = x**Integer(3) + x - Integer(1)>>> p_add = p1.composed_op(p2, operator.add); p_add
˓→needs sage.libs.singularx^6 + x^5 + x^3 + x^2 + 1>>> p_mul = p1.composed_op(p2, operator.mul); p_mul
˓→needs sage.libs.singularx^6 + x^4 + x^2 + x + 1>>> p_div = p1.composed_op(p2, operator.truediv); p_div
˓→needs sage.libs.singularx^6 + x^5 + x^4 + x^2 + 1>>> # needs sage.rings.finite_rings>>> K = GF(Integer(2)**Integer(6), a )>>> r1 = p1.roots(K, multiplicities=False)>>> r2 = p2.roots(K, multiplicities=False)>>> all(p_add(x1+x2).is_zero() for x1 in r1 for x2 in r2)

#␣

#␣

#␣

#␣
(continues on next page)

72

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.singularTrue>>> all(p_mul(x1*x2).is_zero() for x1 in r1 for x2 in r2)
˓→needs sage.libs.singularTrue>>> all(p_div(x1/x2).is_zero() for x1 in r1 for x2 in r2)
˓→needs sage.libs.singular
True
˓→

#␣

#␣

constant_coefficient()
Return the constant coefficient of this polynomial.
OUTPUT: element of base ring
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = -2*x^3 + 2*x - 1/3
sage: f.constant_coefficient()-1/3>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = -Integer(2)*x**Integer(3) + Integer(2)*x - Integer(1)/Integer(3)>>> f.constant_coefficient()-1/3

content_ideal()
Return the content ideal of this polynomial, defined as the ideal generated by its coefficients.
EXAMPLES:
sage: R.<x> = IntegerModRing(4)[]sage: f = x^4 + 3*x^2 + 2
sage: f.content_ideal()
Ideal (2, 3, 1) of Ring of integers modulo 4>>> from sage.all import *>>> R = IntegerModRing(Integer(4))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) + Integer(3)*x**Integer(2) + Integer(2)>>> f.content_ideal()
Ideal (2, 3, 1) of Ring of integers modulo 4

When the base ring is a gcd ring, the content as a ring element is the generator of the content ideal:
sage: R.<x> = ZZ[]
sage: f = 2*x^3 - 4*x^2 + 6*x - 10sage: f.content_ideal().gen()2>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(2)*x**Integer(3) - Integer(4)*x**Integer(2) + Integer(6)*x -␣
˓→Integer(10)>>> f.content_ideal().gen()2

2.1. Univariate Polynomials and Polynomial Rings

73

Polynomials, Release 10.4

cyclotomic_part()
Return the product of the irreducible factors of this polynomial which are cyclotomic polynomials.
The algorithm assumes that the polynomial has rational coefficients.
See also:
is_cyclotomic() is_cyclotomic_product() has_cyclotomic_factor()
EXAMPLES:
sage: P.<x> = PolynomialRing(Integers())
sage: pol = 2*(x^4 + 1)
sage: pol.cyclotomic_part()x^4 + 1
sage: pol = x^4 + 2
sage: pol.cyclotomic_part()1
sage: pol = (x^4 + 1)^2 * (x^4 + 2)
sage: pol.cyclotomic_part()x^8 + 2*x^4 + 1
sage: P.<x> = PolynomialRing(QQ)
sage: pol = (x^4 + 1)^2 * (x^4 + 2)
sage: pol.cyclotomic_part()x^8 + 2*x^4 + 1
sage: pol = (x - 1) * x * (x + 2)
sage: pol.cyclotomic_part()x - 1>>> from sage.all import *>>> P = PolynomialRing(Integers(), names=( x ,)); (x,) = P._first_ngens(1)>>> pol = Integer(2)*(x**Integer(4) + Integer(1))>>> pol.cyclotomic_part()x^4 + 1>>> pol = x**Integer(4) + Integer(2)>>> pol.cyclotomic_part()1>>> pol = (x**Integer(4) + Integer(1))**Integer(2) * (x**Integer(4) +␣˓→Integer(2))>>> pol.cyclotomic_part()x^8 + 2*x^4 + 1>>> P = PolynomialRing(QQ, names=( x ,)); (x,) = P._first_ngens(1)>>> pol = (x**Integer(4) + Integer(1))**Integer(2) * (x**Integer(4) +␣˓→Integer(2))>>> pol.cyclotomic_part()x^8 + 2*x^4 + 1>>> pol = (x - Integer(1)) * x * (x + Integer(2))>>> pol.cyclotomic_part()x - 1

degree(gen=None)
Return the degree of this polynomial. The zero polynomial has degree −1.
EXAMPLES:

74

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: x = ZZ[ x ].0
sage: f = x^93 + 2*x + 1
sage: f.degree()93
sage: x = PolynomialRing(QQ,
sage: f = x^100000
sage: f.degree()100000x , sparse=True).0>>> from sage.all import *>>> x = ZZ[ x ].gen(0)>>> f = x**Integer(93) + Integer(2)*x + Integer(1)>>> f.degree()93>>> x = PolynomialRing(QQ, x , sparse=True).gen(0)>>> f = x**Integer(100000)>>> f.degree()100000sage: x = QQ[ x ].0
sage: f = 2006*x^2006 - x^2 + 3
sage: f.degree()2006
sage: f = 0*x
sage: f.degree()-1
sage: f = x + 33
sage: f.degree()1>>> from sage.all import *>>> x = QQ[ x ].gen(0)>>> f = Integer(2006)*x**Integer(2006) - x**Integer(2) + Integer(3)>>> f.degree()2006>>> f = Integer(0)*x>>> f.degree()-1>>> f = x + Integer(33)>>> f.degree()1

AUTHORS:• Naqi Jaffery (2006-01-24): examples
denominator()
Return a denominator of self.
First, the lcm of the denominators of the entries of self is computed and returned. If this computation fails,
the unit of the parent of self is returned.
Note that some subclasses may implement their own denominator() method. For example, see sage.
rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint

2.1. Univariate Polynomials and Polynomial Rings

75

Polynomials, Release 10.4

Warning: This is not the denominator of the rational function defined by self, which would always be
1 since self is a polynomial.
EXAMPLES:First we compute the denominator of a polynomial with integer coefficients, which is of course 1.
sage: R.<x> = ZZ[]
sage: f = x^3 + 17*x + 1
sage: f.denominator()
1>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + Integer(17)*x + Integer(1)>>> f.denominator()
1

Next we compute the denominator of a polynomial with rational coefficients.
sage: R.<x> = PolynomialRing(QQ)
sage: f = (1/17)*x^19 - (2/3)*x + 1/3; f
1/17*x^19 - 2/3*x + 1/3
sage: f.denominator()
51>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = (Integer(1)/Integer(17))*x**Integer(19) - (Integer(2)/Integer(3))*x +␣˓→Integer(1)/Integer(3); f
1/17*x^19 - 2/3*x + 1/3>>> f.denominator()
51

Finally, we try to compute the denominator of a polynomial with coefficients in the real numbers, which is aring whose elements do not have a denominator() method.
sage: # needs sage.rings.real_mpfr
sage: R.<x> = RR[]
sage: f = x + RR( 0.3 ); f
x + 0.300000000000000
sage: f.denominator()
1.00000000000000>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ x ]; (x,) = R._first_ngens(1)>>> f = x + RR( 0.3 ); f
x + 0.300000000000000>>> f.denominator()
1.00000000000000

Check that the denominator is an element over the base whenever the base has no denominator() method.
This closes Issue #9063.

76

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<a> = GF(5)[]sage: x = R(0)sage: x.denominator()1
sage: type(x.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >sage: isinstance(x.numerator() / x.denominator(), Polynomial)
True
sage: isinstance(x.numerator() / R(1), Polynomial)
False>>> from sage.all import *>>> R = GF(Integer(5))[ a ]; (a,) = R._first_ngens(1)>>> x = R(Integer(0))>>> x.denominator()
1>>> type(x.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >>>> isinstance(x.numerator() / x.denominator(), Polynomial)
True>>> isinstance(x.numerator() / R(Integer(1)), Polynomial)
False

derivative(*args)
The formal derivative of this polynomial, with respect to variables supplied in args.
Multiple variables and iteration counts may be supplied; see documentation for the global derivative()function for more details.
See also:_derivative()
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: g = -x^4 + x^2/2 - x
sage: g.derivative()-4*x^3 + x - 1
sage: g.derivative(x)-4*x^3 + x - 1
sage: g.derivative(x, x)-12*x^2 + 1
sage: g.derivative(x, 2)-12*x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> g = -x**Integer(4) + x**Integer(2)/Integer(2) - x>>> g.derivative()-4*x^3 + x - 1>>> g.derivative(x)-4*x^3 + x - 1>>> g.derivative(x, x)-12*x^2 + 1>>> g.derivative(x, Integer(2))-12*x^2 + 1

2.1. Univariate Polynomials and Polynomial Rings

77

Polynomials, Release 10.4

sage: R.<t> = PolynomialRing(ZZ)
sage: S.<x> = PolynomialRing(R)sage: f = t^3*x^2 + t^4*x^3sage: f.derivative()
3*t^4*x^2 + 2*t^3*x
sage: f.derivative(x)3*t^4*x^2 + 2*t^3*x
sage: f.derivative(t)4*t^3*x^3 + 3*t^2*x^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( t ,)); (t,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x ,)); (x,) = S._first_ngens(1)>>> f = t**Integer(3)*x**Integer(2) + t**Integer(4)*x**Integer(3)>>> f.derivative()
3*t^4*x^2 + 2*t^3*x>>> f.derivative(x)3*t^4*x^2 + 2*t^3*x>>> f.derivative(t)4*t^3*x^3 + 3*t^2*x^2

dict()
Return a sparse dictionary representation of this univariate polynomial.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^3 + -1/7*x + 13
sage: f.dict(){0: 13, 1: -1/7, 3: 1}>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + -Integer(1)/Integer(7)*x + Integer(13)>>> f.dict(){0: 13, 1: -1/7, 3: 1}

diff(*args)
The formal derivative of this polynomial, with respect to variables supplied in args.
Multiple variables and iteration counts may be supplied; see documentation for the global derivative()function for more details.
See also:_derivative()
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: g = -x^4 + x^2/2 - x
sage: g.derivative()-4*x^3 + x - 1
sage: g.derivative(x)-4*x^3 + x - 1
sage: g.derivative(x, x)-12*x^2 + 1(continues on next page)

78

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: g.derivative(x, 2)-12*x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> g = -x**Integer(4) + x**Integer(2)/Integer(2) - x>>> g.derivative()-4*x^3 + x - 1>>> g.derivative(x)-4*x^3 + x - 1>>> g.derivative(x, x)-12*x^2 + 1>>> g.derivative(x, Integer(2))-12*x^2 + 1
sage: R.<t> = PolynomialRing(ZZ)
sage: S.<x> = PolynomialRing(R)sage: f = t^3*x^2 + t^4*x^3sage: f.derivative()
3*t^4*x^2 + 2*t^3*x
sage: f.derivative(x)3*t^4*x^2 + 2*t^3*x
sage: f.derivative(t)4*t^3*x^3 + 3*t^2*x^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( t ,)); (t,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x ,)); (x,) = S._first_ngens(1)>>> f = t**Integer(3)*x**Integer(2) + t**Integer(4)*x**Integer(3)>>> f.derivative()
3*t^4*x^2 + 2*t^3*x>>> f.derivative(x)3*t^4*x^2 + 2*t^3*x>>> f.derivative(t)4*t^3*x^3 + 3*t^2*x^2differentiate(*args)
The formal derivative of this polynomial, with respect to variables supplied in args.
Multiple variables and iteration counts may be supplied; see documentation for the global derivative()function for more details.
See also:_derivative()
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: g = -x^4 + x^2/2 - x
sage: g.derivative()-4*x^3 + x - 1
sage: g.derivative(x)-4*x^3 + x - 1
sage: g.derivative(x, x)-12*x^2 + 1(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

79Polynomials, Release 10.4

(continued from previous page)

sage: g.derivative(x, 2)-12*x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> g = -x**Integer(4) + x**Integer(2)/Integer(2) - x>>> g.derivative()-4*x^3 + x - 1>>> g.derivative(x)-4*x^3 + x - 1>>> g.derivative(x, x)-12*x^2 + 1>>> g.derivative(x, Integer(2))-12*x^2 + 1
sage: R.<t> = PolynomialRing(ZZ)
sage: S.<x> = PolynomialRing(R)sage: f = t^3*x^2 + t^4*x^3sage: f.derivative()
3*t^4*x^2 + 2*t^3*x
sage: f.derivative(x)3*t^4*x^2 + 2*t^3*x
sage: f.derivative(t)4*t^3*x^3 + 3*t^2*x^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( t ,)); (t,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x ,)); (x,) = S._first_ngens(1)>>> f = t**Integer(3)*x**Integer(2) + t**Integer(4)*x**Integer(3)>>> f.derivative()
3*t^4*x^2 + 2*t^3*x>>> f.derivative(x)3*t^4*x^2 + 2*t^3*x>>> f.derivative(t)4*t^3*x^3 + 3*t^2*x^2

discriminant()
Return the discriminant of self.
The discriminant is
𝑅𝑛 := 𝑎2𝑛−2𝑛∏︁(𝑟𝑖 − 𝑟𝑗 )2 ,1<𝑖<𝑗<𝑛where 𝑛 is the degree of self, 𝑎𝑛 is the leading coefficient of self, and the roots of self are 𝑟1 , . . . , 𝑟𝑛 .
OUTPUT: An element of the base ring of the polynomial ring.
ALGORITHM:
Uses the identity 𝑅𝑛 (𝑓 ) := (−1)𝑛(𝑛−1)/2 𝑅(𝑓, 𝑓 ′ )𝑎𝑛−𝑘−2, where 𝑛 is the degree of self, 𝑎𝑛 is the leading𝑛coefficient of self, 𝑓 ′ is the derivative of 𝑓 , and 𝑘 is the degree of 𝑓 ′ . Calls resultant().
EXAMPLES:In the case of elliptic curves in special form, the discriminant is easy to calculate:

80

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<x> = QQ[]
sage: f = x^3 + x + 1
sage: d = f.discriminant(); d˓→needs sage.libs.pari-31
sage: d.parent() is QQ
˓→needs sage.libs.pari
True
sage: EllipticCurve([1, 1]).discriminant()/16
˓→needs sage.libs.pari sage.schemes
-31

#␣

#␣

#␣

>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(1)>>> d = f.discriminant(); d˓→needs sage.libs.pari-31>>> d.parent() is QQ
˓→needs sage.libs.pari
True>>> EllipticCurve([Integer(1), Integer(1)]).discriminant()/Integer(16)˓→# needs sage.libs.pari sage.schemes
-31

#␣

#␣

␣

sage: R.<x> = QQ[]
sage: f = 2*x^3 + x + 1
sage: d = f.discriminant(); d˓→needs sage.libs.pari-116>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(2)*x**Integer(3) + x + Integer(1)>>> d = f.discriminant(); d˓→needs sage.libs.pari
-116

#␣

#␣

We can compute discriminants over univariate and multivariate polynomial rings:
sage: R.<a> = QQ[]
sage: S.<x> = R[]
sage: f = a*x + x + a + 1
sage: d = f.discriminant(); d˓→needs sage.libs.pari
1sage: d.parent() is R
˓→needs sage.libs.pari
True>>> from sage.all import *>>> R = QQ[ a ]; (a,) = R._first_ngens(1)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = a*x + x + a + Integer(1)>>> d = f.discriminant(); d˓→needs sage.libs.pari

#␣

#␣

#␣
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

81

Polynomials, Release 10.4

(continued from previous page)1>>> d.parent() is R
˓→needs sage.libs.pari
True

#␣

sage: R.<a, b> = QQ[]
sage: S.<x> = R[]
sage: f = x^2 + a + b
sage: d = f.discriminant(); d˓→needs sage.libs.pari-4*a - 4*bsage: d.parent() is R
˓→needs sage.libs.pari
True

#␣

#␣

>>> from sage.all import *>>> R = QQ[ a, b ]; (a, b,) = R._first_ngens(2)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = x**Integer(2) + a + b>>> d = f.discriminant(); d˓→needs sage.libs.pari-4*a - 4*b>>> d.parent() is R
˓→needs sage.libs.pari
True

#␣

#␣

dispersion(other=None)
Compute the dispersion of a pair of polynomials.
The dispersion of 𝑓 and 𝑔 is the largest nonnegative integer 𝑛 such that 𝑓 (𝑥 + 𝑛) and 𝑔(𝑥) have a nonconstantcommon factor.
When other is None, compute the auto-dispersion of self, i.e., its dispersion with itself.
See also:
dispersion_set()
EXAMPLES:
sage: Pol.<x> = QQ[]
sage: x.dispersion(x + 1)
˓→needs sage.libs.pari
1sage: (x + 1).dispersion(x)˓→needs sage.libs.pari-Infinity#␣#␣

sage: # needs sage.libs.pari sage.rings.number_field sage.symbolic
sage: Pol.<x> = QQbar[]
sage: pol = Pol([sqrt(5), 1, 3/2])
sage: pol.dispersion()0
sage: (pol*pol(x+3)).dispersion()
382

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> Pol = QQ[ x ]; (x,) = Pol._first_ngens(1)>>> x.dispersion(x + Integer(1))˓→# needs sage.libs.pari
1>>> (x + Integer(1)).dispersion(x)˓→# needs sage.libs.pari-Infinity␣␣>>> # needs sage.libs.pari sage.rings.number_field sage.symbolic>>> Pol = QQbar[ x ]; (x,) = Pol._first_ngens(1)>>> pol = Pol([sqrt(Integer(5)), Integer(1), Integer(3)/Integer(2)])>>> pol.dispersion()0>>> (pol*pol(x+Integer(3))).dispersion()3

dispersion_set(other=None)
Compute the dispersion set of two polynomials.
The dispersion set of 𝑓 and 𝑔 is the set of nonnegative integers 𝑛 such that 𝑓 (𝑥 + 𝑛) and 𝑔(𝑥) have anonconstant common factor.
When other is None, compute the auto-dispersion set of self, i.e., its dispersion set with itself.
ALGORITHM:
See Section 4 of Man & Wright [MW1994].
See also:
dispersion()
EXAMPLES:
sage: Pol.<x> = QQ[]
sage: x.dispersion_set(x + 1)
˓→needs sage.libs.pari[1]sage: (x + 1).dispersion_set(x)˓→needs sage.libs.pari[]
sage: pol = x^3 + x - 7
sage: (pol*pol(x+3)^2).dispersion_set()˓→needs sage.libs.pari[0, 3]>>> from sage.all import *>>> Pol = QQ[ x ]; (x,) = Pol._first_ngens(1)>>> x.dispersion_set(x + Integer(1))˓→# needs sage.libs.pari[1]>>> (x + Integer(1)).dispersion_set(x)˓→# needs sage.libs.pari[]>>> pol = x**Integer(3) + x - Integer(7)>>> (pol*pol(x+Integer(3))**Integer(2)).dispersion_set()

#␣

#␣

#␣

␣

␣

␣
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

83

Polynomials, Release 10.4

(continued from previous page)˓→# needs sage.libs.pari[0, 3]

divides(p)Return True if this polynomial divides 𝑝.
This method is only implemented for polynomials over an integral domain.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: (2*x + 1).divides(4*x**2 - 1)Truesage: (2*x + 1).divides(4*x**2 + 1)
False
sage: (2*x + 1).divides(R(0))
True
sage: R(0).divides(2*x + 1)
False
sage: R(0).divides(R(0))
True
sage: S.<y> = R[]
sage: p = x * y**2 + (2*x + 1) * y + x + 1
sage: q = (x + 1) * y + (3*x + 2)
sage: q.divides(p)False
sage: q.divides(p * q)Truesage: R.<x> = Zmod(6)[]sage: p = 4*x + 3
sage: q = 5*x**2 + x + 2
sage: q.divides(p)False
sage: p.divides(q)False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x + Integer(1)).divides(Integer(4)*x**Integer(2) - Integer(1))
True>>> (Integer(2)*x + Integer(1)).divides(Integer(4)*x**Integer(2) + Integer(1))
False>>> (Integer(2)*x + Integer(1)).divides(R(Integer(0)))
True>>> R(Integer(0)).divides(Integer(2)*x + Integer(1))
False>>> R(Integer(0)).divides(R(Integer(0)))
True>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> p = x * y**Integer(2) + (Integer(2)*x + Integer(1)) * y + x + Integer(1)>>> q = (x + Integer(1)) * y + (Integer(3)*x + Integer(2))>>> q.divides(p)False>>> q.divides(p * q)
True>>> R = Zmod(Integer(6))[ x ]; (x,) = R._first_ngens(1)>>> p = Integer(4)*x + Integer(3)(continues on next page)

84

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> q = Integer(5)*x**Integer(2) + x + Integer(2)>>> q.divides(p)False>>> p.divides(q)Falseeuclidean_degree()Return the degree of this element as an element of an Euclidean domain.
If this polynomial is defined over a field, this is simply its degree().
EXAMPLES:
sage: R.<x> = QQ[]
sage: x.euclidean_degree()1
sage: R.<x> = ZZ[]
sage: x.euclidean_degree()Traceback (most recent call last):...
NotImplementedError>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> x.euclidean_degree()1>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> x.euclidean_degree()Traceback (most recent call last):...
NotImplementedError

exponents()
Return the exponents of the monomials appearing in self.
EXAMPLES:
sage: _.<x> = PolynomialRing(ZZ)
sage: f = x^4 + 2*x^2 + 1
sage: f.exponents()[0, 2, 4]>>> from sage.all import *>>> _ = PolynomialRing(ZZ, names=( x ,)); (x,) = _._first_ngens(1)>>> f = x**Integer(4) + Integer(2)*x**Integer(2) + Integer(1)>>> f.exponents()[0, 2, 4]factor(**kwargs)
Return the factorization of self over its base ring.
INPUT:• kwargs – any keyword arguments are passed to the method _factor_univariate_polynomial() of the base ring if it defines such a method.
OUTPUT:2.1. Univariate Polynomials and Polynomial Rings

85

Polynomials, Release 10.4

A factorization of self over its parent into a unit and irreducible factors. If the parent is a polynomial ringover a field, these factors are monic.
EXAMPLES:
Factorization is implemented over various rings. Over:sage: x = QQ[ x ].0
sage: f = (x^3 - 1)^2
sage: f.factor()˓→needs sage.libs.pari(x - 1)^2 * (x^2 + x + 1)^2#␣>>> from sage.all import *>>> x = QQ[ x ].gen(0)>>> f = (x**Integer(3) - Integer(1))**Integer(2)>>> f.factor()˓→needs sage.libs.pari(x - 1)^2 * (x^2 + x + 1)^2

Since

#␣

is a field, the irreducible factors are monic:

sage: f = 10*x^5 - 1
sage: f.factor()˓→needs sage.libs.pari(10) * (x^5 - 1/10)
sage: f = 10*x^5 - 10sage: f.factor()˓→needs sage.libs.pari(10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1)

#␣#␣>>> from sage.all import *>>> f = Integer(10)*x**Integer(5) - Integer(1)>>> f.factor()˓→needs sage.libs.pari(10) * (x^5 - 1/10)>>> f = Integer(10)*x**Integer(5) - Integer(10)>>> f.factor()˓→needs sage.libs.pari(10) * (x - 1) * (x^4 + x^3 + x^2 + x + 1)

#␣#␣Over Z the irreducible factors need not be monic:
sage: x = ZZ[ x ].0
sage: f = 10*x^5 - 1
sage: f.factor()˓→needs sage.libs.pari
10*x^5 - 1#␣>>> from sage.all import *>>> x = ZZ[ x ].gen(0)>>> f = Integer(10)*x**Integer(5) - Integer(1)>>> f.factor()˓→needs sage.libs.pari
10*x^5 - 1#␣

We factor a non-monic polynomial over a finite field of 25 elements:

86

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(25)sage: R.<x> = k[]sage: f = 2*x^10 + 2*x + 2*a
sage: F = f.factor(); F(2) * (x + a + 2) * (x^2 + 3*x + 4*a + 4) * (x^2 + (a + 1)*x + a + 2)
* (x^5 + (3*a + 4)*x^4 + (3*a + 3)*x^3 + 2*a*x^2 + (3*a + 1)*x + 3*a + 1)>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> k = GF(Integer(25), names=( a ,)); (a,) = k._first_ngens(1)>>> R = k[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(2)*x**Integer(10) + Integer(2)*x + Integer(2)*a>>> F = f.factor(); F(2) * (x + a + 2) * (x^2 + 3*x + 4*a + 4) * (x^2 + (a + 1)*x + a + 2)
* (x^5 + (3*a + 4)*x^4 + (3*a + 3)*x^3 + 2*a*x^2 + (3*a + 1)*x + 3*a + 1)

Notice that the unit factor is included when we multiply 𝐹 back out:
sage: expand(F)˓→needs sage.rings.finite_rings sage.symbolic
2*x^10 + 2*x + 2*a#␣>>> from sage.all import *>>> expand(F)˓→needs sage.rings.finite_rings sage.symbolic
2*x^10 + 2*x + 2*a#␣

A new ring. In the example below, we set the special method _factor_univariate_polynomial()in the base ring which is called to factor univariate polynomials. This facility can be used to easily extend
polynomial factorization to work over new rings you introduce:
sage: # needs sage.libs.ntl
sage: R.<x> = PolynomialRing(IntegerModRing(4), implementation="NTL")
sage: (x^2).factor()
Traceback (most recent call last):...
NotImplementedError: factorization of polynomials over rings withcomposite characteristic is not implemented
sage: def my_factor(f):....:return f.change_ring(ZZ).factor()sage: R.base_ring()._factor_univariate_polynomial = my_factor
sage: (x^2).factor()˓→needs sage.libs.parix^2
sage: del R.base_ring()._factor_univariate_polynomial # clean up#␣>>> from sage.all import *>>> # needs sage.libs.ntl>>> R = PolynomialRing(IntegerModRing(Integer(4)), implementation="NTL",␣
˓→names=( x ,)); (x,) = R._first_ngens(1)>>> (x**Integer(2)).factor()
Traceback (most recent call last):...
NotImplementedError: factorization of polynomials over rings withcomposite characteristic is not implemented(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

87

Polynomials, Release 10.4

(continued from previous page)>>> def my_factor(f):...
return f.change_ring(ZZ).factor()>>> R.base_ring()._factor_univariate_polynomial = my_factor>>> (x**Integer(2)).factor()˓→# needs sage.libs.parix^2>>> del R.base_ring()._factor_univariate_polynomial # clean up␣Arbitrary precision real and complex factorization:
sage: # needs sage.libs.pari sage.rings.real_mpfr
sage: R.<x> = RealField(100)[]
sage: F = factor(x^2 - 3); F(x - 1.7320508075688772935274463415) * (x + 1.7320508075688772935274463415)
sage: expand(F)x^2 - 3.0000000000000000000000000000
sage: factor(x^2 + 1)x^2 + 1.0000000000000000000000000000
sage: # needs sage.libs.pari sage.rings.real_mpfr
sage: R.<x> = ComplexField(100)[]
sage: F = factor(x^2 + 3); F(x - 1.7320508075688772935274463415*I) * (x + 1.
˓→7320508075688772935274463415*I)
sage: expand(F)x^2 + 3.0000000000000000000000000000
sage: factor(x^2 + 1)
(x - I) * (x + I)
sage: f = R(I) * (x^2 + 1) ; f
I*x^2 + I
sage: F = factor(f); F(1.0000000000000000000000000000*I) * (x - I) * (x + I)
sage: expand(F)I*x^2 + I>>> from sage.all import *>>> # needs sage.libs.pari sage.rings.real_mpfr>>> R = RealField(Integer(100))[ x ]; (x,) = R._first_ngens(1)>>> F = factor(x**Integer(2) - Integer(3)); F(x - 1.7320508075688772935274463415) * (x + 1.7320508075688772935274463415)>>> expand(F)x^2 - 3.0000000000000000000000000000>>> factor(x**Integer(2) + Integer(1))
x^2 + 1.0000000000000000000000000000>>> # needs sage.libs.pari sage.rings.real_mpfr>>> R = ComplexField(Integer(100))[ x ]; (x,) = R._first_ngens(1)>>> F = factor(x**Integer(2) + Integer(3)); F(x - 1.7320508075688772935274463415*I) * (x + 1.
˓→7320508075688772935274463415*I)>>> expand(F)x^2 + 3.0000000000000000000000000000>>> factor(x**Integer(2) + Integer(1))(x - I) * (x + I)>>> f = R(I) * (x**Integer(2) + Integer(1)) ; f
I*x^2 + I
(continues on next page)

88

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> F = factor(f); F(1.0000000000000000000000000000*I) * (x - I) * (x + I)>>> expand(F)I*x^2 + I

Over a number field:
sage: # needs sage.rings.number_fieldsage: K.<z> = CyclotomicField(15)sage: x = polygen(K)sage: ((x^3 + z*x + 1)^3 * (x - z)).factor()(x - z) * (x^3 + z*x + 1)^3
sage: cyclotomic_polynomial(12).change_ring(K).factor()(x^2 - z^5 - 1) * (x^2 + z^5)
sage: ((x^3 + z*x + 1)^3 * (x/(z+2) - 1/3)).factor()(-1/331*z^7 + 3/331*z^6 - 6/331*z^5 + 11/331*z^4- 21/331*z^3 + 41/331*z^2 - 82/331*z + 165/331)* (x - 1/3*z - 2/3) * (x^3 + z*x + 1)^3>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(15), names=( z ,)); (z,) = K._first_ngens(1)>>> x = polygen(K)>>> ((x**Integer(3) + z*x + Integer(1))**Integer(3) * (x - z)).factor()(x - z) * (x^3 + z*x + 1)^3>>> cyclotomic_polynomial(Integer(12)).change_ring(K).factor()(x^2 - z^5 - 1) * (x^2 + z^5)>>> ((x**Integer(3) + z*x + Integer(1))**Integer(3) * (x/(z+Integer(2)) -␣˓→Integer(1)/Integer(3))).factor()(-1/331*z^7 + 3/331*z^6 - 6/331*z^5 + 11/331*z^4- 21/331*z^3 + 41/331*z^2 - 82/331*z + 165/331)* (x - 1/3*z - 2/3) * (x^3 + z*x + 1)^3

Over a relative number field:
sage: # needs sage.rings.number_fieldsage: x = polygen(QQ)
sage: K.<z> = CyclotomicField(3)sage: L.<a> = K.extension(x^3 - 2)sage: t = polygen(L, t )sage: f = (t^3 + t + a) * (t^5 + t + z); ft^8 + t^6 + a*t^5 + t^4 + z*t^3 + t^2 + (a + z)*t + z*a
sage: f.factor()(t^3 + t + a) * (t^5 + t + z)>>> from sage.all import *>>> # needs sage.rings.number_field>>> x = polygen(QQ)>>> K = CyclotomicField(Integer(3), names=( z ,)); (z,) = K._first_ngens(1)>>> L = K.extension(x**Integer(3) - Integer(2), names=( a ,)); (a,) = L._˓→first_ngens(1)>>> t = polygen(L, t )>>> f = (t**Integer(3) + t + a) * (t**Integer(5) + t + z); ft^8 + t^6 + a*t^5 + t^4 + z*t^3 + t^2 + (a + z)*t + z*a>>> f.factor()(t^3 + t + a) * (t^5 + t + z)

2.1. Univariate Polynomials and Polynomial Rings

89

Polynomials, Release 10.4

Over the real double field:
sage: # needs numpy
sage: R.<x> = RDF[]
sage: (-2*x^2 - 1).factor()(-2.0) * (x^2 + 0.5000000000000001)
sage: (-2*x^2 - 1).factor().expand()-2.0*x^2 - 1.0000000000000002
sage: f = (x - 1)^3
sage: f.factor() # abs tol 2e-5
(x - 1.0000065719436413) * (x^2 - 1.9999934280563585*x + 0.9999934280995487)>>> from sage.all import *>>> # needs numpy>>> R = RDF[ x ]; (x,) = R._first_ngens(1)>>> (-Integer(2)*x**Integer(2) - Integer(1)).factor()(-2.0) * (x^2 + 0.5000000000000001)>>> (-Integer(2)*x**Integer(2) - Integer(1)).factor().expand()-2.0*x^2 - 1.0000000000000002>>> f = (x - Integer(1))**Integer(3)>>> f.factor() # abs tol 2e-5
(x - 1.0000065719436413) * (x^2 - 1.9999934280563585*x + 0.9999934280995487)

The above output is incorrect because it relies on the roots() method, which does not detect that all theroots are real:
sage: f.roots() # abs tol 2e-5
˓→needs numpy[(1.0000065719436413, 1)]#␣>>> from sage.all import *>>> f.roots() # abs tol 2e-5
˓→needs numpy[(1.0000065719436413, 1)]#␣Over the complex double field the factors are approximate and therefore occur with multiplicity 1:
sage: # needs numpy sage.rings.complex_double
sage: R.<x> = CDF[]
sage: f = (x^2 + 2*R(I))^3
sage: F = f.factor()sage: F # abs tol 3e-5
(x - 1.0000138879287663 + 1.0000013435286879*I)* (x - 0.9999942196864997 + 0.9999873009803959*I)* (x - 0.9999918923847313 + 1.0000113554909125*I)* (x + 0.9999908759550227 - 1.0000069659624138*I)* (x + 0.9999985293216753 - 0.9999886153831807*I)* (x + 1.0000105947233 - 1.0000044186544053*I)
sage: [f(t[0][0]).abs() for t in F] # abs tol 1e-13[1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14,
3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14]>>> from sage.all import *>>> # needs numpy sage.rings.complex_double>>> R = CDF[ x ]; (x,) = R._first_ngens(1)>>> f = (x**Integer(2) + Integer(2)*R(I))**Integer(3)>>> F = f.factor()(continues on next page)

90

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> F # abs tol 3e-5
(x - 1.0000138879287663 + 1.0000013435286879*I)* (x - 0.9999942196864997 + 0.9999873009803959*I)* (x - 0.9999918923847313 + 1.0000113554909125*I)* (x + 0.9999908759550227 - 1.0000069659624138*I)* (x + 0.9999985293216753 - 0.9999886153831807*I)* (x + 1.0000105947233 - 1.0000044186544053*I)>>> [f(t[Integer(0)][Integer(0)]).abs() for t in F] # abs tol 1e-13[1.979365054e-14, 1.97936298566e-14, 1.97936990747e-14,
3.6812407475e-14, 3.65211563729e-14, 3.65220890052e-14]

Factoring polynomials over Z/𝑛Z for composite 𝑛 is not implemented:
sage: R.<x> = PolynomialRing(Integers(35))
sage: f = (x^2 + 2*x + 2) * (x^2 + 3*x + 9)
sage: f.factor()
Traceback (most recent call last):...
NotImplementedError: factorization of polynomials overrings with composite characteristic is not implemented>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(35)), names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> f = (x**Integer(2) + Integer(2)*x + Integer(2)) * (x**Integer(2) +␣˓→Integer(3)*x + Integer(9))>>> f.factor()
Traceback (most recent call last):...
NotImplementedError: factorization of polynomials overrings with composite characteristic is not implemented

Factoring polynomials over the algebraic numbers (see Issue #8544):
sage: R.<x> = QQbar[]
˓→needs sage.rings.number_fieldsage: (x^8 - 1).factor()˓→needs sage.rings.number_field(x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I)* (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I)
* (x + 0.7071067811865475? - 0.7071067811865475?*I)* (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1)>>> from sage.all import *>>> R = QQbar[ x ]; (x,) = R._first_ngens(1)# needs sage.rings.number_field>>> (x**Integer(8) - Integer(1)).factor()˓→# needs sage.rings.number_field(x - 1) * (x - 0.7071067811865475? - 0.7071067811865475?*I)* (x - 0.7071067811865475? + 0.7071067811865475?*I) * (x - I) * (x + I)
* (x + 0.7071067811865475? - 0.7071067811865475?*I)* (x + 0.7071067811865475? + 0.7071067811865475?*I) * (x + 1)

#␣
#␣

␣

Factoring polynomials over the algebraic reals (see Issue #8544):
sage: R.<x> = AA[]˓→needs sage.rings.number_field#␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

91Polynomials, Release 10.4

(continued from previous page)

sage: (x^8 + 1).factor()˓→needs sage.rings.number_field(x^2 - 1.847759065022574?*x + 1.000000000000000?)* (x^2 - 0.7653668647301795?*x + 1.000000000000000?)* (x^2 + 0.7653668647301795?*x + 1.000000000000000?)* (x^2 + 1.847759065022574?*x + 1.000000000000000?)>>> from sage.all import *>>> R = AA[ x ]; (x,) = R._first_ngens(1)# needs sage.rings.number_field>>> (x**Integer(8) + Integer(1)).factor()˓→# needs sage.rings.number_field(x^2 - 1.847759065022574?*x + 1.000000000000000?)* (x^2 - 0.7653668647301795?*x + 1.000000000000000?)* (x^2 + 0.7653668647301795?*x + 1.000000000000000?)* (x^2 + 1.847759065022574?*x + 1.000000000000000?)#␣␣

gcd(other)
Return a greatest common divisor of this polynomial and other.
INPUT:• other – a polynomial in the same ring as this polynomial
OUTPUT:
A greatest common divisor as a polynomial in the same ring as this polynomial. If the base ring is a field, thereturn value is a monic polynomial.
Note: The actual algorithm for computing greatest common divisors depends on the base ring underlying
the polynomial ring. If the base ring defines a method _gcd_univariate_polynomial(), then thismethod will be called (see examples below).
EXAMPLES:
sage: R.<x> = QQ[]
sage: (2*x^2).gcd(2*x)
xsage: R.zero().gcd(0)0sage: (2*x).gcd(0)x>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x**Integer(2)).gcd(Integer(2)*x)x>>> R.zero().gcd(Integer(0))
0>>> (Integer(2)*x).gcd(Integer(0))
x

One can easily add gcd functionality to new rings by providing a method _gcd_univariate_polynomial:

92

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.rings.number_field sage.symbolic
sage: O = ZZ[-sqrt(5)]sage: R.<x> = O[]
sage: a = O.1
sage: p = x + a
sage: q = x^2 - 5sage: p.gcd(q)Traceback (most recent call last):...
NotImplementedError: Order of conductor 2 generated by a in Number
Field in a with defining polynomial x^2 - 5 with a = -2.236067977499790?
does not provide a gcd implementation for univariate polynomials
sage: S.<x> = O.number_field()[]sage: O._gcd_univariate_polynomial = lambda f, g: R(S(f).gcd(S(g)))
sage: p.gcd(q)x + asage: del O._gcd_univariate_polynomial>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> O = ZZ[-sqrt(Integer(5))]>>> R = O[ x ]; (x,) = R._first_ngens(1)>>> a = O.gen(1)>>> p = x + a>>> q = x**Integer(2) - Integer(5)>>> p.gcd(q)Traceback (most recent call last):...
NotImplementedError: Order of conductor 2 generated by a in Number
Field in a with defining polynomial x^2 - 5 with a = -2.236067977499790?
does not provide a gcd implementation for univariate polynomials>>> S = O.number_field()[ x ]; (x,) = S._first_ngens(1)>>> O._gcd_univariate_polynomial = lambda f, g: R(S(f).gcd(S(g)))>>> p.gcd(q)x + a>>> del O._gcd_univariate_polynomial

Use multivariate implementation for polynomials over polynomials rings:
sage: R.<x> = ZZ[]
sage: S.<y> = R[]
sage: T.<z> = S[]
sage: r = 2*x*y + z
sage: p = r * (3*x*y*z - 1)sage: q = r * (x + y + z - 2)sage: p.gcd(q)˓→needs sage.libs.singularz + 2*x*y
sage: R.<x> = QQ[]
sage: S.<y> = R[]
sage: r = 2*x*y + 1
sage: p = r * (x - 1/2 * y)sage: q = r * (x*y^2 - x + 1/3)
sage: p.gcd(q)˓→needs sage.libs.singular
2*x*y + 1

2.1. Univariate Polynomials and Polynomial Rings

#␣

#␣

93

Polynomials, Release 10.4>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> T = S[ z ]; (z,) = T._first_ngens(1)>>> r = Integer(2)*x*y + z>>> p = r * (Integer(3)*x*y*z - Integer(1))>>> q = r * (x + y + z - Integer(2))>>> p.gcd(q)˓→needs sage.libs.singularz + 2*x*y#␣>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> r = Integer(2)*x*y + Integer(1)>>> p = r * (x - Integer(1)/Integer(2) * y)>>> q = r * (x*y**Integer(2) - x + Integer(1)/Integer(3))>>> p.gcd(q)˓→needs sage.libs.singular
2*x*y + 1

#␣global_height(prec=None)
Return the (projective) global height of the polynomial.
This returns the absolute logarithmic height of the coefficients thought of as a projective point.
INPUT:• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: f = 3*x^3 + 2*x^2 + x
sage: exp(f.global_height())
˓→needs sage.symbolic
3.00000000000000#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(3)*x**Integer(3) + Integer(2)*x**Integer(2) + x>>> exp(f.global_height())
˓→needs sage.symbolic
3.00000000000000#␣

Scaling should not change the result:
sage: R.<x> = PolynomialRing(QQ)
sage: f = 1/25*x^2 + 25/3*x + 1
sage: f.global_height()
˓→needs sage.symbolic
6.43775164973640
sage: g = 100 * fsage: g.global_height()
˓→needs sage.symbolic
6.43775164973640

94

#␣

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/Integer(25)*x**Integer(2) + Integer(25)/Integer(3)*x +␣˓→Integer(1)>>> f.global_height()#␣˓→needs sage.symbolic
6.43775164973640>>> g = Integer(100) * f>>> g.global_height()#␣˓→needs sage.symbolic
6.43775164973640
sage: R.<x> = PolynomialRing(QQbar)
˓→needs sage.rings.number_fieldsage: f = QQbar(i)*x^2 + 3*x
˓→needs sage.rings.number_fieldsage: f.global_height()
˓→needs sage.rings.number_field
1.09861228866811

#␣
#␣
#␣

>>> from sage.all import *>>> R = PolynomialRing(QQbar, names=( x ,)); (x,) = R._first_ngens(1)# needs␣
˓→sage.rings.number_field>>> f = QQbar(i)*x**Integer(2) + Integer(3)*x␣˓→# needs sage.rings.number_field>>> f.global_height()#␣˓→needs sage.rings.number_field
1.09861228866811
sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(QQ)
sage: K.<k> = NumberField(x^2 + 5)
sage: T.<t> = PolynomialRing(K)sage: f = 1/1331 * t^2 + 5 * t + 7
sage: f.global_height()
9.13959596745043>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) + Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = PolynomialRing(K, names=( t ,)); (t,) = T._first_ngens(1)>>> f = Integer(1)/Integer(1331) * t**Integer(2) + Integer(5) * t + Integer(7)>>> f.global_height()
9.13959596745043
sage: R.<x> = QQ[]
sage: f = 1/123*x^2 + 12
sage: f.global_height(prec=2)
˓→needs sage.symbolic
8.0#␣

>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

95

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(1)/Integer(123)*x**Integer(2) + Integer(12)>>> f.global_height(prec=Integer(2))˓→# needs sage.symbolic
8.0␣

sage: R.<x> = QQ[]
sage: f = 0*x
sage: f.global_height()
˓→needs sage.rings.real_mpfr
0.000000000000000#␣>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(0)*x>>> f.global_height()
˓→needs sage.rings.real_mpfr
0.000000000000000#␣

gradient()
Return a list of the partial derivative of self with respect to the variable of this univariate polynomial.
There is only one partial derivative.
EXAMPLES:
sage: P.<x> = QQ[]
sage: f = x^2 + (2/3)*x + 1
sage: f.gradient()[2*x + 2/3]
sage: f = P(1)sage: f.gradient()[0]>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(2) + (Integer(2)/Integer(3))*x + Integer(1)>>> f.gradient()[2*x + 2/3]>>> f = P(Integer(1))>>> f.gradient()[0]

hamming_weight()
Return the number of non-zero coefficients of self.
Also called weight, Hamming weight or sparsity.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^3 - x
sage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x + 1)^100(continues on next page)

96

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.number_of_terms()
101
sage: S = GF(5)[ y ]sage: S(f).number_of_terms()5
sage: cyclotomic_polynomial(105).number_of_terms()
33>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) - x>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x + Integer(1))**Integer(100)>>> f.number_of_terms()
101>>> S = GF(Integer(5))[ y ]>>> S(f).number_of_terms()
5>>> cyclotomic_polynomial(Integer(105)).number_of_terms()
33

The method hamming_weight() is an alias:
sage: f.hamming_weight()
101>>> from sage.all import *>>> f.hamming_weight()
101

has_cyclotomic_factor()
Return True if the given polynomial has a nontrivial cyclotomic factor.
The algorithm assumes that the polynomial has rational coefficients.
If the polynomial is known to be irreducible, it may be slightly more efficient to call is_cyclotomic()
instead.
See also:
is_cyclotomic() is_cyclotomic_product() cyclotomic_part()
EXAMPLES:
sage: pol.<x> = PolynomialRing(Rationals())
sage: u = x^5 - 1; u.has_cyclotomic_factor()Truesage: u = x^5 - 2; u.has_cyclotomic_factor()
False
sage: u = pol(cyclotomic_polynomial(7)) * pol.random_element()
sage: u.has_cyclotomic_factor()True

2.1. Univariate Polynomials and Polynomial Rings# random# random97Polynomials, Release 10.4>>> from sage.all import *>>> pol = PolynomialRing(Rationals(), names=( x ,)); (x,) = pol._first_
˓→ngens(1)>>> u = x**Integer(5) - Integer(1); u.has_cyclotomic_factor()True>>> u = x**Integer(5) - Integer(2); u.has_cyclotomic_factor()
False>>> u = pol(cyclotomic_polynomial(Integer(7))) * pol.random_element() #␣˓→random>>> u.has_cyclotomic_factor()# randomTruehomogenize(var='h')Return the homogenization of this polynomial.
The polynomial itself is returned if it is homogeneous already. Otherwise, its monomials are multiplied withthe smallest powers of var such that they all have the same total degree.
INPUT:• var – a variable in the polynomial ring (as a string, an element of the ring, or 0) or a name for a newvariable (default: h )OUTPUT:If var specifies the variable in the polynomial ring, then a homogeneous element in that ring is returned.
Otherwise, a homogeneous element is returned in a polynomial ring with an extra last variable var.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^2 + 1
sage: f.homogenize()x^2 + h^2>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> f.homogenize()x^2 + h^2

The parameter var can be used to specify the name of the variable:
sage: g = f.homogenize( z ); gx^2 + z^2
sage: g.parent()
Multivariate Polynomial Ring in x, z over Rational Field>>> from sage.all import *>>> g = f.homogenize( z ); gx^2 + z^2>>> g.parent()
Multivariate Polynomial Ring in x, z over Rational Field

However, if the polynomial is homogeneous already, then that parameter is ignored and no extra variable isadded to the polynomial ring:98

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: f = x^2
sage: g = f.homogenize( z ); gx^2
sage: g.parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> f = x**Integer(2)>>> g = f.homogenize( z ); g
x^2>>> g.parent()
Univariate Polynomial Ring in x over Rational Field

For compatibility with the multivariate case, if var specifies the variable of the polynomial ring, then themonomials are multiplied with the smallest powers of var such that the result is homogeneous; in otherwords, we end up with a monomial whose leading coefficient is the sum of the coefficients of the polynomial:
sage: f = x^2 + x + 1
sage: f.homogenize( x )3*x^2>>> from sage.all import *>>> f = x**Integer(2) + x + Integer(1)>>> f.homogenize( x )3*x^2

In positive characteristic, the degree can drop in this case:sage: R.<x> = GF(2)[]sage: f = x + 1
sage: f.homogenize(x)0>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = x + Integer(1)>>> f.homogenize(x)0For compatibility with the multivariate case, the parameter var can also be 0 to specify the variable in thepolynomial ring:sage: R.<x> = QQ[]
sage: f = x^2 + x + 1
sage: f.homogenize(0)3*x^2>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + x + Integer(1)>>> f.homogenize(Integer(0))
3*x^2

integral(var=None)
Return the integral of this polynomial.

2.1. Univariate Polynomials and Polynomial Rings

99

Polynomials, Release 10.4

By default, the integration variable is the variable of the polynomial.
Otherwise, the integration variable is the optional parameter var
Note: The integral is always chosen so that the constant term is 0.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R(0).integral()0
sage: f = R(2).integral(); f2*x>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(0)).integral()0>>> f = R(Integer(2)).integral(); f2*xNote that the integral lives over the fraction field of the scalar coefficients:
sage: f.parent()
Univariate Polynomial Ring in x over Rational Field
sage: R(0).integral().parent()
Univariate Polynomial Ring in x over Rational Field
sage: f = x^3 + x - 2
sage: g = f.integral(); g1/4*x^4 + 1/2*x^2 - 2*x
sage: g.parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> f.parent()
Univariate Polynomial Ring in x over Rational Field>>> R(Integer(0)).integral().parent()
Univariate Polynomial Ring in x over Rational Field>>> f = x**Integer(3) + x - Integer(2)>>> g = f.integral(); g1/4*x^4 + 1/2*x^2 - 2*x>>> g.parent()
Univariate Polynomial Ring in x over Rational Field

This shows that the issue at Issue #7711 is resolved:
sage: # needs sage.rings.finite_rings
sage: P.<x,z> = PolynomialRing(GF(2147483647))
sage: Q.<y> = PolynomialRing(P)sage: p = x + y + z
sage: p.integral()-1073741823*y^2 + (x + z)*y
sage: # needs sage.rings.finite_rings(continues on next page)

100

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: P.<x,z> = PolynomialRing(GF(next_prime(2147483647)))
sage: Q.<y> = PolynomialRing(P)sage: p = x + y + z
sage: p.integral()1073741830*y^2 + (x + z)*y>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> P = PolynomialRing(GF(Integer(2147483647)), names=( x , z ,)); (x, z,) =␣
˓→P._first_ngens(2)>>> Q = PolynomialRing(P, names=( y ,)); (y,) = Q._first_ngens(1)>>> p = x + y + z>>> p.integral()-1073741823*y^2 + (x + z)*y>>> # needs sage.rings.finite_rings>>> P = PolynomialRing(GF(next_prime(Integer(2147483647))), names=( x ,˓→)); (x, z,) = P._first_ngens(2)>>> Q = PolynomialRing(P, names=( y ,)); (y,) = Q._first_ngens(1)>>> p = x + y + z>>> p.integral()1073741830*y^2 + (x + z)*yz ,A truly convoluted example:
sage: A.<a1, a2> = PolynomialRing(ZZ)
sage: B.<b> = PolynomialRing(A)sage: C.<c> = PowerSeriesRing(B)sage: R.<x> = PolynomialRing(C)sage: f = a2*x^2 + c*x - a1*b
sage: f.parent()
Univariate Polynomial Ring in x over Power Series Ring in cover Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Integer Ringsage: f.integral()
1/3*a2*x^3 + 1/2*c*x^2 - a1*b*x
sage: f.integral().parent()
Univariate Polynomial Ring in x over Power Series Ring in cover Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Rational Field
sage: g = 3*a2*x^2 + 2*c*x - a1*b
sage: g.integral()a2*x^3 + c*x^2 - a1*b*x
sage: g.integral().parent()
Univariate Polynomial Ring in x over Power Series Ring in cover Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Rational Field>>> from sage.all import *>>> A = PolynomialRing(ZZ, names=( a1 , a2 ,)); (a1, a2,) = A._first_ngens(2)>>> B = PolynomialRing(A, names=( b ,)); (b,) = B._first_ngens(1)>>> C = PowerSeriesRing(B, names=( c ,)); (c,) = C._first_ngens(1)>>> R = PolynomialRing(C, names=( x ,)); (x,) = R._first_ngens(1)>>> f = a2*x**Integer(2) + c*x - a1*b>>> f.parent()
Univariate Polynomial Ring in x over Power Series Ring in c(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

101

Polynomials, Release 10.4

(continued from previous page)

over Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Integer Ring>>> f.integral()
1/3*a2*x^3 + 1/2*c*x^2 - a1*b*x>>> f.integral().parent()
Univariate Polynomial Ring in x over Power Series Ring in cover Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Rational Field>>> g = Integer(3)*a2*x**Integer(2) + Integer(2)*c*x - a1*b>>> g.integral()a2*x^3 + c*x^2 - a1*b*x>>> g.integral().parent()
Univariate Polynomial Ring in x over Power Series Ring in cover Univariate Polynomial Ring in b over Multivariate Polynomial
Ring in a1, a2 over Rational Field

Integration with respect to a variable in the base ring:sage: R.<x> = QQ[]
sage: t = PolynomialRing(R, t ).gen()sage: f = x*t + 5*t^2
sage: f.integral(x)5*x*t^2 + 1/2*x^2*t>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> t = PolynomialRing(R, t ).gen()>>> f = x*t + Integer(5)*t**Integer(2)>>> f.integral(x)5*x*t^2 + 1/2*x^2*t

inverse_mod(a, m)
Invert the polynomial a with respect to m, or raise a ValueError if no such inverse exists.
The parameter m may be either a single polynomial or an ideal (for consistency with inverse_mod() inother rings).
See also:
If you are only interested in the inverse modulo a monomial 𝑥𝑘 then you might use the specialized method
inverse_series_trunc() which is much faster.
EXAMPLES:
sage: S.<t> = QQ[]
sage: f = inverse_mod(t^2 + 1, t^3 + 1); f-1/2*t^2 - 1/2*t + 1/2
sage: f * (t^2 + 1) % (t^3 + 1)
1
sage: f = t.inverse_mod((t + 1)^7); f-t^6 - 7*t^5 - 21*t^4 - 35*t^3 - 35*t^2 - 21*t - 7
sage: (f * t) + (t + 1)^7
1
sage: t.inverse_mod(S.ideal((t + 1)^7)) == f
True

102

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> S = QQ[ t ]; (t,) = S._first_ngens(1)>>> f = inverse_mod(t**Integer(2) + Integer(1), t**Integer(3) + Integer(1)); f-1/2*t^2 - 1/2*t + 1/2>>> f * (t**Integer(2) + Integer(1)) % (t**Integer(3) + Integer(1))
1>>> f = t.inverse_mod((t + Integer(1))**Integer(7)); f-t^6 - 7*t^5 - 21*t^4 - 35*t^3 - 35*t^2 - 21*t - 7>>> (f * t) + (t + Integer(1))**Integer(7)1>>> t.inverse_mod(S.ideal((t + Integer(1))**Integer(7))) == f
True

This also works over inexact rings, but note that due to rounding error the product may not always exactly
equal the constant polynomial 1 and have extra terms with coefficients close to zero.
sage: # needs scipy sage.modules
sage: R.<x> = RDF[]
sage: epsilon = RDF(1).ulp()*50# Allow an error of up to 50 ulp
sage: f = inverse_mod(x^2 + 1, x^5 + x + 1); f # abs tol 1e-14
0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8
sage: poly = f * (x^2 + 1) % (x^5 + x + 1)
sage: # Remove noisy zero terms:
sage: parent(poly)([0.0 if abs(c) <= epsilon else c....:
for c in poly.coefficients(sparse=False)])1.0
sage: f = inverse_mod(x^3 - x + 1, x - 2); f
0.14285714285714285
sage: f * (x^3 - x + 1) % (x - 2)
1.0
sage: g = 5*x^3 + x - 7; m = x^4 - 12*x + 13; f = inverse_mod(g, m); f-0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687..
˓→.
sage: poly = f*g % m
sage: # Remove noisy zero terms:
sage: parent(poly)([0.0 if abs(c) <= epsilon else c # abs tol 1e-14....:
for c in poly.coefficients(sparse=False)])1.0000000000000004>>> from sage.all import *>>> # needs scipy sage.modules>>> R = RDF[ x ]; (x,) = R._first_ngens(1)>>> epsilon = RDF(Integer(1)).ulp()*Integer(50)# Allow an error of up to␣˓→50 ulp>>> f = inverse_mod(x**Integer(2) + Integer(1), x**Integer(5) + x +␣˓→Integer(1)); f# abs tol 1e-14
0.4*x^4 - 0.2*x^3 - 0.4*x^2 + 0.2*x + 0.8>>> poly = f * (x**Integer(2) + Integer(1)) % (x**Integer(5) + x + Integer(1))>>> # Remove noisy zero terms:>>> parent(poly)([RealNumber( 0.0 ) if abs(c) <= epsilon else c...
for c in poly.coefficients(sparse=False)])1.0>>> f = inverse_mod(x**Integer(3) - x + Integer(1), x - Integer(2)); f
0.14285714285714285>>> f * (x**Integer(3) - x + Integer(1)) % (x - Integer(2))
1.0>>> g = Integer(5)*x**Integer(3) + x - Integer(7); m = x**Integer(4) -␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

103

Polynomials, Release 10.4

(continued from previous page)

Integer(12)*x + Integer(13); f = inverse_mod(g, m); f-0.0319636125...*x^3 - 0.0383269759...*x^2 - 0.0463050900...*x + 0.346479687..
˓→.
>>> poly = f*g % m>>> # Remove noisy zero terms:>>> parent(poly)([RealNumber( 0.0 ) if abs(c) <= epsilon else c # abs tol 1e˓→14...
for c in poly.coefficients(sparse=False)])1.0000000000000004
˓→

ALGORITHM: Solve the system 𝑎𝑠 + 𝑚𝑡 = 1, returning 𝑠 as the inverse of 𝑎 mod 𝑚.
Uses the Euclidean algorithm for exact rings, and solves a linear system for the coefficients of 𝑠 and 𝑡 for
inexact rings (as the Euclidean algorithm may not converge in that case).
AUTHORS:• Robert Bradshaw (2007-05-31)
inverse_of_unit()
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x - 90283
sage: f.inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: x - 90283 is not a unit
in Univariate Polynomial Ring in x over Rational Field
sage: f = R(-90283); g = f.inverse_of_unit(); g-1/90283
sage: parent(g)Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x - Integer(90283)>>> f.inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: x - 90283 is not a unit
in Univariate Polynomial Ring in x over Rational Field>>> f = R(-Integer(90283)); g = f.inverse_of_unit(); g-1/90283>>> parent(g)Univariate Polynomial Ring in x over Rational Field

inverse_series_trunc(prec)
Return a polynomial approximation of precision prec of the inverse series of this polynomial.
See also:
The method inverse_mod() allows more generally to invert this polynomial with respect to any ideal.
EXAMPLES:
sage: x = polygen(ZZ)
sage: s = (1 + x).inverse_series_trunc(5)(continues on next page)

104

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: sx^4 - x^3 + x^2 - x + 1
sage: s * (1 + x)x^5 + 1>>> from sage.all import *>>> x = polygen(ZZ)>>> s = (Integer(1) + x).inverse_series_trunc(Integer(5))>>> sx^4 - x^3 + x^2 - x + 1>>> s * (Integer(1) + x)x^5 + 1

Note that the constant coefficient needs to be a unit:
sage: ZZx.<x> = ZZ[]
sage: ZZxy.<y> = ZZx[]sage: (1+x + y**2).inverse_series_trunc(4)Traceback (most recent call last):...
ValueError: constant term x + 1 is not a unit
sage: (1+x + y**2).change_ring(ZZx.fraction_field()).inverse_series_trunc(4)(-1/(x^2 + 2*x + 1))*y^2 + 1/(x + 1)>>> from sage.all import *>>> ZZx = ZZ[ x ]; (x,) = ZZx._first_ngens(1)>>> ZZxy = ZZx[ y ]; (y,) = ZZxy._first_ngens(1)>>> (Integer(1)+x + y**Integer(2)).inverse_series_trunc(Integer(4))
Traceback (most recent call last):...
ValueError: constant term x + 1 is not a unit>>> (Integer(1)+x + y**Integer(2)).change_ring(ZZx.fraction_field()).inverse_
˓→series_trunc(Integer(4))(-1/(x^2 + 2*x + 1))*y^2 + 1/(x + 1)

The method works over any polynomial ring:sage: R = Zmod(4)sage: Rx.<x> = R[]
sage: Rxy.<y> = Rx[]
sage: p = 1 + (1+2*x)*y + x**2*y**4
sage: q = p.inverse_series_trunc(10)sage: (p*q).truncate(11)(2*x^4 + 3*x^2 + 3)*y^10 + 1>>> from sage.all import *>>> R = Zmod(Integer(4))>>> Rx = R[ x ]; (x,) = Rx._first_ngens(1)>>> Rxy = Rx[ y ]; (y,) = Rxy._first_ngens(1)>>> p = Integer(1) + (Integer(1)+Integer(2)*x)*y + x**Integer(2)*y**Integer(4)>>> q = p.inverse_series_trunc(Integer(10))>>> (p*q).truncate(Integer(11))(2*x^4 + 3*x^2 + 3)*y^10 + 1

2.1. Univariate Polynomials and Polynomial Rings

105

Polynomials, Release 10.4

Even noncommutative ones:sage: # needs sage.modules
sage: M = MatrixSpace(ZZ, 2)
sage: x = polygen(M)sage: p = M([1,2,3,4])*x^3 + M([-1,0,0,1])*x^2 + M([1,3,-1,0])*x + M.one()sage: q = p.inverse_series_trunc(5)sage: (p*q).truncate(5) == M.one()True
sage: q = p.inverse_series_trunc(13)sage: (p*q).truncate(13) == M.one()True>>> from sage.all import *>>> # needs sage.modules>>> M = MatrixSpace(ZZ, Integer(2))>>> x = polygen(M)>>> p = M([Integer(1),Integer(2),Integer(3),Integer(4)])*x**Integer(3) + M([˓→Integer(1),Integer(0),Integer(0),Integer(1)])*x**Integer(2) + M([Integer(1),˓→Integer(3),-Integer(1),Integer(0)])*x + M.one()>>> q = p.inverse_series_trunc(Integer(5))>>> (p*q).truncate(Integer(5)) == M.one()True>>> q = p.inverse_series_trunc(Integer(13))>>> (p*q).truncate(Integer(13)) == M.one()True

AUTHORS:• David Harvey (2006-09-09): Newton’s method implementation for power series• Vincent Delecroix (2014-2015): move the implementation directly in polynomial
is_constant()
Return True if this is a constant polynomial.
OUTPUT:• bool – True if and only if this polynomial is constant
EXAMPLES:
sage: R.<x> = ZZ[]
sage: x.is_constant()
False
sage: R(2).is_constant()
True
sage: R(0).is_constant()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> x.is_constant()
False>>> R(Integer(2)).is_constant()
True>>> R(Integer(0)).is_constant()
True

106

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

is_cyclotomic(certificate=False, algorithm='pari')
Test if this polynomial is a cyclotomic polynomial.
A cyclotomic polynomial is a monic, irreducible polynomial such that all roots are roots of unity.
By default the answer is a boolean. But if certificate is True, the result is a non-negative integer: it is
0 if self is not cyclotomic, and a positive integer n if self is the 𝑛-th cyclotomic polynomial.
See also:
is_cyclotomic_product() cyclotomic_part() has_cyclotomic_factor()
INPUT:• certificate – boolean, default to False. Only works with algorithm set to "pari".
• algorithm – either "pari" or "sage" (default is "pari")
ALGORITHM:
The native algorithm implemented in Sage uses the first algorithm of [BD1989]. The algorithm in PARI
(using pari:poliscyclo) is more subtle since it does compute the inverse of the Euler 𝜑 function to determine
the 𝑛 such that the polynomial is the 𝑛-th cyclotomic polynomial.
EXAMPLES:
Quick tests:
sage: # needs sage.libs.pari
sage: P.<x> = ZZ[ x ]sage: (x - 1).is_cyclotomic()True
sage: (x + 1).is_cyclotomic()True
sage: (x^2 - 1).is_cyclotomic()
False
sage: (x^2 + x + 1).is_cyclotomic(certificate=True)3
sage: (x^2 + 2*x + 1).is_cyclotomic(certificate=True)0>>> from sage.all import *>>> # needs sage.libs.pari>>> P = ZZ[ x ]; (x,) = P._first_ngens(1)>>> (x - Integer(1)).is_cyclotomic()True>>> (x + Integer(1)).is_cyclotomic()True>>> (x**Integer(2) - Integer(1)).is_cyclotomic()False>>> (x**Integer(2) + x + Integer(1)).is_cyclotomic(certificate=True)
3>>> (x**Integer(2) + Integer(2)*x + Integer(1)).is_˓→cyclotomic(certificate=True)
0

Test first 100 cyclotomic polynomials:
sage: all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(1, 101))
˓→needs sage.libs.pariTrue

2.1. Univariate Polynomials and Polynomial Rings

#␣

107

Polynomials, Release 10.4>>> from sage.all import *>>> all(cyclotomic_polynomial(i).is_cyclotomic() for i in range(Integer(1),␣
˓→Integer(101)))# needs sage.libs.pari
True

Some more tests:
sage: # needs sage.libs.pari
sage: f = x^16 + x^14 - x^10 + x^8 - x^6 + x^2 + 1
sage: f.is_cyclotomic(algorithm="pari")
False
sage: f.is_cyclotomic(algorithm="sage")
False
sage: g = x^16 + x^14 - x^10 - x^8 - x^6 + x^2 + 1
sage: g.is_cyclotomic(algorithm="pari")Truesage: g.is_cyclotomic(algorithm="sage")Truesage: y = polygen(QQ)
sage: (y/2 - 1/2).is_cyclotomic()
False
sage: (2*(y/2 - 1/2)).is_cyclotomic()
˓→needs sage.libs.pari
True

#␣

>>> from sage.all import *>>> # needs sage.libs.pari>>> f = x**Integer(16) + x**Integer(14) - x**Integer(10) + x**Integer(8) -␣˓→x**Integer(6) + x**Integer(2) + Integer(1)>>> f.is_cyclotomic(algorithm="pari")
False>>> f.is_cyclotomic(algorithm="sage")
False>>> g = x**Integer(16) + x**Integer(14) - x**Integer(10) - x**Integer(8) -␣˓→x**Integer(6) + x**Integer(2) + Integer(1)>>> g.is_cyclotomic(algorithm="pari")
True>>> g.is_cyclotomic(algorithm="sage")True>>> y = polygen(QQ)>>> (y/Integer(2) - Integer(1)/Integer(2)).is_cyclotomic()False>>> (Integer(2)*(y/Integer(2) - Integer(1)/Integer(2))).is_cyclotomic()˓→# needs sage.libs.pari
True␣

Invalid arguments:
sage: (x - 3).is_cyclotomic(algorithm="sage", certificate=True)
˓→needs sage.libs.pari
Traceback (most recent call last):...
ValueError: no implementation of the certificate within Sage

108

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> (x - Integer(3)).is_cyclotomic(algorithm="sage", certificate=True)˓→# needs sage.libs.pari
Traceback (most recent call last):...
ValueError: no implementation of the certificate within Sage␣

Test using other rings:
sage: z = polygen(GF(5))
sage: (z - 1).is_cyclotomic()
Traceback (most recent call last):...
NotImplementedError: not implemented in non-zero characteristic>>> from sage.all import *>>> z = polygen(GF(Integer(5)))>>> (z - Integer(1)).is_cyclotomic()
Traceback (most recent call last):...
NotImplementedError: not implemented in non-zero characteristic

is_cyclotomic_product()
Test whether this polynomial is a product of cyclotomic polynomials.
This method simply calls the function pari:poliscycloprod from the Pari library.
See also:
is_cyclotomic() cyclotomic_part() has_cyclotomic_factor()
EXAMPLES:
sage: x = polygen(ZZ)
sage: (x^5 - 1).is_cyclotomic_product()
˓→needs sage.libs.pari
True
sage: (x^5 + x^4 - x^2 + 1).is_cyclotomic_product()
˓→needs sage.libs.pari
False
sage: p = prod(cyclotomic_polynomial(i) for i in [2, 5, 7, 12])sage: p.is_cyclotomic_product()
˓→needs sage.libs.pari
True

#␣

#␣

#␣

sage: (x^5 - 1/3).is_cyclotomic_product()False
sage: x = polygen(Zmod(5))
sage: (x - 1).is_cyclotomic_product()
Traceback (most recent call last):...
NotImplementedError: not implemented in non-zero characteristic>>> from sage.all import *>>> x = polygen(ZZ)>>> (x**Integer(5) - Integer(1)).is_cyclotomic_product()␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

109

Polynomials, Release 10.4

(continued from previous page)˓→# needs sage.libs.pari

True>>> (x**Integer(5) + x**Integer(4) - x**Integer(2) + Integer(1)).is_˓→cyclotomic_product()# needs sage.libs.pari
False>>> p = prod(cyclotomic_polynomial(i) for i in [Integer(2), Integer(5),␣
˓→Integer(7), Integer(12)])>>> p.is_cyclotomic_product()
˓→needs sage.libs.pari
True

#␣

>>> (x**Integer(5) - Integer(1)/Integer(3)).is_cyclotomic_product()False>>> x = polygen(Zmod(Integer(5)))>>> (x - Integer(1)).is_cyclotomic_product()
Traceback (most recent call last):...
NotImplementedError: not implemented in non-zero characteristic

is_gen()Return True if this polynomial is the distinguished generator of the parent polynomial ring.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R(1).is_gen()False
sage: R(x).is_gen()True>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(1)).is_gen()
False>>> R(x).is_gen()
True

Important - this function doesn’t return True if self equals the generator; it returns True if self is thegenerator.
sage: f = R([0,1]); fx
sage: f.is_gen()False
sage: f is x
False
sage: f == x
True>>> from sage.all import *>>> f = R([Integer(0),Integer(1)]); fx>>> f.is_gen()
False(continues on next page)

110

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f is x
False>>> f == x
True

is_homogeneous()
Return True if this polynomial is homogeneous.
EXAMPLES:
sage: P.<x> = PolynomialRing(QQ)
sage: x.is_homogeneous()
True
sage: P(0).is_homogeneous()
True
sage: (x + 1).is_homogeneous()
False>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x ,)); (x,) = P._first_ngens(1)>>> x.is_homogeneous()
True>>> P(Integer(0)).is_homogeneous()
True>>> (x + Integer(1)).is_homogeneous()
False

is_irreducible()
Return whether this polynomial is irreducible.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: (x^3 + 1).is_irreducible()
˓→needs sage.libs.pari
False
sage: (x^2 - 1).is_irreducible()
˓→needs sage.libs.pari
False
sage: (x^3 + 2).is_irreducible()
˓→needs sage.libs.pari
True
sage: R(0).is_irreducible()
False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(3) + Integer(1)).is_irreducible()˓→# needs sage.libs.pari
False>>> (x**Integer(2) - Integer(1)).is_irreducible()˓→# needs sage.libs.pari
False>>> (x**Integer(3) + Integer(2)).is_irreducible()˓→# needs sage.libs.pari
True

#␣

#␣

#␣

␣

␣

␣

(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

111

Polynomials, Release 10.4

(continued from previous page)>>> R(Integer(0)).is_irreducible()
False

The base ring does matter: for example, 2𝑥 is irreducible as a polynomial insage: R.<x> = ZZ[]
sage: R(2*x).is_irreducible()
˓→needs sage.libs.pari
False
sage: R.<x> = QQ[]
sage: R(2*x).is_irreducible()
˓→needs sage.libs.pari
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(2)*x).is_irreducible()˓→# needs sage.libs.pari
False>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(2)*x).is_irreducible()˓→# needs sage.libs.pari
True[𝑥], but not in Z[𝑥]:
#␣

#␣

␣

␣

is_lorentzian(explain=False)
Return True if this is a Lorentzian polynomial.
A univariate real polynomial is Lorentzian if and only if it is a monomial with positive coefficient, or zero.
The definition is more involved for multivariate real polynomials.
INPUT:• explain – boolean (default: False); if True return a tuple whose first element is the boolean resultof the test, and the second element is a string describing the reason the test failed, or None if the test
succeeded
EXAMPLES:
sage: P.<x> = QQ[]
sage: p1 = x^2
sage: p1.is_lorentzian()True
sage: p2 = 1 + x^2
sage: p2.is_lorentzian()False
sage: p3 = P.zero()sage: p3.is_lorentzian()True
sage: p4 = -2*x^3sage: p4.is_lorentzian()False>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> p1 = x**Integer(2)>>> p1.is_lorentzian()True(continues on next page)

112

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> p2 = Integer(1) + x**Integer(2)>>> p2.is_lorentzian()False>>> p3 = P.zero()>>> p3.is_lorentzian()True>>> p4 = -Integer(2)*x**Integer(3)>>> p4.is_lorentzian()
False

It is an error to check if a polynomial is Lorentzian if its base ring is not a subring of the real numbers, as thenotion is not defined in this case:sage: # needs sage.rings.real_mpfr
sage: Q.<y> = CC[]
sage: q = y^2
sage: q.is_lorentzian()Traceback (most recent call last):...
NotImplementedError: is_lorentzian only implemented for real polynomials>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> Q = CC[ y ]; (y,) = Q._first_ngens(1)>>> q = y**Integer(2)>>> q.is_lorentzian()Traceback (most recent call last):...
NotImplementedError: is_lorentzian only implemented for real polynomials

The method can give a reason for a polynomial failing to be Lorentzian:sage: p = x^2 + 2*x
sage: p.is_lorentzian(explain=True)(False, inhomogeneous )>>> from sage.all import *>>> p = x**Integer(2) + Integer(2)*x>>> p.is_lorentzian(explain=True)(False, inhomogeneous )REFERENCES:
For full definitions and related discussion, see [BrHu2019] and [HMMS2019].
is_monic()
Returns True if this polynomial is monic. The zero polynomial is by definition not monic.
EXAMPLES:
sage: x = QQ[ x ].0
sage: f = x + 33
sage: f.is_monic()True
sage: f = 0*x
sage: f.is_monic()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

113

Polynomials, Release 10.4

(continued from previous page)

False
sage: f = 3*x^3 + x^4 + x^2
sage: f.is_monic()True
sage: f = 2*x^2 + x^3 + 56*x^5sage: f.is_monic()
False>>> from sage.all import *>>> x = QQ[ x ].gen(0)>>> f = x + Integer(33)>>> f.is_monic()True>>> f = Integer(0)*x>>> f.is_monic()
False>>> f = Integer(3)*x**Integer(3) + x**Integer(4) + x**Integer(2)>>> f.is_monic()True>>> f = Integer(2)*x**Integer(2) + x**Integer(3) + Integer(56)*x**Integer(5)>>> f.is_monic()
False

AUTHORS:• Naqi Jaffery (2006-01-24): examples
is_monomial()
Return True if self is a monomial, i.e., a power of the generator.
EXAMPLES:
sage: R.<x> = QQ[]
sage: x.is_monomial()
True
sage: (x + 1).is_monomial()
False
sage: (x^2).is_monomial()
True
sage: R(1).is_monomial()
True>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> x.is_monomial()
True>>> (x + Integer(1)).is_monomial()
False>>> (x**Integer(2)).is_monomial()
True>>> R(Integer(1)).is_monomial()
True

The coefficient must be 1:
sage: (2*x^5).is_monomial()
False

114

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> (Integer(2)*x**Integer(5)).is_monomial()
False

To allow a non-1 leading coefficient, use is_term():
sage: (2*x^5).is_term()
True>>> from sage.all import *>>> (Integer(2)*x**Integer(5)).is_term()
True

Warning: The definition of is_monomial() in Sage up to 4.7.1 was the same as is_term(), i.e.,
it allowed a coefficient not equal to 1.
is_nilpotent()
Return True if this polynomial is nilpotent.
EXAMPLES:
sage: R = Integers(12)sage: S.<x> = R[]
sage: f = 5 + 6*x
sage: f.is_nilpotent()
False
sage: f = 6 + 6*x^2
sage: f.is_nilpotent()
True
sage: f^2
0>>> from sage.all import *>>> R = Integers(Integer(12))>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = Integer(5) + Integer(6)*x>>> f.is_nilpotent()
False>>> f = Integer(6) + Integer(6)*x**Integer(2)>>> f.is_nilpotent()True>>> f**Integer(2)0EXERCISE (Atiyah-McDonald, Ch 1): Let 𝐴[𝑥] be a polynomial ring in one variable. Then 𝑓 =𝐴[𝑥] is nilpotent if and only if every 𝑎𝑖 is nilpotent.

∑︀𝑎 𝑖 𝑥𝑖 ∈is_one()Test whether this polynomial is 1.
EXAMPLES:
sage: R.<x> = QQ[]
sage: (x - 3).is_one()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

115

Polynomials, Release 10.4

(continued from previous page)

False
sage: R(1).is_one()True
sage: R2.<y> = R[]
sage: R2(x).is_one()False
sage: R2(1).is_one()True
sage: R2(-1).is_one()
False>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (x - Integer(3)).is_one()
False>>> R(Integer(1)).is_one()True>>> R2 = R[ y ]; (y,) = R2._first_ngens(1)>>> R2(x).is_one()
False>>> R2(Integer(1)).is_one()True>>> R2(-Integer(1)).is_one()
False

is_primitive(n=None, n_prime_divs=None)
Return True if the polynomial is primitive.
The semantics of “primitive” depend on the polynomial coefficients.
• (field theory) A polynomial of degree 𝑚 over a finite field F𝑞 is primitive if it is irreducible and its root
in F𝑞𝑚 generates the multiplicative group F*𝑞𝑚 .
• (ring theory) A polynomial over a ring is primitive if its coefficients generate the unit ideal.
Calling is_primitive() on a polynomial over an infinite field will raise an error.
The additional inputs to this function are to speed up computation for field semantics (see note).
INPUT:• n (default: None) – if provided, should equal 𝑞−1 where self.parent() is the field with 𝑞 elements;
otherwise it will be computed.
• n_prime_divs (default: None) – if provided, should be a list of the prime divisors of 𝑛; otherwise
it will be computed.
Note: Computation of the prime divisors of 𝑛 can dominate the running time of this method, so performing
this computation externally (e.g., pdivs = n.prime_divisors()) is a good idea for repeated calls to
is_primitive() for polynomials of the same degree.
Results may be incorrect if the wrong 𝑛 and/or factorization are provided.
EXAMPLES:
Field semantics examples.

116

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(2)[ x ]sage: f = x^4 + x^3 + x^2 + x + 1
sage: f.is_irreducible(), f.is_primitive()(True, False)
sage: f = x^3 + x + 1
sage: f.is_irreducible(), f.is_primitive()(True, True)
sage: R.<x> = GF(3)[]sage: f = x^3 - x + 1
sage: f.is_irreducible(), f.is_primitive()(True, True)
sage: f = x^2 + 1
sage: f.is_irreducible(), f.is_primitive()(True, False)
sage: R.<x> = GF(5)[]sage: f = x^2 + x + 1
sage: f.is_primitive()
False
sage: f = x^2 - x + 2
sage: f.is_primitive()
True
sage: x = polygen(QQ); f = x^2 + 1
sage: f.is_primitive()
Traceback (most recent call last):...
NotImplementedError: is_primitive() not defined for polynomials over infinite␣˓→fields.
>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) + x**Integer(3) + x**Integer(2) + x + Integer(1)>>> f.is_irreducible(), f.is_primitive()(True, False)>>> f = x**Integer(3) + x + Integer(1)>>> f.is_irreducible(), f.is_primitive()(True, True)>>> R = GF(Integer(3))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) - x + Integer(1)>>> f.is_irreducible(), f.is_primitive()(True, True)>>> f = x**Integer(2) + Integer(1)>>> f.is_irreducible(), f.is_primitive()(True, False)>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + x + Integer(1)>>> f.is_primitive()
False>>> f = x**Integer(2) - x + Integer(2)>>> f.is_primitive()
True>>> x = polygen(QQ); f = x**Integer(2) + Integer(1)>>> f.is_primitive()
Traceback (most recent call last):...
NotImplementedError: is_primitive() not defined for polynomials over infinite␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

117

Polynomials, Release 10.4

(continued from previous page)

fields.

˓→

Ring semantics examples.
sage: x = polygen(ZZ)
sage: f = 5*x^2 + 2
sage: f.is_primitive()
True
sage: f = 5*x^2 + 5
sage: f.is_primitive()
False
sage: # needs sage.rings.number_fieldsage: K = NumberField(x^2 + 5, a )sage: R = K.ring_of_integers()
sage: a = R.gen(1)sage: a^2
-5sage: f = a*x + 2
sage: f.is_primitive()
True
sage: f = (1+a)*x + 2
sage: f.is_primitive()
False
sage: x = polygen(Integers(10))
sage: f = 5*x^2 + 2
sage: #f.is_primitive() #BUG:: elsewhere in Sage, should return True
sage: f = 4*x^2 + 2
sage: #f.is_primitive() #BUG:: elsewhere in Sage, should return False>>> from sage.all import *>>> x = polygen(ZZ)>>> f = Integer(5)*x**Integer(2) + Integer(2)>>> f.is_primitive()
True>>> f = Integer(5)*x**Integer(2) + Integer(5)>>> f.is_primitive()
False>>> # needs sage.rings.number_field>>> K = NumberField(x**Integer(2) + Integer(5),>>> R = K.ring_of_integers()>>> a = R.gen(Integer(1))>>> a**Integer(2)-5>>> f = a*x + Integer(2)>>> f.is_primitive()
True>>> f = (Integer(1)+a)*x + Integer(2)>>> f.is_primitive()
False

a )

>>> x = polygen(Integers(Integer(10)))>>> f = Integer(5)*x**Integer(2) + Integer(2)>>> #f.is_primitive() #BUG:: elsewhere in Sage, should return True(continues on next page)

118

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(4)*x**Integer(2) + Integer(2)>>> #f.is_primitive() #BUG:: elsewhere in Sage, should return False

is_real_rooted()
Return True if the roots of this polynomial are all real.
EXAMPLES:
sage: # needs sage.libs.pari
sage: R.<x> = PolynomialRing(ZZ)
sage: pol = chebyshev_T(5, x)
sage: pol.is_real_rooted()Truesage: pol = x^2 + 1
sage: pol.is_real_rooted()
False>>> from sage.all import *>>> # needs sage.libs.pari>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = chebyshev_T(Integer(5), x)>>> pol.is_real_rooted()True>>> pol = x**Integer(2) + Integer(1)>>> pol.is_real_rooted()False

is_square(root=False)
Return whether or not polynomial is square.
If the optional argument root is set to True, then also returns the square root (or None, if the polynomial
is not square).
INPUT:• root – whether or not to also return a square root (default: False)
OUTPUT:• bool – whether or not a square• root – (optional) an actual square root if found, and None otherwise.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: (x^2 + 2*x + 1).is_square()True
sage: (x^4 + 2*x^3 - x^2 - 2*x + 1).is_square(root=True)(True, x^2 + x - 1)sage: f = 12 * (x + 1)^2 * (x + 3)^2
sage: f.is_square()False
sage: f.is_square(root=True)(False, None)sage: h = f/3; h(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

119

Polynomials, Release 10.4

(continued from previous page)

4*x^4 + 32*x^3 + 88*x^2 + 96*x + 36
sage: h.is_square(root=True)(True, 2*x^2 + 8*x + 6)
sage: S.<y> = PolynomialRing(RR)
sage: g = 12 * (y + 1)^2 * (y + 3)^2
sage: g.is_square()True>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> (x**Integer(2) + Integer(2)*x + Integer(1)).is_square()True>>> (x**Integer(4) + Integer(2)*x**Integer(3) - x**Integer(2) - Integer(2)*x␣
˓→+ Integer(1)).is_square(root=True)(True, x^2 + x - 1)>>> f = Integer(12) * (x + Integer(1))**Integer(2) * (x +␣˓→Integer(3))**Integer(2)>>> f.is_square()False>>> f.is_square(root=True)(False, None)>>> h = f/Integer(3); h4*x^4 + 32*x^3 + 88*x^2 + 96*x + 36>>> h.is_square(root=True)(True, 2*x^2 + 8*x + 6)>>> S = PolynomialRing(RR, names=( y ,)); (y,) = S._first_ngens(1)>>> g = Integer(12) * (y + Integer(1))**Integer(2) * (y +␣˓→Integer(3))**Integer(2)>>> g.is_square()True

is_squarefree()Return False if this polynomial is not square-free, i.e., if there is a non-unit 𝑔 in the polynomial ring suchthat 𝑔 2 divides self.
Warning: This method is not consistent with squarefree_decomposition() since the latterdoes not factor the content of a polynomial. See the examples below.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (x-1) * (x-2) * (x^2-5) * (x^17-3); fx^21 - 3*x^20 - 3*x^19 + 15*x^18 - 10*x^17 - 3*x^4 + 9*x^3 + 9*x^2 - 45*x + 30
sage: f.is_squarefree()True
sage: (f * (x^2-5)).is_squarefree()
False

120

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = (x-Integer(1)) * (x-Integer(2)) * (x**Integer(2)-Integer(5)) *␣
˓→(x**Integer(17)-Integer(3)); fx^21 - 3*x^20 - 3*x^19 + 15*x^18 - 10*x^17 - 3*x^4 + 9*x^3 + 9*x^2 - 45*x + 30>>> f.is_squarefree()True>>> (f * (x**Integer(2)-Integer(5))).is_squarefree()False

A generic implementation is available, which relies on gcd computations:sage: # needs sage.libs.pari
sage: R.<x> = ZZ[]
sage: (2*x).is_squarefree()True
sage: (4*x).is_squarefree()False
sage: (2*x^2).is_squarefree()False
sage: R(0).is_squarefree()False
sage: S.<y> = QQ[]
sage: R.<x> = S[]
sage: (2*x*y).is_squarefree()True
sage: (2*x*y^2).is_squarefree()False>>> from sage.all import *>>> # needs sage.libs.pari>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x).is_squarefree()True>>> (Integer(4)*x).is_squarefree()False>>> (Integer(2)*x**Integer(2)).is_squarefree()False>>> R(Integer(0)).is_squarefree()False>>> S = QQ[ y ]; (y,) = S._first_ngens(1)>>> R = S[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x*y).is_squarefree()True>>> (Integer(2)*x*y**Integer(2)).is_squarefree()False

In positive characteristic, we compute the square-free decomposition or a full factorization, depending on
which is available:
sage: K.<t> = FunctionField(GF(3))
sage: R.<x> = K[]
sage: (x^3 - x).is_squarefree()True
sage: (x^3 - 1).is_squarefree()#␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

121

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.pari
False
sage: (x^3 + t).is_squarefree()
˓→needs sage.libs.pari
True
sage: (x^3 + t^3).is_squarefree()
˓→needs sage.libs.pari
False
˓→

#␣

#␣

>>> from sage.all import *>>> K = FunctionField(GF(Integer(3)), names=( t ,)); (t,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(3) - x).is_squarefree()True>>> (x**Integer(3) - Integer(1)).is_squarefree()␣˓→# needs sage.libs.pari
False>>> (x**Integer(3) + t).is_squarefree()␣˓→# needs sage.libs.pari
True>>> (x**Integer(3) + t**Integer(3)).is_squarefree()␣˓→# needs sage.libs.pari
False

In the following example, 𝑡2 is a unit in the base field:
sage: R(t^2).is_squarefree()True>>> from sage.all import *>>> R(t**Integer(2)).is_squarefree()
True

This method is not consistent with squarefree_decomposition():sage: R.<x> = ZZ[]
sage: f = 4 * x
sage: f.is_squarefree()
˓→needs sage.libs.pari
False
sage: f.squarefree_decomposition()
˓→needs sage.libs.pari(4) * x>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(4) * x>>> f.is_squarefree()
˓→needs sage.libs.pari
False>>> f.squarefree_decomposition()
˓→needs sage.libs.pari(4) * x

#␣

#␣

#␣

#␣

If you want this method equally not to consider the content, you can remove it as in the following example:

122

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: c = f.content()
sage: (f/c).is_squarefree()
˓→needs sage.libs.pari
True

#␣

>>> from sage.all import *>>> c = f.content()>>> (f/c).is_squarefree()
˓→needs sage.libs.pari
True

#␣

If the base ring is not an integral domain, the question is not mathematically well-defined:
sage: R.<x> = IntegerModRing(9)[]sage: pol = (x + 3) * (x + 6); polx^2
sage: pol.is_squarefree()Traceback (most recent call last):...
TypeError: is_squarefree() is not defined forpolynomials over Ring of integers modulo 9>>> from sage.all import *>>> R = IntegerModRing(Integer(9))[ x ]; (x,) = R._first_ngens(1)>>> pol = (x + Integer(3)) * (x + Integer(6)); polx^2>>> pol.is_squarefree()Traceback (most recent call last):...
TypeError: is_squarefree() is not defined forpolynomials over Ring of integers modulo 9

is_term()
Return True if this polynomial is a nonzero element of the base ring times a power of the variable.
EXAMPLES:
sage: R.<x> = QQ[]
sage: x.is_term()
Truesage: R(0).is_term()
False
sage: R(1).is_term()
Truesage: (3*x^5).is_term()
Truesage: (1 + 3*x^5).is_term()
False>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> x.is_term()
True>>> R(Integer(0)).is_term()
False>>> R(Integer(1)).is_term()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

123

Polynomials, Release 10.4

(continued from previous page)True>>> (Integer(3)*x**Integer(5)).is_term()True>>> (Integer(1) + Integer(3)*x**Integer(5)).is_term()
False

To require that the coefficient is 1, use is_monomial() instead:sage: (3*x^5).is_monomial()
False>>> from sage.all import *>>> (Integer(3)*x**Integer(5)).is_monomial()
False

is_unit()
Return True if this polynomial is a unit.
EXAMPLES:
sage: a = Integers(90384098234^3)
sage: b = a(2*191*236607587)
sage: b.is_nilpotent()
True
sage: # needs sage.libs.pari
sage: R.<x> = a[]sage: f = 3 + b*x + b^2*x^2sage: f.is_unit()
True
sage: f = 3 + b*x + b^2*x^2 + 17*x^3
sage: f.is_unit()
False>>> from sage.all import *>>> a = Integers(Integer(90384098234)**Integer(3))>>> b = a(Integer(2)*Integer(191)*Integer(236607587))>>> b.is_nilpotent()
True>>> # needs sage.libs.pari>>> R = a[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(3) + b*x + b**Integer(2)*x**Integer(2)>>> f.is_unit()
True>>> f = Integer(3) + b*x + b**Integer(2)*x**Integer(2) +␣˓→Integer(17)*x**Integer(3)>>> f.is_unit()
False

EXERCISE (Atiyah-McDonald, Ch 1): Let 𝐴[𝑥] be a polynomial ring in one variable. Then 𝑓 =𝐴[𝑥] is a unit if and only if 𝑎0 is a unit and 𝑎1 , . . . , 𝑎𝑛 are nilpotent.

∑︀𝑎 𝑖 𝑥𝑖 ∈is_weil_polynomial(return_q=False)
Return True if this is a Weil polynomial.
This polynomial must have rational or integer coefficients.
124

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

INPUT:• self – polynomial with rational or integer coefficients• return_q – (default False) if True, return a second value 𝑞 which is the prime power with respect
to which this is 𝑞-Weil, or 0 if there is no such value.
EXAMPLES:
sage: polRing.<x> = PolynomialRing(Rationals())
sage: P0 = x^4 + 5*x^3 + 15*x^2 + 25*x + 25
sage: P1 = x^4 + 25*x^3 + 15*x^2 + 5*x + 25
sage: P2 = x^4 + 5*x^3 + 25*x^2 + 25*x + 25
sage: P0.is_weil_polynomial(return_q=True)
˓→needs sage.libs.pari(True, 5)
sage: P0.is_weil_polynomial(return_q=False)
˓→needs sage.libs.pari
True
sage: P1.is_weil_polynomial(return_q=True)(False, 0)
sage: P1.is_weil_polynomial(return_q=False)
False
sage: P2.is_weil_polynomial()
˓→needs sage.libs.pari
False

#␣

#␣

#␣

>>> from sage.all import *>>> polRing = PolynomialRing(Rationals(), names=( x ,)); (x,) = polRing._
˓→first_ngens(1)>>> P0 = x**Integer(4) + Integer(5)*x**Integer(3) + Integer(15)*x**Integer(2)␣
˓→+ Integer(25)*x + Integer(25)>>> P1 = x**Integer(4) + Integer(25)*x**Integer(3) +␣˓→Integer(15)*x**Integer(2) + Integer(5)*x + Integer(25)>>> P2 = x**Integer(4) + Integer(5)*x**Integer(3) + Integer(25)*x**Integer(2)␣
˓→+ Integer(25)*x + Integer(25)>>> P0.is_weil_polynomial(return_q=True)#␣˓→needs sage.libs.pari(True, 5)>>> P0.is_weil_polynomial(return_q=False)#␣˓→needs sage.libs.pari
True>>> P1.is_weil_polynomial(return_q=True)(False, 0)>>> P1.is_weil_polynomial(return_q=False)
False>>> P2.is_weil_polynomial()#␣˓→needs sage.libs.pari
False

See also:
Polynomial rings have a method weil_polynomials() to compute sets of Weil polynomials. This computation uses the iterator sage.rings.polynomial.weil.weil_polynomials.
WeilPolynomials.
AUTHORS:David Zureick-Brown (2017-10-01)

2.1. Univariate Polynomials and Polynomial Rings

125

Polynomials, Release 10.4

is_zero()Test whether this polynomial is zero.
EXAMPLES:
sage: R = GF(2)[ x ][ y ]sage: R([0,1]).is_zero()False
sage: R([0]).is_zero()Truesage: R([-1]).is_zero()
False>>> from sage.all import *>>> R = GF(Integer(2))[ x ][ y ]>>> R([Integer(0),Integer(1)]).is_zero()
False>>> R([Integer(0)]).is_zero()
True>>> R([-Integer(1)]).is_zero()
False

lc()
Return the leading coefficient of this polynomial.
OUTPUT: element of the base ringThis method is the same as leading_coefficient().
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (-2/5)*x^3 + 2*x - 1/3
sage: f.lc()-2/5>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = (-Integer(2)/Integer(5))*x**Integer(3) + Integer(2)*x - Integer(1)/˓→Integer(3)>>> f.lc()-2/5lcm(other)
Let 𝑓 and 𝑔 be two polynomials. Then this function returns the monic least common multiple of 𝑓 and 𝑔.
leading_coefficient()
Return the leading coefficient of this polynomial.
OUTPUT: element of the base ring
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (-2/5)*x^3 + 2*x - 1/3
sage: f.leading_coefficient()
-2/5

126

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = (-Integer(2)/Integer(5))*x**Integer(3) + Integer(2)*x - Integer(1)/˓→Integer(3)>>> f.leading_coefficient()-2/5

list(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (-2/5)*x^3 + 2*x - 1/3
sage: v = f.list(); v[-1/3, 2, 0, -2/5]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = (-Integer(2)/Integer(5))*x**Integer(3) + Integer(2)*x - Integer(1)/˓→Integer(3)>>> v = f.list(); v[-1/3, 2, 0, -2/5]

Note that v is a list, it is mutable, and each call to the list() method returns a new list:
sage: type(v)<... list >sage: v[0] = 5
sage: f.list()[-1/3, 2, 0, -2/5]>>> from sage.all import *>>> type(v)<... list >>>> v[Integer(0)] = Integer(5)>>> f.list()[-1/3, 2, 0, -2/5]

Here is an example with a generic polynomial ring:sage: R.<x> = QQ[]
sage: S.<y> = R[]
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: type(f)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >sage: v = f.list(); v[-3*x, x, 0, 1]
sage: v[0] = 10
sage: f.list()[-3*x, x, 0, 1]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R[ y ]; (y,) = S._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

127

Polynomials, Release 10.4

(continued from previous page)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> type(f)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >>>> v = f.list(); v[-3*x, x, 0, 1]>>> v[Integer(0)] = Integer(10)>>> f.list()[-3*x, x, 0, 1]

lm()
Return the leading monomial of this polynomial.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (-2/5)*x^3 + 2*x - 1/3
sage: f.lm()x^3
sage: R(5).lm()
1sage: R(0).lm()
0sage: R(0).lm().parent() is R
True>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = (-Integer(2)/Integer(5))*x**Integer(3) + Integer(2)*x - Integer(1)/˓→Integer(3)>>> f.lm()x^3>>> R(Integer(5)).lm()
1>>> R(Integer(0)).lm()
0>>> R(Integer(0)).lm().parent() is R
True

local_height(v, prec=None)
Return the maximum of the local height of the coefficients of this polynomial.
INPUT:• v – a prime or prime ideal of the base ring.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: f = 1/1331*x^2 + 1/4000*x
sage: f.local_height(1331)
˓→needs sage.rings.real_mpfr
7.19368581839511

128

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/Integer(1331)*x**Integer(2) + Integer(1)/Integer(4000)*x>>> f.local_height(Integer(1331))˓→# needs sage.rings.real_mpfr
7.19368581839511

␣

sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 - 5)sage: T.<t> = K[]
sage: I = K.ideal(3)sage: f = 1/3*t^2 + 3
sage: f.local_height(I)1.09861228866811>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = K[ t ]; (t,) = T._first_ngens(1)>>> I = K.ideal(Integer(3))>>> f = Integer(1)/Integer(3)*t**Integer(2) + Integer(3)>>> f.local_height(I)1.09861228866811
sage: R.<x> = QQ[]
sage: f = 1/2*x^2 + 2
sage: f.local_height(2, prec=2)
˓→needs sage.rings.real_mpfr
0.75>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(1)/Integer(2)*x**Integer(2) + Integer(2)>>> f.local_height(Integer(2), prec=Integer(2))˓→# needs sage.rings.real_mpfr
0.75

#␣

␣

local_height_arch(i, prec=None)
Return the maximum of the local height at the i-th infinite place of the coefficients of this polynomial.
INPUT:• i – an integer.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: f = 210*x^2
sage: f.local_height_arch(0)˓→needs sage.rings.real_mpfr
5.34710753071747

2.1. Univariate Polynomials and Polynomial Rings

#␣

129

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(210)*x**Integer(2)>>> f.local_height_arch(Integer(0))˓→# needs sage.rings.real_mpfr
5.34710753071747

␣

sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 - 5)sage: T.<t> = K[]
sage: f = 1/2*t^2 + 3
sage: f.local_height_arch(1, prec=52)
1.09861228866811>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = K[ t ]; (t,) = T._first_ngens(1)>>> f = Integer(1)/Integer(2)*t**Integer(2) + Integer(3)>>> f.local_height_arch(Integer(1), prec=Integer(52))
1.09861228866811
sage: R.<x> = QQ[]
sage: f = 1/2*x^2 + 3
sage: f.local_height_arch(0, prec=2)
˓→needs sage.rings.real_mpfr
1.0#␣

>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(1)/Integer(2)*x**Integer(2) + Integer(3)>>> f.local_height_arch(Integer(0), prec=Integer(2))˓→# needs sage.rings.real_mpfr
1.0

␣

lt()
Return the leading term of this polynomial.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = (-2/5)*x^3 + 2*x - 1/3
sage: f.lt()-2/5*x^3
sage: R(5).lt()
5
sage: R(0).lt()
0
sage: R(0).lt().parent() is R
True>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)(continues on next page)

130

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = (-Integer(2)/Integer(5))*x**Integer(3) + Integer(2)*x - Integer(1)/˓→Integer(3)>>> f.lt()-2/5*x^3>>> R(Integer(5)).lt()
5>>> R(Integer(0)).lt()
0>>> R(Integer(0)).lt().parent() is R
True

map_coefficients(f, new_base_ring=None)
Return the polynomial obtained by applying f to the non-zero coefficients of self.
If f is a sage.categories.map.Map, then the resulting polynomial will be defined over the codomainof f. Otherwise, the resulting polynomial will be over the same ring as self. Set new_base_ring tooverride this behaviour.
INPUT:• f – a callable that will be applied to the coefficients of self.
• new_base_ring (optional) – if given, the resulting polynomial will be defined over this ring.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^2 + 2
sage: f.map_coefficients(lambda a: a + 42)
43*x^2 + 44
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: f = x^(2^32) + 2
sage: f.map_coefficients(lambda a: a + 42)
43*x^4294967296 + 44
sage: # needs sage.symbolic
sage: R.<x> = SR[]
sage: f = (1+I)*x^2 + 3*x - I
sage: f.map_coefficients(lambda z: z.conjugate())(-I + 1)*x^2 + 3*x + I
sage: R.<x> = PolynomialRing(SR, sparse=True)
sage: f = (1+I)*x^(2^32) - I
sage: f.map_coefficients(lambda z: z.conjugate())(-I + 1)*x^4294967296 + I>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(2)>>> f.map_coefficients(lambda a: a + Integer(42))
43*x^2 + 44>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> f = x**(Integer(2)**Integer(32)) + Integer(2)>>> f.map_coefficients(lambda a: a + Integer(42))
43*x^4294967296 + 44>>> # needs sage.symbolic>>> R = SR[ x ]; (x,) = R._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

131

Polynomials, Release 10.4

(continued from previous page)>>> f = (Integer(1)+I)*x**Integer(2) + Integer(3)*x - I>>> f.map_coefficients(lambda z: z.conjugate())(-I + 1)*x^2 + 3*x + I>>> R = PolynomialRing(SR, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> f = (Integer(1)+I)*x**(Integer(2)**Integer(32)) - I>>> f.map_coefficients(lambda z: z.conjugate())(-I + 1)*x^4294967296 + I

Examples with different base ring:sage: R.<x> = ZZ[]
sage: k = GF(2)sage: residue = lambda x: k(x)sage: f = 4*x^2 + x + 3
sage: g = f.map_coefficients(residue); g
x + 1
sage: g.parent()
Univariate Polynomial Ring in x over Integer Ringsage: g = f.map_coefficients(residue, new_base_ring=k); g
x + 1
sage: g.parent()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)
sage: residue = k.coerce_map_from(ZZ)
sage: g = f.map_coefficients(residue); g
x + 1
sage: g.parent()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> k = GF(Integer(2))>>> residue = lambda x: k(x)>>> f = Integer(4)*x**Integer(2) + x + Integer(3)>>> g = f.map_coefficients(residue); g
x + 1>>> g.parent()
Univariate Polynomial Ring in x over Integer Ring>>> g = f.map_coefficients(residue, new_base_ring=k); g
x + 1>>> g.parent()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)>>> residue = k.coerce_map_from(ZZ)>>> g = f.map_coefficients(residue); g
x + 1>>> g.parent()
˓→needs sage.libs.ntl
Univariate Polynomial Ring in x over Finite Field of size 2 (using GF2X)

#␣

#␣

#␣

#␣

mod(other)
Remainder of division of self by other.
EXAMPLES:

132

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<x> = ZZ[]
sage: x % (x+1)-1
sage: (x^3 + x - 1) % (x^2 - 1)
2*x - 1>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> x % (x+Integer(1))-1>>> (x**Integer(3) + x - Integer(1)) % (x**Integer(2) - Integer(1))
2*x - 1monic()
Return this polynomial divided by its leading coefficient. Does not change this polynomial.
EXAMPLES:
sage: x = QQ[ x ].0
sage: f = 2*x^2 + x^3 + 56*x^5sage: f.monic()x^5 + 1/56*x^3 + 1/28*x^2
sage: f = (1/4)*x^2 + 3*x + 1
sage: f.monic()x^2 + 12*x + 4>>> from sage.all import *>>> x = QQ[ x ].gen(0)>>> f = Integer(2)*x**Integer(2) + x**Integer(3) + Integer(56)*x**Integer(5)>>> f.monic()x^5 + 1/56*x^3 + 1/28*x^2>>> f = (Integer(1)/Integer(4))*x**Integer(2) + Integer(3)*x + Integer(1)>>> f.monic()x^2 + 12*x + 4

The following happens because 𝑓 = 0 cannot be made into a monic polynomial
sage: f = 0*x
sage: f.monic()
Traceback (most recent call last):...
ZeroDivisionError: rational division by zero>>> from sage.all import *>>> f = Integer(0)*x>>> f.monic()
Traceback (most recent call last):...
ZeroDivisionError: rational division by zero

Notice that the monic version of a polynomial over the integers is defined over the rationals.
sage: x = ZZ[ x ].0
sage: f = 3*x^19 + x^2 - 37sage: g = f.monic(); gx^19 + 1/3*x^2 - 37/3
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

133

Polynomials, Release 10.4

(continued from previous page)

sage: g.parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> x = ZZ[ x ].gen(0)>>> f = Integer(3)*x**Integer(19) + x**Integer(2) - Integer(37)>>> g = f.monic(); gx^19 + 1/3*x^2 - 37/3>>> g.parent()
Univariate Polynomial Ring in x over Rational Field

AUTHORS:• Naqi Jaffery (2006-01-24): examples
monomial_coefficient(m)Return the coefficient in the base ring of the monomial m in self, where m must have the same parent as
self.
INPUT:• m – a monomial
OUTPUT: Coefficient in base ring.
EXAMPLES:
sage: P.<x> = QQ[]
sage: f = 2 * x
sage: c = f.monomial_coefficient(x); c2
sage: c.parent()
Rational Field
sage: f = x^9 - 1/2*x^2 + 7*x + 5/11
sage: f.monomial_coefficient(x^9)
1sage: f.monomial_coefficient(x^2)-1/2
sage: f.monomial_coefficient(x)7sage: f.monomial_coefficient(x^0)
5/11
sage: f.monomial_coefficient(x^3)
0>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> f = Integer(2) * x>>> c = f.monomial_coefficient(x); c
2>>> c.parent()
Rational Field>>> f = x**Integer(9) - Integer(1)/Integer(2)*x**Integer(2) + Integer(7)*x +␣˓→Integer(5)/Integer(11)>>> f.monomial_coefficient(x**Integer(9))
1(continues on next page)

134

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f.monomial_coefficient(x**Integer(2))-1/2>>> f.monomial_coefficient(x)7>>> f.monomial_coefficient(x**Integer(0))
5/11>>> f.monomial_coefficient(x**Integer(3))
0monomials()
Return the list of the monomials in self in a decreasing order of their degrees.
EXAMPLES:
sage: P.<x> = QQ[]
sage: f = x^2 + (2/3)*x + 1
sage: f.monomials()[x^2, x, 1]
sage: f = P(3/2)
sage: f.monomials()[1]
sage: f = P(0)sage: f.monomials()[]sage: f = x
sage: f.monomials()[x]sage: f = - 1/2*x^2 + x^9 + 7*x + 5/11
sage: f.monomials()[x^9, x^2, x, 1]
sage: # needs sage.rings.number_fieldsage: x = polygen(ZZ, x )sage: K.<rho> = NumberField(x**2 + 1)
sage: R.<y> = QQ[]
sage: p = rho * ysage: p.monomials()[y]>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(2) + (Integer(2)/Integer(3))*x + Integer(1)>>> f.monomials()[x^2, x, 1]>>> f = P(Integer(3)/Integer(2))>>> f.monomials()[1]>>> f = P(Integer(0))>>> f.monomials()[]>>> f = x>>> f.monomials()[x]>>> f = - Integer(1)/Integer(2)*x**Integer(2) + x**Integer(9) + Integer(7)*x␣˓→+ Integer(5)/Integer(11)>>> f.monomials()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

135

Polynomials, Release 10.4

(continued from previous page)[x^9, x^2, x, 1]>>> # needs sage.rings.number_field>>> x = polygen(ZZ, x )>>> K = NumberField(x**Integer(2) + Integer(1), names=( rho ,)); (rho,) = K._
˓→first_ngens(1)>>> R = QQ[ y ]; (y,) = R._first_ngens(1)>>> p = rho * y>>> p.monomials()[y]multiplication_trunc(other, n)
Truncated multiplication
EXAMPLES:
sage: R.<x> = ZZ[]
sage: (x^10 + 5*x^5 + x^2 - 3).multiplication_trunc(x^7 - 3*x^3 + 1, 11)x^10 + x^9 - 15*x^8 - 3*x^7 + 2*x^5 + 9*x^3 + x^2 - 3>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(10) + Integer(5)*x**Integer(5) + x**Integer(2) - Integer(3)).
˓→multiplication_trunc(x**Integer(7) - Integer(3)*x**Integer(3) + Integer(1),␣
˓→Integer(11))
x^10 + x^9 - 15*x^8 - 3*x^7 + 2*x^5 + 9*x^3 + x^2 - 3

Check that coercion is working:sage: R2 = QQ[ x ]sage: x2 = R2.gen()sage: p1 = (x^3 + 1).multiplication_trunc(x2^3 - 2, 5); p1-x^3 - 2sage: p2 = (x2^3 + 1).multiplication_trunc(x^3 - 2, 5); p2-x^3 - 2sage: parent(p1) == parent(p2) == R2
True>>> from sage.all import *>>> R2 = QQ[ x ]>>> x2 = R2.gen()>>> p1 = (x**Integer(3) + Integer(1)).multiplication_trunc(x2**Integer(3) -␣˓→Integer(2), Integer(5)); p1-x^3 - 2>>> p2 = (x2**Integer(3) + Integer(1)).multiplication_trunc(x**Integer(3) -␣˓→Integer(2), Integer(5)); p2-x^3 - 2>>> parent(p1) == parent(p2) == R2
Truenewton_raphson(n, x0)
Return a list of n iterative approximations to a root of this polynomial, computed using the Newton-Raphson
method.
The Newton-Raphson method is an iterative root-finding algorithm. For 𝑓 (𝑥) a polynomial, as is the casehere, this is essentially the same as Horner’s method.

136

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

INPUT:• n – an integer (the number of iterations),• x0 – an initial guess 𝑥0 .
OUTPUT: A list of numbers hopefully approximating a root of 𝑓 (𝑥) = 0.
If one of the iterates is a critical point of 𝑓 , a ZeroDivisionError exception is raised.
EXAMPLES:
sage: x = PolynomialRing(RealField(), x ).gen()˓→needs sage.rings.real_mpfr
sage: f = x^2 - 2
˓→needs sage.rings.real_mpfr
sage: f.newton_raphson(4, 1)
˓→needs sage.rings.real_mpfr[1.50000000000000, 1.41666666666667, 1.41421568627451, 1.41421356237469]>>> from sage.all import *>>> x = PolynomialRing(RealField(), x ).gen()˓→needs sage.rings.real_mpfr>>> f = x**Integer(2) - Integer(2)˓→# needs sage.rings.real_mpfr>>> f.newton_raphson(Integer(4), Integer(1))˓→# needs sage.rings.real_mpfr[1.50000000000000, 1.41666666666667, 1.41421568627451, 1.41421356237469]

#␣
#␣
#␣

#␣
␣
␣

AUTHORS:• David Joyner and William Stein (2005-11-28)
newton_slopes(p, lengths=False)
Return the 𝑝-adic slopes of the Newton polygon of self, when this makes sense.
OUTPUT:
If lengths is False, a list of rational numbers. If lengths is True, a list of couples (𝑠, 𝑙) where 𝑠 is
the slope and 𝑙 the length of the corresponding segment in the Newton polygon.
EXAMPLES:
sage: x = QQ[ x ].0
sage: f = x^3 + 2
sage: f.newton_slopes(2)˓→needs sage.libs.pari[1/3, 1/3, 1/3]
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^5 + 6*x^2 + 4
sage: p.newton_slopes(2)˓→needs sage.libs.pari[1/2, 1/2, 1/3, 1/3, 1/3]
sage: p.newton_slopes(2, lengths=True)[(1/2, 2), (1/3, 3)]
sage: (x^2^100 + 27).newton_slopes(3, lengths=True)[(3/1267650600228229401496703205376, 1267650600228229401496703205376)]#␣#␣>>> from sage.all import *>>> x = QQ[ x ].gen(0)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

137

Polynomials, Release 10.4

(continued from previous page)>>> f = x**Integer(3) + Integer(2)>>> f.newton_slopes(Integer(2))˓→# needs sage.libs.pari[1/3, 1/3, 1/3]>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(5) + Integer(6)*x**Integer(2) + Integer(4)>>> p.newton_slopes(Integer(2))˓→# needs sage.libs.pari[1/2, 1/2, 1/3, 1/3, 1/3]>>> p.newton_slopes(Integer(2), lengths=True)[(1/2, 2), (1/3, 3)]>>> (x**Integer(2)**Integer(100) + Integer(27)).newton_slopes(Integer(3),␣
˓→lengths=True)[(3/1267650600228229401496703205376, 1267650600228229401496703205376)]

␣␣

ALGORITHM: Uses PARI if lengths is False.
norm(p)Return the 𝑝-norm of this polynomial.
DEFINITION: For integer 𝑝, the 𝑝-norm of a polynomial is the 𝑝th root of the sum of the 𝑝th powers of theabsolute values of the coefficients of the polynomial.
INPUT:• p – (positive integer or +infinity) the degree of the norm
EXAMPLES:
sage: # needs sage.rings.real_mpfr
sage: R.<x> = RR[]
sage: f = x^6 + x^2 + -x^4 - 2*x^3sage: f.norm(2)2.64575131106459
sage: (sqrt(1^2 + 1^2 + (-1)^2 + (-2)^2)).n()˓→needs sage.symbolic
2.64575131106459#␣>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(6) + x**Integer(2) + -x**Integer(4) -␣˓→Integer(2)*x**Integer(3)>>> f.norm(Integer(2))
2.64575131106459>>> (sqrt(Integer(1)**Integer(2) + Integer(1)**Integer(2) + (˓→Integer(1))**Integer(2) + (-Integer(2))**Integer(2))).n()˓→# needs sage.symbolic
2.64575131106459
sage: f.norm(1)˓→needs sage.rings.real_mpfr
5.00000000000000
sage: f.norm(infinity)
˓→needs sage.rings.real_mpfr
2.00000000000000

138

␣

#␣

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> f.norm(Integer(1))˓→# needs sage.rings.real_mpfr
5.00000000000000>>> f.norm(infinity)
˓→needs sage.rings.real_mpfr
2.00000000000000
sage: f.norm(-1)˓→needs sage.rings.real_mpfr
Traceback (most recent call last):...
ValueError: The degree of the norm must be positive>>> from sage.all import *>>> f.norm(-Integer(1))˓→# needs sage.rings.real_mpfr
Traceback (most recent call last):...
ValueError: The degree of the norm must be positive

␣

#␣

#␣

␣

AUTHORS:• Didier Deshommes• William Stein: fix bugs, add definition, etc.
nth_root(n)Return a 𝑛-th root of this polynomial.
This is computed using Newton method in the ring of power series. This method works only when the basering is an integral domain. Moreover, for polynomial whose coefficient of lower degree is different from 1,
the elements of the base ring should have a method nth_root() implemented.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: a = 27 * (x+3)**6 * (x+5)**3
sage: a.nth_root(3)3*x^3 + 33*x^2 + 117*x + 135
sage: b = 25 * (x^2 + x + 1)
sage: b.nth_root(2)Traceback (most recent call last):...
ValueError: not a 2nd power
sage: R(0).nth_root(3)0sage: R.<x> = QQ[]
sage: a = 1/4 * (x/7 + 3/2)^2 * (x/2 + 5/3)^4
sage: a.nth_root(2)1/56*x^3 + 103/336*x^2 + 365/252*x + 25/12
sage: # needs sage.rings.number_fieldsage: K.<sqrt2> = QuadraticField(2)sage: R.<x> = K[]
sage: a = (x + sqrt2)^3 * ((1+sqrt2)*x - 1/sqrt2)^6
sage: b = a.nth_root(3); b(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

139

Polynomials, Release 10.4

(continued from previous page)(2*sqrt2 + 3)*x^3 + (2*sqrt2 + 2)*x^2 + (-2*sqrt2 - 3/2)*x + 1/2*sqrt2
sage: b^3 == aTruesage: # needs sage.rings.number_fieldsage: R.<x> = QQbar[]
sage: p = x**3 + QQbar(2).sqrt() * x - QQbar(3).sqrt()
sage: r = (p**5).nth_root(5)sage: r * p[0] == p * r[0]Truesage: p = (x+1)^20 + x^20
sage: p.nth_root(20)Traceback (most recent call last):...
ValueError: not a 20th power
sage: # needs sage.rings.finite_rings
sage: z = GF(4).gen()sage: R.<x> = GF(4)[]sage: p = z*x**4 + 2*x - 1
sage: r = (p**15).nth_root(15)sage: r * p[0] == p * r[0]Truesage: ((x+1)**2).nth_root(2)x + 1sage: ((x+1)**4).nth_root(4)x + 1sage: ((x+1)**12).nth_root(12)x + 1
sage: (x^4 + x^3 + 1).nth_root(2)Traceback (most recent call last):...
ValueError: not a 2nd power
sage: p = (x+1)^17 + x^17
sage: r = p.nth_root(17)Traceback (most recent call last):...
ValueError: not a 17th power
sage: R1.<x> = QQ[]
sage: R2.<y> = R1[]
sage: R3.<z> = R2[]
sage: (((y**2+x)*z^2 + x*y*z + 2*x)**3).nth_root(3)(y^2 + x)*z^2 + x*y*z + 2*x
sage: ((x+y+z)**5).nth_root(5)z + y + x>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> a = Integer(27) * (x+Integer(3))**Integer(6) * (x+Integer(5))**Integer(3)>>> a.nth_root(Integer(3))
3*x^3 + 33*x^2 + 117*x + 135>>> b = Integer(25) * (x**Integer(2) + x + Integer(1))>>> b.nth_root(Integer(2))
Traceback (most recent call last):(continues on next page)

140

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)...
ValueError: not a 2nd power>>> R(Integer(0)).nth_root(Integer(3))
0>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> a = Integer(1)/Integer(4) * (x/Integer(7) + Integer(3)/˓→Integer(2))**Integer(2) * (x/Integer(2) + Integer(5)/Integer(3))**Integer(4)>>> a.nth_root(Integer(2))
1/56*x^3 + 103/336*x^2 + 365/252*x + 25/12>>> # needs sage.rings.number_field>>> K = QuadraticField(Integer(2), names=( sqrt2 ,)); (sqrt2,) = K._first_
˓→ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> a = (x + sqrt2)**Integer(3) * ((Integer(1)+sqrt2)*x - Integer(1)/˓→sqrt2)**Integer(6)>>> b = a.nth_root(Integer(3)); b(2*sqrt2 + 3)*x^3 + (2*sqrt2 + 2)*x^2 + (-2*sqrt2 - 3/2)*x + 1/2*sqrt2>>> b**Integer(3) == a
True>>> # needs sage.rings.number_field>>> R = QQbar[ x ]; (x,) = R._first_ngens(1)>>> p = x**Integer(3) + QQbar(Integer(2)).sqrt() * x - QQbar(Integer(3)).
˓→sqrt()>>> r = (p**Integer(5)).nth_root(Integer(5))>>> r * p[Integer(0)] == p * r[Integer(0)]True>>> p = (x+Integer(1))**Integer(20) + x**Integer(20)>>> p.nth_root(Integer(20))
Traceback (most recent call last):...
ValueError: not a 20th power>>> # needs sage.rings.finite_rings>>> z = GF(Integer(4)).gen()>>> R = GF(Integer(4))[ x ]; (x,) = R._first_ngens(1)>>> p = z*x**Integer(4) + Integer(2)*x - Integer(1)>>> r = (p**Integer(15)).nth_root(Integer(15))>>> r * p[Integer(0)] == p * r[Integer(0)]True>>> ((x+Integer(1))**Integer(2)).nth_root(Integer(2))
x + 1>>> ((x+Integer(1))**Integer(4)).nth_root(Integer(4))
x + 1>>> ((x+Integer(1))**Integer(12)).nth_root(Integer(12))
x + 1>>> (x**Integer(4) + x**Integer(3) + Integer(1)).nth_root(Integer(2))
Traceback (most recent call last):...
ValueError: not a 2nd power>>> p = (x+Integer(1))**Integer(17) + x**Integer(17)>>> r = p.nth_root(Integer(17))
Traceback (most recent call last):...
ValueError: not a 17th power(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

141

Polynomials, Release 10.4

(continued from previous page)>>> R1 = QQ[ x ]; (x,) = R1._first_ngens(1)>>> R2 = R1[ y ]; (y,) = R2._first_ngens(1)>>> R3 = R2[ z ]; (z,) = R3._first_ngens(1)>>> (((y**Integer(2)+x)*z**Integer(2) + x*y*z + Integer(2)*x)**Integer(3)).
˓→nth_root(Integer(3))(y^2 + x)*z^2 + x*y*z + 2*x>>> ((x+y+z)**Integer(5)).nth_root(Integer(5))
z + y + x

Here we consider a base ring without nth_root method. The third example with a non-trivial coefficientof lowest degree raises an error:
sage: # needs sage.libs.pari
sage: R.<x> = QQ[]
sage: R2 = R.quotient(x**2 + 1)
sage: x = R2.gen()sage: R3.<y> = R2[]
sage: (y**2 - 2*y + 1).nth_root(2)-y + 1
sage: (y**3).nth_root(3)ysage: (y**2 + x).nth_root(2)Traceback (most recent call last):...
AttributeError: ... has no attribute

nth_root ...

>>> from sage.all import *>>> # needs sage.libs.pari>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R2 = R.quotient(x**Integer(2) + Integer(1))>>> x = R2.gen()>>> R3 = R2[ y ]; (y,) = R3._first_ngens(1)>>> (y**Integer(2) - Integer(2)*y + Integer(1)).nth_root(Integer(2))-y + 1>>> (y**Integer(3)).nth_root(Integer(3))
y>>> (y**Integer(2) + x).nth_root(Integer(2))
Traceback (most recent call last):...
AttributeError: ... has no attribute nth_root ...

number_of_real_roots()
Return the number of real roots of this polynomial, counted without multiplicity.
EXAMPLES:
sage: # needs sage.libs.pari
sage: R.<x> = PolynomialRing(ZZ)
sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3)sage: pol.number_of_real_roots()
3sage: pol = (x - 1) * (x - 2) * (x - 3)sage: # needs sage.libs.pari sage.rings.real_mpfr
sage: pol2 = pol.change_ring(CC)sage: pol2.number_of_real_roots()(continues on next page)

142

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)3
sage: R.<x> = PolynomialRing(CC)sage: pol = (x - 1) * (x - CC(I))
sage: pol.number_of_real_roots()
1>>> from sage.all import *>>> # needs sage.libs.pari>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = (x - Integer(1))**Integer(2) * (x - Integer(2))**Integer(2) * (x -␣˓→Integer(3))>>> pol.number_of_real_roots()3>>> pol = (x - Integer(1)) * (x - Integer(2)) * (x - Integer(3))>>> # needs sage.libs.pari sage.rings.real_mpfr>>> pol2 = pol.change_ring(CC)>>> pol2.number_of_real_roots()3>>> R = PolynomialRing(CC, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = (x - Integer(1)) * (x - CC(I))>>> pol.number_of_real_roots()
1

number_of_roots_in_interval(a=None, b=None)
Return the number of roots of this polynomial in the interval [𝑎, 𝑏], counted without multiplicity. The endpoints 𝑎, 𝑏 default to -Infinity, Infinity (which are also valid input values).
Calls the PARI routine pari:polsturm.
Note that as of version 2.8, PARI includes the left endpoint of the interval (and no longer uses Sturm’salgorithm on exact inputs). pari:polsturm requires a polynomial with real coefficients; in case PARI returns
an error, we try again after taking the GCD of self with its complex conjugate.
EXAMPLES:
sage: # needs sage.libs.pari
sage: R.<x> = PolynomialRing(ZZ)
sage: pol = (x - 1)^2 * (x - 2)^2 * (x - 3)sage: pol.number_of_roots_in_interval(1, 2)
2
sage: pol.number_of_roots_in_interval(1.01, 2)
1sage: pol.number_of_roots_in_interval(None, 2)2
sage: pol.number_of_roots_in_interval(1, Infinity)3
sage: pol.number_of_roots_in_interval()
3
sage: pol = (x - 1) * (x - 2) * (x - 3)sage: # needs sage.libs.pari sage.rings.real_mpfr
sage: pol2 = pol.change_ring(CC)sage: pol2.number_of_roots_in_interval()
3
sage: R.<x> = PolynomialRing(CC)sage: pol = (x - 1) * (x - CC(I))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

143

Polynomials, Release 10.4

(continued from previous page)

sage: pol.number_of_roots_in_interval(0, 2)
1>>> from sage.all import *>>> # needs sage.libs.pari>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = (x - Integer(1))**Integer(2) * (x - Integer(2))**Integer(2) * (x -␣˓→Integer(3))>>> pol.number_of_roots_in_interval(Integer(1), Integer(2))
2>>> pol.number_of_roots_in_interval(RealNumber( 1.01 ), Integer(2))
1>>> pol.number_of_roots_in_interval(None, Integer(2))
2>>> pol.number_of_roots_in_interval(Integer(1), Infinity)3>>> pol.number_of_roots_in_interval()
3>>> pol = (x - Integer(1)) * (x - Integer(2)) * (x - Integer(3))>>> # needs sage.libs.pari sage.rings.real_mpfr>>> pol2 = pol.change_ring(CC)>>> pol2.number_of_roots_in_interval()
3>>> R = PolynomialRing(CC, names=( x ,)); (x,) = R._first_ngens(1)>>> pol = (x - Integer(1)) * (x - CC(I))>>> pol.number_of_roots_in_interval(Integer(0), Integer(2))
1number_of_terms()
Return the number of non-zero coefficients of self.
Also called weight, Hamming weight or sparsity.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^3 - x
sage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x + 1)^100
sage: f.number_of_terms()
101
sage: S = GF(5)[ y ]sage: S(f).number_of_terms()5
sage: cyclotomic_polynomial(105).number_of_terms()
33>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) - x>>> f.number_of_terms()2(continues on next page)

144

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> R(Integer(0)).number_of_terms()0>>> f = (x + Integer(1))**Integer(100)>>> f.number_of_terms()
101>>> S = GF(Integer(5))[ y ]>>> S(f).number_of_terms()
5>>> cyclotomic_polynomial(Integer(105)).number_of_terms()
33

The method hamming_weight() is an alias:
sage: f.hamming_weight()
101>>> from sage.all import *>>> f.hamming_weight()
101

numerator()
Return a numerator of self, computed as self * self.denominator()
Note that some subclasses may implement its own numerator function. For example, see sage.rings.
polynomial.polynomial_rational_flint.Polynomial_rational_flint
Warning: This is not the numerator of the rational function defined by self, which would always beself since self is a polynomial.
EXAMPLES:First we compute the numerator of a polynomial with integer coefficients, which is of course self.
sage: R.<x> = ZZ[]
sage: f = x^3 + 17*x + 1
sage: f.numerator()x^3 + 17*x + 1
sage: f == f.numerator()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + Integer(17)*x + Integer(1)>>> f.numerator()x^3 + 17*x + 1>>> f == f.numerator()
True

Next we compute the numerator of a polynomial with rational coefficients.
sage: R.<x> = PolynomialRing(QQ)
sage: f = (1/17)*x^19 - (2/3)*x + 1/3; f
1/17*x^19 - 2/3*x + 1/3
sage: f.numerator()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

145

Polynomials, Release 10.4

(continued from previous page)

3*x^19 - 34*x + 17
sage: f == f.numerator()
False>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = (Integer(1)/Integer(17))*x**Integer(19) - (Integer(2)/Integer(3))*x +␣˓→Integer(1)/Integer(3); f
1/17*x^19 - 2/3*x + 1/3>>> f.numerator()
3*x^19 - 34*x + 17>>> f == f.numerator()
False

We try to compute the denominator of a polynomial with coefficients in the real numbers, which is a ring
whose elements do not have a denominator method.
sage: # needs sage.rings.real_mpfr
sage: R.<x> = RR[]
sage: f = x + RR( 0.3 ); f
x + 0.300000000000000
sage: f.numerator()x + 0.300000000000000>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ x ]; (x,) = R._first_ngens(1)>>> f = x + RR( 0.3 ); f
x + 0.300000000000000>>> f.numerator()x + 0.300000000000000

We check that the computation of the numerator and denominator are valid.
sage: # needs sage.rings.number_field sage.symbolic
sage: K = NumberField(symbolic_expression( x^3+2 ),sage: f = K.random_element()
sage: f.numerator() / f.denominator() == f
Truea )[ s,t ][ x ]sage: R = RR[ x ]sage: f = R.random_element()
sage: f.numerator() / f.denominator() == f
True>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> K = NumberField(symbolic_expression( x^3+2 ),>>> f = K.random_element()>>> f.numerator() / f.denominator() == f
Truea )[ s,t ][ x ]>>> R = RR[ x ]>>> f = R.random_element()>>> f.numerator() / f.denominator() == f
True

146

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

ord(p=None)
This is the same as the valuation of self at 𝑝. See the documentation for valuation().
EXAMPLES:
sage: R.<x> = ZZ[]
sage: (x^2 + x).ord(x + 1)
1>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2) + x).ord(x + Integer(1))
1padded_list(n=None)
Return list of coefficients of self up to (but not including) 𝑞 𝑛 .
Includes 0’s in the list on the right so that the list has length 𝑛.
INPUT:• n – (default: None); if given, an integer that is at least 0
EXAMPLES:
sage: x = polygen(QQ)
sage: f = 1 + x^3 + 23*x^5sage: f.padded_list()[1, 0, 0, 1, 0, 23]
sage: f.padded_list(10)[1, 0, 0, 1, 0, 23, 0, 0, 0, 0]
sage: len(f.padded_list(10))
10sage: f.padded_list(3)[1, 0, 0]
sage: f.padded_list(0)[]sage: f.padded_list(-1)
Traceback (most recent call last):...
ValueError: n must be at least 0>>> from sage.all import *>>> x = polygen(QQ)>>> f = Integer(1) + x**Integer(3) + Integer(23)*x**Integer(5)>>> f.padded_list()[1, 0, 0, 1, 0, 23]>>> f.padded_list(Integer(10))[1, 0, 0, 1, 0, 23, 0, 0, 0, 0]>>> len(f.padded_list(Integer(10)))10>>> f.padded_list(Integer(3))[1, 0, 0]>>> f.padded_list(Integer(0))[]>>> f.padded_list(-Integer(1))
Traceback (most recent call last):...
ValueError: n must be at least 02.1. Univariate Polynomials and Polynomial Rings

147

Polynomials, Release 10.4

plot(xmin=None, xmax=None, *args, **kwds)
Return a plot of this polynomial.
INPUT:• xmin – float• xmax – float• *args, **kwds – passed to either plot or point
OUTPUT: returns a graphic object.
EXAMPLES:
sage: x = polygen(GF(389))
sage: plot(x^2 + 1, rgbcolor=(0,0,1))
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive
sage: x = polygen(QQ)
sage: plot(x^2 + 1, rgbcolor=(1,0,0))˓→needs sage.plot
Graphics object consisting of 1 graphics primitive#␣#␣>>> from sage.all import *>>> x = polygen(GF(Integer(389)))>>> plot(x**Integer(2) + Integer(1), rgbcolor=(Integer(0),Integer(0),˓→Integer(1)))# needs sage.plot
Graphics object consisting of 1 graphics primitive>>> x = polygen(QQ)>>> plot(x**Integer(2) + Integer(1), rgbcolor=(Integer(1),Integer(0),˓→Integer(0)))# needs sage.plot
Graphics object consisting of 1 graphics primitive

polynomial(var)
Let var be one of the variables of the parent of self. This returns self viewed as a univariate polynomial
in var over the polynomial ring generated by all the other variables of the parent.
For univariate polynomials, if var is the generator of the parent ring, we return this polynomial, otherwise
raise an error.
EXAMPLES:
sage: R.<x> = QQ[]
sage: (x + 1).polynomial(x)x + 1>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (x + Integer(1)).polynomial(x)x + 1

power_trunc(n, prec)
Truncated n-th power of this polynomial up to precision prec
INPUT:• n – (non-negative integer) power to be taken• prec – (integer) the precision

148

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x> = ZZ[]
sage: (3*x^2 - 2*x + 1).power_trunc(5, 8)-1800*x^7 + 1590*x^6 - 1052*x^5 + 530*x^4 - 200*x^3 + 55*x^2 - 10*x + 1
sage: ((3*x^2 - 2*x + 1)^5).truncate(8)-1800*x^7 + 1590*x^6 - 1052*x^5 + 530*x^4 - 200*x^3 + 55*x^2 - 10*x + 1
sage: S.<y> = R[]
sage: (x + y).power_trunc(5,5)
5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5
sage: ((x + y)^5).truncate(5)5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5
sage: R.<x> = GF(3)[]sage: p = x^2 - x + 1
sage: q = p.power_trunc(80, 20); qx^19 + x^18 + ... + 2*x^4 + 2*x^3 + x + 1
sage: (p^80).truncate(20) == q
True
sage: R.<x> = GF(7)[]sage: p = (x^2 + x + 1).power_trunc(2^100, 100); p2*x^99 + x^98 + x^95 + 2*x^94 + ... + 3*x^2 + 2*x + 1
sage: for i in range(100):....:
q1 = (x^2 + x + 1).power_trunc(2^100 + i, 100)....:
q2 = p * (x^2 + x + 1).power_trunc(i, 100)....:
q2 = q2.truncate(100)....:assert q1 == q2, "i = {}".format(i)>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(3)*x**Integer(2) - Integer(2)*x + Integer(1)).power_
˓→trunc(Integer(5), Integer(8))-1800*x^7 + 1590*x^6 - 1052*x^5 + 530*x^4 - 200*x^3 + 55*x^2 - 10*x + 1>>> ((Integer(3)*x**Integer(2) - Integer(2)*x + Integer(1))**Integer(5)).
˓→truncate(Integer(8))-1800*x^7 + 1590*x^6 - 1052*x^5 + 530*x^4 - 200*x^3 + 55*x^2 - 10*x + 1>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> (x + y).power_trunc(Integer(5),Integer(5))
5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5>>> ((x + y)**Integer(5)).truncate(Integer(5))
5*x*y^4 + 10*x^2*y^3 + 10*x^3*y^2 + 5*x^4*y + x^5>>> R = GF(Integer(3))[ x ]; (x,) = R._first_ngens(1)>>> p = x**Integer(2) - x + Integer(1)>>> q = p.power_trunc(Integer(80), Integer(20)); qx^19 + x^18 + ... + 2*x^4 + 2*x^3 + x + 1>>> (p**Integer(80)).truncate(Integer(20)) == q
True>>> R = GF(Integer(7))[ x ]; (x,) = R._first_ngens(1)>>> p = (x**Integer(2) + x + Integer(1)).power_trunc(Integer(2)**Integer(100),
˓→ Integer(100)); p2*x^99 + x^98 + x^95 + 2*x^94 + ... + 3*x^2 + 2*x + 1(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

149

Polynomials, Release 10.4

(continued from previous page)>>> for i in range(Integer(100)):...
q1 = (x**Integer(2) + x + Integer(1)).power_
˓→trunc(Integer(2)**Integer(100) + i, Integer(100))...
q2 = p * (x**Integer(2) + x + Integer(1)).power_trunc(i, Integer(100))...
q2 = q2.truncate(Integer(100))...
assert q1 == q2, "i = {}".format(i)prec()
Return the precision of this polynomial. This is always infinity, since polynomials are of infinite precision bydefinition (there is no big-oh).
EXAMPLES:
sage: x = polygen(ZZ)
sage: (x^5 + x + 1).prec()+Infinity
sage: x.prec()+Infinity>>> from sage.all import *>>> x = polygen(ZZ)>>> (x**Integer(5) + x + Integer(1)).prec()+Infinity>>> x.prec()+Infinity

pseudo_quo_rem(other)Compute the pseudo-division of two polynomials.
INPUT:• other – a nonzero polynomial
OUTPUT:
𝑄 and 𝑅 such that 𝑙𝑚−𝑛+1 self = 𝑄 · other + 𝑅 where 𝑚 is the degree of this polynomial, 𝑛 is the degree ofother, 𝑙 is the leading coefficient of other. The result is such that deg(𝑅) < deg(other).
ALGORITHM:
Algorithm 3.1.2 in [Coh1993].
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^4 + 6*x^3 + x^2 - x + 2
sage: q = 2*x^2 - 3*x - 1
sage: quo, rem = p.pseudo_quo_rem(q); quo, rem(4*x^2 + 30*x + 51, 175*x + 67)
sage: 2^(4-2+1)*p == quo*q + rem
True
sage: S.<T> = R[]
sage: p = (-3*x^2 - x)*T^3 - 3*x*T^2 + (x^2 - x)*T + 2*x^2 + 3*x - 2
sage: q = (-x^2 - 4*x - 5)*T^2 + (6*x^2 + x + 1)*T + 2*x^2 - x
sage: quo, rem = p.pseudo_quo_rem(q); quo, rem((3*x^4 + 13*x^3 + 19*x^2 + 5*x)*T + 18*x^4 + 12*x^3 + 16*x^2 + 16*x,(-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T(continues on next page)

150

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)- 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50)
sage: (-x^2 - 4*x - 5)^(3-2+1) * p == quo*q + rem
True>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(4) + Integer(6)*x**Integer(3) + x**Integer(2) - x +␣˓→Integer(2)>>> q = Integer(2)*x**Integer(2) - Integer(3)*x - Integer(1)>>> quo, rem = p.pseudo_quo_rem(q); quo, rem(4*x^2 + 30*x + 51, 175*x + 67)>>> Integer(2)**(Integer(4)-Integer(2)+Integer(1))*p == quo*q + rem
True>>> S = R[ T ]; (T,) = S._first_ngens(1)>>> p = (-Integer(3)*x**Integer(2) - x)*T**Integer(3) -␣˓→Integer(3)*x*T**Integer(2) + (x**Integer(2) - x)*T +␣˓→Integer(2)*x**Integer(2) + Integer(3)*x - Integer(2)>>> q = (-x**Integer(2) - Integer(4)*x - Integer(5))*T**Integer(2) +␣˓→(Integer(6)*x**Integer(2) + x + Integer(1))*T + Integer(2)*x**Integer(2) - x>>> quo, rem = p.pseudo_quo_rem(q); quo, rem((3*x^4 + 13*x^3 + 19*x^2 + 5*x)*T + 18*x^4 + 12*x^3 + 16*x^2 + 16*x,(-113*x^6 - 106*x^5 - 133*x^4 - 101*x^3 - 42*x^2 - 41*x)*T- 34*x^6 + 13*x^5 + 54*x^4 + 126*x^3 + 134*x^2 - 5*x - 50)>>> (-x**Integer(2) - Integer(4)*x - Integer(5))**(Integer(3)˓→Integer(2)+Integer(1)) * p == quo*q + rem
Trueradical()Return the radical of self.
Over a field, this is the product of the distinct irreducible factors of self. (This is also sometimes called the“square-free part” of self, but that term is ambiguous; it is sometimes used to mean the quotient of selfby its maximal square factor.)
EXAMPLES:
sage: P.<x> = ZZ[]
sage: t = (x^2-x+1)^3 * (3*x-1)^2
sage: t.radical()
3*x^3 - 4*x^2 + 4*x - 1
sage: radical(12 * x^5)
6*x>>> from sage.all import *>>> P = ZZ[ x ]; (x,) = P._first_ngens(1)>>> t = (x**Integer(2)-x+Integer(1))**Integer(3) * (Integer(3)*x˓→Integer(1))**Integer(2)>>> t.radical()
3*x^3 - 4*x^2 + 4*x - 1>>> radical(Integer(12) * x**Integer(5))
6*x

If self has a factor of multiplicity divisible by the characteristic (see Issue #8736):

2.1. Univariate Polynomials and Polynomial Rings

151

Polynomials, Release 10.4

sage: P.<x> = GF(2)[]sage: (x^3 + x^2).radical()˓→needs sage.rings.finite_ringsx^2 + x#␣>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> (x**Integer(3) + x**Integer(2)).radical()˓→# needs sage.rings.finite_ringsx^2 + x␣

rational_reconstruct(*args, **kwds)
Deprecated: Use rational_reconstruction() instead. See Issue #12696 for details.
rational_reconstruction(m, n_deg=None, d_deg=None)
Return a tuple of two polynomials (n, d) where self * d is congruent to n modulo m and n.degree()<= n_deg and d.degree() <= d_deg.
INPUT:• m – a univariate polynomial• n_deg – (optional) an integer; the default is ⌊(deg(𝑚) − 1)/2⌋• d_deg – (optional) an integer; the default is ⌊(deg(𝑚) − 1)/2⌋
ALGORITHM:
The algorithm is based on the extended Euclidean algorithm for the polynomial greatest common divisor.
EXAMPLES:
Over

[𝑧]:

sage: z = PolynomialRing(QQ, z ).gen()sage: p = -z**16 - z**15 - z**14 + z**13 + z**12 + z**11 - z**5 - z**4 - z**3␣
˓→+ z**2 + z + 1
sage: m = z**21
sage: n, d = p.rational_reconstruction(m); n, d(z^4 + 2*z^3 + 3*z^2 + 2*z + 1,z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1)
sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> z = PolynomialRing(QQ, z ).gen()>>> p = -z**Integer(16) - z**Integer(15) - z**Integer(14) + z**Integer(13) +␣˓→z**Integer(12) + z**Integer(11) - z**Integer(5) - z**Integer(4) -␣˓→z**Integer(3) + z**Integer(2) + z + Integer(1)>>> m = z**Integer(21)>>> n, d = p.rational_reconstruction(m); n, d(z^4 + 2*z^3 + 3*z^2 + 2*z + 1,z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1)>>> ((p*d - n) % m).is_zero()
True

Over Z[𝑧]:152

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: z = PolynomialRing(ZZ, z ).gen()sage: p = -z**16 - z**15 - z**14 + z**13 + z**12 + z**11 - z**5 - z**4 - z**3␣
˓→+ z**2 + z + 1
sage: m = z**21
sage: n, d = p.rational_reconstruction(m); n, d(z^4 + 2*z^3 + 3*z^2 + 2*z + 1,z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1)
sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> z = PolynomialRing(ZZ, z ).gen()>>> p = -z**Integer(16) - z**Integer(15) - z**Integer(14) + z**Integer(13) +␣˓→z**Integer(12) + z**Integer(11) - z**Integer(5) - z**Integer(4) -␣˓→z**Integer(3) + z**Integer(2) + z + Integer(1)>>> m = z**Integer(21)>>> n, d = p.rational_reconstruction(m); n, d(z^4 + 2*z^3 + 3*z^2 + 2*z + 1,z^10 + z^9 + z^8 + z^7 + z^6 + z^5 + z^4 + z^3 + z^2 + z + 1)>>> ((p*d - n) % m).is_zero()
True

Over an integral domain, d might not be monic:
sage: P = PolynomialRing(ZZ, x )sage: x = P.gen()sage: p = 7*x^5 - 10*x^4 + 16*x^3 - 32*x^2 + 128*x + 256
sage: m = x^5
sage: n, d = p.rational_reconstruction(m, 3, 2); n, d(-32*x^3 + 384*x^2 + 2304*x + 2048, 5*x + 8)
sage: ((p*d - n) % m).is_zero()Truesage: n, d = p.rational_reconstruction(m, 4, 0); n, d(-10*x^4 + 16*x^3 - 32*x^2 + 128*x + 256, 1)
sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> P = PolynomialRing(ZZ, x )>>> x = P.gen()>>> p = Integer(7)*x**Integer(5) - Integer(10)*x**Integer(4) +␣˓→Integer(16)*x**Integer(3) - Integer(32)*x**Integer(2) + Integer(128)*x +␣˓→Integer(256)>>> m = x**Integer(5)>>> n, d = p.rational_reconstruction(m, Integer(3), Integer(2)); n, d(-32*x^3 + 384*x^2 + 2304*x + 2048, 5*x + 8)>>> ((p*d - n) % m).is_zero()True>>> n, d = p.rational_reconstruction(m, Integer(4), Integer(0)); n, d(-10*x^4 + 16*x^3 - 32*x^2 + 128*x + 256, 1)>>> ((p*d - n) % m).is_zero()
True

Over

(𝑡)[𝑧]:

sage: P = PolynomialRing(QQ,
sage: t = P.gen()t )(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

153

Polynomials, Release 10.4

(continued from previous page)

sage: Pz = PolynomialRing(P.fraction_field(), z )sage: z = Pz.gen()sage: # p = (1 + t^2*z + z^4) / (1 - t*z)
sage: p = (1 + t^2*z + z^4)*(1 - t*z).inverse_mod(z^9)
sage: m = z^9sage: n, d = p.rational_reconstruction(m); n, d(-1/t*z^4 - t*z - 1/t, z - 1/t)
sage: ((p*d - n) % m).is_zero()Truesage: w = PowerSeriesRing(P.fraction_field(), w ).gen()sage: n = -10*t^2*z^4 + (-t^2 + t - 1)*z^3 + (-t - 8)*z^2 + z + 2*t^2 - t
sage: d = z^4 + (2*t + 4)*z^3 + (-t + 5)*z^2 + (t^2 + 2)*z + t^2 + 2*t + 1
sage: prec = 9
sage: x = n.subs(z=w)/d.subs(z=w) + O(w^prec)
sage: # needs sage.libs.flint (otherwise timeout)
sage: nc, dc = Pz(x.list()).rational_reconstruction(z^prec)
sage: (nc, dc) == (n, d)
True>>> from sage.all import *>>> P = PolynomialRing(QQ, t )>>> t = P.gen()>>> Pz = PolynomialRing(P.fraction_field(), z )>>> z = Pz.gen()>>> # p = (1 + t^2*z + z^4) / (1 - t*z)>>> p = (Integer(1) + t**Integer(2)*z + z**Integer(4))*(Integer(1) - t*z).
˓→inverse_mod(z**Integer(9))>>> m = z**Integer(9)>>> n, d = p.rational_reconstruction(m); n, d(-1/t*z^4 - t*z - 1/t, z - 1/t)>>> ((p*d - n) % m).is_zero()True>>> w = PowerSeriesRing(P.fraction_field(), w ).gen()>>> n = -Integer(10)*t**Integer(2)*z**Integer(4) + (-t**Integer(2) + t -␣˓→Integer(1))*z**Integer(3) + (-t - Integer(8))*z**Integer(2) + z +␣˓→Integer(2)*t**Integer(2) - t>>> d = z**Integer(4) + (Integer(2)*t + Integer(4))*z**Integer(3) + (-t +␣˓→Integer(5))*z**Integer(2) + (t**Integer(2) + Integer(2))*z + t**Integer(2)␣
˓→+ Integer(2)*t + Integer(1)>>> prec = Integer(9)>>> x = n.subs(z=w)/d.subs(z=w) + O(w**prec)>>> # needs sage.libs.flint (otherwise timeout)>>> nc, dc = Pz(x.list()).rational_reconstruction(z**prec)>>> (nc, dc) == (n, d)
True

Over

[𝑡][𝑧]:

sage: P = PolynomialRing(QQ, t )sage: t = P.gen()sage: z = PolynomialRing(P, z ).gen()sage: # p = (1 + t^2*z + z^4) / (1 - t*z) mod z^9sage: p = (1 + t^2*z + z^4) * sum((t*z)**i for i in range(9))
sage: m = z^9(continues on next page)

154

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: n, d = p.rational_reconstruction(m,); n, d(-z^4 - t^2*z - 1, t*z - 1)sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> P = PolynomialRing(QQ, t )>>> t = P.gen()>>> z = PolynomialRing(P, z ).gen()>>> # p = (1 + t^2*z + z^4) / (1 - t*z) mod z^9>>> p = (Integer(1) + t**Integer(2)*z + z**Integer(4)) * sum((t*z)**i for i␣˓→in range(Integer(9)))>>> m = z**Integer(9)>>> n, d = p.rational_reconstruction(m,); n, d(-z^4 - t^2*z - 1, t*z - 1)>>> ((p*d - n) % m).is_zero()
True

Over

5:

sage: # needs sage.rings.padics
sage: x = PolynomialRing(Qp(5), x ).gen()sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2
sage: m = x^6
sage: n, d = p.rational_reconstruction(m, 3, 2)
sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> # needs sage.rings.padics>>> x = PolynomialRing(Qp(Integer(5)), x ).gen()>>> p = Integer(4)*x**Integer(5) + Integer(3)*x**Integer(4) +␣˓→Integer(2)*x**Integer(3) + Integer(2)*x**Integer(2) + Integer(4)*x +␣˓→Integer(2)>>> m = x**Integer(6)>>> n, d = p.rational_reconstruction(m, Integer(3), Integer(2))>>> ((p*d - n) % m).is_zero()
True

Can also be used to obtain known Padé approximations:sage: z = PowerSeriesRing(QQ, z ).gen()sage: P = PolynomialRing(QQ, x )sage: x = P.gen()sage: p = P(z.exp().list())
sage: m = x^5
sage: n, d = p.rational_reconstruction(m, 4, 0); n, d
(1/24*x^4 + 1/6*x^3 + 1/2*x^2 + x + 1, 1)
sage: ((p*d - n) % m).is_zero()Truesage: m = x^3
sage: n, d = p.rational_reconstruction(m, 1, 1); n, d(-x - 2, x - 2)sage: ((p*d - n) % m).is_zero()Truesage: p = P(log(1-z).list())(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

155

Polynomials, Release 10.4

(continued from previous page)

sage: m = x^9sage: n, d = p.rational_reconstruction(m, 4, 4); n, d
(25/6*x^4 - 130/3*x^3 + 105*x^2 - 70*x, x^4 - 20*x^3 + 90*x^2 - 140*x + 70)
sage: ((p*d - n) % m).is_zero()Truesage: p = P(sqrt(1+z).list())
sage: m = x^6
sage: n, d = p.rational_reconstruction(m, 3, 2); n, d
(1/6*x^3 + 3*x^2 + 8*x + 16/3, x^2 + 16/3*x + 16/3)
sage: ((p*d - n) % m).is_zero()Truesage: p = P((2*z).exp().list())
sage: m = x^7
sage: n, d = p.rational_reconstruction(m, 3, 3); n, d(-x^3 - 6*x^2 - 15*x - 15, x^3 - 6*x^2 + 15*x - 15)sage: ((p*d - n) % m).is_zero()True>>> from sage.all import *>>> z = PowerSeriesRing(QQ, z ).gen()>>> P = PolynomialRing(QQ, x )>>> x = P.gen()>>> p = P(z.exp().list())>>> m = x**Integer(5)>>> n, d = p.rational_reconstruction(m, Integer(4), Integer(0)); n, d
(1/24*x^4 + 1/6*x^3 + 1/2*x^2 + x + 1, 1)>>> ((p*d - n) % m).is_zero()True>>> m = x**Integer(3)>>> n, d = p.rational_reconstruction(m, Integer(1), Integer(1)); n, d(-x - 2, x - 2)>>> ((p*d - n) % m).is_zero()True>>> p = P(log(Integer(1)-z).list())>>> m = x**Integer(9)>>> n, d = p.rational_reconstruction(m, Integer(4), Integer(4)); n, d
(25/6*x^4 - 130/3*x^3 + 105*x^2 - 70*x, x^4 - 20*x^3 + 90*x^2 - 140*x + 70)>>> ((p*d - n) % m).is_zero()True>>> p = P(sqrt(Integer(1)+z).list())>>> m = x**Integer(6)>>> n, d = p.rational_reconstruction(m, Integer(3), Integer(2)); n, d
(1/6*x^3 + 3*x^2 + 8*x + 16/3, x^2 + 16/3*x + 16/3)>>> ((p*d - n) % m).is_zero()True>>> p = P((Integer(2)*z).exp().list())>>> m = x**Integer(7)>>> n, d = p.rational_reconstruction(m, Integer(3), Integer(3)); n, d(-x^3 - 6*x^2 - 15*x - 15, x^3 - 6*x^2 + 15*x - 15)>>> ((p*d - n) % m).is_zero()
True

Over R[𝑧]:sage: # needs sage.rings.real_mpfr
sage: z = PowerSeriesRing(RR, z ).gen()(continues on next page)

156

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: P = PolynomialRing(RR, x )sage: x = P.gen()sage: p = P((2*z).exp().list())
sage: m = x^7
sage: n, d = p.rational_reconstruction(m, 3, 3); n, d # absolute tolerance␣
˓→1e-10(-x^3 - 6.0*x^2 - 15.0*x - 15.0, x^3 - 6.0*x^2 + 15.0*x - 15.0)>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> z = PowerSeriesRing(RR, z ).gen()>>> P = PolynomialRing(RR, x )>>> x = P.gen()>>> p = P((Integer(2)*z).exp().list())>>> m = x**Integer(7)>>> n, d = p.rational_reconstruction(m, Integer(3), Integer(3)); n, d
˓→absolute tolerance 1e-10(-x^3 - 6.0*x^2 - 15.0*x - 15.0, x^3 - 6.0*x^2 + 15.0*x - 15.0)#␣

See also:• sage.matrix.berlekamp_massey,• sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint.
rational_reconstruction()
real_roots()
Return the real roots of this polynomial, without multiplicities.
Calls self.roots(ring=RR), unless this is a polynomial with floating-point real coefficients, in whichcase it calls self.roots().
EXAMPLES:
sage: x = polygen(ZZ)
sage: (x^2 - x - 1).real_roots()
˓→needs sage.libs.pari sage.rings.real_mpfr[-0.618033988749895, 1.61803398874989]>>> from sage.all import *>>> x = polygen(ZZ)>>> (x**Integer(2) - x - Integer(1)).real_roots()˓→# needs sage.libs.pari sage.rings.real_mpfr[-0.618033988749895, 1.61803398874989]#␣␣

reciprocal_transform(R=1, q=1)
Transform a general polynomial into a self-reciprocal polynomial.
The input 𝑄 and output 𝑃 satisfy the relation
𝑃 (𝑥) = 𝑄(𝑥 + 𝑞/𝑥)𝑥deg(𝑄) 𝑅(𝑥).
√ √In this relation, 𝑄 has all roots in the real interval [−2 𝑞, 2 𝑞] if and only if 𝑃 has all roots on the circle√|𝑥| = 𝑞 and 𝑅 divides 𝑥2 − 𝑞.
See also:
The inverse operation is trace_polynomial().
2.1. Univariate Polynomials and Polynomial Rings

157

Polynomials, Release 10.4

INPUT:• R – polynomial• q – scalar (default: 1)
EXAMPLES:
sage: pol.<x> = PolynomialRing(Rationals())
sage: u = x^2 + x - 1
sage: u.reciprocal_transform()x^4 + x^3 + x^2 + x + 1
sage: u.reciprocal_transform(R=x-1)
x^5 - 1
sage: u.reciprocal_transform(q=3)
x^4 + x^3 + 5*x^2 + 3*x + 9>>> from sage.all import *>>> pol = PolynomialRing(Rationals(), names=( x ,)); (x,) = pol._first_
˓→ngens(1)>>> u = x**Integer(2) + x - Integer(1)>>> u.reciprocal_transform()x^4 + x^3 + x^2 + x + 1>>> u.reciprocal_transform(R=x-Integer(1))
x^5 - 1>>> u.reciprocal_transform(q=Integer(3))
x^4 + x^3 + 5*x^2 + 3*x + 9

resultant(other)
Return the resultant of self and other.
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
ALGORITHM:
Uses PARI’s function pari:polresultant. For base rings that are not supported by PARI, the resultant is computed as the determinant of the Sylvester matrix.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^3 + x + 1; g = x^3 - x - 1
sage: r = f.resultant(g); r
˓→needs sage.libs.pari-8
sage: r.parent() is QQ
˓→needs sage.libs.pari
True

#␣

#␣

>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(1); g = x**Integer(3) - x - Integer(1)>>> r = f.resultant(g); r#␣˓→needs sage.libs.pari-8>>> r.parent() is QQ#␣(continues on next page)

158

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.pariTrue˓→

We can compute resultants over univariate and multivariate polynomial rings:
sage: R.<a> = QQ[]
sage: S.<x> = R[]
sage: f = x^2 + a; g = x^3 + a
sage: r = f.resultant(g); r
˓→needs sage.libs.paria^3 + a^2
sage: r.parent() is R
˓→needs sage.libs.pari
True>>> from sage.all import *>>> R = QQ[ a ]; (a,) = R._first_ngens(1)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = x**Integer(2) + a; g = x**Integer(3) + a>>> r = f.resultant(g); r
˓→needs sage.libs.paria^3 + a^2>>> r.parent() is R
˓→needs sage.libs.pari
True

#␣

#␣

#␣

#␣

sage: R.<a, b> = QQ[]
sage: S.<x> = R[]
sage: f = x^2 + a; g = x^3 + b
sage: r = f.resultant(g); r
˓→needs sage.libs.paria^3 + b^2
sage: r.parent() is R
˓→needs sage.libs.pari
True>>> from sage.all import *>>> R = QQ[ a, b ]; (a, b,) = R._first_ngens(2)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = x**Integer(2) + a; g = x**Integer(3) + b>>> r = f.resultant(g); r
˓→needs sage.libs.paria^3 + b^2>>> r.parent() is R
˓→needs sage.libs.pari
True

#␣

#␣

#␣

#␣

reverse(degree=None)
Return polynomial but with the coefficients reversed.
If an optional degree argument is given, the coefficient list will be truncated or zero padded as necessary
before reversing it. Assuming that the constant coefficient of self is nonzero, the reverse polynomial will
have the specified degree.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

159

Polynomials, Release 10.4

sage: R.<x> = ZZ[]; S.<y> = R[]
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: f.reverse()-3*x*y^3 + x*y^2 + 1
sage: f.reverse(degree=2)-3*x*y^2 + x*y
sage: f.reverse(degree=5)-3*x*y^5 + x*y^4 + y^2>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1); S = R[ y ]; (y,) = S._first_
˓→ngens(1)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> f.reverse()-3*x*y^3 + x*y^2 + 1>>> f.reverse(degree=Integer(2))-3*x*y^2 + x*y>>> f.reverse(degree=Integer(5))-3*x*y^5 + x*y^4 + y^2

revert_series(n)Return a polynomial f such that f(self(x)) = self(f(x)) = x mod x^n.
Currently, this is only implemented over some coefficient rings.
EXAMPLES:
sage: Pol.<x> = QQ[]
sage: (x + x^3/6 + x^5/120).revert_series(6)3/40*x^5 - 1/6*x^3 + x
sage: Pol.<x> = CBF[]#␣˓→needs sage.libs.flint
sage: (x + x^3/6 + x^5/120).revert_series(6)#␣˓→needs sage.libs.flint([0.075000000000000 +/- ...e-17])*x^5 + ([-0.166666666666667 +/- ...e-16])*x^
˓→3 + xsage: # needs sage.symbolic
sage: Pol.<x> = SR[]
sage: x.revert_series(6)Traceback (most recent call last):...
NotImplementedError: only implemented for certain base rings>>> from sage.all import *>>> Pol = QQ[ x ]; (x,) = Pol._first_ngens(1)>>> (x + x**Integer(3)/Integer(6) + x**Integer(5)/Integer(120)).revert_
˓→series(Integer(6))
3/40*x^5 - 1/6*x^3 + x>>> Pol = CBF[ x ]; (x,) = Pol._first_ngens(1)# needs sage.libs.flint>>> (x + x**Integer(3)/Integer(6) + x**Integer(5)/Integer(120)).revert_
˓→series(Integer(6))# needs sage.libs.flint([0.075000000000000 +/- ...e-17])*x^5 + ([-0.166666666666667 +/- ...e-16])*x^
˓→3 + x(continues on next page)

160

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> # needs sage.symbolic>>> Pol = SR[ x ]; (x,) = Pol._first_ngens(1)>>> x.revert_series(Integer(6))
Traceback (most recent call last):...
NotImplementedError: only implemented for certain base rings

root_field(names, check_irreducible=True)
Return the field generated by the roots of the irreducible polynomial self. The output is either a number
field, relative number field, a quotient of a polynomial ring over a field, or the fraction field of the base ring.
EXAMPLES:
sage: R.<x> = QQ[ x ]sage: f = x^3 + x + 17
sage: f.root_field( a )˓→needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + x + 17>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(17)>>> f.root_field( a )˓→needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + x + 17#␣#␣

sage: R.<x> = QQ[ x ]sage: f = x - 3
sage: f.root_field( b )˓→needs sage.rings.number_field
Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x - Integer(3)>>> f.root_field( b )˓→needs sage.rings.number_field
Rational Field#␣#␣

sage: R.<x> = ZZ[ x ]sage: f = x^3 + x + 17
sage: f.root_field( b )˓→needs sage.rings.number_field
Number Field in b with defining polynomial x^3 + x + 17>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(17)>>> f.root_field( b )˓→needs sage.rings.number_field
Number Field in b with defining polynomial x^3 + x + 17#␣#␣

sage: # needs sage.rings.number_fieldsage: y = QQ[ x ].0(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

161

Polynomials, Release 10.4

(continued from previous page)

sage: L.<a> = NumberField(y^3 - 2)sage: R.<x> = L[ x ]sage: f = x^3 + x + 17
sage: f.root_field( c )Number Field in c with defining polynomial x^3 + x + 17 over its base field>>> from sage.all import *>>> # needs sage.rings.number_field>>> y = QQ[ x ].gen(0)>>> L = NumberField(y**Integer(3) - Integer(2), names=( a ,)); (a,) = L._˓→first_ngens(1)>>> R = L[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(17)>>> f.root_field( c )Number Field in c with defining polynomial x^3 + x + 17 over its base fieldsage: # needs sage.rings.finite_rings
sage: R.<x> = PolynomialRing(GF(9, a ))sage: f = x^3 + x^2 + 8
sage: K.<alpha> = f.root_field(); K
Univariate Quotient Polynomial Ring in alphaover Finite Field in a of size 3^2 with modulus x^3 + x^2 + 2
sage: alpha^2 + 1
alpha^2 + 1
sage: alpha^3 + alpha^2
1>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(9), a ), names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> f = x**Integer(3) + x**Integer(2) + Integer(8)>>> K = f.root_field(names=( alpha ,)); (alpha,) = K._first_ngens(1); K
Univariate Quotient Polynomial Ring in alphaover Finite Field in a of size 3^2 with modulus x^3 + x^2 + 2>>> alpha**Integer(2) + Integer(1)alpha^2 + 1>>> alpha**Integer(3) + alpha**Integer(2)1sage: R.<x> = QQ[]
sage: f = x^2
sage: K.<alpha> = f.root_field()
˓→needs sage.libs.pari
Traceback (most recent call last):...
ValueError: polynomial must be irreducible#␣>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2)>>> K = f.root_field(names=( alpha ,)); (alpha,) = K._first_ngens(1)# needs␣
˓→sage.libs.pari
Traceback (most recent call last):...
(continues on next page)

162

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

ValueError: polynomial must be irreducibleroots(ring=None, multiplicities=True, algorithm=None, **kwds)
Return the roots of this polynomial (by default, in the base ring of this polynomial).
INPUT:• ring – the ring to find roots in• multiplicities – bool (default: True) if True return list of pairs (𝑟, 𝑛), where 𝑟 is the root and𝑛 is the multiplicity. If False, just return the unique roots, with no information about multiplicities.
• algorithm – the root-finding algorithm to use. We attempt to select a reasonable algorithm by default,
but this lets the caller override our choice.
By default, this finds all the roots that lie in the base ring of the polynomial. However, the ring parameter canbe used to specify a ring to look for roots in.
If the polynomial and the output ring are both exact (integers, rationals, finite fields, etc.), then the output
should always be correct (or raise an exception, if that case is not yet handled).
If the output ring is approximate (floating-point real or complex numbers), then the answer will be estimatednumerically, using floating-point arithmetic of at least the precision of the output ring. If the polynomial is
ill-conditioned, meaning that a small change in the coefficients of the polynomial will lead to a relatively largechange in the location of the roots, this may give poor results. Distinct roots may be returned as multiple
roots, multiple roots may be returned as distinct roots, real roots may be lost entirely (because the numericalestimate thinks they are complex roots). Note that polynomials with multiple roots are always ill-conditioned;
there’s a footnote at the end of the docstring about this.
If the output ring is a RealIntervalField or ComplexIntervalField of a given precision, thenthe answer will always be correct (or an exception will be raised, if a case is not implemented). Each root
will be contained in one of the returned intervals, and the intervals will be disjoint. (The returned intervals
may be of higher precision than the specified output ring.)
At the end of this docstring (after the examples) is a description of all the cases implemented in this function,and the algorithms used. That section also describes the possibilities for the algorithm keyword, for thecases where multiple algorithms exist.
EXAMPLES:
sage: # needs sage.libs.pari
sage: x = QQ[ x ].0
sage: f = x^3 - 1
sage: f.roots()[(1, 1)]
sage: f.roots(ring=CC)# ... - low order bits slightly different on ppc
˓→needs sage.rings.real_mpfr[(1.00000000000000, 1),(-0.500000000000000 - 0.86602540378443...*I, 1),(-0.500000000000000 + 0.86602540378443...*I, 1)]
sage: f = (x^3 - 1)^2
sage: f.roots()[(1, 2)]sage: f = -19*x + 884736
sage: f.roots()[(884736/19, 1)]
sage: (f^20).roots()[(884736/19, 20)]

2.1. Univariate Polynomials and Polynomial Rings

#␣

163

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.libs.pari>>> x = QQ[ x ].gen(0)>>> f = x**Integer(3) - Integer(1)>>> f.roots()[(1, 1)]>>> f.roots(ring=CC)# ... - low order bits slightly different on ppc
˓→needs sage.rings.real_mpfr[(1.00000000000000, 1),(-0.500000000000000 - 0.86602540378443...*I, 1),(-0.500000000000000 + 0.86602540378443...*I, 1)]>>> f = (x**Integer(3) - Integer(1))**Integer(2)>>> f.roots()[(1, 2)]>>> f = -Integer(19)*x + Integer(884736)>>> f.roots()[(884736/19, 1)]>>> (f**Integer(20)).roots()[(884736/19, 20)]#␣sage: # needs sage.rings.number_fieldsage: K.<z> = CyclotomicField(3)sage: f = K.defining_polynomial()
sage: f.roots(ring=GF(7))[(4, 1), (2, 1)]
sage: g = f.change_ring(GF(7))
sage: g.roots()[(4, 1), (2, 1)]
sage: g.roots(multiplicities=False)[4, 2]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(3), names=( z ,)); (z,) = K._first_ngens(1)>>> f = K.defining_polynomial()>>> f.roots(ring=GF(Integer(7)))[(4, 1), (2, 1)]>>> g = f.change_ring(GF(Integer(7)))>>> g.roots()[(4, 1), (2, 1)]>>> g.roots(multiplicities=False)[4, 2]A new ring. In the example below, we add the special method _roots_univariate_polynomial()
to the base ring, and observe that this method is called instead to find roots of polynomials over this ring.
This facility can be used to easily extend root finding to work over new rings you introduce:
sage: R.<x> = QQ[]
sage: (x^2 + 1).roots()
˓→needs sage.libs.pari[]
sage: def my_roots(f, *args, **kwds):....:
return f.change_ring(CDF).roots()
sage: QQ._roots_univariate_polynomial = my_roots
sage: (x^2 + 1).roots() # abs tol 1e-14
˓→needs numpy#␣#␣(continues on next page)

164

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[(2.7755575615628914e-17 - 1.0*I, 1), (0.9999999999999997*I, 1)]
sage: del QQ._roots_univariate_polynomial>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2) + Integer(1)).roots()˓→# needs sage.libs.pari[]>>> def my_roots(f, *args, **kwds):...
return f.change_ring(CDF).roots()>>> QQ._roots_univariate_polynomial = my_roots>>> (x**Integer(2) + Integer(1)).roots() # abs tol 1e-14
˓→# needs numpy[(2.7755575615628914e-17 - 1.0*I, 1), (0.9999999999999997*I, 1)]>>> del QQ._roots_univariate_polynomial␣␣

An example over RR, which illustrates that only the roots in RR are returned:
sage: # needs numpy sage.rings.real_mpfr
sage: x = RR[ x ].0
sage: f = x^3 - 2
sage: f.roots()[(1.25992104989487, 1)]
sage: f.factor()(x - 1.25992104989487) * (x^2 + 1.25992104989487*x + 1.58740105196820)
sage: x = RealField(100)[ x ].0
sage: f = x^3 - 2
sage: f.roots()[(1.2599210498948731647672106073, 1)]>>> from sage.all import *>>> # needs numpy sage.rings.real_mpfr>>> x = RR[ x ].gen(0)>>> f = x**Integer(3) - Integer(2)>>> f.roots()[(1.25992104989487, 1)]>>> f.factor()(x - 1.25992104989487) * (x^2 + 1.25992104989487*x + 1.58740105196820)>>> x = RealField(Integer(100))[ x ].gen(0)>>> f = x**Integer(3) - Integer(2)>>> f.roots()[(1.2599210498948731647672106073, 1)]
sage: # needs sage.rings.real_mpfr
sage: x = CC[ x ].0
sage: f = x^3 - 2
sage: f.roots()
˓→needs numpy[(1.25992104989487, 1),(-0.62996052494743... - 1.09112363597172*I, 1),(-0.62996052494743... + 1.09112363597172*I, 1)]
sage: f.roots(algorithm= pari )˓→needs sage.libs.pari[(1.25992104989487, 1),(-0.629960524947437 - 1.09112363597172*I, 1),(-0.629960524947437 + 1.09112363597172*I, 1)]

2.1. Univariate Polynomials and Polynomial Rings

#␣

#␣

165

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> x = CC[ x ].gen(0)>>> f = x**Integer(3) - Integer(2)>>> f.roots()
˓→needs numpy[(1.25992104989487, 1),(-0.62996052494743... - 1.09112363597172*I, 1),(-0.62996052494743... + 1.09112363597172*I, 1)]>>> f.roots(algorithm= pari )˓→needs sage.libs.pari[(1.25992104989487, 1),(-0.629960524947437 - 1.09112363597172*I, 1),(-0.629960524947437 + 1.09112363597172*I, 1)]#␣#␣Another example showing that only roots in the base ring are returned:
sage: x = polygen(ZZ)
sage: f = (2*x - 3) * (x - 1) * (x + 1)
sage: f.roots()
˓→needs sage.libs.pari[(1, 1), (-1, 1)]
sage: f.roots(ring=QQ)
˓→needs sage.libs.pari[(3/2, 1), (1, 1), (-1, 1)]#␣#␣>>> from sage.all import *>>> x = polygen(ZZ)>>> f = (Integer(2)*x - Integer(3)) * (x - Integer(1)) * (x + Integer(1))>>> f.roots()#␣˓→needs sage.libs.pari[(1, 1), (-1, 1)]>>> f.roots(ring=QQ)#␣˓→needs sage.libs.pari[(3/2, 1), (1, 1), (-1, 1)]

An example where we compute the roots lying in a subring of the base ring:sage: Pols.<n> = QQ[]
sage: pol = (n - 1/2)^2 * (n - 1)^2 * (n - 2)sage: pol.roots(ZZ)
˓→needs sage.libs.pari[(2, 1), (1, 2)]#␣>>> from sage.all import *>>> Pols = QQ[ n ]; (n,) = Pols._first_ngens(1)>>> pol = (n - Integer(1)/Integer(2))**Integer(2) * (n -␣˓→Integer(1))**Integer(2) * (n - Integer(2))>>> pol.roots(ZZ)
˓→needs sage.libs.pari[(2, 1), (1, 2)]#␣An example involving large numbers:
sage: # needs numpy sage.rings.real_mpfr
sage: x = RR[ x ].0
sage: f = x^2 - 1e100(continues on next page)

166

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.roots()[(-1.00000000000000e50, 1), (1.00000000000000e50, 1)]
sage: f = x^10 - 2 * (5*x - 1)^2
sage: f.roots(multiplicities=False)[-1.6772670339941..., 0.19995479628..., 0.20004530611..., 1.5763035161844...]>>> from sage.all import *>>> # needs numpy sage.rings.real_mpfr>>> x = RR[ x ].gen(0)>>> f = x**Integer(2) - RealNumber( 1e100 )>>> f.roots()[(-1.00000000000000e50, 1), (1.00000000000000e50, 1)]>>> f = x**Integer(10) - Integer(2) * (Integer(5)*x - Integer(1))**Integer(2)>>> f.roots(multiplicities=False)[-1.6772670339941..., 0.19995479628..., 0.20004530611..., 1.5763035161844...]sage: # needs numpy sage.rings.real_mpfr
sage: x = CC[ x ].0
sage: i = CC.0
sage: f = (x - 1) * (x - i)sage: f.roots(multiplicities=False)[1.00000000000000, 1.00000000000000*I]
sage: g = (x - 1.33 + 1.33*i) * (x - 2.66 - 2.66*i)
sage: g.roots(multiplicities=False)[1.33000000000000 - 1.33000000000000*I, 2.66000000000000 + 2.66000000000000*I]>>> from sage.all import *>>> # needs numpy sage.rings.real_mpfr>>> x = CC[ x ].gen(0)>>> i = CC.gen(0)>>> f = (x - Integer(1)) * (x - i)>>> f.roots(multiplicities=False)[1.00000000000000, 1.00000000000000*I]>>> g = (x - RealNumber( 1.33 ) + RealNumber( 1.33 )*i) * (x - RealNumber( 2.
˓→66 ) - RealNumber( 2.66 )*i)>>> g.roots(multiplicities=False)[1.33000000000000 - 1.33000000000000*I, 2.66000000000000 + 2.66000000000000*I]

Describing roots using radical expressions:sage: x = QQ[ x ].0
sage: f = x^2 + 2
sage: f.roots(SR)˓→needs sage.symbolic[(-I*sqrt(2), 1), (I*sqrt(2), 1)]
sage: f.roots(SR, multiplicities=False)
˓→needs sage.symbolic[-I*sqrt(2), I*sqrt(2)]>>> from sage.all import *>>> x = QQ[ x ].gen(0)>>> f = x**Integer(2) + Integer(2)>>> f.roots(SR)˓→needs sage.symbolic[(-I*sqrt(2), 1), (I*sqrt(2), 1)]

#␣

#␣

#␣

(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

167

Polynomials, Release 10.4

(continued from previous page)>>> f.roots(SR, multiplicities=False)
˓→needs sage.symbolic[-I*sqrt(2), I*sqrt(2)]#␣The roots of some polynomials cannot be described using radical expressions:sage: (x^5 - x + 1).roots(SR)˓→needs sage.symbolic[]#␣>>> from sage.all import *>>> (x**Integer(5) - x + Integer(1)).roots(SR)˓→# needs sage.symbolic[]␣For some other polynomials, no roots can be found at the moment due to the way roots are computed. Issue#17516 addresses these defects. Until that gets implemented, one such example is the following:
sage: f = x^6 - 300*x^5 + 30361*x^4 - 1061610*x^3 + 1141893*x^2 - 915320*x +␣˓→101724
sage: f.roots()#␣˓→needs sage.libs.pari[]>>> from sage.all import *>>> f = x**Integer(6) - Integer(300)*x**Integer(5) +␣˓→Integer(30361)*x**Integer(4) - Integer(1061610)*x**Integer(3) +␣˓→Integer(1141893)*x**Integer(2) - Integer(915320)*x + Integer(101724)>>> f.roots()
˓→needs sage.libs.pari[]#␣A purely symbolic roots example:
sage: # needs sage.symbolic
sage: X = var( X )sage: f = expand((X - 1) * (X - I)^3 * (X^2 - sqrt(2))); fX^6 - (3*I + 1)*X^5 - sqrt(2)*X^4 + (3*I - 3)*X^4 + (3*I + 1)*sqrt(2)*X^3+ (I + 3)*X^3 - (3*I - 3)*sqrt(2)*X^2 - I*X^2 - (I + 3)*sqrt(2)*X + I*sqrt(2)sage: f.roots()[(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)]>>> from sage.all import *>>> # needs sage.symbolic>>> X = var( X )>>> f = expand((X - Integer(1)) * (X - I)**Integer(3) * (X**Integer(2) -␣˓→sqrt(Integer(2)))); fX^6 - (3*I + 1)*X^5 - sqrt(2)*X^4 + (3*I - 3)*X^4 + (3*I + 1)*sqrt(2)*X^3+ (I + 3)*X^3 - (3*I - 3)*sqrt(2)*X^2 - I*X^2 - (I + 3)*sqrt(2)*X + I*sqrt(2)>>> f.roots()[(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)]

The same operation, performed over a polynomial ring with symbolic coefficients:

168

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.symbolic
sage: X = SR[ X ].0
sage: f = (X - 1) * (X - I)^3 * (X^2 - sqrt(2)); fX^6 + (-3*I - 1)*X^5 + (-sqrt(2) + 3*I - 3)*X^4 + ((3*I + 1)*sqrt(2) + I +␣˓→3)*X^3+ (-(3*I - 3)*sqrt(2) - I)*X^2 + (-(I + 3)*sqrt(2))*X + I*sqrt(2)sage: f.roots()[(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)]
sage: f.roots(multiplicities=False)[I, -2^(1/4), 2^(1/4), 1]>>> from sage.all import *>>> # needs sage.symbolic>>> X = SR[ X ].gen(0)>>> f = (X - Integer(1)) * (X - I)**Integer(3) * (X**Integer(2) -␣˓→sqrt(Integer(2))); fX^6 + (-3*I - 1)*X^5 + (-sqrt(2) + 3*I - 3)*X^4 + ((3*I + 1)*sqrt(2) + I +␣˓→3)*X^3+ (-(3*I - 3)*sqrt(2) - I)*X^2 + (-(I + 3)*sqrt(2))*X + I*sqrt(2)>>> f.roots()[(I, 3), (-2^(1/4), 1), (2^(1/4), 1), (1, 1)]>>> f.roots(multiplicities=False)[I, -2^(1/4), 2^(1/4), 1]

A couple of examples where the base ring does not have a factorization algorithm (yet). Note that this iscurrently done via a rather naive enumeration, so could be very slow:
sage: R = Integers(6)sage: S.<x> = R[ x ]sage: p = x^2 - 1
sage: p.roots()
Traceback (most recent call last):...
NotImplementedError: root finding with multiplicities for this polynomial
not implemented (try the multiplicities=False option)
sage: p.roots(multiplicities=False)
˓→needs sage.libs.pari[5, 1]
sage: R = Integers(9)sage: A = PolynomialRing(R, y )sage: y = A.gen()sage: f = 10*y^2 - y^3 - 9sage: f.roots(multiplicities=False)
˓→needs sage.libs.pari[1, 0, 3, 6]#␣#␣>>> from sage.all import *>>> R = Integers(Integer(6))>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> p = x**Integer(2) - Integer(1)>>> p.roots()
Traceback (most recent call last):...
NotImplementedError: root finding with multiplicities for this polynomial
not implemented (try the multiplicities=False option)>>> p.roots(multiplicities=False)#␣˓→needs sage.libs.pari(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

169

Polynomials, Release 10.4

(continued from previous page)[5, 1]>>> R = Integers(Integer(9))>>> A = PolynomialRing(R, y )>>> y = A.gen()>>> f = Integer(10)*y**Integer(2) - y**Integer(3) - Integer(9)>>> f.roots(multiplicities=False)
˓→needs sage.libs.pari[1, 0, 3, 6]#␣An example over the complex double field (where root finding is fast, thanks to NumPy):
sage: # needs numpy sage.rings.complex_double
sage: R.<x> = CDF[]
sage: f = R.cyclotomic_polynomial(5); fx^4 + x^3 + x^2 + x + 1.0
sage: f.roots(multiplicities=False) # abs tol 1e-9[-0.8090169943749469 - 0.5877852522924724*I, -0.8090169943749473 + 0.
˓→5877852522924724*I,
0.30901699437494773 - 0.951056516295154*I, 0.30901699437494756 + 0.
˓→9510565162951525*I]
sage: [z^5 for z in f.roots(multiplicities=False)] # abs tol 2e-14[0.9999999999999957 - 1.2864981197413038e-15*I, 0.9999999999999976 + 3.
˓→062854959141552e-15*I,
1.0000000000000024 + 1.1331077795295987e-15*I, 0.9999999999999953 - 2.
˓→0212861992297117e-15*I]
sage: f = CDF[ x ]([1,2,3,4]); f
4.0*x^3 + 3.0*x^2 + 2.0*x + 1.0
sage: r = f.roots(multiplicities=False)
sage: [f(a).abs() for a in r] # abs tol 1e-14[2.574630599127759e-15, 1.457101633618084e-15, 1.1443916996305594e-15]>>> from sage.all import *>>> # needs numpy sage.rings.complex_double>>> R = CDF[ x ]; (x,) = R._first_ngens(1)>>> f = R.cyclotomic_polynomial(Integer(5)); fx^4 + x^3 + x^2 + x + 1.0>>> f.roots(multiplicities=False) # abs tol 1e-9[-0.8090169943749469 - 0.5877852522924724*I, -0.8090169943749473 + 0.
˓→5877852522924724*I,
0.30901699437494773 - 0.951056516295154*I, 0.30901699437494756 + 0.
˓→9510565162951525*I]>>> [z**Integer(5) for z in f.roots(multiplicities=False)] # abs tol 2e-14[0.9999999999999957 - 1.2864981197413038e-15*I, 0.9999999999999976 + 3.
˓→062854959141552e-15*I,
1.0000000000000024 + 1.1331077795295987e-15*I, 0.9999999999999953 - 2.
˓→0212861992297117e-15*I]>>> f = CDF[ x ]([Integer(1),Integer(2),Integer(3),Integer(4)]); f
4.0*x^3 + 3.0*x^2 + 2.0*x + 1.0>>> r = f.roots(multiplicities=False)>>> [f(a).abs() for a in r] # abs tol 1e-14[2.574630599127759e-15, 1.457101633618084e-15, 1.1443916996305594e-15]

Another example over RDF:
sage: x = RDF[ x ].0
sage: ((x^3 - 1)).roots()# abs tol 4e-16#␣(continues on next page)

170

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs numpy[(1.0000000000000002, 1)]
sage: ((x^3 - 1)).roots(multiplicities=False)
˓→needs numpy[1.0000000000000002]
˓→# abs tol 4e-16>>> from sage.all import *>>> x = RDF[ x ].gen(0)>>> ((x**Integer(3) - Integer(1))).roots() # abs tol 4e-16
˓→# needs numpy[(1.0000000000000002, 1)]>>> ((x**Integer(3) - Integer(1))).roots(multiplicities=False)
˓→16# needs numpy[1.0000000000000002]#␣␣# abs tol 4e-More examples involving the complex double field:
sage: # needs numpy sage.rings.complex_double sage.rings.real_mpfr
sage: x = CDF[ x ].0
sage: i = CDF.0
sage: f = x^3 + 2*i; fx^3 + 2.0*I
sage: f.roots()[(-1.09112363597172... - 0.62996052494743...*I, 1),(...1.25992104989487...*I, 1),(1.09112363597172... - 0.62996052494743...*I, 1)]
sage: f.roots(multiplicities=False)[-1.09112363597172... - 0.62996052494743...*I, ...1.25992104989487...*I,
1.09112363597172... - 0.62996052494743...*I]
sage: [abs(f(z)) for z in f.roots(multiplicities=False)] # abs tol 1e-14[8.95090418262362e-16, 8.728374398092689e-16, 1.0235750533041806e-15]
sage: f = i*x^3 + 2; fI*x^3 + 2.0
sage: f.roots()[(-1.09112363597172... + 0.62996052494743...*I, 1),(...1.25992104989487...*I, 1),(1.09112363597172... + 0.62996052494743...*I, 1)]
sage: abs(f(f.roots()[0][0])) # abs tol 1e-13
1.1102230246251565e-16>>> from sage.all import *>>> # needs numpy sage.rings.complex_double sage.rings.real_mpfr>>> x = CDF[ x ].gen(0)>>> i = CDF.gen(0)>>> f = x**Integer(3) + Integer(2)*i; fx^3 + 2.0*I>>> f.roots()[(-1.09112363597172... - 0.62996052494743...*I, 1),(...1.25992104989487...*I, 1),(1.09112363597172... - 0.62996052494743...*I, 1)]>>> f.roots(multiplicities=False)[-1.09112363597172... - 0.62996052494743...*I, ...1.25992104989487...*I,
1.09112363597172... - 0.62996052494743...*I]>>> [abs(f(z)) for z in f.roots(multiplicities=False)] # abs tol 1e-14[8.95090418262362e-16, 8.728374398092689e-16, 1.0235750533041806e-15]>>> f = i*x**Integer(3) + Integer(2); f(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

171

Polynomials, Release 10.4

(continued from previous page)I*x^3 + 2.0>>> f.roots()[(-1.09112363597172... + 0.62996052494743...*I, 1),(...1.25992104989487...*I, 1),(1.09112363597172... + 0.62996052494743...*I, 1)]>>> abs(f(f.roots()[Integer(0)][Integer(0)])) # abs tol 1e-13
1.1102230246251565e-16

Examples using real root isolation:
sage: x = polygen(ZZ)
sage: f = x^2 - x - 1
sage: f.roots()
˓→needs sage.libs.pari[]
sage: f.roots(ring=AA)
˓→needs sage.rings.number_field[(-0.618033988749895?, 1), (1.618033988749895?, 1)]#␣#␣

sage: # needs sage.rings.real_interval_fieldsage: f.roots(ring=RIF)[(-0.6180339887498948482045868343657?, 1), (1.6180339887498948482045868343657?
˓→, 1)]
sage: f.roots(ring=RIF, multiplicities=False)[-0.6180339887498948482045868343657?, 1.6180339887498948482045868343657?]
sage: f.roots(ring=RealIntervalField(150))[(-0.6180339887498948482045868343656381177203091798057628621354486227?, 1),(1.618033988749894848204586834365638117720309179805762862135448623?, 1)]
sage: f = f^2 * (x - 1)sage: f.roots(ring=RIF)[(-0.6180339887498948482045868343657?, 2),(1.0000000000000000000000000000000?, 1),(1.6180339887498948482045868343657?, 2)]
sage: f.roots(ring=RIF, multiplicities=False)[-0.6180339887498948482045868343657?,
1.0000000000000000000000000000000?,
1.6180339887498948482045868343657?]>>> from sage.all import *>>> x = polygen(ZZ)>>> f = x**Integer(2) - x - Integer(1)>>> f.roots()
˓→needs sage.libs.pari[]>>> f.roots(ring=AA)
˓→needs sage.rings.number_field[(-0.618033988749895?, 1), (1.618033988749895?, 1)]#␣#␣>>> # needs sage.rings.real_interval_field>>> f.roots(ring=RIF)[(-0.6180339887498948482045868343657?, 1), (1.6180339887498948482045868343657?
˓→, 1)]>>> f.roots(ring=RIF, multiplicities=False)[-0.6180339887498948482045868343657?, 1.6180339887498948482045868343657?]>>> f.roots(ring=RealIntervalField(Integer(150)))[(-0.6180339887498948482045868343656381177203091798057628621354486227?, 1),(continues on next page)

172

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(1.618033988749894848204586834365638117720309179805762862135448623?, 1)]>>> f = f**Integer(2) * (x - Integer(1))>>> f.roots(ring=RIF)[(-0.6180339887498948482045868343657?, 2),(1.0000000000000000000000000000000?, 1),(1.6180339887498948482045868343657?, 2)]>>> f.roots(ring=RIF, multiplicities=False)[-0.6180339887498948482045868343657?,
1.0000000000000000000000000000000?,
1.6180339887498948482045868343657?]

Examples using complex root isolation:
sage: x = polygen(ZZ)
sage: p = x^5 - x - 1
sage: p.roots()
˓→needs sage.libs.pari[]
sage: p.roots(ring=CIF)
˓→needs sage.rings.complex_interval_field[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]
sage: p.roots(ring=ComplexIntervalField(200))
˓→needs sage.rings.complex_interval_field[(1.167303978261418684256045899854842180720560371525489039140082?, 1),(-0.76488443360058472602982318770854173032899665194736756700778? - 0.
˓→35247154603172624931794709140258105439420648082424733283770?*I, 1),(-0.76488443360058472602982318770854173032899665194736756700778? + 0.
˓→35247154603172624931794709140258105439420648082424733283770?*I, 1),(0.18123244446987538390180023778112063996871646618462304743774? - 1.
˓→08395410131771066843034449298076657427364024315511565430114?*I, 1),(0.18123244446987538390180023778112063996871646618462304743774? + 1.
˓→08395410131771066843034449298076657427364024315511565430114?*I, 1)]
sage: rts = p.roots(ring=QQbar); rts
˓→needs sage.rings.number_field[(1.167303978261419?, 1),(-0.7648844336005847? - 0.3524715460317263?*I, 1),(-0.7648844336005847? + 0.3524715460317263?*I, 1),(0.1812324444698754? - 1.083954101317711?*I, 1),(0.1812324444698754? + 1.083954101317711?*I, 1)]
sage: p.roots(ring=AA)
˓→needs sage.rings.number_field[(1.167303978261419?, 1)]
sage: p = (x - rts[4][0])^2 * (3*x^2 + x + 1)
˓→needs sage.rings.number_fieldsage: p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-0.1666666666666667? - 0.552770798392567?*I, 1),(-0.1666666666666667? + 0.552770798392567?*I, 1),(0.1812324444698754? + 1.083954101317711?*I, 2)]
sage: p.roots(ring=CIF)
˓→needs sage.rings.complex_interval_field[(-0.1666666666666667? - 0.552770798392567?*I, 1),(-0.1666666666666667? + 0.552770798392567?*I, 1),

#␣

#␣

#␣

#␣

#␣

#␣
#␣

#␣

(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

173

Polynomials, Release 10.4

(continued from previous page)(0.1812324444698754? + 1.083954101317711?*I, 2)]>>> from sage.all import *>>> x = polygen(ZZ)>>> p = x**Integer(5) - x - Integer(1)>>> p.roots()
˓→needs sage.libs.pari[]>>> p.roots(ring=CIF)
˓→needs sage.rings.complex_interval_field[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]>>> p.roots(ring=ComplexIntervalField(Integer(200)))˓→# needs sage.rings.complex_interval_field[(1.167303978261418684256045899854842180720560371525489039140082?, 1),(-0.76488443360058472602982318770854173032899665194736756700778? - 0.
˓→35247154603172624931794709140258105439420648082424733283770?*I, 1),(-0.76488443360058472602982318770854173032899665194736756700778? + 0.
˓→35247154603172624931794709140258105439420648082424733283770?*I, 1),(0.18123244446987538390180023778112063996871646618462304743774? - 1.
˓→08395410131771066843034449298076657427364024315511565430114?*I, 1),(0.18123244446987538390180023778112063996871646618462304743774? + 1.
˓→08395410131771066843034449298076657427364024315511565430114?*I, 1)]>>> rts = p.roots(ring=QQbar); rts
˓→needs sage.rings.number_field[(1.167303978261419?, 1),(-0.7648844336005847? - 0.3524715460317263?*I, 1),(-0.7648844336005847? + 0.3524715460317263?*I, 1),(0.1812324444698754? - 1.083954101317711?*I, 1),(0.1812324444698754? + 1.083954101317711?*I, 1)]>>> p.roots(ring=AA)
˓→needs sage.rings.number_field[(1.167303978261419?, 1)]>>> p = (x - rts[Integer(4)][Integer(0)])**Integer(2) *␣˓→(Integer(3)*x**Integer(2) + x + Integer(1))˓→needs sage.rings.number_field>>> p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-0.1666666666666667? - 0.552770798392567?*I, 1),(-0.1666666666666667? + 0.552770798392567?*I, 1),(0.1812324444698754? + 1.083954101317711?*I, 2)]>>> p.roots(ring=CIF)
˓→needs sage.rings.complex_interval_field[(-0.1666666666666667? - 0.552770798392567?*I, 1),(-0.1666666666666667? + 0.552770798392567?*I, 1),(0.1812324444698754? + 1.083954101317711?*I, 2)]

#␣

#␣

␣

#␣

#␣

#␣
#␣

#␣

In some cases, it is possible to isolate the roots of polynomials over complex ball fields:
sage: # needs sage.libs.flint
sage: Pol.<x> = CBF[]
sage: (x^2 + 2).roots(multiplicities=False)[[+/- ...e-19] + [-1.414213562373095 +/- ...e-17]*I,(continues on next page)

174

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[+/- ...e-19] + [1.414213562373095 +/- ...e-17]*I]
sage: (x^3 - 1/2).roots(RBF, multiplicities=False)[[0.7937005259840997 +/- ...e-17]]
sage: ((x - 1)^2).roots(multiplicities=False, proof=False)
doctest:...
UserWarning: roots may have been lost...
[[1.00000000000 +/- ...e-12] + [+/- ...e-11]*I,[1.0000000000 +/- ...e-12] + [+/- ...e-12]*I]>>> from sage.all import *>>> # needs sage.libs.flint>>> Pol = CBF[ x ]; (x,) = Pol._first_ngens(1)>>> (x**Integer(2) + Integer(2)).roots(multiplicities=False)[[+/- ...e-19] + [-1.414213562373095 +/- ...e-17]*I,[+/- ...e-19] + [1.414213562373095 +/- ...e-17]*I]>>> (x**Integer(3) - Integer(1)/Integer(2)).roots(RBF, multiplicities=False)[[0.7937005259840997 +/- ...e-17]]>>> ((x - Integer(1))**Integer(2)).roots(multiplicities=False, proof=False)
doctest:...
UserWarning: roots may have been lost...
[[1.00000000000 +/- ...e-12] + [+/- ...e-11]*I,[1.0000000000 +/- ...e-12] + [+/- ...e-12]*I]

Note that coefficients in a number field with defining polynomial 𝑥2 +1 are considered to be Gaussian rationals(with the generator mapping to +𝐼), if you ask for complex roots.
sage: # needs sage.rings.number_fieldsage: K.<im> = QuadraticField(-1)
sage: y = polygen(K)sage: p = y^4 - 2 - imsage: p.roots(ring=CC)[(-1.2146389322441... - 0.14142505258239...*I, 1),(-0.14142505258239... + 1.2146389322441...*I, 1),(0.14142505258239... - 1.2146389322441...*I, 1),(1.2146389322441... + 0.14142505258239...*I, 1)]
sage: p = p^2 * (y^2 - 2)sage: p.roots(ring=CIF)[(-1.414213562373095?, 1), (1.414213562373095?, 1),(-1.214638932244183? - 0.141425052582394?*I, 2),(-0.141425052582394? + 1.214638932244183?*I, 2),(0.141425052582394? - 1.214638932244183?*I, 2),(1.214638932244183? + 0.141425052582394?*I, 2)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(1), names=( im ,)); (im,) = K._first_ngens(1)>>> y = polygen(K)>>> p = y**Integer(4) - Integer(2) - im>>> p.roots(ring=CC)[(-1.2146389322441... - 0.14142505258239...*I, 1),(-0.14142505258239... + 1.2146389322441...*I, 1),(0.14142505258239... - 1.2146389322441...*I, 1),(1.2146389322441... + 0.14142505258239...*I, 1)]>>> p = p**Integer(2) * (y**Integer(2) - Integer(2))>>> p.roots(ring=CIF)[(-1.414213562373095?, 1), (1.414213562373095?, 1),(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

175

Polynomials, Release 10.4

(continued from previous page)(-1.214638932244183? - 0.141425052582394?*I, 2),(-0.141425052582394? + 1.214638932244183?*I, 2),(0.141425052582394? - 1.214638932244183?*I, 2),(1.214638932244183? + 0.141425052582394?*I, 2)]Note that one should not use NumPy when wanting high precision output as it does not support any of thehigh precision types:
sage: # needs numpy sage.rings.real_mpfr sage.symbolic
sage: R.<x> = RealField(200)[]
sage: f = x^2 - R(pi)sage: f.roots()[(-1.7724538509055160272981674833411451827975494561223871282138, 1),(1.7724538509055160272981674833411451827975494561223871282138, 1)]
sage: f.roots(algorithm= numpy )doctest... UserWarning: NumPy does not support arbitrary precision arithmetic.
The roots found will likely have less precision than you expect.
[(-1.77245385090551..., 1), (1.77245385090551..., 1)]>>> from sage.all import *>>> # needs numpy sage.rings.real_mpfr sage.symbolic>>> R = RealField(Integer(200))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) - R(pi)>>> f.roots()[(-1.7724538509055160272981674833411451827975494561223871282138, 1),(1.7724538509055160272981674833411451827975494561223871282138, 1)]>>> f.roots(algorithm= numpy )doctest... UserWarning: NumPy does not support arbitrary precision arithmetic.
The roots found will likely have less precision than you expect.
[(-1.77245385090551..., 1), (1.77245385090551..., 1)]

We can also find roots over number fields:
sage: K.<z> = CyclotomicField(15)˓→needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(K)˓→needs sage.rings.number_fieldsage: (x^2 + x + 1).roots()
˓→needs sage.rings.number_field[(z^5, 1), (-z^5 - 1, 1)]

#␣
#␣
#␣

>>> from sage.all import *>>> K = CyclotomicField(Integer(15), names=( z ,)); (z,) = K._first_ngens(1)#␣
˓→needs sage.rings.number_field>>> R = PolynomialRing(K, names=( x ,)); (x,) = R._first_ngens(1)# needs sage.
˓→rings.number_field>>> (x**Integer(2) + x + Integer(1)).roots()␣˓→# needs sage.rings.number_field[(z^5, 1), (-z^5 - 1, 1)]

There are many combinations of floating-point input and output types that work. (Note that some of themare quite pointless like using algorithm= numpy with high-precision types.)sage: # needs numpy sage.rings.complex_double sage.rings.real_mpfr
sage: rflds = (RR, RDF, RealField(100))
sage: cflds = (CC, CDF, ComplexField(100))(continues on next page)

176

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: def cross(a, b):....:
return list(cartesian_product_iterator([a, b]))sage: flds = cross(rflds, rflds) + cross(rflds, cflds) + cross(cflds, cflds)
sage: for (fld_in, fld_out) in flds:....:
x = polygen(fld_in)....:
f = x^3 - fld_in(2)....:x2 = polygen(fld_out)....:
f2 = x2^3 - fld_out(2)....:for algo in (None, pari , numpy ):....:rts = f.roots(ring=fld_out, multiplicities=False)....:
rts = sorted(rts, key=lambda x: x.imag())....:
if fld_in == fld_out and algo is None:....:
print("{} {}".format(fld_in, rts))....:
for rt in rts:....:
assert(abs(f2(rt)) <= 1e-10)....:
assert(rt.parent() == fld_out)
Real Field with 53 bits of precision [1.25992104989487]
Real Double Field [1.25992104989...]Real Field with 100 bits of precision [1.2599210498948731647672106073]
Complex Field with 53 bits of precision [-0.62996052494743... - 1.
˓→09112363597172*I, 1.25992104989487, -0.62996052494743... + 1.
˓→09112363597172*I]
Complex Double Field [-0.629960524947... - 1.0911236359717...*I, 1.
˓→25992104989487..., -0.629960524947... + 1.0911236359717...*I]
Complex Field with 100 bits of precision [-0.62996052494743658238360530364 -␣˓→1.0911236359717214035600726142*I, 1.2599210498948731647672106073, -0.
˓→62996052494743658238360530364 + 1.0911236359717214035600726142*I]>>> from sage.all import *>>> # needs numpy sage.rings.complex_double sage.rings.real_mpfr>>> rflds = (RR, RDF, RealField(Integer(100)))>>> cflds = (CC, CDF, ComplexField(Integer(100)))>>> def cross(a, b):...
return list(cartesian_product_iterator([a, b]))>>> flds = cross(rflds, rflds) + cross(rflds, cflds) + cross(cflds, cflds)>>> for (fld_in, fld_out) in flds:...
x = polygen(fld_in)...
f = x**Integer(3) - fld_in(Integer(2))...
x2 = polygen(fld_out)...
f2 = x2**Integer(3) - fld_out(Integer(2))...
for algo in (None, pari , numpy ):...
rts = f.roots(ring=fld_out, multiplicities=False)...
rts = sorted(rts, key=lambda x: x.imag())...
if fld_in == fld_out and algo is None:...
print("{} {}".format(fld_in, rts))...
for rt in rts:...
assert(abs(f2(rt)) <= RealNumber( 1e-10 ))...
assert(rt.parent() == fld_out)
Real Field with 53 bits of precision [1.25992104989487]
Real Double Field [1.25992104989...]Real Field with 100 bits of precision [1.2599210498948731647672106073]
Complex Field with 53 bits of precision [-0.62996052494743... - 1.
˓→09112363597172*I, 1.25992104989487, -0.62996052494743... + 1.
˓→09112363597172*I]
Complex Double Field [-0.629960524947... - 1.0911236359717...*I, 1.
˓→25992104989487..., -0.629960524947... + 1.0911236359717...*I](continues on next page)2.1. Univariate Polynomials and Polynomial Rings

177

Polynomials, Release 10.4

(continued from previous page)

Complex Field with 100 bits of precision [-0.62996052494743658238360530364 -␣˓→1.0911236359717214035600726142*I, 1.2599210498948731647672106073, -0.
˓→62996052494743658238360530364 + 1.0911236359717214035600726142*I]

Note that we can find the roots of a polynomial with algebraic coefficients:
sage: # needs sage.rings.number_fieldsage: rt2 = sqrt(AA(2))
sage: rt3 = sqrt(AA(3))
sage: x = polygen(AA)sage: f = (x - rt2) * (x - rt3); fx^2 - 3.146264369941973?*x + 2.449489742783178?
sage: rts = f.roots(); rts[(1.414213562373095?, 1), (1.732050807568878?, 1)]
sage: rts[0][0] == rt2
True
sage: f.roots(ring=RealIntervalField(150))[(1.414213562373095048801688724209698078569671875376948073176679738?, 1),(1.732050807568877293527446341505872366942805253810380628055806980?, 1)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> rt2 = sqrt(AA(Integer(2)))>>> rt3 = sqrt(AA(Integer(3)))>>> x = polygen(AA)>>> f = (x - rt2) * (x - rt3); fx^2 - 3.146264369941973?*x + 2.449489742783178?
>>> rts = f.roots(); rts[(1.414213562373095?, 1), (1.732050807568878?, 1)]>>> rts[Integer(0)][Integer(0)] == rt2
True>>> f.roots(ring=RealIntervalField(Integer(150)))[(1.414213562373095048801688724209698078569671875376948073176679738?, 1),(1.732050807568877293527446341505872366942805253810380628055806980?, 1)]

We can handle polynomials with huge coefficients.
This number doesn’t even fit in an IEEE double-precision float, but RR and CC allow a much larger range offloating-point numbers:
sage: bigc = 2^1500
sage: CDF(bigc)
˓→needs sage.rings.complex_double+infinity
sage: CC(bigc)
˓→needs sage.rings.real_mpfr
3.50746621104340e451>>> from sage.all import *>>> bigc = Integer(2)**Integer(1500)>>> CDF(bigc)
˓→needs sage.rings.complex_double+infinity>>> CC(bigc)
˓→needs sage.rings.real_mpfr
3.50746621104340e451

178

#␣

#␣

#␣

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Polynomials using such large coefficients can’t be handled by numpy, but pari can deal with them:sage: x = polygen(QQ)
sage: p = x + bigc
sage: p.roots(ring=RR, algorithm= numpy )˓→needs numpy sage.rings.real_mpfr
Traceback (most recent call last):...
LinAlgError: Array must not contain infs or NaNs
sage: p.roots(ring=RR, algorithm= pari )˓→needs sage.libs.pari sage.rings.real_mpfr[(-3.50746621104340e451, 1)]
sage: p.roots(ring=AA)
˓→needs sage.rings.number_field[(-3.5074662110434039?e451, 1)]
sage: p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-3.5074662110434039?e451, 1)]
sage: p = bigc*x + 1
sage: p.roots(ring=RR)
˓→needs numpy[(-2.85106096489671e-452, 1)]
sage: p.roots(ring=AA)
˓→needs sage.rings.number_field[(-2.8510609648967059?e-452, 1)]
sage: p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-2.8510609648967059?e-452, 1)]
sage: p = x^2 - bigc
sage: p.roots(ring=RR)
˓→needs numpy[(-5.92238652153286e225, 1), (5.92238652153286e225, 1)]
sage: p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-5.9223865215328558?e225, 1), (5.9223865215328558?e225, 1)]>>> from sage.all import *>>> x = polygen(QQ)>>> p = x + bigc>>> p.roots(ring=RR, algorithm= numpy )˓→needs numpy sage.rings.real_mpfr
Traceback (most recent call last):...
LinAlgError: Array must not contain infs or NaNs>>> p.roots(ring=RR, algorithm= pari )˓→needs sage.libs.pari sage.rings.real_mpfr[(-3.50746621104340e451, 1)]>>> p.roots(ring=AA)
˓→needs sage.rings.number_field[(-3.5074662110434039?e451, 1)]>>> p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-3.5074662110434039?e451, 1)]>>> p = bigc*x + Integer(1)>>> p.roots(ring=RR)
˓→needs numpy[(-2.85106096489671e-452, 1)]>>> p.roots(ring=AA)

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣

#␣
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

179

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field[(-2.8510609648967059?e-452, 1)]>>> p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-2.8510609648967059?e-452, 1)]>>> p = x**Integer(2) - bigc>>> p.roots(ring=RR)
˓→needs numpy[(-5.92238652153286e225, 1), (5.92238652153286e225, 1)]>>> p.roots(ring=QQbar)
˓→needs sage.rings.number_field[(-5.9223865215328558?e225, 1), (5.9223865215328558?e225, 1)]
˓→

#␣

#␣

#␣

Check that Issue #30522 is fixed:
sage: PolynomialRing(SR, names="x")("x^2").roots()
˓→needs sage.symbolic[(0, 2)]>>> from sage.all import *>>> PolynomialRing(SR, names="x")("x^2").roots()
˓→needs sage.symbolic[(0, 2)]#␣#␣

Check that Issue #30523 is fixed:
sage: PolynomialRing(SR, names="x")("x^2 + q").roots()
˓→needs sage.symbolic[(-sqrt(-q), 1), (sqrt(-q), 1)]>>> from sage.all import *>>> PolynomialRing(SR, names="x")("x^2 + q").roots()
˓→needs sage.symbolic[(-sqrt(-q), 1), (sqrt(-q), 1)]#␣#␣

ALGORITHM:
For brevity, we will use RR to mean any RealField of any precision; similarly for RIF, CC, and CIF.
Since Sage has no specific implementation of Gaussian rationals (or of number fields with embedding, at all),when we refer to Gaussian rationals below we will accept any number field with defining polynomial 𝑥2 + 1,
mapping the field generator to +I.
We call the base ring of the polynomial 𝐾, and the ring given by the ring argument 𝐿. (If ring is not
specified, then 𝐿 is the same as 𝐾.)
If 𝐾 and 𝐿 are floating-point (RDF, CDF, RR, or CC), then a floating-point root-finder is used. If 𝐿 is
RDF or CDF, then we default to using NumPy’s roots(); otherwise, we use PARI’s function pari:polroots.
This choice can be overridden with algorithm= pari or algorithm= numpy . If the algorithm
is unspecified and NumPy’s roots() algorithm fails, then we fall back to PARI (NumPy will fail if somecoefficient is infinite, for instance).
If 𝐿 is SR (or one of its subrings), then the roots will be radical expressions, computed as the solutions ofa symbolic polynomial expression. At the moment this delegates to sage.symbolic.expression.
Expression.solve() which in turn uses Maxima to find radical solutions. Some solutions may be lostin this approach. Once Issue #17516 gets implemented, all possible radical solutions should become available.
If 𝐿 is AA or RIF, and 𝐾 is ZZ, QQ, or AA, then the root isolation algorithm sage.rings.polynomial.

180

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

real_roots.real_roots() is used. (You can call real_roots() directly to get more control than
this method gives.)
If 𝐿 is QQbar or CIF, and 𝐾 is ZZ, QQ, AA, QQbar, or the Gaussian rationals, then the root isolation
algorithm sage.rings.polynomial.complex_roots.complex_roots() is used. (You cancall complex_roots() directly to get more control than this method gives.)
If 𝐿 is AA and 𝐾 is QQbar or the Gaussian rationals, then complex_roots() is used (as above) to findroots in QQbar, then these roots are filtered to select only the real roots.
If 𝐿 is floating-point and 𝐾 is not, then we attempt to change the polynomial ring to 𝐿 (usingchange_ring()) (or, if 𝐿 is complex and 𝐾 is not, to the corresponding real field). Then we use either PARI or NumPy as specified above.
For all other cases where 𝐾 is different from 𝐿, we attempt to use .change_ring(L). When that fails
but 𝐿 is a subring of 𝐾, we also attempt to compute the roots over 𝐾 and filter the ones belonging to 𝐿.
The next method, which is used if 𝐾 is an integral domain, is to attempt to factor the polynomial. If thissucceeds, then for every degree-one factor 𝑎𝑥 + 𝑏, we add −𝑏/𝑎 as a root (as long as this quotient is actuallyin the desired ring).
If factoring over 𝐾 is not implemented (or 𝐾 is not an integral domain), and 𝐾 is finite, then we find theroots by enumerating all elements of 𝐾 and checking whether the polynomial evaluates to zero at that value.
Note: We mentioned above that polynomials with multiple roots are always ill-conditioned; if your input isgiven to 𝑛 bits of precision, you should not expect more than 𝑛/𝑘 good bits for a 𝑘-fold root. (You can get
solutions that make the polynomial evaluate to a number very close to zero; basically the problem is that witha multiple root, there are many such numbers, and it’s difficult to choose between them.)
To see why this is true, consider the naive floating-point error analysis model where you just pretend that all
floating-point numbers are somewhat imprecise - a little ‘fuzzy’, if you will. Then the graph of a floating-point
polynomial will be a fuzzy line. Consider the graph of (𝑥 − 1)3 ; this will be a fuzzy line with a horizontal
tangent at 𝑥 = 1, 𝑦 = 0. If the fuzziness extends up and down by about j, then it will extend left and right by
about cube_root(j).
shift(n)Return this polynomial multiplied by the power 𝑥𝑛 . If 𝑛 is negative, terms below 𝑥𝑛 will be discarded. Does
not change this polynomial (since polynomials are immutable).
EXAMPLES:
sage: R.<x> = QQ[]
sage: p = x^2 + 2*x + 4
sage: p.shift(0)x^2 + 2*x + 4
sage: p.shift(-1)
x + 2
sage: p.shift(-5)
0sage: p.shift(2)x^4 + 2*x^3 + 4*x^2>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> p = x**Integer(2) + Integer(2)*x + Integer(4)>>> p.shift(Integer(0))
x^2 + 2*x + 4(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

181

Polynomials, Release 10.4

(continued from previous page)>>> p.shift(-Integer(1))
x + 2>>> p.shift(-Integer(5))
0>>> p.shift(Integer(2))
x^4 + 2*x^3 + 4*x^2

One can also use the infix shift operator:
sage: f = x^3 + x
sage: f >> 2xsage: f << 2x^5 + x^3>>> from sage.all import *>>> f = x**Integer(3) + x>>> f >> Integer(2)x>>> f << Integer(2)x^5 + x^3

AUTHORS:• David Harvey (2006-08-06)• Robert Bradshaw (2007-04-18): Added support for infix operator.
specialization(D=None, phi=None)
Specialization of this polynomial.
Given a family of polynomials defined over a polynomial ring. A specialization is a particular member of thatfamily. The specialization can be specified either by a dictionary or a SpecializationMorphism.
INPUT:• D – dictionary (optional)• phi – SpecializationMorphism (optional)
OUTPUT: a new polynomial
EXAMPLES:
sage: R.<c> = PolynomialRing(ZZ)
sage: S.<z> = PolynomialRing(R)sage: F = c*z^2 + c^2
sage: F.specialization({c:2})
2*z^2 + 4>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( c ,)); (c,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( z ,)); (z,) = S._first_ngens(1)>>> F = c*z**Integer(2) + c**Integer(2)>>> F.specialization({c:Integer(2)})
2*z^2 + 4

182

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: A.<c> = QQ[]
sage: R.<x> = Frac(A)[]sage: X = (1 + x/c).specialization({c:20})
sage: X
1/20*x + 1
sage: X.parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> A = QQ[ c ]; (c,) = A._first_ngens(1)>>> R = Frac(A)[ x ]; (x,) = R._first_ngens(1)>>> X = (Integer(1) + x/c).specialization({c:Integer(20)})>>> X
1/20*x + 1>>> X.parent()
Univariate Polynomial Ring in x over Rational Field

splitting_field(names=None, map=False, **kwds)
Compute the absolute splitting field of a given polynomial.
INPUT:• names – (default: None) a variable name for the splitting field.
• map – (default: False) also return an embedding of self into the resulting field.
• kwds – additional keywords depending on the type. Currently, only number fields are implemented.
See sage.rings.number_field.splitting_field.splitting_field() for the documentation of these keywords.
OUTPUT:If map is False, the splitting field as an absolute field. If map is True, a tuple (K, phi) where phi isan embedding of the base field of self in K.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: K.<a> = (x^3 + 2).splitting_field(); K˓→needs sage.rings.number_field
Number Field in a with defining polynomialx^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1
sage: K.<a> = (x^3 - 3*x + 1).splitting_field(); K˓→needs sage.rings.number_field
Number Field in a with defining polynomial x^3 - 3*x + 1#␣#␣>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> K = (x**Integer(3) + Integer(2)).splitting_field(names=( a ,)); (a,) = K._
˓→first_ngens(1); K# needs sage.rings.number_
˓→field
Number Field in a with defining polynomialx^6 + 3*x^5 + 6*x^4 + 11*x^3 + 12*x^2 - 3*x + 1>>> K = (x**Integer(3) - Integer(3)*x + Integer(1)).splitting_field(names=( a˓→ ,)); (a,) = K._first_ngens(1); K# needs sage.
˓→rings.number_field
Number Field in a with defining polynomial x^3 - 3*x + 1

Relative situation:
2.1. Univariate Polynomials and Polynomial Rings

183

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(QQ)
sage: K.<a> = NumberField(x^3 + 2)
sage: S.<t> = PolynomialRing(K)sage: L.<b> = (t^2 - a).splitting_field()sage: L
Number Field in b with defining polynomial t^6 + 2>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(3) + Integer(2), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> S = PolynomialRing(K, names=( t ,)); (t,) = S._first_ngens(1)>>> L = (t**Integer(2) - a).splitting_field(names=( b ,)); (b,) = L._first_
˓→ngens(1)>>> L
Number Field in b with defining polynomial t^6 + 2

With map=True, we also get the embedding of the base field into the splitting field:
sage: L.<b>, phi = (t^2 - a).splitting_field(map=True)
˓→needs sage.rings.number_fieldsage: phi
˓→needs sage.rings.number_field
Ring morphism:
From: Number Field in a with defining polynomial x^3 + 2
To:
Number Field in b with defining polynomial t^6 + 2
Defn: a |--> b^2#␣#␣>>> from sage.all import *>>> L, phi = (t**Integer(2) - a).splitting_field(map=True, names=( b ,)); (b,˓→) = L._first_ngens(1)# needs sage.rings.number_field>>> phi#␣˓→needs sage.rings.number_field
Ring morphism:
From: Number Field in a with defining polynomial x^3 + 2
To:
Number Field in b with defining polynomial t^6 + 2
Defn: a |--> b^2

An example over a finite field:
sage: P.<x> = PolynomialRing(GF(7))
sage: t = x^2 + 1
sage: t.splitting_field( b )˓→needs sage.rings.finite_rings
Finite Field in b of size 7^2sage: P.<x> = PolynomialRing(GF(7^3, a ))˓→needs sage.rings.finite_rings
sage: t = x^2 + 1
sage: t.splitting_field( b , map=True)
˓→needs sage.rings.finite_rings(Finite Field in b of size 7^6,
Ring morphism:
From: Finite Field in a of size 7^3

#␣

#␣

#␣

(continues on next page)

184

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

To:
Finite Field in b of size 7^6
Defn: a |--> 2*b^4 + 6*b^3 + 2*b^2 + 3*b + 2)>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(7)), names=( x ,)); (x,) = P._first_ngens(1)>>> t = x**Integer(2) + Integer(1)>>> t.splitting_field( b )#␣˓→needs sage.rings.finite_rings
Finite Field in b of size 7^2>>> P = PolynomialRing(GF(Integer(7)**Integer(3), a ), names=( x ,)); (x,) =␣
˓→P._first_ngens(1)# needs sage.rings.finite_rings>>> t = x**Integer(2) + Integer(1)>>> t.splitting_field( b , map=True)#␣˓→needs sage.rings.finite_rings(Finite Field in b of size 7^6,
Ring morphism:
From: Finite Field in a of size 7^3
To:
Finite Field in b of size 7^6
Defn: a |--> 2*b^4 + 6*b^3 + 2*b^2 + 3*b + 2)

If the extension is trivial and the generators have the same name, the map will be the identity:
sage: t = 24*x^13 + 2*x^12 + 14
sage: t.splitting_field( a , map=True)
˓→needs sage.rings.finite_rings(Finite Field in a of size 7^3,
Identity endomorphism of Finite Field in a of size 7^3)#␣sage: t = x^56 - 14*x^3sage: t.splitting_field( b , map=True)
˓→needs sage.rings.finite_rings(Finite Field in b of size 7^3,
Ring morphism:
From: Finite Field in a of size 7^3
To:
Finite Field in b of size 7^3
Defn: a |--> b)#␣>>> from sage.all import *>>> t = Integer(24)*x**Integer(13) + Integer(2)*x**Integer(12) + Integer(14)>>> t.splitting_field( a , map=True)#␣˓→needs sage.rings.finite_rings(Finite Field in a of size 7^3,
Identity endomorphism of Finite Field in a of size 7^3)>>> t = x**Integer(56) - Integer(14)*x**Integer(3)>>> t.splitting_field( b , map=True)
˓→needs sage.rings.finite_rings(Finite Field in b of size 7^3,
Ring morphism:
From: Finite Field in a of size 7^3
To:
Finite Field in b of size 7^3
Defn: a |--> b)#␣

See also:
sage.rings.number_field.splitting_field.splitting_field() for more examples
2.1. Univariate Polynomials and Polynomial Rings

185

Polynomials, Release 10.4

over number fields
square()Return the square of this polynomial.
Todo:• This is just a placeholder; for now it just uses ordinary multiplication. But generally speaking, squaring
is faster than ordinary multiplication, and it’s frequently used, so subclasses may choose to provide a
specialised squaring routine.
• Perhaps this even belongs at a lower level? RingElement or something?
AUTHORS:• David Harvey (2006-09-09)
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^3 + 1
sage: f.square()x^6 + 2*x^3 + 1
sage: f*fx^6 + 2*x^3 + 1>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + Integer(1)>>> f.square()x^6 + 2*x^3 + 1>>> f*fx^6 + 2*x^3 + 1

squarefree_decomposition()
Return the square-free decomposition of this polynomial. This is a partial factorization into square-free,
coprime polynomials.
EXAMPLES:
sage: x = polygen(QQ)
sage: p = 37 * (x - 1)^3 * (x - 2)^3 * (x - 1/3)^7 * (x - 3/7)
sage: p.squarefree_decomposition()(37*x - 111/7) * (x^2 - 3*x + 2)^3 * (x - 1/3)^7
sage: p = 37 * (x - 2/3)^2
sage: p.squarefree_decomposition()(37) * (x - 2/3)^2
sage: x = polygen(GF(3))
sage: x.squarefree_decomposition()xsage: f = QQbar[ x ](1)˓→needs sage.rings.number_fieldsage: f.squarefree_decomposition()
˓→needs sage.rings.number_field
1

186

#␣
#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> x = polygen(QQ)>>> p = Integer(37) * (x - Integer(1))**Integer(3) * (x -␣˓→Integer(2))**Integer(3) * (x - Integer(1)/Integer(3))**Integer(7) * (x -␣˓→Integer(3)/Integer(7))>>> p.squarefree_decomposition()(37*x - 111/7) * (x^2 - 3*x + 2)^3 * (x - 1/3)^7>>> p = Integer(37) * (x - Integer(2)/Integer(3))**Integer(2)>>> p.squarefree_decomposition()(37) * (x - 2/3)^2>>> x = polygen(GF(Integer(3)))>>> x.squarefree_decomposition()x>>> f = QQbar[ x ](Integer(1))␣˓→# needs sage.rings.number_field>>> f.squarefree_decomposition()#␣˓→needs sage.rings.number_field
1

subresultants(other)
Return the nonzero subresultant polynomials of self and other.
INPUT:• other – a polynomial
OUTPUT: a list of polynomials in the same ring as self
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^8 + x^6 - 3*x^4 - 3*x^3 + 8*x^2 + 2*x - 5
sage: g = 3*x^6 + 5*x^4 - 4*x^2 - 9*x + 21
sage: f.subresultants(g)[260708,
9326*x - 12300,
169*x^2 + 325*x - 637,
65*x^2 + 125*x - 245,
25*x^4 - 5*x^2 + 15,
15*x^4 - 3*x^2 + 9]>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(8) + x**Integer(6) - Integer(3)*x**Integer(4) -␣˓→Integer(3)*x**Integer(3) + Integer(8)*x**Integer(2) + Integer(2)*x -␣
˓→Integer(5)>>> g = Integer(3)*x**Integer(6) + Integer(5)*x**Integer(4) -␣˓→Integer(4)*x**Integer(2) - Integer(9)*x + Integer(21)>>> f.subresultants(g)[260708,
9326*x - 12300,
169*x^2 + 325*x - 637,
65*x^2 + 125*x - 245,
25*x^4 - 5*x^2 + 15,
15*x^4 - 3*x^2 + 9]

ALGORITHM:
We use the schoolbook algorithm with Lazard’s optimization described in [Duc1998]
2.1. Univariate Polynomials and Polynomial Rings

187

Polynomials, Release 10.4

REFERENCES:
Wikipedia article Polynomial_greatest_common_divisor#Subresultants
subs(in_dict=None, *args, **kwds)
Substitute the variable in self.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = x^3 + x - 3
sage: f.subs(x=5)
127
sage: f.subs(5)127sage: f.subs({x:2})
7
sage: f.subs({})
x^3 + x - 3
sage: f.subs({ x :2})
Traceback (most recent call last):...
TypeError: keys do not match self s parent>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x - Integer(3)>>> f.subs(x=Integer(5))
127>>> f.subs(Integer(5))
127>>> f.subs({x:Integer(2)})
7>>> f.subs({})
x^3 + x - 3>>> f.subs({ x :Integer(2)})
Traceback (most recent call last):...
TypeError: keys do not match self s parent

sylvester_matrix(right, variable=None)
Return the Sylvester matrix of self and right.
Note that the Sylvester matrix is not defined if one of the polynomials is zero.
INPUT:• right – a polynomial in the same ring as self.
• variable – optional, included for compatibility with the multivariate case only. The variable of thepolynomials.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
sage: M = f.sylvester_matrix(g); M˓→needs sage.modules[ 42 317 134 1786
0
0
0]

#␣

(continues on next page)

188

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

[
[
[
[
[
[

0
0
0
18
0
0

42
0
0
141
18
0

317
42
0
12
141
18

134 178600]
317 134 1786
0]42 317 134 1786]
100
47
0
0]
12 10047
0]141
12 10047]>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38))>>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) +␣˓→Integer(2)*x + Integer(1))>>> M = f.sylvester_matrix(g); M˓→needs sage.modules[ 42 317 134 1786
0
0
0]
[
0
42 317 134 1786
0
0]
[
0
0
42 317 134 1786
0]
[
0
0
0
42 317 134 1786][ 18 141
12 10047
00][0
18 141
12 10047
0][00
18 141
12 10047]#␣

If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will bezero:
sage: M.determinant()
˓→needs sage.modules0>>> from sage.all import *>>> M.determinant()
˓→needs sage.modules
0

#␣

#␣

If self and right are polynomials of positive degree, the determinant of the Sylvester matrix is the resultant of the polynomials.:sage: h1 = R._random_nonzero_element()
sage: h2 = R._random_nonzero_element()
sage: M1 = h1.sylvester_matrix(h2)˓→needs sage.modules
sage: M1.determinant() == h1.resultant(h2)˓→needs sage.libs.pari sage.modules
True>>> from sage.all import *>>> h1 = R._random_nonzero_element()>>> h2 = R._random_nonzero_element()>>> M1 = h1.sylvester_matrix(h2)˓→needs sage.modules>>> M1.determinant() == h1.resultant(h2)˓→needs sage.libs.pari sage.modules
True

#␣
#␣

#␣
#␣

The rank of the Sylvester matrix is related to the degree of the gcd of self and right:
2.1. Univariate Polynomials and Polynomial Rings

189

Polynomials, Release 10.4

sage: f.gcd(g).degree() == f.degree() + g.degree() - M.rank()
˓→needs sage.modules
True
sage: h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank()
˓→needs sage.modules
True>>> from sage.all import *>>> f.gcd(g).degree() == f.degree() + g.degree() - M.rank()
˓→needs sage.modules
True>>> h1.gcd(h2).degree() == h1.degree() + h2.degree() - M1.rank()
˓→needs sage.modules
True

#␣

#␣

#␣

#␣

symmetric_power(k, monic=False)
Return the polynomial whose roots are products of 𝑘-th distinct roots of this.
EXAMPLES:
sage: x = polygen(QQ)
sage: f = x^4 - x + 2
sage: [f.symmetric_power(k) for k in range(5)]˓→needs sage.libs.singular[x - 1, x^4 - x + 2, x^6 - 2*x^4 - x^3 - 4*x^2 + 8, x^4 - x^3 + 8, x - 2]sage: f = x^5 - 2*x + 2
sage: [f.symmetric_power(k) for k in range(6)]˓→needs sage.libs.singular[x - 1,x^5 - 2*x + 2,
x^10 + 2*x^8 - 4*x^6 - 8*x^5 - 8*x^4 - 8*x^3 + 16,
x^10 + 4*x^7 - 8*x^6 + 16*x^5 - 16*x^4 + 32*x^2 + 64,
x^5 + 2*x^4 - 16,
x + 2]#␣sage: R.<a,b,c,d> = ZZ[]
sage: x = polygen(R)sage: f = (x - a) * (x - b) * (x - c) * (x - d)sage: [f.symmetric_power(k).factor() for k in range(5)]˓→needs sage.libs.singular[x - 1,(-x + d) * (-x + c) * (-x + b) * (-x + a),(x - c*d) * (x - b*d) * (x - a*d) * (x - b*c) * (x - a*c) * (x - a*b),(x - b*c*d) * (x - a*c*d) * (x - a*b*d) * (x - a*b*c),
x - a*b*c*d]>>> from sage.all import *>>> x = polygen(QQ)>>> f = x**Integer(4) - x + Integer(2)>>> [f.symmetric_power(k) for k in range(Integer(5))]˓→# needs sage.libs.singular[x - 1, x^4 - x + 2, x^6 - 2*x^4 - x^3 - 4*x^2 + 8, x^4 - x^3 + 8, x - 2]>>> f = x**Integer(5) - Integer(2)*x + Integer(2)>>> [f.symmetric_power(k) for k in range(Integer(6))]˓→# needs sage.libs.singular

#␣

#␣

␣

␣
(continues on next page)

190

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[x - 1,x^5 - 2*x + 2,
x^10 + 2*x^8 - 4*x^6 - 8*x^5 - 8*x^4 - 8*x^3 + 16,
x^10 + 4*x^7 - 8*x^6 + 16*x^5 - 16*x^4 + 32*x^2 + 64,
x^5 + 2*x^4 - 16,
x + 2]>>> R = ZZ[ a, b, c, d ]; (a, b, c, d,) = R._first_ngens(4)>>> x = polygen(R)>>> f = (x - a) * (x - b) * (x - c) * (x - d)>>> [f.symmetric_power(k).factor() for k in range(Integer(5))]˓→# needs sage.libs.singular[x - 1,(-x + d) * (-x + c) * (-x + b) * (-x + a),(x - c*d) * (x - b*d) * (x - a*d) * (x - b*c) * (x - a*c) * (x - a*b),(x - b*c*d) * (x - a*c*d) * (x - a*b*d) * (x - a*b*c),
x - a*b*c*d]

␣

trace_polynomial()
Compute the trace polynomial and cofactor.
The input 𝑃 and output 𝑄 satisfy the relation
𝑃 (𝑥) = 𝑄(𝑥 + 𝑞/𝑥)𝑥deg(𝑄) 𝑅(𝑥).
√ √In this relation, 𝑄 has all roots in the real interval [−2 𝑞, 2 𝑞] if and only if 𝑃 has all roots on the circle√
2|𝑥| = 𝑞 and 𝑅 divides 𝑥 − 𝑞. We thus require that the base ring of this polynomial have a coercion to thereal numbers.
See also:
The inverse operation is reciprocal_transform().
OUTPUT:• Q – trace polynomial• R – cofactor• q – scaling factor
EXAMPLES:
sage: pol.<x> = PolynomialRing(Rationals())
sage: u = x^5 - 1; u.trace_polynomial()(x^2 + x - 1, x - 1, 1)
sage: u = x^4 + x^3 + 5*x^2 + 3*x + 9
sage: u.trace_polynomial()(x^2 + x - 1, 1, 3)>>> from sage.all import *>>> pol = PolynomialRing(Rationals(), names=( x ,)); (x,) = pol._first_
˓→ngens(1)>>> u = x**Integer(5) - Integer(1); u.trace_polynomial()(x^2 + x - 1, x - 1, 1)>>> u = x**Integer(4) + x**Integer(3) + Integer(5)*x**Integer(2) +␣˓→Integer(3)*x + Integer(9)>>> u.trace_polynomial()(x^2 + x - 1, 1, 3)

2.1. Univariate Polynomials and Polynomial Rings

191

Polynomials, Release 10.4

We check that this function works for rings that have a coercion to the reals:
sage: # needs sage.rings.number_fieldsage: K.<a> = NumberField(x^2 - 2, embedding=1.4)
sage: u = x^4 + a*x^3 + 3*x^2 + 2*a*x + 4
sage: u.trace_polynomial()(x^2 + a*x - 1, 1, 2)
sage: (u*(x^2-2)).trace_polynomial()(x^2 + a*x - 1, x^2 - 2, 2)
sage: (u*(x^2-2)^2).trace_polynomial()(x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, 1, 2)
sage: (u*(x^2-2)^3).trace_polynomial()(x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, x^2 - 2, 2)
sage: u = x^4 + a*x^3 + 3*x^2 + 4*a*x + 16
sage: u.trace_polynomial()(x^2 + a*x - 5, 1, 4)
sage: (u*(x-2)).trace_polynomial()(x^2 + a*x - 5, x - 2, 4)
sage: (u*(x+2)).trace_polynomial()(x^2 + a*x - 5, x + 2, 4)>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = NumberField(x**Integer(2) - Integer(2), embedding=RealNumber( 1.4 ),␣
˓→names=( a ,)); (a,) = K._first_ngens(1)>>> u = x**Integer(4) + a*x**Integer(3) + Integer(3)*x**Integer(2) +␣˓→Integer(2)*a*x + Integer(4)>>> u.trace_polynomial()(x^2 + a*x - 1, 1, 2)>>> (u*(x**Integer(2)-Integer(2))).trace_polynomial()(x^2 + a*x - 1, x^2 - 2, 2)>>> (u*(x**Integer(2)-Integer(2))**Integer(2)).trace_polynomial()(x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, 1, 2)>>> (u*(x**Integer(2)-Integer(2))**Integer(3)).trace_polynomial()(x^4 + a*x^3 - 9*x^2 - 8*a*x + 8, x^2 - 2, 2)>>> u = x**Integer(4) + a*x**Integer(3) + Integer(3)*x**Integer(2) +␣˓→Integer(4)*a*x + Integer(16)>>> u.trace_polynomial()(x^2 + a*x - 5, 1, 4)>>> (u*(x-Integer(2))).trace_polynomial()(x^2 + a*x - 5, x - 2, 4)>>> (u*(x+Integer(2))).trace_polynomial()(x^2 + a*x - 5, x + 2, 4)

truncate(n)Return the polynomial of degree < 𝑛 which is equivalent to self modulo 𝑥𝑛 .
EXAMPLES:
sage: R.<x> = ZZ[]; S.<y> = PolynomialRing(R, sparse=True)
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: f.truncate(2)x*y - 3*x
sage: f.truncate(1)-3*xsage: f.truncate(0)0192

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1); S = PolynomialRing(R, sparse=True,␣
˓→names=( y ,)); (y,) = S._first_ngens(1)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> f.truncate(Integer(2))
x*y - 3*x>>> f.truncate(Integer(1))-3*x>>> f.truncate(Integer(0))
0valuation(p=None)
If 𝑓 = 𝑎𝑟 𝑥𝑟 + 𝑎𝑟+1 𝑥𝑟+1 + · · ·, with 𝑎𝑟 nonzero, then the valuation of 𝑓 is 𝑟. The valuation of the zeropolynomial is ∞.
If a prime (or non-prime) 𝑝 is given, then the valuation is the largest power of 𝑝 which divides self.
The valuation at ∞ is -self.degree().
EXAMPLES:
sage: P.<x> = ZZ[]
sage: (x^2 + x).valuation()1
sage: (x^2 + x).valuation(x + 1)
1
sage: (x^2 + 1).valuation()0
sage: (x^3 + 1).valuation(infinity)-3
sage: P(0).valuation()+Infinity>>> from sage.all import *>>> P = ZZ[ x ]; (x,) = P._first_ngens(1)>>> (x**Integer(2) + x).valuation()1>>> (x**Integer(2) + x).valuation(x + Integer(1))
1>>> (x**Integer(2) + Integer(1)).valuation()0>>> (x**Integer(3) + Integer(1)).valuation(infinity)-3>>> P(Integer(0)).valuation()+Infinity

variable_name()
Return name of variable used in this polynomial as a string.
OUTPUT: string
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = t^3 + 3/2*t + 5
sage: f.variable_name()t2.1. Univariate Polynomials and Polynomial Rings

193

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + Integer(3)/Integer(2)*t + Integer(5)>>> f.variable_name()tvariables()Return the tuple of variables occurring in this polynomial.
EXAMPLES:
sage: R.<x> = QQ[]
sage: x.variables()(x,)>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> x.variables()(x,)

A constant polynomial has no variables.
sage: R(2).variables()()>>> from sage.all import *>>> R(Integer(2)).variables()()

xgcd(other)
Return an extended gcd of this polynomial and other.
INPUT:• other – a polynomial in the same ring as this polynomial
OUTPUT:
A tuple (r, s, t) where r is a greatest common divisor of this polynomial and other, and s and t aresuch that r = s*self + t*other holds.
Note: The actual algorithm for computing the extended gcd depends on the base ring underlying the polynomial ring. If the base ring defines a method _xgcd_univariate_polynomial(), then this method
will be called (see examples below).
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQbar[]
sage: (2*x^2).gcd(2*x)
xsage: R.zero().gcd(0)0sage: (2*x).gcd(0)x194

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x**Integer(2)).gcd(Integer(2)*x)x>>> R.zero().gcd(Integer(0))
0>>> (Integer(2)*x).gcd(Integer(0))
x

One can easily add xgcd functionality to new rings by providing a method _xgcd_univariate_polynomial():sage: R.<x> = QQ[]
sage: S.<y> = R[]
sage: h1 = y*x
sage: h2 = y^2*x^2sage: h1.xgcd(h2)Traceback (most recent call last):...
NotImplementedError: Univariate Polynomial Ring in x over Rational Field
does not provide an xgcd implementation for univariate polynomials
sage: T.<x,y> = QQ[]
sage: def poor_xgcd(f, g):....:
ret = S(T(f).gcd(g))....:
if ret == f: return ret, S.one(), S.zero()....:
if ret == g: return ret, S.zero(), S.one()....:raise NotImplementedError
sage: R._xgcd_univariate_polynomial = poor_xgcd
sage: h1.xgcd(h2)(x*y, 1, 0)
sage: del R._xgcd_univariate_polynomial>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> h1 = y*x>>> h2 = y**Integer(2)*x**Integer(2)>>> h1.xgcd(h2)Traceback (most recent call last):...
NotImplementedError: Univariate Polynomial Ring in x over Rational Field
does not provide an xgcd implementation for univariate polynomials>>> T = QQ[ x, y ]; (x, y,) = T._first_ngens(2)>>> def poor_xgcd(f, g):...
ret = S(T(f).gcd(g))...
if ret == f: return ret, S.one(), S.zero()...
if ret == g: return ret, S.zero(), S.one()...
raise NotImplementedError>>> R._xgcd_univariate_polynomial = poor_xgcd>>> h1.xgcd(h2)(x*y, 1, 0)>>> del R._xgcd_univariate_polynomialclass sage.rings.polynomial.polynomial_element.PolynomialBaseringInjection
Bases: Morphism
This class is used for conversion from a ring to a polynomial over that ring.
2.1. Univariate Polynomials and Polynomial Rings

195

Polynomials, Release 10.4

It calls the _new_constant_poly() method on the generator, which should be optimized for a particularpolynomial type.
Technically, it should be a method of the polynomial ring, but few polynomial rings are Cython classes, and so, asa method of a Cython polynomial class, it is faster.
EXAMPLES:
We demonstrate that most polynomial ring classes use polynomial base injection maps for coercion. They aresupposed to be the fastest maps for that purpose. See Issue #9944.
sage: # needs sage.rings.padics
sage: R.<x> = Qp(3)[]sage: R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: 3-adic Field with capped relative precision 20
To:
Univariate Polynomial Ring in x over
3-adic Field with capped relative precision 20
sage: R.<x,y> = Qp(3)[]sage: R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: 3-adic Field with capped relative precision 20
To:
Multivariate Polynomial Ring in x, y over
3-adic Field with capped relative precision 20
sage: R.<x,y> = QQ[]
sage: R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: Rational Field
To:
Multivariate Polynomial Ring in x, y over Rational Field
sage: R.<x> = QQ[]
sage: R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: Rational Field
To:
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> # needs sage.rings.padics>>> R = Qp(Integer(3))[ x ]; (x,) = R._first_ngens(1)>>> R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: 3-adic Field with capped relative precision 20
To:
Univariate Polynomial Ring in x over
3-adic Field with capped relative precision 20>>> R = Qp(Integer(3))[ x, y ]; (x, y,) = R._first_ngens(2)>>> R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: 3-adic Field with capped relative precision 20
To:
Multivariate Polynomial Ring in x, y over
3-adic Field with capped relative precision 20>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> R.coerce_map_from(R.base_ring())
Polynomial base injection morphism:
From: Rational Field
To:
Multivariate Polynomial Ring in x, y over Rational Field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.coerce_map_from(R.base_ring())(continues on next page)

196

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Polynomial base injection morphism:
From: Rational Field
To:
Univariate Polynomial Ring in x over Rational Field

By Issue #9944, there are now only very few exceptions:sage: PolynomialRing(QQ,names=[]).coerce_map_from(QQ)
Call morphism:
From: Rational Field
To:
Multivariate Polynomial Ring in no variables over Rational Field>>> from sage.all import *>>> PolynomialRing(QQ,names=[]).coerce_map_from(QQ)
Call morphism:
From: Rational Field
To:
Multivariate Polynomial Ring in no variables over Rational Field

is_injective()
Return whether this morphism is injective.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: S.<y> = R[]
sage: S.coerce_map_from(R).is_injective()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> S.coerce_map_from(R).is_injective()
True

Check that Issue #23203 has been resolved:
sage: R.is_subring(S)True# indirect doctest>>> from sage.all import *>>> R.is_subring(S) # indirect doctest
Trueis_surjective()
Return whether this morphism is surjective.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R.coerce_map_from(ZZ).is_surjective()
False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R.coerce_map_from(ZZ).is_surjective()
False

2.1. Univariate Polynomials and Polynomial Rings

197

Polynomials, Release 10.4

section()class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense
Bases: Polynomial
A generic dense polynomial.
EXAMPLES:
sage: f = QQ[ x ][ y ].random_element()
sage: loads(f.dumps()) == f
True>>> from sage.all import *>>> f = QQ[ x ][ y ].random_element()>>> loads(f.dumps()) == f
Trueconstant_coefficient()
Return the constant coefficient of this polynomial.
OUTPUT: element of base ring
EXAMPLES:
sage: R.<t> = QQ[]
sage: S.<x> = R[]
sage: f = x*t + x + t
sage: f.constant_coefficient()t>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> f = x*t + x + t>>> f.constant_coefficient()t

degree(gen=None)
EXAMPLES:
sage: R.<x> = RDF[]
sage: f = (1+2*x^7)^5
sage: f.degree()35>>> from sage.all import *>>> R = RDF[ x ]; (x,) = R._first_ngens(1)>>> f = (Integer(1)+Integer(2)*x**Integer(7))**Integer(5)>>> f.degree()35

is_term()
Return True if this polynomial is a nonzero element of the base ring times a power of the variable.
EXAMPLES:

198

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.symbolic
sage: R.<x> = SR[]
sage: R(0).is_term()
False
sage: R(1).is_term()
Truesage: (3*x^5).is_term()
Truesage: (1 + 3*x^5).is_term()
False>>> from sage.all import *>>> # needs sage.symbolic>>> R = SR[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(0)).is_term()
False>>> R(Integer(1)).is_term()True>>> (Integer(3)*x**Integer(5)).is_term()True>>> (Integer(1) + Integer(3)*x**Integer(5)).is_term()
False

list(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: R.<x> = GF(17)[]
sage: f = (1+2*x)^3 + 3*x; f8*x^3 + 12*x^2 + 9*x + 1
sage: f.list()[1, 9, 12, 8]>>> from sage.all import *>>> R = GF(Integer(17))[ x ]; (x,) = R._first_ngens(1)>>> f = (Integer(1)+Integer(2)*x)**Integer(3) + Integer(3)*x; f8*x^3 + 12*x^2 + 9*x + 1>>> f.list()[1, 9, 12, 8]

quo_rem(other)
Return the quotient and remainder of the Euclidean division of self and other.
Raises a ZeroDivisionError if other is zero. Raises an ArithmeticError if the division is notexact.
EXAMPLES:
sage: P.<x> = QQ[]
sage: R.<y> = P[]
sage: f = y^10 + R.random_element(9)sage: g = y^5 + R.random_element(4)sage: q, r = f.quo_rem(g)sage: f == q*g + r
True
sage: g = x*y^5(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

199

Polynomials, Release 10.4

(continued from previous page)

sage: f.quo_rem(g)Traceback (most recent call last):...
ArithmeticError: division non exact (consider coercing
to polynomials over the fraction field)
sage: g = 0
sage: f.quo_rem(g)Traceback (most recent call last):...
ZeroDivisionError: division by zero polynomial>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> R = P[ y ]; (y,) = R._first_ngens(1)>>> f = y**Integer(10) + R.random_element(Integer(9))>>> g = y**Integer(5) + R.random_element(Integer(4))>>> q, r = f.quo_rem(g)>>> f == q*g + r
True>>> g = x*y**Integer(5)>>> f.quo_rem(g)Traceback (most recent call last):...
ArithmeticError: division non exact (consider coercing
to polynomials over the fraction field)>>> g = Integer(0)>>> f.quo_rem(g)Traceback (most recent call last):...
ZeroDivisionError: division by zero polynomial

Polynomials over noncommutative rings are also allowed (after Issue #34733):
sage: # needs sage.combinat sage.modules
sage: HH = QuaternionAlgebra(QQ, -1, -1)
sage: P.<x> = HH[]
sage: f = P.random_element(5)sage: g = P.random_element((0, 5))
sage: q, r = f.quo_rem(g)sage: f == q*g + r
True>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> HH = QuaternionAlgebra(QQ, -Integer(1), -Integer(1))>>> P = HH[ x ]; (x,) = P._first_ngens(1)>>> f = P.random_element(Integer(5))>>> g = P.random_element((Integer(0), Integer(5)))>>> q, r = f.quo_rem(g)>>> f == q*g + r
True

shift(n)Return this polynomial multiplied by the power 𝑥𝑛 .
If 𝑛 is negative, terms below 𝑥𝑛 will be discarded. Does not change this polynomial.

200

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x> = PolynomialRing(PolynomialRing(QQ, y ), x )sage: p = x^2 + 2*x + 4
sage: type(p)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >sage: p.shift(0)x^2 + 2*x + 4
sage: p.shift(-1)
x + 2
sage: p.shift(2)x^4 + 2*x^3 + 4*x^2>>> from sage.all import *>>> R = PolynomialRing(PolynomialRing(QQ, y ), x , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> p = x**Integer(2) + Integer(2)*x + Integer(4)>>> type(p)<class sage.rings.polynomial.polynomial_element.Polynomial_generic_dense >>>> p.shift(Integer(0))
x^2 + 2*x + 4>>> p.shift(-Integer(1))
x + 2>>> p.shift(Integer(2))
x^4 + 2*x^3 + 4*x^2

AUTHORS:• David Harvey (2006-08-06)
truncate(n)Return the polynomial of degree < 𝑛 which is equivalent to self modulo 𝑥𝑛 .
EXAMPLES:
sage: S.<q> = QQ[ t ][ q ]sage: f = (1 + q^10 + q^11 + q^12).truncate(11); fq^10 + 1
sage: f = (1 + q^10 + q^100).truncate(50); fq^10 + 1
sage: f.degree()10
sage: f = (1 + q^10 + q^100).truncate(500); fq^100 + q^10 + 1>>> from sage.all import *>>> S = QQ[ t ][ q ]; (q,) = S._first_ngens(1)>>> f = (Integer(1) + q**Integer(10) + q**Integer(11) + q**Integer(12)).
˓→truncate(Integer(11)); fq^10 + 1>>> f = (Integer(1) + q**Integer(10) + q**Integer(100)).truncate(Integer(50));
˓→ fq^10 + 1>>> f.degree()10>>> f = (Integer(1) + q**Integer(10) + q**Integer(100)).
˓→truncate(Integer(500)); fq^100 + q^10 + 1

2.1. Univariate Polynomials and Polynomial Rings

201

Polynomials, Release 10.4

class
sage.rings.polynomial.polynomial_element.Polynomial_generic_dense_inexact
Bases: Polynomial_generic_dense
A dense polynomial over an inexact ring.
AUTHOR:• Xavier Caruso (2013-03)
degree(secure=False)
INPUT:• secure – a boolean (default: False)
OUTPUT: The degree of self.
If secure is True and the degree of this polynomial is not determined (because the leading coefficient is
indistinguishable from 0), an error is raised
If secure is False, the returned value is the largest 𝑛 so that the coefficient of 𝑥𝑛 does not compare equal
to 0.
EXAMPLES:
sage: # needs sage.rings.padics
sage: K = Qp(3, 10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.degree()1
sage: (f - T).degree()0
sage: (f - T).degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0
sage: # needs sage.rings.padics
sage: x = O(3^5)
sage: li = [3^i * x for i in range(0,5)]; li[O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)]sage: f = R(li); fO(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5)
sage: f.degree()-1
sage: f.degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0>>> from sage.all import *>>> # needs sage.rings.padics>>> K = Qp(Integer(3), Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.degree()1(continues on next page)

202

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> (f - T).degree()0>>> (f - T).degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0>>> # needs sage.rings.padics>>> x = O(Integer(3)**Integer(5))>>> li = [Integer(3)**i * x for i in range(Integer(0),Integer(5))]; li[O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)]>>> f = R(li); fO(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5)>>> f.degree()-1>>> f.degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0

AUTHOR:• Xavier Caruso (2013-03)
prec_degree()Return the largest 𝑛 so that precision information is stored about the coefficient of 𝑥𝑛 .
Always greater than or equal to degree.
EXAMPLES:
sage: # needs sage.rings.padics
sage: K = Qp(3, 10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.degree()1
sage: f.prec_degree()1
sage: g = f - T; g
˓→needs sage.rings.padics
O(3^10)*T + 2 + O(3^10)sage: g.degree()
˓→needs sage.rings.padics
0sage: g.prec_degree()
˓→needs sage.rings.padics
1

#␣

#␣

#␣

>>> from sage.all import *>>> # needs sage.rings.padics>>> K = Qp(Integer(3), Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

203

Polynomials, Release 10.4

(continued from previous page)>>> f.degree()1>>> f.prec_degree()1>>> g = f - T; g
˓→needs sage.rings.padics
O(3^10)*T + 2 + O(3^10)>>> g.degree()
˓→needs sage.rings.padics
0>>> g.prec_degree()
˓→needs sage.rings.padics
1

#␣

#␣

#␣

AUTHOR:• Xavier Caruso (2013-03)
sage.rings.polynomial.polynomial_element.generic_power_trunc(p, n, prec)
Generic truncated power algorithm
INPUT:• p – a polynomial• n – an integer (of type sage.rings.integer.Integer)• prec – a precision (should fit into a C long)sage.rings.polynomial.polynomial_element.is_Polynomial(f)Return True if f is of type univariate polynomial.
This function is deprecated.
INPUT:• f – an object
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_element import is_Polynomial
sage: R.<x> = ZZ[]
sage: is_Polynomial(x^3 + x + 1)
doctest:...: DeprecationWarning: the function is_Polynomial is deprecated;
use isinstance(x, sage.rings.polynomial.polynomial_element.Polynomial) instead
See https://github.com/sagemath/sage/issues/32709 for details.
Truesage: S.<y> = R[]
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: is_Polynomial(f)True>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_element import is_Polynomial>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> is_Polynomial(x**Integer(3) + x + Integer(1))
doctest:...: DeprecationWarning: the function is_Polynomial is deprecated;(continues on next page)

204

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)use isinstance(x, sage.rings.polynomial.polynomial_element.Polynomial) instead
See https://github.com/sagemath/sage/issues/32709 for details.
True>>> S = R[ y ]; (y,) = S._first_ngens(1)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> is_Polynomial(f)TrueHowever this function does not return True for genuine multivariate polynomial type objects or symbolic polynomials, since those are not of the same data type as univariate polynomials:
sage: R.<x,y> = QQ[]
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: is_Polynomial(f)False
sage: # needs sage.symbolic
sage: var( x,y )(x, y)
sage: f = y^3 + x*y - 3*x; fy^3 + x*y - 3*x
sage: is_Polynomial(f)False>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> is_Polynomial(f)False>>> # needs sage.symbolic>>> var( x,y )(x, y)>>> f = y**Integer(3) + x*y - Integer(3)*x; fy^3 + x*y - 3*x>>> is_Polynomial(f)Falsesage.rings.polynomial.polynomial_element.make_generic_polynomial(parent, coeffs)
sage.rings.polynomial.polynomial_element.polynomial_is_variable(x)Test whether the given polynomial is a variable of its parent ring.
Implemented for instances of Polynomial and MPolynomial.
See also:• sage.rings.polynomial.polynomial_element.Polynomial.is_gen()• sage.rings.polynomial.multi_polynomial.MPolynomial.is_generator()
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

205

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polynomial_element import polynomial_is_variable
sage: R.<x> = QQ[]
sage: polynomial_is_variable(x)True
sage: polynomial_is_variable(R([0,1]))True
sage: polynomial_is_variable(x^2)
False
sage: polynomial_is_variable(R(42))
False>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_element import polynomial_is_variable>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> polynomial_is_variable(x)True>>> polynomial_is_variable(R([Integer(0),Integer(1)]))True>>> polynomial_is_variable(x**Integer(2))
False>>> polynomial_is_variable(R(Integer(42)))
False
sage: R.<y,z> = QQ[]
sage: polynomial_is_variable(y)True
sage: polynomial_is_variable(z)True
sage: polynomial_is_variable(y^2)
False
sage: polynomial_is_variable(y+z)
False
sage: polynomial_is_variable(R(42))
False>>> from sage.all import *>>> R = QQ[ y, z ]; (y, z,) = R._first_ngens(2)>>> polynomial_is_variable(y)True>>> polynomial_is_variable(z)True>>> polynomial_is_variable(y**Integer(2))
False>>> polynomial_is_variable(y+z)
False>>> polynomial_is_variable(R(Integer(42)))
False
sage: polynomial_is_variable(42)False>>> from sage.all import *>>> polynomial_is_variable(Integer(42))
False

sage.rings.polynomial.polynomial_element.universal_discriminant()
206

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Return the discriminant of the ‘universal’ univariate polynomial 𝑎𝑛 𝑥𝑛 + · · · + 𝑎1 𝑥 + 𝑎0 in Z[𝑎0 , . . . , 𝑎𝑛 ][𝑥].
INPUT:• n – degree of the polynomial
OUTPUT:The discriminant as a polynomial in 𝑛 + 1 variables over Z. The result will be cached, so subsequent computationsof discriminants of the same degree will be faster.
EXAMPLES:
sage: # needs sage.libs.pari
sage: from sage.rings.polynomial.polynomial_element import universal_discriminantsage: universal_discriminant(1)1sage: universal_discriminant(2)a1^2 - 4*a0*a2
sage: universal_discriminant(3)a1^2*a2^2 - 4*a0*a2^3 - 4*a1^3*a3 + 18*a0*a1*a2*a3 - 27*a0^2*a3^2
sage: universal_discriminant(4).degrees()(3, 4, 4, 4, 3)>>> from sage.all import *>>> # needs sage.libs.pari>>> from sage.rings.polynomial.polynomial_element import universal_discriminant>>> universal_discriminant(Integer(1))
1>>> universal_discriminant(Integer(2))
a1^2 - 4*a0*a2>>> universal_discriminant(Integer(3))
a1^2*a2^2 - 4*a0*a2^3 - 4*a1^3*a3 + 18*a0*a1*a2*a3 - 27*a0^2*a3^2>>> universal_discriminant(Integer(4)).degrees()(3, 4, 4, 4, 3)

See also:
Polynomial.discriminant()

2.1.4 Univariate Polynomials over domains and fields
AUTHORS:• William Stein: first version• Martin Albrecht: Added singular coercion.
• David Harvey: split off polynomial_integer_dense_ntl.pyx (2007-09)• Robert Bradshaw: split off polynomial_modn_dense_ntl.pyx (2007-09)
class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv(parent,
is_gen=False,
construct=False)
Bases: Polynomial_generic_domain
A generic class for polynomials over complete discrete valuation domains and fields.

2.1. Univariate Polynomials and Polynomial Rings

207

Polynomials, Release 10.4

AUTHOR:• Xavier Caruso (2013-03)
factor_of_slope(slope=None)
INPUT:• slope – a rational number (default: the first slope in the Newton polygon of self)
OUTPUT:
The factor of self corresponding to the slope slope (i.e. the unique monic divisor of self whose slope
is slope and degree is the length of slope in the Newton polygon).
EXAMPLES:
sage: # needs sage.geometry.polyhedron sage.rings.padics
sage: K = Qp(5)sage: R.<x> = K[]
sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
sage: g = f.factor_of_slope(0)sage: g.newton_slopes()[0, 0, 0]
sage: (f % g).is_zero()Truesage: h = f.factor_of_slope()
sage: h.newton_slopes()[1]
sage: (f % h).is_zero()True>>> from sage.all import *>>> # needs sage.geometry.polyhedron sage.rings.padics>>> K = Qp(Integer(5))>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]>>> g = f.factor_of_slope(Integer(0))>>> g.newton_slopes()[0, 0, 0]>>> (f % g).is_zero()True>>> h = f.factor_of_slope()>>> h.newton_slopes()[1]>>> (f % h).is_zero()True

If slope is not a slope of self, the corresponding factor is 1:
sage: f.factor_of_slope(-1)˓→needs sage.geometry.polyhedron sage.rings.padics
1 + O(5^20)

208

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> f.factor_of_slope(-Integer(1))˓→# needs sage.geometry.polyhedron sage.rings.padics
1 + O(5^20)

␣

AUTHOR:• Xavier Caruso (2013-03-20)
hensel_lift(a)Lift 𝑎 to a root of this polynomial (using Newton iteration).
If 𝑎 is not close enough to a root (so that Newton iteration does not converge), an error is raised.
EXAMPLES:
sage: # needs sage.rings.padics
sage: K = Qp(5, 10)
sage: P.<x> = PolynomialRing(K)sage: f = x^2 + 1
sage: root = f.hensel_lift(2); root
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)sage: f(root)
O(5^10)sage: g = (x^2 + 1) * (x - 7)
˓→needs sage.rings.padics
sage: g.hensel_lift(2) # here, 2 is a multiple root modulo p
˓→needs sage.rings.padics
Traceback (most recent call last):...
ValueError: a is not close enough to a root of this polynomial#␣#␣>>> from sage.all import *>>> # needs sage.rings.padics>>> K = Qp(Integer(5), Integer(10))>>> P = PolynomialRing(K, names=( x ,)); (x,) = P._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> root = f.hensel_lift(Integer(2)); root
2 + 5 + 2*5^2 + 5^3 + 3*5^4 + 4*5^5 + 2*5^6 + 3*5^7 + 3*5^9 + O(5^10)>>> f(root)
O(5^10)>>> g = (x**Integer(2) + Integer(1)) * (x - Integer(7))˓→# needs sage.rings.padics>>> g.hensel_lift(Integer(2)) # here, 2 is a multiple root modulo p˓→# needs sage.rings.padics
Traceback (most recent call last):...
ValueError: a is not close enough to a root of this polynomial␣␣

AUTHOR:• Xavier Caruso (2013-03-23)
newton_polygon()
Return a list of vertices of the Newton polygon of this polynomial.

2.1. Univariate Polynomials and Polynomial Rings

209

Polynomials, Release 10.4

Note: If some coefficients have not enough precision an error is raised.
EXAMPLES:
sage: # needs sage.geometry.polyhedron sage.rings.padics
sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_polygon()
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)
sage: g = f + K(0,0)*t^4; g(5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21)
sage: g.newton_polygon()Traceback (most recent call last):...
PrecisionError: The coefficient of t^4 has not enough precision>>> from sage.all import *>>> # needs sage.geometry.polyhedron sage.rings.padics>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_polygon()
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)>>> g = f + K(Integer(0),Integer(0))*t**Integer(4); g(5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21)>>> g.newton_polygon()Traceback (most recent call last):...
PrecisionError: The coefficient of t^4 has not enough precision

AUTHOR:• Xavier Caruso (2013-03-20)
newton_slopes(repetition=True)
Return a list of the Newton slopes of this polynomial.
These are the valuations of the roots of this polynomial.
If repetition is True, each slope is repeated a number of times equal to its multiplicity. Otherwise it
appears only one time.
EXAMPLES:
sage: # needs sage.geometry.polyhedron sage.rings.padics
sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_polygon()
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)
sage: f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
sage: f.newton_slopes(repetition=False)[1, 0, -1/3]

210

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.geometry.polyhedron sage.rings.padics>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_polygon()
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)>>> f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]>>> f.newton_slopes(repetition=False)[1, 0, -1/3]

AUTHOR:• Xavier Caruso (2013-03-20)
slope_factorization()
Return a factorization of self into a product of factors corresponding to each slope in the Newton polygon.
EXAMPLES:
sage: # needs sage.geometry.polyhedron sage.rings.padics
sage: K = Qp(5)sage: R.<x> = K[]
sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]
sage: F = f.slope_factorization()sage: F.prod() == f
True
sage: for (f,_) in F:....:
print(f.newton_slopes())[-1/3, -1/3, -1/3, -1/3, -1/3, -1/3][0, 0, 0][1]>>> from sage.all import *>>> # needs sage.geometry.polyhedron sage.rings.padics>>> K = Qp(Integer(5))>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_slopes()[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]>>> F = f.slope_factorization()>>> F.prod() == f
True>>> for (f,_) in F:...
print(f.newton_slopes())[-1/3, -1/3, -1/3, -1/3, -1/3, -1/3][0, 0, 0][1]

AUTHOR:• Xavier Caruso (2013-03-20)
2.1. Univariate Polynomials and Polynomial Rings

211

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdvf(parent,
is_gen=False,
construct=False)
Bases: Polynomial_generic_cdv, Polynomial_generic_fieldclass sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdvr(parent,
is_gen=False,
construct=False)
Bases: Polynomial_generic_cdv
classsage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_cdv
Bases: Polynomial_generic_dense_inexact, Polynomial_generic_cdv
classsage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_cdvf
Bases: Polynomial_generic_dense_cdv, Polynomial_generic_cdvf
classsage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_cdvr
Bases: Polynomial_generic_dense_cdv, Polynomial_generic_cdvr

class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_dense_field(parent,
x=Noncheck=
is_gen=construct=
Bases: Polynomial_generic_dense, Polynomial_generic_fieldclass sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_domain(parent,
is_gen=False,
construct=False)
Bases: Polynomial, IntegralDomainElement
is_unit()
Return True if this polynomial is a unit.
EXERCISE (Atiyah-McDonald, Ch 1): Let 𝐴[𝑥] be a polynomial ring in one variable. Then 𝑓 =𝐴[𝑥] is a unit if and only if 𝑎0 is a unit and 𝑎1 , . . . , 𝑎𝑛 are nilpotent.

∑︀𝑎𝑖 𝑥𝑖 ∈

EXAMPLES:
sage: R.<z> = PolynomialRing(ZZ, sparse=True)
sage: (2 + z^3).is_unit()
False
sage: f = -1 + 3*z^3; f
3*z^3 - 1sage: f.is_unit()(continues on next page)212

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

False
sage: R(-3).is_unit()
False
sage: R(-1).is_unit()
True
sage: R(0).is_unit()
False>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( z ,)); (z,) = R._first_
˓→ngens(1)>>> (Integer(2) + z**Integer(3)).is_unit()
False>>> f = -Integer(1) + Integer(3)*z**Integer(3); f
3*z^3 - 1>>> f.is_unit()
False>>> R(-Integer(3)).is_unit()
False>>> R(-Integer(1)).is_unit()
True>>> R(Integer(0)).is_unit()
False

class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_field(parent,
is_gen=False,
construct=False)
Bases:Polynomial_singular_repr,
mainElement

Polynomial_generic_domain,

EuclideanDo-quo_rem(other)
Return a tuple (quotient, remainder) where self = quotient * other + remainder.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<y> = PolynomialRing(QQ)
sage: K.<t> = NumberField(y^2 - 2)sage: P.<x> = PolynomialRing(K)sage: x.quo_rem(K(1))(x, 0)
sage: x.xgcd(K(1))(1, 0, 1)>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( y ,)); (y,) = R._first_ngens(1)>>> K = NumberField(y**Integer(2) - Integer(2), names=( t ,)); (t,) = K._
˓→first_ngens(1)>>> P = PolynomialRing(K, names=( x ,)); (x,) = P._first_ngens(1)>>> x.quo_rem(K(Integer(1)))(x, 0)>>> x.xgcd(K(Integer(1)))(1, 0, 1)

2.1. Univariate Polynomials and Polynomial Rings

213

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse(parent,
x=None,check=True,is_gen=False,
construct=False)
Bases: Polynomial
A generic sparse polynomial.
The Polynomial_generic_sparse class defines functionality for sparse polynomials over any base ring. A
sparse polynomial is represented using a dictionary which maps each exponent to the corresponding coefficient.
The coefficients must never be zero.
EXAMPLES:
sage: R.<x> = PolynomialRing(PolynomialRing(QQ, y ), sparse=True)
sage: f = x^3 - x + 17
sage: type(f)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_with_
˓→category.element_class >sage: loads(f.dumps()) == f
True>>> from sage.all import *>>> R = PolynomialRing(PolynomialRing(QQ, y ), sparse=True, names=( x ,)); (x,)␣
˓→= R._first_ngens(1)>>> f = x**Integer(3) - x + Integer(17)>>> type(f)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_with_
˓→category.element_class >>>> loads(f.dumps()) == fTrue

A more extensive example:
sage: # needs sage.libs.pari
sage: A.<T> = PolynomialRing(Integers(5), sparse=True)
sage: f = T^2 + 1; B = A.quo(f)sage: C.
 = PolynomialRing(B)sage: C
Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar
over Ring of integers modulo 5 with modulus T^2 + 1
sage: s + T
s + Tbar
sage: (s + T)**2s^2 + 2*Tbar*s + 4>>> from sage.all import *>>> # needs sage.libs.pari>>> A = PolynomialRing(Integers(Integer(5)), sparse=True, names=( T ,)); (T,) = A.
˓→_first_ngens(1)>>> f = T**Integer(2) + Integer(1); B = A.quo(f)>>> C = PolynomialRing(B, names=( s ,)); (s,) = C._first_ngens(1)>>> C
Univariate Polynomial Ring in s over Univariate Quotient Polynomial Ring in Tbar
(continues on next page)

214

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

over Ring of integers modulo 5 with modulus T^2 + 1>>> s + T
s + Tbar>>> (s + T)**Integer(2)s^2 + 2*Tbar*s + 4

coefficients(sparse=True)
Return the coefficients of the monomials appearing in self.
EXAMPLES:
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
sage: f = 5 + w^1997 - w^10000; f
7*w^10000 + w^1997 + 5
sage: f.coefficients()[5, 1, 7]>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(8)), sparse=True, names=( w ,)); (w,)␣
˓→= R._first_ngens(1)>>> f = Integer(5) + w**Integer(1997) - w**Integer(10000); f
7*w^10000 + w^1997 + 5>>> f.coefficients()[5, 1, 7]degree(gen=None)
Return the degree of this sparse polynomial.
EXAMPLES:
sage: R.<z> = PolynomialRing(ZZ, sparse=True)
sage: f = 13*z^50000 + 15*z^2 + 17*z
sage: f.degree()50000>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( z ,)); (z,) = R._first_
˓→ngens(1)>>> f = Integer(13)*z**Integer(50000) + Integer(15)*z**Integer(2) +␣˓→Integer(17)*z>>> f.degree()50000

dict()
Return a new copy of the dict of the underlying elements of self.
EXAMPLES:
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
sage: f = 5 + w^1997 - w^10000; f
7*w^10000 + w^1997 + 5
sage: d = f.dict(); d{0: 5, 1997: 1, 10000: 7}
sage: d[0] = 10
sage: f.dict(){0: 5, 1997: 1, 10000: 7}

2.1. Univariate Polynomials and Polynomial Rings

215

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(8)), sparse=True, names=( w ,)); (w,)␣
˓→= R._first_ngens(1)>>> f = Integer(5) + w**Integer(1997) - w**Integer(10000); f
7*w^10000 + w^1997 + 5>>> d = f.dict(); d{0: 5, 1997: 1, 10000: 7}>>> d[Integer(0)] = Integer(10)>>> f.dict(){0: 5, 1997: 1, 10000: 7}

exponents()
Return the exponents of the monomials appearing in self.
EXAMPLES:
sage: R.<w> = PolynomialRing(Integers(8), sparse=True)
sage: f = 5 + w^1997 - w^10000; f
7*w^10000 + w^1997 + 5
sage: f.exponents()[0, 1997, 10000]>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(8)), sparse=True, names=( w ,)); (w,)␣
˓→= R._first_ngens(1)>>> f = Integer(5) + w**Integer(1997) - w**Integer(10000); f
7*w^10000 + w^1997 + 5>>> f.exponents()[0, 1997, 10000]

gcd(other, algorithm=None)
Return the gcd of this polynomial and other
INPUT:• other – a polynomial defined over the same ring as this polynomial.
ALGORITHM:
Two algorithms are provided:• generic – Uses the generic implementation, which depends on the base ring being a UFD or a field.
• dense – The polynomials are converted to the dense representation, their gcd is computed and is converted back to the sparse representation.
Default is dense for polynomials over Z and generic in the other cases.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^6 + 7*x^5 + 8*x^4 + 6*x^3 + 2*x^2 + x + 2
sage: q = 2*x^4 - x^3 - 2*x^2 - 4*x - 1
sage: gcd(p, q)x^2 + x + 1
sage: gcd(p, q, algorithm="dense")x^2 + x + 1
sage: gcd(p, q, algorithm="generic")x^2 + x + 1(continues on next page)

216

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: gcd(p, q, algorithm="foobar")
Traceback (most recent call last):...
ValueError: Unknown algorithm foobar>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(6) + Integer(7)*x**Integer(5) + Integer(8)*x**Integer(4) +␣˓→Integer(6)*x**Integer(3) + Integer(2)*x**Integer(2) + x + Integer(2)>>> q = Integer(2)*x**Integer(4) - x**Integer(3) - Integer(2)*x**Integer(2) -␣˓→Integer(4)*x - Integer(1)>>> gcd(p, q)x^2 + x + 1>>> gcd(p, q, algorithm="dense")x^2 + x + 1>>> gcd(p, q, algorithm="generic")x^2 + x + 1>>> gcd(p, q, algorithm="foobar")
Traceback (most recent call last):...
ValueError: Unknown algorithm foobar

integral(var=None)
Return the integral of this polynomial.
By default, the integration variable is the variable of the polynomial.
Otherwise, the integration variable is the optional parameter var
Note: The integral is always chosen so that the constant term is 0.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: (1 + 3*x^10 - 2*x^100).integral()-2/101*x^101 + 3/11*x^11 + x>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> (Integer(1) + Integer(3)*x**Integer(10) - Integer(2)*x**Integer(100)).
˓→integral()-2/101*x^101 + 3/11*x^11 + xlist(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: R.<z> = PolynomialRing(Integers(100), sparse=True)
sage: f = 13*z^5 + 15*z^2 + 17*z
sage: f.list()[0, 17, 15, 0, 0, 13]

2.1. Univariate Polynomials and Polynomial Rings

217

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), sparse=True, names=( z ,)); (z,˓→) = R._first_ngens(1)>>> f = Integer(13)*z**Integer(5) + Integer(15)*z**Integer(2) + Integer(17)*z>>> f.list()[0, 17, 15, 0, 0, 13]

number_of_terms()
Return the number of nonzero terms.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^100 - 3*x^10 + 12
sage: p.number_of_terms()
3>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(100) - Integer(3)*x**Integer(10) + Integer(12)>>> p.number_of_terms()3

quo_rem(other)
Return the quotient and remainder of the Euclidean division of self and other.
Raises ZeroDivisionError if other is zero.
Raises ArithmeticError if other has a nonunit leading coefficient and this causes the Euclidean division to fail.
EXAMPLES:
sage: P.<x> = PolynomialRing(ZZ, sparse=True)
sage: R.<y> = PolynomialRing(P, sparse=True)
sage: f = R.random_element(10)sage: while x.divides(f.leading_coefficient()):....:
f = R.random_element(10)sage: g = y^5 + R.random_element(4)sage: q, r = f.quo_rem(g)sage: f == q*g + r and r.degree() < g.degree()True
sage: g = x*y^5
sage: f.quo_rem(g)Traceback (most recent call last):...
ArithmeticError: Division non exact(consider coercing to polynomials over the fraction field)
sage: g = 0
sage: f.quo_rem(g)Traceback (most recent call last):...
ZeroDivisionError: Division by zero polynomial>>> from sage.all import *>>> P = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = P._first_(continues on next page)

218

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)ngens(1)>>> R = PolynomialRing(P, sparse=True, names=( y ,)); (y,) = R._first_ngens(1)>>> f = R.random_element(Integer(10))>>> while x.divides(f.leading_coefficient()):...
f = R.random_element(Integer(10))>>> g = y**Integer(5) + R.random_element(Integer(4))>>> q, r = f.quo_rem(g)>>> f == q*g + r and r.degree() < g.degree()True>>> g = x*y**Integer(5)>>> f.quo_rem(g)Traceback (most recent call last):...
ArithmeticError: Division non exact(consider coercing to polynomials over the fraction field)>>> g = Integer(0)>>> f.quo_rem(g)Traceback (most recent call last):...
ZeroDivisionError: Division by zero polynomial˓→

If the leading coefficient of other is not a unit, Euclidean division may still work:
sage: f = -x*y^10 + 2*x*y^7 + y^3 - 2*x^2*y^2 - ysage: g = x*y^5
sage: f.quo_rem(g)(-y^5 + 2*y^2, y^3 - 2*x^2*y^2 - y)>>> from sage.all import *>>> f = -x*y**Integer(10) + Integer(2)*x*y**Integer(7) + y**Integer(3) -␣˓→Integer(2)*x**Integer(2)*y**Integer(2) - y>>> g = x*y**Integer(5)>>> f.quo_rem(g)(-y^5 + 2*y^2, y^3 - 2*x^2*y^2 - y)

Polynomials over noncommutative rings are also allowed:
sage: # needs sage.combinat sage.modules
sage: HH = QuaternionAlgebra(QQ, -1, -1)
sage: P.<x> = PolynomialRing(HH, sparse=True)
sage: f = P.random_element(5)sage: g = P.random_element((0, 5))
sage: q, r = f.quo_rem(g)sage: f == q*g + r
True>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> HH = QuaternionAlgebra(QQ, -Integer(1), -Integer(1))>>> P = PolynomialRing(HH, sparse=True, names=( x ,)); (x,) = P._first_
˓→ngens(1)>>> f = P.random_element(Integer(5))>>> g = P.random_element((Integer(0), Integer(5)))>>> q, r = f.quo_rem(g)>>> f == q*g + r
True

2.1. Univariate Polynomials and Polynomial Rings

219

Polynomials, Release 10.4

AUTHORS:• Bruno Grenet (2014-07-09)
reverse(degree=None)
Return this polynomial but with the coefficients reversed.
If an optional degree argument is given, the coefficient list will be truncated or zero padded as necessary andthe reverse polynomial will have the specified degree.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^4 + 2*x^2^100
sage: p.reverse()x^1267650600228229401496703205372 + 2
sage: p.reverse(10)x^6>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(4) + Integer(2)*x**Integer(2)**Integer(100)>>> p.reverse()x^1267650600228229401496703205372 + 2>>> p.reverse(Integer(10))
x^6shift(n)Return this polynomial multiplied by the power 𝑥𝑛 .
If 𝑛 is negative, terms below 𝑥𝑛 will be discarded. Does not change this polynomial.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: p = x^100000 + 2*x + 4
sage: type(p)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_
˓→with_category.element_class >sage: p.shift(0)x^100000 + 2*x + 4
sage: p.shift(-1)
x^99999 + 2
sage: p.shift(-100002)0sage: p.shift(2)x^100002 + 2*x^3 + 4*x^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> p = x**Integer(100000) + Integer(2)*x + Integer(4)>>> type(p)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain_
˓→with_category.element_class >>>> p.shift(Integer(0))
x^100000 + 2*x + 4>>> p.shift(-Integer(1))(continues on next page)

220

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x^99999 + 2>>> p.shift(-Integer(100002))0>>> p.shift(Integer(2))
x^100002 + 2*x^3 + 4*x^2

AUTHOR: - David Harvey (2006-08-06)
truncate(n)Return the polynomial of degree < 𝑛 equal to self modulo 𝑥𝑛 .
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, sparse=True)
sage: (x^11 + x^10 + 1).truncate(11)x^10 + 1
sage: (x^2^500 + x^2^100 + 1).truncate(2^101)
x^1267650600228229401496703205376 + 1>>> from sage.all import *>>> R = PolynomialRing(ZZ, sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> (x**Integer(11) + x**Integer(10) + Integer(1)).truncate(Integer(11))
x^10 + 1>>> (x**Integer(2)**Integer(500) + x**Integer(2)**Integer(100) + Integer(1)).
˓→truncate(Integer(2)**Integer(101))x^1267650600228229401496703205376 + 1

valuation(p=None)
Return the valuation of self.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: R.<w> = PolynomialRing(GF(9, a ), sparse=True)
sage: f = w^1997 - w^10000
sage: f.valuation()
1997
sage: R(19).valuation()0
sage: R(0).valuation()+Infinity>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(9), a ), sparse=True, names=( w ,)); (w,)␣
˓→= R._first_ngens(1)>>> f = w**Integer(1997) - w**Integer(10000)>>> f.valuation()
1997>>> R(Integer(19)).valuation()0>>> R(Integer(0)).valuation()+Infinity

2.1. Univariate Polynomials and Polynomial Rings

221

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse_cdv(parent,
x=None,check=T
is_gen=F
construct=F
Bases: Polynomial_generic_sparse, Polynomial_generic_cdv

class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse_cdvf(parent,
x=Noncheck=
is_gen=construct=
Bases: Polynomial_generic_sparse_cdv, Polynomial_generic_cdvf

class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse_cdvr(parent,
x=Noncheck=
is_gen=construct=
Bases: Polynomial_generic_sparse_cdv, Polynomial_generic_cdvr

class sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse_field(parent,
x=No
check
is_genconstruct
Bases: Polynomial_generic_sparse, Polynomial_generic_field
EXAMPLES:
sage: R.<x> = PolynomialRing(Frac(RR[ t ]), sparse=True)
sage: f = x^3 - x + 17
sage: type(f)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.
˓→element_class >sage: loads(f.dumps()) == f
True>>> from sage.all import *>>> R = PolynomialRing(Frac(RR[ t ]), sparse=True, names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> f = x**Integer(3) - x + Integer(17)>>> type(f)<class sage.rings.polynomial.polynomial_ring.PolynomialRing_field_with_category.
˓→element_class >>>> loads(f.dumps()) == f
True

222

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

2.1.5 Univariate Polynomials over GF(2) via NTL’s GF2X
AUTHOR: - Martin Albrecht (2008-10) initial implementation
sage.rings.polynomial.polynomial_gf2x.GF2X_BuildIrred_list(n)Return the list of coefficients of the lexicographically smallest irreducible polynomial of degree 𝑛 over the field of
2 elements.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list
sage: GF2X_BuildIrred_list(2)[1, 1, 1]
sage: GF2X_BuildIrred_list(3)[1, 1, 0, 1]
sage: GF2X_BuildIrred_list(4)[1, 1, 0, 0, 1]
sage: GF(2)[ x ](GF2X_BuildIrred_list(33))
x^33 + x^6 + x^3 + x + 1>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list>>> GF2X_BuildIrred_list(Integer(2))[1, 1, 1]>>> GF2X_BuildIrred_list(Integer(3))[1, 1, 0, 1]>>> GF2X_BuildIrred_list(Integer(4))[1, 1, 0, 0, 1]>>> GF(Integer(2))[ x ](GF2X_BuildIrred_list(Integer(33)))
x^33 + x^6 + x^3 + x + 1

sage.rings.polynomial.polynomial_gf2x.GF2X_BuildRandomIrred_list(n)Return the list of coefficients of an irreducible polynomial of degree 𝑛 of minimal weight over the field of 2
elements.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildRandomIrred_list
sage: GF2X_BuildRandomIrred_list(2)[1, 1, 1]
sage: GF2X_BuildRandomIrred_list(3) in [[1, 1, 0, 1], [1, 0, 1, 1]]
True>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildRandomIrred_list>>> GF2X_BuildRandomIrred_list(Integer(2))[1, 1, 1]>>> GF2X_BuildRandomIrred_list(Integer(3)) in [[Integer(1), Integer(1),␣
˓→Integer(0), Integer(1)], [Integer(1), Integer(0), Integer(1), Integer(1)]]True

sage.rings.polynomial.polynomial_gf2x.GF2X_BuildSparseIrred_list(n)Return the list of coefficients of an irreducible polynomial of degree 𝑛 of minimal weight over the field of 2
elements.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

223

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list,␣
˓→GF2X_BuildSparseIrred_list
sage: all([GF2X_BuildSparseIrred_list(n) == GF2X_BuildIrred_list(n)....:for n in range(1,33)])
True
sage: GF(2)[ x ](GF2X_BuildSparseIrred_list(33))
x^33 + x^10 + 1>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_gf2x import GF2X_BuildIrred_list, GF2X_
˓→BuildSparseIrred_list>>> all([GF2X_BuildSparseIrred_list(n) == GF2X_BuildIrred_list(n)...
for n in range(Integer(1),Integer(33))])
True>>> GF(Integer(2))[ x ](GF2X_BuildSparseIrred_list(Integer(33)))
x^33 + x^10 + 1

class sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X
Bases: Polynomial_template
Univariate Polynomials over F2 via NTL’s GF2X.
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x^3 + x^2 + 1
x^3 + x^2 + 1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x**Integer(3) + x**Integer(2) + Integer(1)x^3 + x^2 + 1

is_irreducible()
Return whether this polynomial is irreducible over F2 .
EXAMPLES:
sage: R.<x> = GF(2)[]sage: (x^2 + 1).is_irreducible()False
sage: (x^3 + x + 1).is_irreducible()True>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2) + Integer(1)).is_irreducible()False>>> (x**Integer(3) + x + Integer(1)).is_irreducible()
True

Test that caching works:
sage: R.<x> = GF(2)[]sage: f = x^2 + 1
sage: f.is_irreducible()(continues on next page)

224

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

False
sage: f.is_irreducible.cache
False>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> f.is_irreducible()
False>>> f.is_irreducible.cache
False

modular_composition(g, h, algorithm=None)
Compute 𝑓 (𝑔) (mod ℎ).
Both implementations use Brent-Kung’s Algorithm 2.1 (Fast Algorithms for Manipulation of Formal Power
Series, JACM 1978).
INPUT:• g – a polynomial• h – a polynomial• algorithm – either native or ntl (default: native )EXAMPLES:
sage: P.<x> = GF(2)[]sage: r = 279
sage: f = x^r + x +1
sage: g = x^r
sage: g.modular_composition(g, f) == g(g) % f
True
sage: P.<x> = GF(2)[]sage: f = x^29 + x^24 + x^22 + x^21 + x^20 + x^16 + x^15 + x^14 + x^10 + x^9␣˓→+ x^8 + x^7 + x^6 + x^5 + x^2
sage: g = x^31 + x^30 + x^28 + x^26 + x^24 + x^21 + x^19 + x^18 + x^11 + x^10␣
˓→+ x^9 + x^8 + x^5 + x^2 + 1
sage: h = x^30 + x^28 + x^26 + x^25 + x^24 + x^22 + x^21 + x^18 + x^17 + x^15␣
˓→+ x^13 + x^12 + x^11 + x^10 + x^9 + x^4
sage: f.modular_composition(g, h) == f(g) % h
True>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> r = Integer(279)>>> f = x**r + x +Integer(1)>>> g = x**r>>> g.modular_composition(g, f) == g(g) % f
True>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(29) + x**Integer(24) + x**Integer(22) + x**Integer(21) +␣˓→x**Integer(20) + x**Integer(16) + x**Integer(15) + x**Integer(14) +␣˓→x**Integer(10) + x**Integer(9) + x**Integer(8) + x**Integer(7) +␣˓→x**Integer(6) + x**Integer(5) + x**Integer(2)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

225

Polynomials, Release 10.4

(continued from previous page)>>> g = x**Integer(31) + x**Integer(30) + x**Integer(28) + x**Integer(26) +␣˓→x**Integer(24) + x**Integer(21) + x**Integer(19) + x**Integer(18) +␣˓→x**Integer(11) + x**Integer(10) + x**Integer(9) + x**Integer(8) +␣˓→x**Integer(5) + x**Integer(2) + Integer(1)>>> h = x**Integer(30) + x**Integer(28) + x**Integer(26) + x**Integer(25) +␣˓→x**Integer(24) + x**Integer(22) + x**Integer(21) + x**Integer(18) +␣˓→x**Integer(17) + x**Integer(15) + x**Integer(13) + x**Integer(12) +␣˓→x**Integer(11) + x**Integer(10) + x**Integer(9) + x**Integer(4)>>> f.modular_composition(g, h) == f(g) % h
True

AUTHORS:• Paul Zimmermann (2008-10) initial implementation• Martin Albrecht (2008-10) performance improvements
class sage.rings.polynomial.polynomial_gf2x.Polynomial_template
Bases: Polynomial
Template for interfacing to external C / C++ libraries for implementations of polynomials.
AUTHORS:• Robert Bradshaw (2008-10): original idea for templating• Martin Albrecht (2008-10): initial implementation
This file implements a simple templating engine for linking univariate polynomials to their C/C++ library implementations. It requires a ‘linkage’ file which implements the celement_ functions (see sage.libs.ntl.
ntl_GF2X_linkage for an example). Both parts are then plugged together by inclusion of the linkage filewhen inheriting from this class. See sage.rings.polynomial.polynomial_gf2x for an example.
We illustrate the generic glueing using univariate polynomials over GF(2).
Note: Implementations using this template MUST implement coercion from base ring elements and get_unsafe(). See Polynomial_GF2X for an example.
degree()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.degree()1
sage: P(1).degree()0
sage: P(0).degree()-1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.degree()1>>> P(Integer(1)).degree()0>>> P(Integer(0)).degree()-1

226

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

gcd(other)
Return the greatest common divisor of self and other.
EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x*(x+1)
sage: f.gcd(x+1)
x + 1
sage: f.gcd(x^2)
x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.gcd(x+Integer(1))
x + 1>>> f.gcd(x**Integer(2))
xget_cparent()
is_gen()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_gen()True
sage: (x+1).is_gen()False>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.is_gen()True>>> (x+Integer(1)).is_gen()
False

is_one()EXAMPLES:
sage: P.<x> = GF(2)[]sage: P(1).is_one()True>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> P(Integer(1)).is_one()True

is_zero()
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_zero()
False

2.1. Univariate Polynomials and Polynomial Rings

227

Polynomials, Release 10.4>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.is_zero()
False

list(copy=True)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.list()[0, 1]
sage: list(x)[0, 1]>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.list()[0, 1]>>> list(x)[0, 1]

quo_rem(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^2 + x + 1
sage: f.quo_rem(x + 1)
(x, 1)>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(2) + x + Integer(1)>>> f.quo_rem(x + Integer(1))(x, 1)

shift(n)EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^3 + x^2 + 1
sage: f.shift(1)x^4 + x^3 + x
sage: f.shift(-1)
x^2 + x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(3) + x**Integer(2) + Integer(1)>>> f.shift(Integer(1))
x^4 + x^3 + x>>> f.shift(-Integer(1))
x^2 + xtruncate(n)Returns this polynomial mod 𝑥𝑛 .
228

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x> =GF(2)[]sage: f = sum(x^n for n in range(10)); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
sage: f.truncate(6)x^5 + x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = sum(x**n for n in range(Integer(10))); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1>>> f.truncate(Integer(6))
x^5 + x^4 + x^3 + x^2 + x + 1

If the precision is higher than the degree of the polynomial then the polynomial itself is returned:
sage: f.truncate(10) is f
True>>> from sage.all import *>>> f.truncate(Integer(10)) is f
True

If the precision is negative, the zero polynomial is returned:
sage: f.truncate(-1)
0>>> from sage.all import *>>> f.truncate(-Integer(1))
0xgcd(other)Computes extended gcd of self and other.
EXAMPLES:
sage: P.<x> = GF(7)[]sage: f = x*(x+1)
sage: f.xgcd(x+1)(x + 1, 0, 1)
sage: f.xgcd(x^2)(x, 1, 6)>>> from sage.all import *>>> P = GF(Integer(7))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.xgcd(x+Integer(1))(x + 1, 0, 1)>>> f.xgcd(x**Integer(2))(x, 1, 6)

sage.rings.polynomial.polynomial_gf2x.make_element(parent, args)

2.1. Univariate Polynomials and Polynomial Rings

229

Polynomials, Release 10.4

2.1.6 Univariate polynomials over number fields
AUTHOR:• Luis Felipe Tabera Alonso (2014-02): initial version.
EXAMPLES:
Define a polynomial over an absolute number field and perform basic operations with them:sage: x = polygen(ZZ, x )sage: N.<a> = NumberField(x^2 - 2)sage: K.<x> = N[]
sage: f = x - asage: g = x^3 - 2*a + 1
sage: f * (x + a)x^2 - 2sage: f + g
x^3 + x - 3*a + 1
sage: g // fx^2 + a*x + 2
sage: g % f
1
sage: factor(x^3 - 2*a*x^2 - 2*x + 4*a)(x - 2*a) * (x - a) * (x + a)
sage: gcd(f, x - a)x - a>>> from sage.all import *>>> x = polygen(ZZ, x )>>> N = NumberField(x**Integer(2) - Integer(2), names=( a ,)); (a,) = N._first_
˓→ngens(1)>>> K = N[ x ]; (x,) = K._first_ngens(1)>>> f = x - a>>> g = x**Integer(3) - Integer(2)*a + Integer(1)>>> f * (x + a)x^2 - 2>>> f + gx^3 + x - 3*a + 1>>> g // fx^2 + a*x + 2>>> g % f
1>>> factor(x**Integer(3) - Integer(2)*a*x**Integer(2) - Integer(2)*x + Integer(4)*a)(x - 2*a) * (x - a) * (x + a)>>> gcd(f, x - a)x - aPolynomials are aware of embeddings of the underlying field:
sage: # needs sage.rings.padics
sage: x = polygen(ZZ, x )sage: Q7 = Qp(7)sage: r1 = Q7(3 + 7 + 2*7^2 + 6*7^3 + 7^4 + 2*7^5 + 7^6 + 2*7^7 + 4*7^8....:+ 6*7^9 + 6*7^10 + 2*7^11 + 7^12 + 7^13 + 2*7^15 + 7^16 + 7^17....:
+ 4*7^18 + 6*7^19)
sage: N.<b> = NumberField(x^2 - 2, embedding=r1)
sage: K.<t> = N[](continues on next page)

230

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = t^3 - 2*t + 1
sage: f(r1)
1 + O(7^20)>>> from sage.all import *>>> # needs sage.rings.padics>>> x = polygen(ZZ, x )>>> Q7 = Qp(Integer(7))>>> r1 = Q7(Integer(3) + Integer(7) + Integer(2)*Integer(7)**Integer(2) +␣˓→Integer(6)*Integer(7)**Integer(3) + Integer(7)**Integer(4) +␣˓→Integer(2)*Integer(7)**Integer(5) + Integer(7)**Integer(6) +␣˓→Integer(2)*Integer(7)**Integer(7) + Integer(4)*Integer(7)**Integer(8)...
+ Integer(6)*Integer(7)**Integer(9) + Integer(6)*Integer(7)**Integer(10)␣
˓→+ Integer(2)*Integer(7)**Integer(11) + Integer(7)**Integer(12) +␣˓→Integer(7)**Integer(13) + Integer(2)*Integer(7)**Integer(15) +␣˓→Integer(7)**Integer(16) + Integer(7)**Integer(17)...
+ Integer(4)*Integer(7)**Integer(18) +␣˓→Integer(6)*Integer(7)**Integer(19))>>> N = NumberField(x**Integer(2) - Integer(2), embedding=r1, names=( b ,)); (b,) = N.
˓→_first_ngens(1)>>> K = N[ t ]; (t,) = K._first_ngens(1)>>> f = t**Integer(3) - Integer(2)*t + Integer(1)>>> f(r1)
1 + O(7^20)

We can also construct polynomials over relative number fields:
sage: # needs sage.symbolic
sage: N.<i, s2> = QQ[I, sqrt(2)]sage: K.<x> = N[]
sage: f = x - s2sage: g = x^3 - 2*i*x^2 + s2*x
sage: f * (x + s2)x^2 - 2sage: f + g
x^3 - 2*I*x^2 + (sqrt2 + 1)*x - sqrt2
sage: g // fx^2 + (-2*I + sqrt2)*x - 2*sqrt2*I + sqrt2 + 2
sage: g % f-4*I + 2*sqrt2 + 2
sage: factor(i*x^4 - 2*i*x^2 + 9*i)(I) * (x - I + sqrt2) * (x + I - sqrt2) * (x - I - sqrt2) * (x + I + sqrt2)
sage: gcd(f, x - i)1>>> from sage.all import *>>> # needs sage.symbolic>>> N = QQ[I, sqrt(Integer(2))]; (i, s2,) = N._first_ngens(2)>>> K = N[ x ]; (x,) = K._first_ngens(1)>>> f = x - s2>>> g = x**Integer(3) - Integer(2)*i*x**Integer(2) + s2*x>>> f * (x + s2)x^2 - 2>>> f + gx^3 - 2*I*x^2 + (sqrt2 + 1)*x - sqrt2>>> g // f(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

231

Polynomials, Release 10.4

(continued from previous page)x^2 + (-2*I + sqrt2)*x - 2*sqrt2*I + sqrt2 + 2>>> g % f
-4*I + 2*sqrt2 + 2>>> factor(i*x**Integer(4) - Integer(2)*i*x**Integer(2) + Integer(9)*i)(I) * (x - I + sqrt2) * (x + I - sqrt2) * (x - I - sqrt2) * (x + I + sqrt2)>>> gcd(f, x - i)
1class sage.rings.polynomial.polynomial_number_field.Polynomial_absolute_number_field_dense(

Bases: Polynomial_generic_dense_field
Class of dense univariate polynomials over an absolute number field.
gcd(other)Compute the monic gcd of two univariate polynomials using PARI.
INPUT:• other – a polynomial with the same parent as self.
OUTPUT: The monic gcd of self and other.
EXAMPLES:
sage: x = polygen(ZZ, x )sage: N.<a> = NumberField(x^3 - 1/2, a )sage: R.<r> = N[ r ]sage: f = (5/4*a^2 - 2*a + 4)*r^2 + (5*a^2 - 81/5*a - 17/2)*r + 4/5*a^2 +␣
˓→24*a + 6
sage: g = (5/4*a^2 - 2*a + 4)*r^2 + (-11*a^2 + 79/5*a - 7/2)*r - 4/5*a^2 -␣
˓→24*a - 6
sage: gcd(f, g**2)
r - 60808/96625*a^2 - 69936/96625*a - 149212/96625
sage: R = QQ[I][ x ]sage: f = R.random_element(2)sage: g = f + 1
sage: h = R.random_element(2).monic()
sage: f *= hsage: g *= hsage: gcd(f, g) - h
0sage: f.gcd(g) - h
0>>> from sage.all import *>>> x = polygen(ZZ, x )>>> N = NumberField(x**Integer(3) - Integer(1)/Integer(2), a , names=( a ,));
˓→ (a,) = N._first_ngens(1)>>> R = N[ r ]; (r,) = R._first_ngens(1)>>> f = (Integer(5)/Integer(4)*a**Integer(2) - Integer(2)*a +␣˓→Integer(4))*r**Integer(2) + (Integer(5)*a**Integer(2) - Integer(81)/(continues on next page)

232

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(5)*a - Integer(17)/Integer(2))*r + Integer(4)/˓→Integer(5)*a**Integer(2) + Integer(24)*a + Integer(6)>>> g = (Integer(5)/Integer(4)*a**Integer(2) - Integer(2)*a +␣˓→Integer(4))*r**Integer(2) + (-Integer(11)*a**Integer(2) + Integer(79)/
˓→Integer(5)*a - Integer(7)/Integer(2))*r - Integer(4)/˓→Integer(5)*a**Integer(2) - Integer(24)*a - Integer(6)>>> gcd(f, g**Integer(2))
r - 60808/96625*a^2 - 69936/96625*a - 149212/96625>>> R = QQ[I][ x ]>>> f = R.random_element(Integer(2))>>> g = f + Integer(1)>>> h = R.random_element(Integer(2)).monic()>>> f *= h>>> g *= h>>> gcd(f, g) - h
0>>> f.gcd(g) - h0˓→class sage.rings.polynomial.polynomial_number_field.Polynomial_relative_number_field_dense(

Bases: Polynomial_generic_dense_field
Class of dense univariate polynomials over a relative number field.
gcd(other)Compute the monic gcd of two polynomials.
Currently, the method checks corner cases in which one of the polynomials is zero or a constant. Then,computes an absolute extension and performs the computations there.
INPUT:• other – a polynomial with the same parent as self.
OUTPUT:
The monic gcd of self and other.
See Polynomial_absolute_number_field_dense.gcd() for more details.
EXAMPLES:
sage: # needs sage.symbolic
sage: N = QQ[sqrt(2), sqrt(3)]sage: s2, s3 = N.gens()
sage: x = polygen(N)sage: f = x^4 - 5*x^2 + 6
sage: g = x^3 + (-2*s2 + s3)*x^2 + (-2*s3*s2 + 2)*x + 2*s3
sage: gcd(f, g)
x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2
sage: f.gcd(g)x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2

2.1. Univariate Polynomials and Polynomial Rings

233

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.symbolic>>> N = QQ[sqrt(Integer(2)), sqrt(Integer(3))]>>> s2, s3 = N.gens()>>> x = polygen(N)>>> f = x**Integer(4) - Integer(5)*x**Integer(2) + Integer(6)>>> g = x**Integer(3) + (-Integer(2)*s2 + s3)*x**Integer(2) + (˓→Integer(2)*s3*s2 + Integer(2))*x + Integer(2)*s3>>> gcd(f, g)
x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2>>> f.gcd(g)x^2 + (-sqrt2 + sqrt3)*x - sqrt3*sqrt2

2.1.7 Dense univariate polynomials over Z, implemented using FLINTAUTHORS:• David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx (2007-09); a lot of this was based on Joel
Mohler’s recent rewrite of the NTL wrapper• David Harvey: split off from polynomial_element_generic.py (2007-09)• Burcin Erocal: rewrote to use FLINT (2008-06-16)
class sage.rings.polynomial.polynomial_integer_dense_flint.
Polynomial_integer_dense_flint
Bases: Polynomial
A dense polynomial over the integers, implemented via FLINT.
_add_(right)
Return self plus right.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = 2*x + 1
sage: g = -3*x^2 + 6
sage: f + g-3*x^2 + 2*x + 7>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(2)*x + Integer(1)>>> g = -Integer(3)*x**Integer(2) + Integer(6)>>> f + g
-3*x^2 + 2*x + 7_sub_(right)
Return self minus right.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = 2*x + 1
sage: g = -3*x^2 + 6(continues on next page)

234

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f - g
3*x^2 + 2*x - 5>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(2)*x + Integer(1)>>> g = -Integer(3)*x**Integer(2) + Integer(6)>>> f - g
3*x^2 + 2*x - 5_lmul_(right)
Return self multiplied by right, where right is a scalar (integer).
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: x*3
3*x
sage: (2*x^2 + 4)*3
6*x^2 + 12>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> x*Integer(3)3*x>>> (Integer(2)*x**Integer(2) + Integer(4))*Integer(3)6*x^2 + 12

_rmul_(right)
Return self multiplied by right, where right is a scalar (integer).
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: 3*x
3*x
sage: 3*(2*x^2 + 4)
6*x^2 + 12>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> Integer(3)*x
3*x>>> Integer(3)*(Integer(2)*x**Integer(2) + Integer(4))
6*x^2 + 12

_mul_(right)
Return self multiplied by right.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: (x - 2)*(x^2 - 8*x + 16)
x^3 - 10*x^2 + 32*x - 32

2.1. Univariate Polynomials and Polynomial Rings

235

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> (x - Integer(2))*(x**Integer(2) - Integer(8)*x + Integer(16))
x^3 - 10*x^2 + 32*x - 32

_mul_trunc_(right, n)
Truncated multiplication
See also:_mul_() for standard multiplication
EXAMPLES:
sage: x = polygen(ZZ)
sage: p1 = 1 + x + x^2 + x^4
sage: p2 = -2 + 3*x^2 + 5*x^4sage: p1._mul_trunc_(p2, 4)
3*x^3 + x^2 - 2*x - 2
sage: (p1*p2).truncate(4)3*x^3 + x^2 - 2*x - 2
sage: p1._mul_trunc_(p2, 6)
5*x^5 + 6*x^4 + 3*x^3 + x^2 - 2*x - 2>>> from sage.all import *>>> x = polygen(ZZ)>>> p1 = Integer(1) + x + x**Integer(2) + x**Integer(4)>>> p2 = -Integer(2) + Integer(3)*x**Integer(2) + Integer(5)*x**Integer(4)>>> p1._mul_trunc_(p2, Integer(4))
3*x^3 + x^2 - 2*x - 2>>> (p1*p2).truncate(Integer(4))
3*x^3 + x^2 - 2*x - 2>>> p1._mul_trunc_(p2, Integer(6))
5*x^5 + 6*x^4 + 3*x^3 + x^2 - 2*x - 2

content()
Return the greatest common divisor of the coefficients of this polynomial. The sign is the sign of the leading
coefficient. The content of the zero polynomial is zero.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: (2*x^2 - 4*x^4 + 14*x^7).content()2
sage: x.content()
1
sage: R(1).content()
1
sage: R(0).content()0>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> (Integer(2)*x**Integer(2) - Integer(4)*x**Integer(4) +␣˓→Integer(14)*x**Integer(7)).content()2>>> x.content()(continues on next page)

236

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)1>>> R(Integer(1)).content()
1>>> R(Integer(0)).content()0

degree(gen=None)
Return the degree of this polynomial.
The zero polynomial has degree −1.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: x.degree()1
sage: (x^2).degree()2
sage: R(1).degree()0
sage: R(0).degree()-1>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> x.degree()1>>> (x**Integer(2)).degree()2>>> R(Integer(1)).degree()0>>> R(Integer(0)).degree()-1

disc(proof=True)
Return the discriminant of self, which is by definition(−1)𝑚(𝑚−1)/2 resultant(𝑎, 𝑎′ )/ lc(𝑎),where 𝑚 = deg(𝑎), and lc(𝑎) is the leading coefficient of a. If proof is False (the default is True), then thisfunction may use a randomized strategy that errors with probability no more than 2−80 .
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = 3*x^3 + 2*x + 1
sage: f.discriminant()-339
sage: f.discriminant(proof=False)-339>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(3)*x**Integer(3) + Integer(2)*x + Integer(1)>>> f.discriminant()-339(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

237

Polynomials, Release 10.4

(continued from previous page)>>> f.discriminant(proof=False)-339

discriminant(proof=True)
Return the discriminant of self, which is by definition(−1)𝑚(𝑚−1)/2 resultant(𝑎, 𝑎′ )/ lc(𝑎),where 𝑚 = deg(𝑎), and lc(𝑎) is the leading coefficient of a. If proof is False (the default is True), then thisfunction may use a randomized strategy that errors with probability no more than 2−80 .
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = 3*x^3 + 2*x + 1
sage: f.discriminant()-339
sage: f.discriminant(proof=False)-339>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(3)*x**Integer(3) + Integer(2)*x + Integer(1)>>> f.discriminant()-339>>> f.discriminant(proof=False)-339

factor()This function overrides the generic polynomial factorization to make a somewhat intelligent decision to use
PARI or NTL based on some benchmarking.
Note: This function factors the content of the polynomial, which can take very long if it’s a really big integer.
If you do not need the content factored, divide it out of your polynomial before calling this function.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^4 - 1
sage: f.factor()(x - 1) * (x + 1) * (x^2 + 1)
sage: f = 1 - x
sage: f.factor()(-1) * (x - 1)sage: f.factor().unit()-1sage: f = -30*x; f.factor()(-1) * 2 * 3 * 5 * x>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) - Integer(1)>>> f.factor()(x - 1) * (x + 1) * (x^2 + 1)>>> f = Integer(1) - x>>> f.factor()(continues on next page)

238

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(-1) * (x - 1)>>> f.factor().unit()-1>>> f = -Integer(30)*x; f.factor()(-1) * 2 * 3 * 5 * x

factor_mod(p)Return the factorization of self modulo the prime 𝑝.
INPUT:• p – prime
OUTPUT: factorization of self reduced modulo 𝑝.
EXAMPLES:
sage: R.<x> = ZZ[ x ]sage: f = -3*x*(x-2)*(x-9) + x
sage: f.factor_mod(3)xsage: f = -3 * x * (x - 2) * (x - 9)sage: f.factor_mod(3)Traceback (most recent call last):...
ArithmeticError: factorization of 0 is not defined
sage: f = 2 * x * (x - 2) * (x - 9)sage: f.factor_mod(7)(2) * x * (x + 5)^2>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = -Integer(3)*x*(x-Integer(2))*(x-Integer(9)) + x>>> f.factor_mod(Integer(3))
x>>> f = -Integer(3) * x * (x - Integer(2)) * (x - Integer(9))>>> f.factor_mod(Integer(3))
Traceback (most recent call last):...
ArithmeticError: factorization of 0 is not defined>>> f = Integer(2) * x * (x - Integer(2)) * (x - Integer(9))>>> f.factor_mod(Integer(7))(2) * x * (x + 5)^2

factor_padic(p, prec=10)Return 𝑝-adic factorization of self to given precision.
INPUT:• p – prime• prec – integer; the precision
OUTPUT: factorization of self over the completion at 𝑝.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

239

Polynomials, Release 10.4

sage: R.<x> = PolynomialRing(ZZ)
sage: f = x^2 + 1
sage: f.factor_padic(5, 4)((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> f.factor_padic(Integer(5), Integer(4))((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))

A more difficult example:
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
sage: f.factor_padic(5, 10)(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2* ((5 + O(5^10))*x + 1 + O(5^10))^2>>> from sage.all import *>>> f = Integer(100) * (Integer(5)*x + Integer(1))**Integer(2) * (x +␣˓→Integer(5))**Integer(2)>>> f.factor_padic(Integer(5), Integer(10))(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2* ((5 + O(5^10))*x + 1 + O(5^10))^2

gcd(right)
Return the GCD of self and right. The leading coefficient need not be 1.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
sage: f.gcd(g)6*x + 47>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38))>>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) +␣˓→Integer(2)*x + Integer(1))>>> f.gcd(g)6*x + 47

inverse_series_trunc(prec)
Return a polynomial approximation of precision prec of the inverse series of this polynomial.
EXAMPLES:
sage: x = polygen(ZZ)
sage: p = 1 + x + 2*x^2sage: q5 = p.inverse_series_trunc(5)sage: q5
(continues on next page)

240

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)-x^4 + 3*x^3 - x^2 - x + 1
sage: p*q5
-2*x^6 + 5*x^5 + 1
sage: (x-1).inverse_series_trunc(5)-x^4 - x^3 - x^2 - x - 1
sage: q100 = p.inverse_series_trunc(100)sage: (q100 * p).truncate(100)1>>> from sage.all import *>>> x = polygen(ZZ)>>> p = Integer(1) + x + Integer(2)*x**Integer(2)>>> q5 = p.inverse_series_trunc(Integer(5))>>> q5-x^4 + 3*x^3 - x^2 - x + 1>>> p*q5-2*x^6 + 5*x^5 + 1>>> (x-Integer(1)).inverse_series_trunc(Integer(5))-x^4 - x^3 - x^2 - x - 1>>> q100 = p.inverse_series_trunc(Integer(100))>>> (q100 * p).truncate(Integer(100))1

is_one()Return True if self is equal to one.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R(0).is_one()False
sage: R(1).is_one()True
sage: x.is_one()
False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(0)).is_one()
False>>> R(Integer(1)).is_one()True>>> x.is_one()
False

is_zero()Return True if self is equal to zero.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R(0).is_zero()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

241

Polynomials, Release 10.4

(continued from previous page)True
sage: R(1).is_zero()False
sage: x.is_zero()
False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R(Integer(0)).is_zero()
True>>> R(Integer(1)).is_zero()False>>> x.is_zero()
False

lcm(right)
Return the LCM of self and right.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
sage: h = f.lcm(g); h
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786
sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1)
True>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38))>>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) +␣˓→Integer(2)*x + Integer(1))>>> h = f.lcm(g); h
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786>>> h == (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38)) * (Integer(3)*x**Integer(3) + Integer(2)*x +␣˓→Integer(1))
Truelist(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: x = PolynomialRing(ZZ, x ).0
sage: f = x^3 + 3*x - 17sage: f.list()[-17, 3, 0, 1]
sage: f = PolynomialRing(ZZ, x )(0)sage: f.list()[]>>> from sage.all import *>>> x = PolynomialRing(ZZ, x ).gen(0)(continues on next page)242

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = x**Integer(3) + Integer(3)*x - Integer(17)>>> f.list()[-17, 3, 0, 1]>>> f = PolynomialRing(ZZ, x )(Integer(0))>>> f.list()[]

pseudo_divrem(B)Write A = self. This function computes polynomials 𝑄 and 𝑅 and an integer 𝑑 such thatlead(𝐵)𝑑 𝐴 = 𝐵𝑄 + 𝑅
where R has degree less than that of B.
INPUT:• B – a polynomial over Z
OUTPUT:• Q, R – polynomials• d – nonnegative integer
EXAMPLES:
sage: R.<x> = ZZ[ x ]sage: A = R(range(10))
sage: B = 3*R([-1, 0, 1])
sage: Q, R, d = A.pseudo_divrem(B)sage: Q, R, d
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 75*x + 60, 1)
sage: B.leading_coefficient()^d * A == B*Q + R
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> A = R(range(Integer(10)))>>> B = Integer(3)*R([-Integer(1), Integer(0), Integer(1)])>>> Q, R, d = A.pseudo_divrem(B)>>> Q, R, d
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 75*x + 60, 1)>>> B.leading_coefficient()**d * A == B*Q + R
True

quo_rem(right)
Attempts to divide self by right, and return a quotient and remainder.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = R(range(10)); g = R([-1, 0, 1])
sage: q, r = f.quo_rem(g)sage: q, r
(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)
sage: q*g + r == f
True(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

243

Polynomials, Release 10.4

(continued from previous page)

sage: f = x^2
sage: f.quo_rem(0)Traceback (most recent call last):...
ZeroDivisionError: division by zero polynomial
sage: f = (x^2 + 3) * (2*x - 1)sage: f.quo_rem(2*x - 1)(x^2 + 3, 0)
sage: f = x^2
sage: f.quo_rem(2*x - 1)
(0, x^2)>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = R(range(Integer(10))); g = R([-Integer(1), Integer(0), Integer(1)])>>> q, r = f.quo_rem(g)>>> q, r(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)>>> q*g + r == f
True>>> f = x**Integer(2)>>> f.quo_rem(Integer(0))
Traceback (most recent call last):...
ZeroDivisionError: division by zero polynomial>>> f = (x**Integer(2) + Integer(3)) * (Integer(2)*x - Integer(1))>>> f.quo_rem(Integer(2)*x - Integer(1))(x^2 + 3, 0)>>> f = x**Integer(2)>>> f.quo_rem(Integer(2)*x - Integer(1))(0, x^2)

real_root_intervals()
Return isolating intervals for the real roots of this polynomial.
EXAMPLES: We compute the roots of the characteristic polynomial of some Salem numbers:
sage: R.<x> = PolynomialRing(ZZ)
sage: f = 1 - x^2 - x^3 - x^4 + x^6
sage: f.real_root_intervals()
˓→needs sage.libs.linbox[((1/2, 3/4), 1), ((1, 3/2), 1)]#␣>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1) - x**Integer(2) - x**Integer(3) - x**Integer(4) +␣˓→x**Integer(6)>>> f.real_root_intervals()
˓→needs sage.libs.linbox[((1/2, 3/4), 1), ((1, 3/2), 1)]#␣resultant(other, proof=True)
244

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Return the resultant of self and other, which must lie in the same polynomial ring.
If proof=False (the default is proof=True), then this function may use a randomized strategy thaterrors with probability no more than 2−80 .
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: x = PolynomialRing(ZZ, x ).0
sage: f = x^3 + x + 1; g = x^3 - x - 1
sage: r = f.resultant(g); r-8
sage: r.parent() is ZZ
True>>> from sage.all import *>>> x = PolynomialRing(ZZ, x ).gen(0)>>> f = x**Integer(3) + x + Integer(1);>>> r = f.resultant(g); r-8>>> r.parent() is ZZ
True

g = x**Integer(3) - x - Integer(1)reverse(degree=None)
Return a polynomial with the coefficients of this polynomial reversed.
If an optional degree argument is given the coefficient list will be truncated or zero padded as necessary before
computing the reverse.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: p = R([1,2,3,4]); p4*x^3 + 3*x^2 + 2*x + 1
sage: p.reverse()x^3 + 2*x^2 + 3*x + 4
sage: p.reverse(degree=6)x^6 + 2*x^5 + 3*x^4 + 4*x^3sage: p.reverse(degree=2)x^2 + 2*x + 3>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> p = R([Integer(1),Integer(2),Integer(3),Integer(4)]); p4*x^3 + 3*x^2 + 2*x + 1>>> p.reverse()x^3 + 2*x^2 + 3*x + 4>>> p.reverse(degree=Integer(6))
x^6 + 2*x^5 + 3*x^4 + 4*x^3>>> p.reverse(degree=Integer(2))
x^2 + 2*x + 3

revert_series(n)Return a polynomial 𝑓 such that 𝑓 ( self (𝑥)) = self (𝑓 (𝑥)) = 𝑥 (mod 𝑥𝑛 ).
2.1. Univariate Polynomials and Polynomial Rings

245

Polynomials, Release 10.4

EXAMPLES:
sage: R.<t> = ZZ[]
sage: f = t - t^3 + t^5
sage: f.revert_series(6)2*t^5 + t^3 + t
sage: f.revert_series(-1)
Traceback (most recent call last):...
ValueError: argument n must be a non-negative integer, got -1
sage: g = - t^3 + t^5
sage: g.revert_series(6)Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1>>> from sage.all import *>>> R = ZZ[ t ]; (t,) = R._first_ngens(1)>>> f = t - t**Integer(3) + t**Integer(5)>>> f.revert_series(Integer(6))
2*t^5 + t^3 + t>>> f.revert_series(-Integer(1))
Traceback (most recent call last):...
ValueError: argument n must be a non-negative integer, got -1>>> g = - t**Integer(3) + t**Integer(5)>>> g.revert_series(Integer(6))
Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1

squarefree_decomposition()
Return the square-free decomposition of self. This is a partial factorization of self into square-free,relatively prime polynomials.
This is a wrapper for the NTL function SquareFreeDecomp.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: p = (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
sage: p.squarefree_decomposition()(x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3
sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
sage: p.squarefree_decomposition()(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> p = (x-Integer(1))**Integer(2) * (x-Integer(2))**Integer(2) * (x˓→Integer(3))**Integer(3) * (x-Integer(4))>>> p.squarefree_decomposition()(continues on next page)

246

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3>>> p = Integer(37) * (x-Integer(1))**Integer(2) * (x-Integer(2))**Integer(2)␣
˓→* (x-Integer(3))**Integer(3) * (x-Integer(4))>>> p.squarefree_decomposition()(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3

xgcd(right)
Return a triple (𝑔, 𝑠, 𝑡) such that 𝑔 = 𝑠 · self + 𝑡 · right and such that 𝑔 is the gcd of self and rightup to a divisor of the resultant of self and other.
As integer polynomials do not form a principal ideal domain, it is not always possible given 𝑎 and 𝑏 to find apair 𝑠, 𝑡 such that 𝑔𝑐𝑑(𝑎, 𝑏) = 𝑠𝑎 + 𝑡𝑏. Take 𝑎 = 𝑥 + 2 and 𝑏 = 𝑥 + 4 as an example for which the gcd is 1
but the best you can achieve in the Bezout identity is 2.
If self and right are coprime as polynomials over the rationals, then g is guaranteed to be the resultant
of self and right, as a constant polynomial.
EXAMPLES:
sage: P.<x> = PolynomialRing(ZZ)
sage: (x + 2).xgcd(x + 4)
(2, -1, 1)
sage: (x + 2).resultant(x + 4)
2
sage: (x + 2).gcd(x + 4)
1
sage: F = (x^2 + 2)*x^3; G = (x^2 + 2) * (x - 3)sage: g, u, v = F.xgcd(G)sage: g, u, v
(27*x^2 + 54, 1, -x^2 - 3*x - 9)sage: u*F + v*G
27*x^2 + 54
sage: zero = P(0)sage: x.xgcd(zero)(x, 1, 0)
sage: zero.xgcd(x)(x, 0, 1)
sage: F = (x - 3)^3; G = (x - 15)^2
sage: g, u, v = F.xgcd(G)sage: g, u, v
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)
sage: u*F + v*G2985984>>> from sage.all import *>>> P = PolynomialRing(ZZ, names=( x ,)); (x,) = P._first_ngens(1)>>> (x + Integer(2)).xgcd(x + Integer(4))(2, -1, 1)>>> (x + Integer(2)).resultant(x + Integer(4))
2>>> (x + Integer(2)).gcd(x + Integer(4))
1(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

247

Polynomials, Release 10.4

(continued from previous page)>>> F = (x**Integer(2) + Integer(2))*x**Integer(3); G = (x**Integer(2) +␣˓→Integer(2)) * (x - Integer(3))>>> g, u, v = F.xgcd(G)>>> g, u, v
(27*x^2 + 54, 1, -x^2 - 3*x - 9)>>> u*F + v*G
27*x^2 + 54>>> zero = P(Integer(0))>>> x.xgcd(zero)(x, 1, 0)>>> zero.xgcd(x)(x, 0, 1)>>> F = (x - Integer(3))**Integer(3); G = (x - Integer(15))**Integer(2)>>> g, u, v = F.xgcd(G)>>> g, u, v
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)>>> u*F + v*G2985984

2.1.8 Dense univariate polynomials over Z, implemented using NTL.
AUTHORS:• David Harvey: split off from polynomial_element_generic.py (2007-09)• David Harvey: rewrote to talk to NTL directly, instead of via ntl.pyx (2007-09); a lot of this was based on Joel
Mohler’s recent rewrite of the NTL wrapper
Sage includes two implementations of dense univariate polynomials over Z; this file contains the implementation based on NTL, but there is also an implementation based on FLINT in sage.rings.polynomial.
polynomial_integer_dense_flint.
The FLINT implementation is preferred (FLINT’s arithmetic operations are generally faster), so it is the default; to use
the NTL implementation, you can do:sage: K.<x> = PolynomialRing(ZZ, implementation= NTL )sage: K
Univariate Polynomial Ring in x over Integer Ring (using NTL)>>> from sage.all import *>>> K = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = K._first_
˓→ngens(1)>>> K
Univariate Polynomial Ring in x over Integer Ring (using NTL)

class sage.rings.polynomial.polynomial_integer_dense_ntl.
Polynomial_integer_dense_ntl
Bases: Polynomial
A dense polynomial over the integers, implemented via NTL.

248

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

content()
Return the greatest common divisor of the coefficients of this polynomial. The sign is the sign of the leading
coefficient. The content of the zero polynomial is zero.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: (2*x^2 - 4*x^4 + 14*x^7).content()2
sage: (2*x^2 - 4*x^4 - 14*x^7).content()-2
sage: x.content()
1
sage: R(1).content()
1
sage: R(0).content()0>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> (Integer(2)*x**Integer(2) - Integer(4)*x**Integer(4) +␣˓→Integer(14)*x**Integer(7)).content()2>>> (Integer(2)*x**Integer(2) - Integer(4)*x**Integer(4) -␣˓→Integer(14)*x**Integer(7)).content()-2>>> x.content()
1>>> R(Integer(1)).content()
1>>> R(Integer(0)).content()0

degree(gen=None)
Return the degree of this polynomial. The zero polynomial has degree −1.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: x.degree()1
sage: (x^2).degree()2
sage: R(1).degree()0
sage: R(0).degree()-1>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> x.degree()1>>> (x**Integer(2)).degree()2>>> R(Integer(1)).degree()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

249

Polynomials, Release 10.4

(continued from previous page)0>>> R(Integer(0)).degree()-1

discriminant(proof=True)
Return the discriminant of self, which is by definition(−1)𝑚(𝑚−1)/2 resultant(𝑎, 𝑎′ )/𝑙𝑐(𝑎),where 𝑚 = 𝑑𝑒𝑔(𝑎), and 𝑙𝑐(𝑎) is the leading coefficient of a. If proof is False (the default is True), thenthis function may use a randomized strategy that errors with probability no more than 2−80 .
EXAMPLES:
sage: f = ntl.ZZX([1,2,0,3])
sage: f.discriminant()-339
sage: f.discriminant(proof=False)-339>>> from sage.all import *>>> f = ntl.ZZX([Integer(1),Integer(2),Integer(0),Integer(3)])>>> f.discriminant()-339>>> f.discriminant(proof=False)-339

factor()This function overrides the generic polynomial factorization to make a somewhat intelligent decision to use
PARI or NTL based on some benchmarking.
Note: This function factors the content of the polynomial, which can take very long if it’s a really big integer.
If you do not need the content factored, divide it out of your polynomial before calling this function.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = x^4 - 1
sage: f.factor()(x - 1) * (x + 1) * (x^2 + 1)
sage: f = 1 - x
sage: f.factor()(-1) * (x - 1)sage: f.factor().unit()-1sage: f = -30*x; f.factor()(-1) * 2 * 3 * 5 * x>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) - Integer(1)>>> f.factor()(x - 1) * (x + 1) * (x^2 + 1)>>> f = Integer(1) - x>>> f.factor()(-1) * (x - 1)(continues on next page)

250

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f.factor().unit()-1>>> f = -Integer(30)*x; f.factor()(-1) * 2 * 3 * 5 * x

factor_mod(p)Return the factorization of self modulo the prime 𝑝.
INPUT:• p – prime
OUTPUT: factorization of self reduced modulo 𝑝.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, x , implementation= NTL )sage: f = -3*x*(x-2)*(x-9) + x
sage: f.factor_mod(3)xsage: f = -3*x*(x-2)*(x-9)
sage: f.factor_mod(3)Traceback (most recent call last):...
ArithmeticError: factorization of 0 is not defined
sage: f = 2*x*(x-2)*(x-9)
sage: f.factor_mod(7)(2) * x * (x + 5)^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, x , implementation= NTL , names=( x ,)); (x,) = R.
˓→_first_ngens(1)>>> f = -Integer(3)*x*(x-Integer(2))*(x-Integer(9)) + x>>> f.factor_mod(Integer(3))
x>>> f = -Integer(3)*x*(x-Integer(2))*(x-Integer(9))>>> f.factor_mod(Integer(3))
Traceback (most recent call last):...
ArithmeticError: factorization of 0 is not defined>>> f = Integer(2)*x*(x-Integer(2))*(x-Integer(9))>>> f.factor_mod(Integer(7))(2) * x * (x + 5)^2

factor_padic(p, prec=10)Return 𝑝-adic factorization of self to given precision.
INPUT:• p – prime• prec – integer; the precision
OUTPUT:• factorization of self over the completion at 𝑝.
EXAMPLES:
2.1. Univariate Polynomials and Polynomial Rings

251

Polynomials, Release 10.4

sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: f = x^2 + 1
sage: f.factor_padic(5, 4)((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> f.factor_padic(Integer(5), Integer(4))((1 + O(5^4))*x + 2 + 5 + 2*5^2 + 5^3 + O(5^4))* ((1 + O(5^4))*x + 3 + 3*5 + 2*5^2 + 3*5^3 + O(5^4))

A more difficult example:
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
sage: f.factor_padic(5, 10)(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2* ((5 + O(5^10))*x + 1 + O(5^10))^2>>> from sage.all import *>>> f = Integer(100) * (Integer(5)*x + Integer(1))**Integer(2) * (x +␣˓→Integer(5))**Integer(2)>>> f.factor_padic(Integer(5), Integer(10))(4 + O(5^10)) * (5 + O(5^11))^2 * ((1 + O(5^10))*x + 5 + O(5^10))^2* ((5 + O(5^10))*x + 1 + O(5^10))^2

gcd(right)
Return the GCD of self and right. The leading coefficient need not be 1.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)
sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
sage: f.gcd(g)6*x + 47>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38))>>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) +␣˓→Integer(2)*x + Integer(1))>>> f.gcd(g)6*x + 47lcm(right)
Return the LCM of self and right.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: f = (6*x + 47) * (7*x^2 - 2*x + 38)(continues on next page)

252

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: g = (6*x + 47) * (3*x^3 + 2*x + 1)
sage: h = f.lcm(g); h
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786
sage: h == (6*x + 47) * (7*x^2 - 2*x + 38) * (3*x^3 + 2*x + 1)
True>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38))>>> g = (Integer(6)*x + Integer(47)) * (Integer(3)*x**Integer(3) +␣˓→Integer(2)*x + Integer(1))>>> h = f.lcm(g); h
126*x^6 + 951*x^5 + 486*x^4 + 6034*x^3 + 585*x^2 + 3706*x + 1786>>> h == (Integer(6)*x + Integer(47)) * (Integer(7)*x**Integer(2) -␣˓→Integer(2)*x + Integer(38)) * (Integer(3)*x**Integer(3) + Integer(2)*x +␣˓→Integer(1))
Truelist(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: x = PolynomialRing(ZZ,
sage: f = x^3 + 3*x - 17sage: f.list()[-17, 3, 0, 1]
sage: f = PolynomialRing(ZZ,
sage: f.list()[]

x , implementation= NTL ).0

x , implementation= NTL )(0)>>> from sage.all import *>>> x = PolynomialRing(ZZ, x , implementation= NTL ).gen(0)>>> f = x**Integer(3) + Integer(3)*x - Integer(17)>>> f.list()[-17, 3, 0, 1]>>> f = PolynomialRing(ZZ, x , implementation= NTL )(Integer(0))>>> f.list()[]

quo_rem(right)
Attempt to divide self by right, and return a quotient and remainder.
If right is monic, then it returns (q, r) where self = q * right + r and deg(r) < deg(right).
If right is not monic, then it returns (𝑞, 0) where q = self/right if right exactly divides self,otherwise it raises an exception.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: f = R(range(10)); g = R([-1, 0, 1])
sage: q, r = f.quo_rem(g)sage: q, r
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

253

Polynomials, Release 10.4

(continued from previous page)(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)
sage: q*g + r == f
True
sage: 0//(2*x)
0sage: f = x^2
sage: f.quo_rem(0)Traceback (most recent call last):...
ArithmeticError: division by zero polynomial
sage: f = (x^2 + 3) * (2*x - 1)sage: f.quo_rem(2*x - 1)(x^2 + 3, 0)
sage: f = x^2
sage: f.quo_rem(2*x - 1)
Traceback (most recent call last):...
ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first)>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = R(range(Integer(10))); g = R([-Integer(1), Integer(0), Integer(1)])>>> q, r = f.quo_rem(g)>>> q, r(9*x^7 + 8*x^6 + 16*x^5 + 14*x^4 + 21*x^3 + 18*x^2 + 24*x + 20, 25*x + 20)>>> q*g + r == f
True>>> Integer(0)//(Integer(2)*x)0>>> f = x**Integer(2)>>> f.quo_rem(Integer(0))
Traceback (most recent call last):...
ArithmeticError: division by zero polynomial>>> f = (x**Integer(2) + Integer(3)) * (Integer(2)*x - Integer(1))>>> f.quo_rem(Integer(2)*x - Integer(1))(x^2 + 3, 0)>>> f = x**Integer(2)>>> f.quo_rem(Integer(2)*x - Integer(1))
Traceback (most recent call last):...
ArithmeticError: division not exact in Z[x] (consider coercing to Q[x] first)

real_root_intervals()
Returns isolating intervals for the real roots of this polynomial.
EXAMPLES: We compute the roots of the characteristic polynomial of some Salem numbers:

254

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: f = 1 - x^2 - x^3 - x^4 + x^6
sage: f.real_root_intervals()
˓→needs sage.libs.linbox[((1/2, 3/4), 1), ((1, 3/2), 1)]#␣>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = Integer(1) - x**Integer(2) - x**Integer(3) - x**Integer(4) +␣˓→x**Integer(6)>>> f.real_root_intervals()#␣˓→needs sage.libs.linbox[((1/2, 3/4), 1), ((1, 3/2), 1)]

resultant(other, proof=True)
Returns the resultant of self and other, which must lie in the same polynomial ring.
If proof=False (the default is proof=True), then this function may use a randomized strategy thaterrors with probability no more than 2−80 .
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: x = PolynomialRing(ZZ, x , implementation= NTL ).0
sage: f = x^3 + x + 1; g = x^3 - x - 1
sage: r = f.resultant(g); r-8
sage: r.parent() is ZZ
True>>> from sage.all import *>>> x = PolynomialRing(ZZ, x , implementation= NTL ).gen(0)>>> f = x**Integer(3) + x + Integer(1); g = x**Integer(3) - x - Integer(1)>>> r = f.resultant(g); r-8>>> r.parent() is ZZ
Truesquarefree_decomposition()
Return the square-free decomposition of self. This is a partial factorization of self into square-free,relatively prime polynomials.
This is a wrapper for the NTL function SquareFreeDecomp.
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ, implementation= NTL )sage: p = 37 * (x-1)^2 * (x-2)^2 * (x-3)^3 * (x-4)
sage: p.squarefree_decomposition()(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3

2.1. Univariate Polynomials and Polynomial Rings

255

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> p = Integer(37) * (x-Integer(1))**Integer(2) * (x-Integer(2))**Integer(2)␣
˓→* (x-Integer(3))**Integer(3) * (x-Integer(4))>>> p.squarefree_decomposition()(37) * (x - 4) * (x^2 - 3*x + 2)^2 * (x - 3)^3

xgcd(right)
This function can’t in general return (𝑔, 𝑠, 𝑡) as above, since they need not exist. Instead, over the integers,
we first multiply 𝑔 by a divisor of the resultant of 𝑎/𝑔 and 𝑏/𝑔, up to sign, and return g, u, v such that g= s*self + s*right. But note that this 𝑔 may be a multiple of the gcd.
If self and right are coprime as polynomials over the rationals, then g is guaranteed to be the resultant
of self and right, as a constant polynomial.
EXAMPLES:
sage: P.<x> = PolynomialRing(ZZ, implementation= NTL )sage: F = (x^2 + 2)*x^3; G = (x^2+2)*(x-3)
sage: g, u, v = F.xgcd(G)sage: g, u, v
(27*x^2 + 54, 1, -x^2 - 3*x - 9)sage: u*F + v*G
27*x^2 + 54
sage: x.xgcd(P(0))(x, 1, 0)
sage: f = P(0)sage: f.xgcd(x)(x, 0, 1)
sage: F = (x-3)^3; G = (x-15)^2
sage: g, u, v = F.xgcd(G)sage: g, u, v
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)
sage: u*F + v*G2985984>>> from sage.all import *>>> P = PolynomialRing(ZZ, implementation= NTL , names=( x ,)); (x,) = P._
˓→first_ngens(1)>>> F = (x**Integer(2) + Integer(2))*x**Integer(3); G =␣
˓→(x**Integer(2)+Integer(2))*(x-Integer(3))>>> g, u, v = F.xgcd(G)>>> g, u, v
(27*x^2 + 54, 1, -x^2 - 3*x - 9)>>> u*F + v*G
27*x^2 + 54>>> x.xgcd(P(Integer(0)))(x, 1, 0)>>> f = P(Integer(0))>>> f.xgcd(x)(x, 0, 1)>>> F = (x-Integer(3))**Integer(3); G = (x-Integer(15))**Integer(2)>>> g, u, v = F.xgcd(G)>>> g, u, v
(2985984, -432*x + 8208, 432*x^2 + 864*x + 14256)>>> u*F + v*G(continues on next page)

256

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)2985984

2.1.9 Univariate polynomials over

implemented via FLINTAUTHOR:• Sebastian Pancratz
classsage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
Bases: Polynomial
Univariate polynomials over the rationals, implemented via FLINT.
Internally, we represent rational polynomial as the quotient of an integer polynomial and a positive denominator
which is coprime to the content of the numerator.
_add_(right)
Return the sum of two rational polynomials.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 2/3 + t + 2*t^3sage: g = -1 + t/3 - 10/11*t^4
sage: f + g-10/11*t^4 + 2*t^3 + 4/3*t - 1/3>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(2)/Integer(3) + t + Integer(2)*t**Integer(3)>>> g = -Integer(1) + t/Integer(3) - Integer(10)/Integer(11)*t**Integer(4)>>> f + g
-10/11*t^4 + 2*t^3 + 4/3*t - 1/3_sub_(right)
Return the difference of two rational polynomials.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = -10/11*t^4 + 2*t^3 + 4/3*t - 1/3
sage: g = 2*t^3sage: f - g-10/11*t^4 + 4/3*t - 1/3# indirect doctest>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = -Integer(10)/Integer(11)*t**Integer(4) + Integer(2)*t**Integer(3) +␣˓→Integer(4)/Integer(3)*t - Integer(1)/Integer(3)>>> g = Integer(2)*t**Integer(3)>>> f - g
# indirect doctest-10/11*t^4 + 4/3*t - 1/3

2.1. Univariate Polynomials and Polynomial Rings

257

Polynomials, Release 10.4

_lmul_(right)
Return self * right, where right is a rational number.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 3/2*t^3 - t + 1/3
sage: f * 6
9*t^3 - 6*t + 2# indirect doctest>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(3)/Integer(2)*t**Integer(3) - t + Integer(1)/Integer(3)>>> f * Integer(6)# indirect doctest
9*t^3 - 6*t + 2_rmul_(left)
Return left * self, where left is a rational number.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 3/2*t^3 - t + 1/3
sage: 6 * f
9*t^3 - 6*t + 2# indirect doctest>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(3)/Integer(2)*t**Integer(3) - t + Integer(1)/Integer(3)>>> Integer(6) * f# indirect doctest
9*t^3 - 6*t + 2_mul_(right)
Return the product of self and right.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = -1 + 3*t/2 - t^3sage: g = 2/3 + 7/3*t + 3*t^2
sage: f * g# indirect doctest-3*t^5 - 7/3*t^4 + 23/6*t^3 + 1/2*t^2 - 4/3*t - 2/3>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = -Integer(1) + Integer(3)*t/Integer(2) - t**Integer(3)>>> g = Integer(2)/Integer(3) + Integer(7)/Integer(3)*t +␣˓→Integer(3)*t**Integer(2)>>> f * g
# indirect doctest-3*t^5 - 7/3*t^4 + 23/6*t^3 + 1/2*t^2 - 4/3*t - 2/3_mul_trunc_(right, n)
Truncated multiplication.
EXAMPLES:

258

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: x = polygen(QQ)
sage: p1 = 1/2 - 3*x + 2/7*x**3
sage: p2 = x + 2/5*x**5 + x**7
sage: p1._mul_trunc_(p2, 5)
2/7*x^4 - 3*x^2 + 1/2*x
sage: (p1*p2).truncate(5)2/7*x^4 - 3*x^2 + 1/2*x
sage: p1._mul_trunc_(p2, 1)
0
sage: p1._mul_trunc_(p2, 0)
Traceback (most recent call last):...
ValueError: n must be > 0>>> from sage.all import *>>> x = polygen(QQ)>>> p1 = Integer(1)/Integer(2) - Integer(3)*x + Integer(2)/˓→Integer(7)*x**Integer(3)>>> p2 = x + Integer(2)/Integer(5)*x**Integer(5) + x**Integer(7)>>> p1._mul_trunc_(p2, Integer(5))
2/7*x^4 - 3*x^2 + 1/2*x>>> (p1*p2).truncate(Integer(5))
2/7*x^4 - 3*x^2 + 1/2*x>>> p1._mul_trunc_(p2, Integer(1))
0>>> p1._mul_trunc_(p2, Integer(0))
Traceback (most recent call last):...
ValueError: n must be > 0

ALGORITHM:
Call the FLINT method fmpq_poly_mullow.
degree()Return the degree of self.
By convention, the degree of the zero polynomial is −1.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
sage: f.degree()4
sage: g = R(0)sage: g.degree()-1>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) + t + t**Integer(2)/Integer(2) + t**Integer(3)/Integer(3)␣
˓→+ t**Integer(4)/Integer(4)>>> f.degree()4>>> g = R(Integer(0))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

259

Polynomials, Release 10.4

(continued from previous page)>>> g.degree()-1denominator()
Return the denominator of self.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = (3 * t^3 + 1) / -3
sage: f.denominator()3>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = (Integer(3) * t**Integer(3) + Integer(1)) / -Integer(3)>>> f.denominator()3

disc()
Return the discriminant of this polynomial.
The discriminant 𝑅𝑛 is defined as
𝑅𝑛 = 𝑎2𝑛−2𝑛∏︁(𝑟𝑖 − 𝑟𝑗 )2 ,1≤𝑖<𝑗≤𝑛where 𝑛 is the degree of this polynomial, 𝑎𝑛 is the leading coefficient and the roots overare 𝑟1 , . . . , 𝑟𝑛 .

The discriminant of constant polynomials is defined to be 0.
OUTPUT: Discriminant, an element of the base ring of the polynomial ring(𝑛−𝑘−2)

Note: Note the identity 𝑅𝑛 (𝑓 ) := (−1)(𝑛(𝑛−1)/2) 𝑅(𝑓, 𝑓 ′ )𝑎𝑛, where 𝑛 is the degree of this polynomial, 𝑎𝑛 is the leading coefficient, 𝑓 ′ is the derivative of 𝑓 , and 𝑘 is the degree of 𝑓 ′ . Calls resultant().
ALGORITHM:
Use PARI.
EXAMPLES:In the case of elliptic curves in special form, the discriminant is easy to calculate:sage: R.<t> = QQ[]
sage: f = t^3 + t + 1
sage: d = f.discriminant(); d-31
sage: d.parent() is QQ
True
sage: EllipticCurve([1, 1]).discriminant() / 16
˓→needs sage.schemes
-31

260

#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + t + Integer(1)>>> d = f.discriminant(); d-31>>> d.parent() is QQ
True>>> EllipticCurve([Integer(1), Integer(1)]).discriminant() / Integer(16)˓→# needs sage.schemes-31␣

sage: R.<t> = QQ[]
sage: f = 2*t^3 + t + 1
sage: d = f.discriminant(); d-116>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(2)*t**Integer(3) + t + Integer(1)>>> d = f.discriminant(); d-116
sage: R.<t> = QQ[]
sage: f = t^3 + 3*t - 17sage: f.discriminant()-7911>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + Integer(3)*t - Integer(17)>>> f.discriminant()-7911

discriminant()
Return the discriminant of this polynomial.
The discriminant 𝑅𝑛 is defined as
𝑅𝑛 = 𝑎2𝑛−2𝑛∏︁(𝑟𝑖 − 𝑟𝑗 )2 ,1≤𝑖<𝑗≤𝑛where 𝑛 is the degree of this polynomial, 𝑎𝑛 is the leading coefficient and the roots overare 𝑟1 , . . . , 𝑟𝑛 .

The discriminant of constant polynomials is defined to be 0.
OUTPUT: Discriminant, an element of the base ring of the polynomial ring(𝑛−𝑘−2)

Note: Note the identity 𝑅𝑛 (𝑓 ) := (−1)(𝑛(𝑛−1)/2) 𝑅(𝑓, 𝑓 ′ )𝑎𝑛, where 𝑛 is the degree of this polynomial, 𝑎𝑛 is the leading coefficient, 𝑓 ′ is the derivative of 𝑓 , and 𝑘 is the degree of 𝑓 ′ . Calls resultant().
ALGORITHM:
Use PARI.
EXAMPLES:In the case of elliptic curves in special form, the discriminant is easy to calculate:
2.1. Univariate Polynomials and Polynomial Rings

261

Polynomials, Release 10.4

sage: R.<t> = QQ[]
sage: f = t^3 + t + 1
sage: d = f.discriminant(); d-31
sage: d.parent() is QQ
True
sage: EllipticCurve([1, 1]).discriminant() / 16
˓→needs sage.schemes-31#␣>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + t + Integer(1)>>> d = f.discriminant(); d-31>>> d.parent() is QQ
True>>> EllipticCurve([Integer(1), Integer(1)]).discriminant() / Integer(16)˓→# needs sage.schemes-31␣

sage: R.<t> = QQ[]
sage: f = 2*t^3 + t + 1
sage: d = f.discriminant(); d-116>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(2)*t**Integer(3) + t + Integer(1)>>> d = f.discriminant(); d-116
sage: R.<t> = QQ[]
sage: f = t^3 + 3*t - 17sage: f.discriminant()-7911>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + Integer(3)*t - Integer(17)>>> f.discriminant()-7911

factor_mod(p)Return the factorization of self modulo the prime 𝑝.
Assumes that the degree of this polynomial is at least one, and raises a ValueError otherwise.
INPUT:• p – Prime number
OUTPUT: Factorization of this polynomial modulo 𝑝
EXAMPLES:

262

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<x> = QQ[]
sage: (x^5 + 17*x^3 + x + 3).factor_mod(3)x * (x^2 + 1)^2
sage: (x^5 + 2).factor_mod(5)(x + 2)^5>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(5) + Integer(17)*x**Integer(3) + x + Integer(3)).factor_
˓→mod(Integer(3))
x * (x^2 + 1)^2>>> (x**Integer(5) + Integer(2)).factor_mod(Integer(5))(x + 2)^5

Variable names that are reserved in PARI, such as zeta, are supported (see Issue #20631):
sage: R.<zeta> = QQ[]
sage: (zeta^2 + zeta + 1).factor_mod(7)(zeta + 3) * (zeta + 5)>>> from sage.all import *>>> R = QQ[ zeta ]; (zeta,) = R._first_ngens(1)>>> (zeta**Integer(2) + zeta + Integer(1)).factor_mod(Integer(7))(zeta + 3) * (zeta + 5)

factor_padic(p, prec=10)Return the 𝑝-adic factorization of this polynomial to the given precision.
INPUT:• p – Prime number• prec – Integer; the precision
OUTPUT: factorization of self viewed as a 𝑝-adic polynomial
EXAMPLES:
sage: # needs sage.rings.padic
sage: R.<x> = QQ[]
sage: f = x^3 - 2
sage: f.factor_padic(2)(1 + O(2^10))*x^3 + O(2^10)*x^2 + O(2^10)*x+ 2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10)sage: f.factor_padic(3)(1 + O(3^10))*x^3 + O(3^10)*x^2 + O(3^10)*x+ 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 +␣˓→O(3^10)
sage: f.factor_padic(5)((1 + O(5^10))*x+ 2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))* ((1 + O(5^10))*x^2+ (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x+ 4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10))>>> from sage.all import *>>> # needs sage.rings.padic>>> R = QQ[ x ]; (x,) = R._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

263

Polynomials, Release 10.4

(continued from previous page)>>> f = x**Integer(3) - Integer(2)>>> f.factor_padic(Integer(2))(1 + O(2^10))*x^3 + O(2^10)*x^2 + O(2^10)*x+ 2 + 2^2 + 2^3 + 2^4 + 2^5 + 2^6 + 2^7 + 2^8 + 2^9 + O(2^10)>>> f.factor_padic(Integer(3))(1 + O(3^10))*x^3 + O(3^10)*x^2 + O(3^10)*x+ 1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 +␣˓→O(3^10)>>> f.factor_padic(Integer(5))((1 + O(5^10))*x+ 2 + 4*5 + 2*5^2 + 2*5^3 + 5^4 + 3*5^5 + 4*5^7 + 2*5^8 + 5^9 + O(5^10))* ((1 + O(5^10))*x^2+ (3 + 2*5^2 + 2*5^3 + 3*5^4 + 5^5 + 4*5^6 + 2*5^8 + 3*5^9 + O(5^10))*x+ 4 + 5 + 2*5^2 + 4*5^3 + 4*5^4 + 3*5^5 + 3*5^6 + 4*5^7 + 4*5^9 + O(5^10))

The input polynomial is considered to have “infinite” precision, therefore the 𝑝-adic factorization of the polynomial is not the same as first coercing to 𝑝 and then factoring (see also Issue #15422):
sage: # needs sage.rings.padic
sage: f = x^2 - 3^6sage: f.factor_padic(3, 5)((1 + O(3^5))*x + 3^3 + O(3^5)) * ((1 + O(3^5))*x + 2*3^3 + 2*3^4 + O(3^5))sage: f.change_ring(Qp(3,5)).factor()
Traceback (most recent call last):...
PrecisionError: p-adic factorization not well-defined since
the discriminant is zero up to the requestion p-adic precision>>> from sage.all import *>>> # needs sage.rings.padic>>> f = x**Integer(2) - Integer(3)**Integer(6)>>> f.factor_padic(Integer(3), Integer(5))((1 + O(3^5))*x + 3^3 + O(3^5)) * ((1 + O(3^5))*x + 2*3^3 + 2*3^4 + O(3^5))>>> f.change_ring(Qp(Integer(3),Integer(5))).factor()
Traceback (most recent call last):...
PrecisionError: p-adic factorization not well-defined since
the discriminant is zero up to the requestion p-adic precision

A more difficult example:
sage: R.<x> = QQ[]
sage: f = 100 * (5*x + 1)^2 * (x + 5)^2
sage: f.factor_padic(5, 10)
˓→needs sage.rings.padic(4*5^4 + O(5^14)) * ((1 + O(5^9))*x + 5^-1 + O(5^9))^2* ((1 + O(5^10))*x + 5 + O(5^10))^2>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(100) * (Integer(5)*x + Integer(1))**Integer(2) * (x +␣˓→Integer(5))**Integer(2)>>> f.factor_padic(Integer(5), Integer(10))˓→# needs sage.rings.padic(4*5^4 + O(5^14)) * ((1 + O(5^9))*x + 5^-1 + O(5^9))^2* ((1 + O(5^10))*x + 5 + O(5^10))^2

264

#␣

␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Try some bogus inputs:
sage: # needs sage.rings.padic
sage: f.factor_padic(3, -1)
Traceback (most recent call last):...
ValueError: prec_cap must be non-negative
sage: f.factor_padic(6, 10)
Traceback (most recent call last):...
ValueError: p must be prime
sage: f.factor_padic( hello , world )Traceback (most recent call last):...
TypeError: unable to convert hello to an integer>>> from sage.all import *>>> # needs sage.rings.padic>>> f.factor_padic(Integer(3), -Integer(1))
Traceback (most recent call last):...
ValueError: prec_cap must be non-negative>>> f.factor_padic(Integer(6), Integer(10))
Traceback (most recent call last):...
ValueError: p must be prime>>> f.factor_padic( hello , world )Traceback (most recent call last):...
TypeError: unable to convert hello to an integer

galois_group(pari_group=False, algorithm='pari')
Return the Galois group of this polynomial as a permutation group.
INPUT:• self – Irreducible polynomial• pari_group – bool (default: False); if True instead return the Galois group as a PARI group. This
has a useful label in it, and may be slightly faster since it doesn’t require looking up a group in GAP. To
get a permutation group from a PARI group P, type PermutationGroup(P).
• algorithm – pari , gap , kash , magma (default: pari , for degrees is at most 11;
gap , for degrees from 12 to 15; kash , for degrees from 16 or more).
OUTPUT: Galois group
ALGORITHM:
The Galois group is computed using PARI in C library mode, or possibly GAP, KASH, or MAGMA.
Note: The PARI documentation contains the following warning: The method used is that of resolvent
polynomials and is sensitive to the current precision. The precision is updated internally but, in very rarecases, a wrong result may be returned if the initial precision was not sufficient.
GAP uses the “Transitive Groups Libraries” from the “TransGrp” GAP package which comes installed withthe “gap” Sage package.

2.1. Univariate Polynomials and Polynomial Rings

265

Polynomials, Release 10.4

MAGMA does not return a provably correct result. Please see the MAGMA documentation for how to obtaina provably correct result.
EXAMPLES:
sage: # needs sage.groups sage.libs.pari
sage: R.<x> = QQ[]
sage: f = x^4 - 17*x^3 - 2*x + 1
sage: G = f.galois_group(); G
Transitive group number 5 of degree 4
sage: G.gens()((1,2,3,4), (1,2))
sage: G.order()24>>> from sage.all import *>>> # needs sage.groups sage.libs.pari>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) - Integer(17)*x**Integer(3) - Integer(2)*x + Integer(1)>>> G = f.galois_group(); G
Transitive group number 5 of degree 4>>> G.gens()((1,2,3,4), (1,2))>>> G.order()24

It is potentially useful to instead obtain the corresponding PARI group, which is little more than a 4-tuple. See
the PARI manual for the exact details. (Note that the third entry in the tuple is in the new standard ordering.)sage: # needs sage.groups sage.libs.pari
sage: f = x^4 - 17*x^3 - 2*x + 1
sage: G = f.galois_group(pari_group=True); G
PARI group [24, -1, 5, "S4"] of degree 4
sage: PermutationGroup(G)Transitive group number 5 of degree 4>>> from sage.all import *>>> # needs sage.groups sage.libs.pari>>> f = x**Integer(4) - Integer(17)*x**Integer(3) - Integer(2)*x + Integer(1)>>> G = f.galois_group(pari_group=True); G
PARI group [24, -1, 5, "S4"] of degree 4>>> PermutationGroup(G)Transitive group number 5 of degree 4

You can use KASH or GAP to compute Galois groups as well. The advantage is that KASH (resp. GAP) can
compute Galois groups of fields up to degree 23 (resp. 15), whereas PARI only goes to degree 11. (In my
not-so-thorough experiments PARI is faster than KASH.)
sage: R.<x> = QQ[]
sage: f = x^4 - 17*x^3 - 2*x + 1
sage: f.galois_group(algorithm= kash )Transitive group number 5 of degree 4# optional - kash

sage: # needs sage.libs.gap
sage: f = x^4 - 17*x^3 - 2*x + 1
sage: f.galois_group(algorithm= gap )(continues on next page)

266

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Transitive group number 5 of degree 4
sage: f = x^13 - 17*x^3 - 2*x + 1
sage: f.galois_group(algorithm= gap )Transitive group number 9 of degree 13
sage: f = x^12 - 2*x^8 - x^7 + 2*x^6 + 4*x^4 - 2*x^3 - x^2 - x + 1
sage: f.galois_group(algorithm= gap )Transitive group number 183 of degree 12
sage: f.galois_group(algorithm= magma )Transitive group number 5 of degree 4# optional - magma>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(4) - Integer(17)*x**Integer(3) - Integer(2)*x + Integer(1)>>> f.galois_group(algorithm= kash )# optional - kash
Transitive group number 5 of degree 4>>> # needs sage.libs.gap>>> f = x**Integer(4) - Integer(17)*x**Integer(3) - Integer(2)*x + Integer(1)>>> f.galois_group(algorithm= gap )Transitive group number 5 of degree 4>>> f = x**Integer(13) - Integer(17)*x**Integer(3) - Integer(2)*x + Integer(1)>>> f.galois_group(algorithm= gap )Transitive group number 9 of degree 13>>> f = x**Integer(12) - Integer(2)*x**Integer(8) - x**Integer(7) +␣˓→Integer(2)*x**Integer(6) + Integer(4)*x**Integer(4) -␣˓→Integer(2)*x**Integer(3) - x**Integer(2) - x + Integer(1)>>> f.galois_group(algorithm= gap )Transitive group number 183 of degree 12>>> f.galois_group(algorithm= magma )Transitive group number 5 of degree 4# optional - magma

galois_group_davenport_smith_test(num_trials=50, assume_irreducible=False)
Use the Davenport-Smith test to attempt to certify that 𝑓 has Galois group 𝐴𝑛 or 𝑆𝑛 .
Return 1 if the Galois group is certified as 𝑆𝑛 , 2 if 𝐴𝑛 , or 0 if no conclusion is reached.
By default, we first check that 𝑓 is irreducible. For extra efficiency, one can override this by specifying
assume_irreducible=True; this yields undefined results if 𝑓 is not irreducible.
A corresponding function in Magma is IsEasySnAn.
EXAMPLES:
sage: P.<x> = QQ[]
sage: u = x^7 + x + 1
sage: u.galois_group_davenport_smith_test()
1sage: u = x^7 - x^4 - x^3 + 3*x^2 - 1
sage: u.galois_group_davenport_smith_test()
2
sage: u = x^7 - 2
sage: u.galois_group_davenport_smith_test()
02.1. Univariate Polynomials and Polynomial Rings

267

Polynomials, Release 10.4>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> u = x**Integer(7) + x + Integer(1)>>> u.galois_group_davenport_smith_test()
1>>> u = x**Integer(7) - x**Integer(4) - x**Integer(3) +␣˓→Integer(3)*x**Integer(2) - Integer(1)>>> u.galois_group_davenport_smith_test()
2>>> u = x**Integer(7) - Integer(2)>>> u.galois_group_davenport_smith_test()
0

gcd(right)
Return the (monic) greatest common divisor of self and right.
Corner cases: if self and right are both zero, returns zero. If only one of them is zero, returns the otherpolynomial, up to normalisation.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3sage: g = 1/2 + 4*t + 2*t^4/3
sage: f.gcd(g)1sage: f = (-3*t + 1/2) * f
sage: g = (-3*t + 1/2) * (4*t^2/3 - 1) * g
sage: f.gcd(g)t - 1/6>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = -Integer(2) + Integer(3)*t/Integer(2) + Integer(4)*t**Integer(2)/˓→Integer(7) - t**Integer(3)>>> g = Integer(1)/Integer(2) + Integer(4)*t + Integer(2)*t**Integer(4)/˓→Integer(3)>>> f.gcd(g)1>>> f = (-Integer(3)*t + Integer(1)/Integer(2)) * f>>> g = (-Integer(3)*t + Integer(1)/Integer(2)) * (Integer(4)*t**Integer(2)/˓→Integer(3) - Integer(1)) * g>>> f.gcd(g)t - 1/6

hensel_lift(p, e)
Assuming that this polynomial factors modulo 𝑝 into distinct monic factors, computes the Hensel lifts of thesefactors modulo 𝑝𝑒 . We assume that self has integer coefficients.
Return an empty list if this polynomial has degree less than one.
INPUT:• p – Prime number; coerceable to Integer• e – Exponent; coerceable to Integer
OUTPUT: Hensel lifts; list of polynomials over Z/𝑝𝑒 Z
EXAMPLES:
268

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: R.<x> = QQ[]
sage: R((x-1)*(x+1)).hensel_lift(7, 2)[x + 1, x + 48]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R((x-Integer(1))*(x+Integer(1))).hensel_lift(Integer(7), Integer(2))[x + 1, x + 48]

If the input polynomial 𝑓 is not monic, we get a factorization of 𝑓 /𝑙𝑐(𝑓 ):sage: R(2*x^2 - 2).hensel_lift(7, 2)[x + 1, x + 48]>>> from sage.all import *>>> R(Integer(2)*x**Integer(2) - Integer(2)).hensel_lift(Integer(7),␣
˓→Integer(2))[x + 1, x + 48]

inverse_series_trunc(prec)
Return a polynomial approximation of precision prec of the inverse series of this polynomial.
EXAMPLES:
sage: x = polygen(QQ)
sage: p = 2 + x - 3/5*x**2
sage: q5 = p.inverse_series_trunc(5)sage: q5
151/800*x^4 - 17/80*x^3 + 11/40*x^2 - 1/4*x + 1/2
sage: q5 * p-453/4000*x^6 + 253/800*x^5 + 1
sage: q100 = p.inverse_series_trunc(100)sage: (q100 * p).truncate(100)1>>> from sage.all import *>>> x = polygen(QQ)>>> p = Integer(2) + x - Integer(3)/Integer(5)*x**Integer(2)>>> q5 = p.inverse_series_trunc(Integer(5))>>> q5151/800*x^4 - 17/80*x^3 + 11/40*x^2 - 1/4*x + 1/2>>> q5 * p-453/4000*x^6 + 253/800*x^5 + 1>>> q100 = p.inverse_series_trunc(Integer(100))>>> (q100 * p).truncate(Integer(100))1

is_irreducible()
Return whether this polynomial is irreducible.
This method computes the primitive part as an element of Z[𝑡] and calls the method is_irreduciblefor elements of that polynomial ring.
By definition, over any integral domain, an element 𝑟 is irreducible if and only if it is non-zero, not a unit andwhenever 𝑟 = 𝑎𝑏 then 𝑎 or 𝑏 is a unit.
2.1. Univariate Polynomials and Polynomial Rings

269

Polynomials, Release 10.4

EXAMPLES:
sage: R.<t> = QQ[]
sage: (t^2 + 2).is_irreducible()True
sage: (t^2 - 1).is_irreducible()
False>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> (t**Integer(2) + Integer(2)).is_irreducible()True>>> (t**Integer(2) - Integer(1)).is_irreducible()
False

is_one()Return whether or not this polynomial is one.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R([0,1]).is_one()False
sage: R([1]).is_one()True
sage: R([0]).is_one()False
sage: R([-1]).is_one()False
sage: R([1,1]).is_one()
False>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R([Integer(0),Integer(1)]).is_one()
False>>> R([Integer(1)]).is_one()True>>> R([Integer(0)]).is_one()
False>>> R([-Integer(1)]).is_one()
False>>> R([Integer(1),Integer(1)]).is_one()
False

is_zero()Return whether or not self is the zero polynomial.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 1 - t + 1/2*t^2 - 1/3*t^3sage: f.is_zero()False
sage: R(0).is_zero()
True

270

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) - t + Integer(1)/Integer(2)*t**Integer(2) - Integer(1)/˓→Integer(3)*t**Integer(3)>>> f.is_zero()
False>>> R(Integer(0)).is_zero()Truelcm(right)
Return the monic (or zero) least common multiple of self and right.
Corner cases: if either of self and right are zero, returns zero. This behaviour is ensures that the relationlcm(𝑎, 𝑏) · gcd(𝑎, 𝑏) = 𝑎 · 𝑏 holds up to multiplication by rationals.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = -2 + 3*t/2 + 4*t^2/7 - t^3sage: g = 1/2 + 4*t + 2*t^4/3
sage: f.lcm(g)t^7 - 4/7*t^6 - 3/2*t^5 + 8*t^4 - 75/28*t^3 - 66/7*t^2 + 87/8*t + 3/2
sage: f.lcm(g) * f.gcd(g) // (f * g)
-3/2>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = -Integer(2) + Integer(3)*t/Integer(2) + Integer(4)*t**Integer(2)/˓→Integer(7) - t**Integer(3)>>> g = Integer(1)/Integer(2) + Integer(4)*t + Integer(2)*t**Integer(4)/˓→Integer(3)>>> f.lcm(g)t^7 - 4/7*t^6 - 3/2*t^5 + 8*t^4 - 75/28*t^3 - 66/7*t^2 + 87/8*t + 3/2>>> f.lcm(g) * f.gcd(g) // (f * g)
-3/2list(copy=True)
Return a list with the coefficients of self.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 1 + t + t^2/2 + t^3/3 + t^4/4
sage: f.list()[1, 1, 1/2, 1/3, 1/4]
sage: g = R(0)sage: g.list()[]>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) + t + t**Integer(2)/Integer(2) + t**Integer(3)/Integer(3)␣
˓→+ t**Integer(4)/Integer(4)>>> f.list()[1, 1, 1/2, 1/3, 1/4]>>> g = R(Integer(0))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

271

Polynomials, Release 10.4

(continued from previous page)>>> g.list()[]

numerator()
Return the numerator of self.
Representing self as the quotient of an integer polynomial and a positive integer denominator (coprime to thecontent of the polynomial), returns the integer polynomial.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = (3 * t^3 + 1) / -3
sage: f.numerator()-3*t^3 - 1>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = (Integer(3) * t**Integer(3) + Integer(1)) / -Integer(3)>>> f.numerator()-3*t^3 - 1

quo_rem(right)
Return the quotient and remainder of the Euclidean division of self and right.
Raises a ZeroDivisionError if right is zero.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = R.random_element(2000)
sage: g = R.random_element(1000)
sage: q, r = f.quo_rem(g)sage: f == q*g + r
True>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = R.random_element(Integer(2000))>>> g = R.random_element(Integer(1000))>>> q, r = f.quo_rem(g)>>> f == q*g + r
True

real_root_intervals()
Return isolating intervals for the real roots of self.
EXAMPLES:
We compute the roots of the characteristic polynomial of some Salem numbers:
sage: R.<t> = QQ[]
sage: f = 1 - t^2 - t^3 - t^4 + t^6
sage: f.real_root_intervals()[((1/2, 3/4), 1), ((1, 3/2), 1)]

272

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) - t**Integer(2) - t**Integer(3) - t**Integer(4) +␣˓→t**Integer(6)>>> f.real_root_intervals()[((1/2, 3/4), 1), ((1, 3/2), 1)]

resultant(right)
Return the resultant of self and right.
Enumerating the roots over as 𝑟1 , . . . , 𝑟𝑚 and 𝑠1 , . . . , 𝑠𝑛 and letting 𝑥 and 𝑦 denote the leading coefficientsof 𝑓 and 𝑔, the resultant of the two polynomials is defined by∏︁
𝑥deg 𝑔 𝑦 deg 𝑓(𝑟𝑖 − 𝑠𝑗 ).
𝑖,𝑗Corner cases: if one of the polynomials is zero, the resultant is zero. Note that otherwise if one of thepolynomials is constant, the last term in the above is the empty product.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = (t - 2/3) * (t + 4/5) * (t - 1)sage: g = (t - 1/3) * (t + 1/2) * (t + 1)
sage: f.resultant(g)119/1350
sage: h = (t - 1/3) * (t + 1/2) * (t - 1)sage: f.resultant(h)0>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = (t - Integer(2)/Integer(3)) * (t + Integer(4)/Integer(5)) * (t -␣˓→Integer(1))>>> g = (t - Integer(1)/Integer(3)) * (t + Integer(1)/Integer(2)) * (t +␣˓→Integer(1))>>> f.resultant(g)119/1350>>> h = (t - Integer(1)/Integer(3)) * (t + Integer(1)/Integer(2)) * (t -␣˓→Integer(1))>>> f.resultant(h)0reverse(degree=None)
Reverse the coefficients of this polynomial (thought of as a polynomial of degree degree).
INPUT:• degree (None or integral value that fits in an unsigned long, default: degree of self) - if
specified, truncate or zero pad the list of coefficients to this degree before reversing it.
EXAMPLES:
We first consider the simplest case, where we reverse all coefficients of a polynomial and obtain a polynomialof the same degree:
sage: R.<t> = QQ[]
sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

273

Polynomials, Release 10.4

(continued from previous page)

sage: f.reverse()t^4 + t^3 + 1/2*t^2 + 1/3*t + 1/4>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) + t + t**Integer(2) / Integer(2) + t**Integer(3) /␣˓→Integer(3) + t**Integer(4) / Integer(4)>>> f.reverse()t^4 + t^3 + 1/2*t^2 + 1/3*t + 1/4

Next, an example where the returned polynomial has lower degree because the original polynomial has low
coefficients equal to zero:sage: R.<t> = QQ[]
sage: f = 3/4*t^2 + 6*t^7
sage: f.reverse()
3/4*t^5 + 6>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(3)/Integer(4)*t**Integer(2) + Integer(6)*t**Integer(7)>>> f.reverse()
3/4*t^5 + 6

The next example illustrates the passing of a value for degree less than the length of self, notationallyresulting in truncation prior to reversing:sage: R.<t> = QQ[]
sage: f = 1 + t + t^2 / 2 + t^3 / 3 + t^4 / 4sage: f.reverse(2)t^2 + t + 1/2>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) + t + t**Integer(2) / Integer(2) + t**Integer(3) /␣˓→Integer(3) + t**Integer(4) / Integer(4)>>> f.reverse(Integer(2))
t^2 + t + 1/2

Now we illustrate the passing of a value for degree greater than the length of self, notationally resulting
in zero padding at the top end prior to reversing:sage: R.<t> = QQ[]
sage: f = 1 + t + t^2 / 2 + t^3 / 3
sage: f.reverse(4)t^4 + t^3 + 1/2*t^2 + 1/3*t>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) + t + t**Integer(2) / Integer(2) + t**Integer(3) /␣˓→Integer(3)>>> f.reverse(Integer(4))
t^4 + t^3 + 1/2*t^2 + 1/3*trevert_series(n)274Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Return a polynomial 𝑓 such that f(self(x)) = self(f(x)) = x mod x^n.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = t - t^3/6 + t^5/120
sage: f.revert_series(6)3/40*t^5 + 1/6*t^3 + t
sage: f.revert_series(-1)
Traceback (most recent call last):
ValueError: argument n must be a non-negative integer, got -1
sage: g = - t^3/3 + t^5/5
sage: g.revert_series(6)Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = t - t**Integer(3)/Integer(6) + t**Integer(5)/Integer(120)>>> f.revert_series(Integer(6))
3/40*t^5 + 1/6*t^3 + t>>> f.revert_series(-Integer(1))
Traceback (most recent call last):
ValueError: argument n must be a non-negative integer, got -1>>> g = - t**Integer(3)/Integer(3) + t**Integer(5)/Integer(5)>>> g.revert_series(Integer(6))
Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1

truncate(n)Return self truncated modulo 𝑡𝑛 .
INPUT:• n – The power of 𝑡 modulo which self is truncated
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 1 - t + 1/2*t^2 - 1/3*t^3sage: f.truncate(0)0sage: f.truncate(2)-t + 1>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(1) - t + Integer(1)/Integer(2)*t**Integer(2) - Integer(1)/˓→Integer(3)*t**Integer(3)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

275

Polynomials, Release 10.4

(continued from previous page)>>> f.truncate(Integer(0))
0>>> f.truncate(Integer(2))-t + 1xgcd(right)
Return polynomials 𝑑, 𝑠, and 𝑡 such that d == s * self + t * right, where 𝑑 is the (monic) greatest
common divisor of self and right. The choice of 𝑠 and 𝑡 is not specified any further.
Corner cases: if self and right are zero, returns zero polynomials. Otherwise, if only self is zero,
returns (d, s, t) = (right, 0, 1) up to normalisation, and similarly if only right is zero.
EXAMPLES:
sage: R.<t> = QQ[]
sage: f = 2/3 + 3/4 * t - t^2sage: g = -3 + 1/7 * t
sage: f.xgcd(g)(1, -12/5095, -84/5095*t - 1701/5095)>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(2)/Integer(3) + Integer(3)/Integer(4) * t - t**Integer(2)>>> g = -Integer(3) + Integer(1)/Integer(7) * t>>> f.xgcd(g)(1, -12/5095, -84/5095*t - 1701/5095)

2.1.10 Dense univariate polynomials over Z/𝑛Z, implemented using FLINT
This module gives a fast implementation of (Z/𝑛Z)[𝑥] whenever 𝑛 is at most sys.maxsize. We use it by default inpreference to NTL when the modulus is small, falling back to NTL if the modulus is too large, as in the example below.
EXAMPLES:
sage: R.<a> = PolynomialRing(Integers(100))
sage: type(a)<class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint >sage: R.<a> = PolynomialRing(Integers(5*2^64))
sage: type(a)<class sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ >sage: R.<a> = PolynomialRing(Integers(5*2^64), implementation="FLINT")
Traceback (most recent call last):...
ValueError: FLINT does not support modulus 92233720368547758080>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), names=( a ,)); (a,) = R._first_ngens(1)>>> type(a)<class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint >>>> R = PolynomialRing(Integers(Integer(5)*Integer(2)**Integer(64)), names=( a ,));␣
˓→(a,) = R._first_ngens(1)>>> type(a)<class sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ >>>> R = PolynomialRing(Integers(Integer(5)*Integer(2)**Integer(64)), implementation=(continues on next page)

276

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)"FLINT", names=( a ,)); (a,) = R._first_ngens(1)Traceback (most recent call last):...
ValueError: FLINT does not support modulus 92233720368547758080
˓→

AUTHORS:• Burcin Erocal (2008-11) initial implementation• Martin Albrecht (2009-01) another initial implementation
class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template
Bases: Polynomial
Template for interfacing to external C / C++ libraries for implementations of polynomials.
AUTHORS:• Robert Bradshaw (2008-10): original idea for templating• Martin Albrecht (2008-10): initial implementation
This file implements a simple templating engine for linking univariate polynomials to their C/C++ library implementations. It requires a ‘linkage’ file which implements the celement_ functions (see sage.libs.ntl.
ntl_GF2X_linkage for an example). Both parts are then plugged together by inclusion of the linkage filewhen inheriting from this class. See sage.rings.polynomial.polynomial_gf2x for an example.
We illustrate the generic glueing using univariate polynomials over GF(2).
Note: Implementations using this template MUST implement coercion from base ring elements and get_unsafe(). See Polynomial_GF2X for an example.
degree()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.degree()1
sage: P(1).degree()0
sage: P(0).degree()-1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.degree()1>>> P(Integer(1)).degree()0>>> P(Integer(0)).degree()-1gcd(other)
Return the greatest common divisor of self and other.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

277

Polynomials, Release 10.4

sage: P.<x> = GF(2)[]sage: f = x*(x+1)
sage: f.gcd(x+1)
x + 1
sage: f.gcd(x^2)
x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.gcd(x+Integer(1))
x + 1>>> f.gcd(x**Integer(2))
xget_cparent()
is_gen()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_gen()True
sage: (x+1).is_gen()False>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.is_gen()True>>> (x+Integer(1)).is_gen()
False

is_one()EXAMPLES:
sage: P.<x> = GF(2)[]sage: P(1).is_one()True>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> P(Integer(1)).is_one()True

is_zero()
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_zero()
False>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)(continues on next page)

278

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> x.is_zero()
False

list(copy=True)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.list()[0, 1]
sage: list(x)[0, 1]>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.list()[0, 1]>>> list(x)[0, 1]

quo_rem(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^2 + x + 1
sage: f.quo_rem(x + 1)
(x, 1)>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(2) + x + Integer(1)>>> f.quo_rem(x + Integer(1))(x, 1)

shift(n)EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^3 + x^2 + 1
sage: f.shift(1)x^4 + x^3 + x
sage: f.shift(-1)
x^2 + x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(3) + x**Integer(2) + Integer(1)>>> f.shift(Integer(1))
x^4 + x^3 + x>>> f.shift(-Integer(1))
x^2 + xtruncate(n)Returns this polynomial mod 𝑥𝑛 .
EXAMPLES:
2.1. Univariate Polynomials and Polynomial Rings

279

Polynomials, Release 10.4

sage: R.<x> =GF(2)[]sage: f = sum(x^n for n in range(10)); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
sage: f.truncate(6)x^5 + x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = sum(x**n for n in range(Integer(10))); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1>>> f.truncate(Integer(6))
x^5 + x^4 + x^3 + x^2 + x + 1

If the precision is higher than the degree of the polynomial then the polynomial itself is returned:
sage: f.truncate(10) is f
True>>> from sage.all import *>>> f.truncate(Integer(10)) is f
True

If the precision is negative, the zero polynomial is returned:
sage: f.truncate(-1)
0>>> from sage.all import *>>> f.truncate(-Integer(1))
0xgcd(other)Computes extended gcd of self and other.
EXAMPLES:
sage: P.<x> = GF(7)[]sage: f = x*(x+1)
sage: f.xgcd(x+1)(x + 1, 0, 1)
sage: f.xgcd(x^2)(x, 1, 6)>>> from sage.all import *>>> P = GF(Integer(7))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.xgcd(x+Integer(1))(x + 1, 0, 1)>>> f.xgcd(x**Integer(2))(x, 1, 6)class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
Bases: Polynomial_template
Polynomial on Z/𝑛Z implemented via FLINT.

280

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

_add_(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x + 1
x + 1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x + Integer(1)x + 1_sub_(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x - 1
x + 1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x - Integer(1)x + 1_lmul_(left)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: t = x^2 + x + 1
sage: 0*t
0sage: 1*tx^2 + x + 1
sage: R.<y> = GF(5)[]sage: u = y^2 + y + 1
sage: 3*u
3*y^2 + 3*y + 3
sage: 5*u0sage: (2^81)*u2*y^2 + 2*y + 2
sage: (-2^81)*u3*y^2 + 3*y + 3>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> t = x**Integer(2) + x + Integer(1)>>> Integer(0)*t0>>> Integer(1)*tx^2 + x + 1>>> R = GF(Integer(5))[ y ]; (y,) = R._first_ngens(1)>>> u = y**Integer(2) + y + Integer(1)>>> Integer(3)*u(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

281

Polynomials, Release 10.4

(continued from previous page)

3*y^2 + 3*y + 3>>> Integer(5)*u0>>> (Integer(2)**Integer(81))*u2*y^2 + 2*y + 2>>> (-Integer(2)**Integer(81))*u3*y^2 + 3*y + 3
sage: P.<x> = GF(2)[]sage: t = x^2 + x + 1
sage: t*00
sage: t*1x^2 + x + 1
sage: R.<y> = GF(5)[]sage: u = y^2 + y + 1
sage: u*3
3*y^2 + 3*y + 3
sage: u*50>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> t = x**Integer(2) + x + Integer(1)>>> t*Integer(0)0>>> t*Integer(1)x^2 + x + 1>>> R = GF(Integer(5))[ y ]; (y,) = R._first_ngens(1)>>> u = y**Integer(2) + y + Integer(1)>>> u*Integer(3)3*y^2 + 3*y + 3>>> u*Integer(5)0_rmul_(right)
Multiply self on the right by a scalar.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: f = (x^3 + x + 5)
sage: f._rmul_(7)7*x^3 + 7*x + 35
sage: f*7
7*x^3 + 7*x + 35>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = (x**Integer(3) + x + Integer(5))>>> f._rmul_(Integer(7))
7*x^3 + 7*x + 35>>> f*Integer(7)7*x^3 + 7*x + 35

282

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

_mul_(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x*(x+1)
x^2 + x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x*(x+Integer(1))
x^2 + x_mul_trunc_(right, n)
Return the product of this polynomial and other truncated to the given length 𝑛.
This function is usually more efficient than simply doing the multiplication and then truncating. The function
is tuned for length 𝑛 about half the length of a full product.
EXAMPLES:
sage: P.<a> = GF(7)[]sage: a = P(range(10)); b = P(range(5, 15))
sage: a._mul_trunc_(b, 5)
4*a^4 + 6*a^3 + 2*a^2 + 5*a>>> from sage.all import *>>> P = GF(Integer(7))[ a ]; (a,) = P._first_ngens(1)>>> a = P(range(Integer(10))); b = P(range(Integer(5), Integer(15)))>>> a._mul_trunc_(b, Integer(5))
4*a^4 + 6*a^3 + 2*a^2 + 5*a

factor()Return the factorization of the polynomial.
EXAMPLES:
sage: R.<x> = GF(5)[]sage: (x^2 + 1).factor()(x + 2) * (x + 3)>>> from sage.all import *>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2) + Integer(1)).factor()(x + 2) * (x + 3)

It also works for prime-power moduli:
sage: R.<x> = Zmod(23^5)[]
sage: (x^3 + 1).factor()(x + 1) * (x^2 + 6436342*x + 1)>>> from sage.all import *>>> R = Zmod(Integer(23)**Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(3) + Integer(1)).factor()(x + 1) * (x^2 + 6436342*x + 1)

2.1. Univariate Polynomials and Polynomial Rings

283

Polynomials, Release 10.4

is_irreducible()
Return whether this polynomial is irreducible.
EXAMPLES:
sage: R.<x> = GF(5)[]sage: (x^2 + 1).is_irreducible()False
sage: (x^3 + x + 1).is_irreducible()True>>> from sage.all import *>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2) + Integer(1)).is_irreducible()False>>> (x**Integer(3) + x + Integer(1)).is_irreducible()
True

Not implemented when the base ring is not a field:
sage: S.
 = Zmod(10)[]sage: (s^2).is_irreducible()
Traceback (most recent call last):...
NotImplementedError: checking irreducibility of polynomials
over rings with composite characteristic is not implemented>>> from sage.all import *>>> S = Zmod(Integer(10))[ s ]; (s,) = S._first_ngens(1)>>> (s**Integer(2)).is_irreducible()
Traceback (most recent call last):...
NotImplementedError: checking irreducibility of polynomials
over rings with composite characteristic is not implemented

minpoly_mod(other)Thinwrapperforsage.rings.polynomial.polynomial_modn_dense_ntl.
Polynomial_dense_mod_n.minpoly_mod().
EXAMPLES:
sage: R.<x> = GF(127)[]
sage: type(x)<class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint >sage: (x^5 - 3).minpoly_mod(x^3 + 5*x - 1)x^3 + 34*x^2 + 125*x + 95>>> from sage.all import *>>> R = GF(Integer(127))[ x ]; (x,) = R._first_ngens(1)>>> type(x)<class sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint >>>> (x**Integer(5) - Integer(3)).minpoly_mod(x**Integer(3) + Integer(5)*x -␣
˓→Integer(1))
x^3 + 34*x^2 + 125*x + 95

monic()
Return this polynomial divided by its leading coefficient.
284

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Raises ValueError if the leading coefficient is not invertible in the base ring.
EXAMPLES:
sage: R.<x> = GF(5)[]sage: (2*x^2 + 1).monic()x^2 + 3>>> from sage.all import *>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2)*x**Integer(2) + Integer(1)).monic()x^2 + 3

rational_reconstruct(*args, **kwds)
Deprecated: Use rational_reconstruction() instead. See Issue #12696 for details.
rational_reconstruction(m, n_deg=0, d_deg=0)Construct a rational function 𝑛/𝑑 such that 𝑝 * 𝑑 is equivalent to 𝑛 modulo 𝑚 where 𝑝 is this polynomial.
EXAMPLES:
sage: P.<x> = GF(5)[]sage: p = 4*x^5 + 3*x^4 + 2*x^3 + 2*x^2 + 4*x + 2
sage: n, d = p.rational_reconstruction(x^9, 4, 4); n, d
(3*x^4 + 2*x^3 + x^2 + 2*x, x^4 + 3*x^3 + x^2 + x)
sage: (p*d % x^9) == nTrue>>> from sage.all import *>>> P = GF(Integer(5))[ x ]; (x,) = P._first_ngens(1)>>> p = Integer(4)*x**Integer(5) + Integer(3)*x**Integer(4) +␣˓→Integer(2)*x**Integer(3) + Integer(2)*x**Integer(2) + Integer(4)*x +␣˓→Integer(2)>>> n, d = p.rational_reconstruction(x**Integer(9), Integer(4), Integer(4));␣
˓→n, d(3*x^4 + 2*x^3 + x^2 + 2*x, x^4 + 3*x^3 + x^2 + x)>>> (p*d % x**Integer(9)) == nTrue

Check that Issue #37169 is fixed - it does not throw an error:
sage: R.<x> = Zmod(4)[]sage: _.<z> = R.quotient_ring(x^2 - 1)sage: c = 2 * z + 1
sage: c * Zmod(2).zero()
Traceback (most recent call last):...
RuntimeError: Aborted>>> from sage.all import *>>> R = Zmod(Integer(4))[ x ]; (x,) = R._first_ngens(1)>>> _ = R.quotient_ring(x**Integer(2) - Integer(1), names=( z ,)); (z,) = _._˓→first_ngens(1)>>> c = Integer(2) * z + Integer(1)>>> c * Zmod(Integer(2)).zero()
Traceback (most recent call last):...
RuntimeError: Aborted

2.1. Univariate Polynomials and Polynomial Rings

285

Polynomials, Release 10.4

resultant(other)
Return the resultant of self and other, which must lie in the same polynomial ring.
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: R.<x> = GF(19)[ x ]sage: f = x^3 + x + 1; g = x^3 - x - 1
sage: r = f.resultant(g); r
11
sage: r.parent() is GF(19)True>>> from sage.all import *>>> R = GF(Integer(19))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(1); g = x**Integer(3) - x - Integer(1)>>> r = f.resultant(g); r
11>>> r.parent() is GF(Integer(19))
True

The following example shows that Issue #11782 has been fixed:
sage: R.<x> = ZZ.quo(9)[ x ]sage: f = 2*x^3 + x^2 + x; g = 6*x^2 + 2*x + 1
sage: f.resultant(g)5>>> from sage.all import *>>> R = ZZ.quo(Integer(9))[ x ]; (x,) = R._first_ngens(1)>>> f = Integer(2)*x**Integer(3) + x**Integer(2) + x; g =␣˓→Integer(6)*x**Integer(2) + Integer(2)*x + Integer(1)>>> f.resultant(g)5reverse(degree=None)
Return a polynomial with the coefficients of this polynomial reversed.
If the optional argument degree is given, the coefficient list will be truncated or zero padded as necessary
before computing the reverse.
EXAMPLES:
sage: R.<x> = GF(5)[]sage: p = R([1,2,3,4]); p4*x^3 + 3*x^2 + 2*x + 1
sage: p.reverse()x^3 + 2*x^2 + 3*x + 4
sage: p.reverse(degree=6)x^6 + 2*x^5 + 3*x^4 + 4*x^3sage: p.reverse(degree=2)x^2 + 2*x + 3
sage: R.<x> = GF(101)[](continues on next page)

286

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = x^3 - x + 2; fx^3 + 100*x + 2
sage: f.reverse()
2*x^3 + 100*x^2 + 1
sage: f.reverse() == f(1/x) * x^f.degree()True>>> from sage.all import *>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> p = R([Integer(1),Integer(2),Integer(3),Integer(4)]); p4*x^3 + 3*x^2 + 2*x + 1>>> p.reverse()x^3 + 2*x^2 + 3*x + 4>>> p.reverse(degree=Integer(6))
x^6 + 2*x^5 + 3*x^4 + 4*x^3>>> p.reverse(degree=Integer(2))
x^2 + 2*x + 3>>> R = GF(Integer(101))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(3) - x + Integer(2); fx^3 + 100*x + 2>>> f.reverse()
2*x^3 + 100*x^2 + 1>>> f.reverse() == f(Integer(1)/x) * x**f.degree()
True

Note that if 𝑓 has zero constant coefficient, its reverse will have lower degree.
sage: f = x^3 + 2*x
sage: f.reverse()
2*x^2 + 1>>> from sage.all import *>>> f = x**Integer(3) + Integer(2)*x>>> f.reverse()
2*x^2 + 1

In this case, reverse is not an involution unless we explicitly specify a degree.
sage: fx^3 + 2*x
sage: f.reverse().reverse()x^2 + 2sage: f.reverse(5).reverse(5)x^3 + 2*x>>> from sage.all import *>>> fx^3 + 2*x>>> f.reverse().reverse()x^2 + 2>>> f.reverse(Integer(5)).reverse(Integer(5))
x^3 + 2*x

revert_series(n)Return a polynomial 𝑓 such that f(self(x)) = self(f(x)) = x (mod 𝑥𝑛 ).
2.1. Univariate Polynomials and Polynomial Rings

287

Polynomials, Release 10.4

EXAMPLES:
sage: R.<t> = GF(5)[]sage: f = t + 2*t^2 - t^3 - 3*t^4sage: f.revert_series(5)3*t^4 + 4*t^3 + 3*t^2 + t
sage: f.revert_series(-1)
Traceback (most recent call last):...
ValueError: argument n must be a non-negative integer, got -1
sage: g = - t^3 + t^5
sage: g.revert_series(6)Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1
sage: g = t + 2*t^2 - t^3 -3*t^4 + t^5
sage: g.revert_series(6)Traceback (most recent call last):...
ValueError: the integers 1 up to n=5 are required to be invertible over the␣˓→base field>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> f = t + Integer(2)*t**Integer(2) - t**Integer(3) -␣˓→Integer(3)*t**Integer(4)>>> f.revert_series(Integer(5))
3*t^4 + 4*t^3 + 3*t^2 + t>>> f.revert_series(-Integer(1))
Traceback (most recent call last):...
ValueError: argument n must be a non-negative integer, got -1>>> g = - t**Integer(3) + t**Integer(5)>>> g.revert_series(Integer(6))
Traceback (most recent call last):...
ValueError: self must have constant coefficient 0 and a unit for coefficient␣
˓→t^1>>> g = t + Integer(2)*t**Integer(2) - t**Integer(3) ˓→Integer(3)*t**Integer(4) + t**Integer(5)>>> g.revert_series(Integer(6))
Traceback (most recent call last):...
ValueError: the integers 1 up to n=5 are required to be invertible over the␣˓→base fieldsmall_roots(*args, **kwds)
See sage.rings.polynomial.polynomial_modn_dense_ntl.small_roots() for the
documentation of this function.
EXAMPLES:

288

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: N = 10001
sage: K = Zmod(10001)
sage: P.<x> = PolynomialRing(K)sage: f = x^3 + 10*x^2 + 5000*x - 222
sage: f.small_roots()[4]>>> from sage.all import *>>> N = Integer(10001)>>> K = Zmod(Integer(10001))>>> P = PolynomialRing(K, names=( x ,)); (x,) = P._first_ngens(1)>>> f = x**Integer(3) + Integer(10)*x**Integer(2) + Integer(5000)*x -␣
˓→Integer(222)>>> f.small_roots()[4]squarefree_decomposition()
Return the squarefree decomposition of this polynomial.
EXAMPLES:
sage: R.<x> = GF(5)[]sage: ((x+1)*(x^2+1)^2*x^3).squarefree_decomposition()(x + 1) * (x^2 + 1)^2 * x^3>>> from sage.all import *>>> R = GF(Integer(5))[ x ]; (x,) = R._first_ngens(1)>>> ((x+Integer(1))*(x**Integer(2)+Integer(1))**Integer(2)*x**Integer(3)).
˓→squarefree_decomposition()(x + 1) * (x^2 + 1)^2 * x^3sage.rings.polynomial.polynomial_zmod_flint.make_element(parent, args)

2.1.11 Dense univariate polynomials over Z/𝑛Z, implemented using NTLThis implementation is generally slower than the FLINT implementation in polynomial_zmod_flint, so we use
FLINT by default when the modulus is small enough; but NTL does not require that 𝑛 be int-sized, so we use it as
default when 𝑛 is too large for FLINT.
Note that the classes Polynomial_dense_modn_ntl_zz and Polynomial_dense_modn_ntl_ZZ are different; the former is limited to moduli less than a certain bound, while the latter supports arbitrarily large moduli.
AUTHORS:• Robert Bradshaw: Split off from polynomial_element_generic.py (2007-09)• Robert Bradshaw: Major rewrite to use NTL directly (2007-09)
class sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n
Bases: Polynomial
A dense polynomial over the integers modulo n, where n is composite, with the underlying arithmetic done using
NTL.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

289

Polynomials, Release 10.4

sage: R.<x> = PolynomialRing(Integers(16), implementation= NTL )sage: f = x^3 - x + 17
sage: f^2
x^6 + 14*x^4 + 2*x^3 + x^2 + 14*x + 1
sage: loads(f.dumps()) == f
True
sage: R.<x> = PolynomialRing(Integers(100), implementation= NTL )sage: p = 3*x
sage: q = 7*x
sage: p + q
10*x
sage: R.<x> = PolynomialRing(Integers(8), implementation= NTL )sage: parent(p)Univariate Polynomial Ring in x over Ring of integers modulo 100 (using NTL)
sage: p + q
10*x
sage: R({10:-1})
7*x^10>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(16)), implementation= NTL , names=( x ,));
˓→ (x,) = R._first_ngens(1)>>> f = x**Integer(3) - x + Integer(17)>>> f**Integer(2)x^6 + 14*x^4 + 2*x^3 + x^2 + 14*x + 1>>> loads(f.dumps()) == f
True>>> R = PolynomialRing(Integers(Integer(100)), implementation= NTL , names=( x ,˓→)); (x,) = R._first_ngens(1)>>> p = Integer(3)*x>>> q = Integer(7)*x>>> p + q
10*x>>> R = PolynomialRing(Integers(Integer(8)), implementation= NTL , names=( x ,));␣
˓→(x,) = R._first_ngens(1)>>> parent(p)Univariate Polynomial Ring in x over Ring of integers modulo 100 (using NTL)>>> p + q
10*x>>> R({Integer(10):-Integer(1)})
7*x^10degree(gen=None)
Return the degree of this polynomial.
The zero polynomial has degree -1.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(100), implementation= NTL )sage: (x^3 + 3*x - 17).degree()3
sage: R.zero().degree()-1290

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> (x**Integer(3) + Integer(3)*x - Integer(17)).degree()3>>> R.zero().degree()-1

int_list()list(copy=True)
Return a new copy of the list of the underlying elements of self.
EXAMPLES:
sage: _.<x> = PolynomialRing(Integers(100), implementation= NTL )sage: f = x^3 + 3*x - 17sage: f.list()[83, 3, 0, 1]>>> from sage.all import *>>> _ = PolynomialRing(Integers(Integer(100)), implementation= NTL , names=( x˓→ ,)); (x,) = _._first_ngens(1)>>> f = x**Integer(3) + Integer(3)*x - Integer(17)>>> f.list()[83, 3, 0, 1]

minpoly_mod(other)Compute the minimal polynomial of this polynomial modulo another polynomial in the same ring.
ALGORITHM:
NTL’s MinPolyMod(), which uses Shoup’s algorithm [Sho1999].
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(101), implementation= NTL )sage: f = x^17 + x^2 - 1
sage: (x^2).minpoly_mod(f)x^17 + 100*x^2 + 2*x + 100>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(101)), implementation= NTL , names=( x ,));␣
˓→(x,) = R._first_ngens(1)>>> f = x**Integer(17) + x**Integer(2) - Integer(1)>>> (x**Integer(2)).minpoly_mod(f)x^17 + 100*x^2 + 2*x + 100

ntl_ZZ_pX()
Return underlying NTL representation of this polynomial. Additional ‘’bonus’’ functionality is available
through this function.
Warning: You must call ntl.set_modulus(ntl.ZZ(n)) before doing arithmetic with this object!

2.1. Univariate Polynomials and Polynomial Rings

291

Polynomials, Release 10.4

ntl_set_directly(v)Set the value of this polynomial directly from a vector or string.
Polynomials over the integers modulo n are stored internally using NTL’s ZZ_pX class. Use this function to
set the value of this polynomial using the NTL constructor, which is potentially very fast. The input v is eithera vector of ints or a string of the form [ n1 n2 n3 ... ] where the ni are integers and there are nocommas between them. The optimal input format is the string format, since that’s what NTL uses by default.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(100), implementation= NTL )sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_
˓→dense_mod_n as poly_modn_dense
sage: poly_modn_dense(R, ([1,-2,3]))
3*x^2 + 98*x + 1
sage: f = poly_modn_dense(R, 0)
sage: f.ntl_set_directly([1,-2,3])
sage: f3*x^2 + 98*x + 1
sage: f.ntl_set_directly( [1 -2 3 4] )sage: f4*x^3 + 3*x^2 + 98*x + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_
˓→dense_mod_n as poly_modn_dense>>> poly_modn_dense(R, ([Integer(1),-Integer(2),Integer(3)]))3*x^2 + 98*x + 1>>> f = poly_modn_dense(R, Integer(0))>>> f.ntl_set_directly([Integer(1),-Integer(2),Integer(3)])>>> f
3*x^2 + 98*x + 1>>> f.ntl_set_directly( [1 -2 3 4] )>>> f
4*x^3 + 3*x^2 + 98*x + 1

quo_rem(right)
Return a tuple (quotient, remainder) where self = quotient*other + remainder.
shift(n)Return this polynomial multiplied by the power 𝑥𝑛 . If 𝑛 is negative, terms below 𝑥𝑛 will be discarded. Does
not change this polynomial.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(12345678901234567890), implementation=
˓→ NTL )sage: p = x^2 + 2*x + 4
sage: p.shift(0)x^2 + 2*x + 4
sage: p.shift(-1)
x + 2
sage: p.shift(-5)
0sage: p.shift(2)x^4 + 2*x^3 + 4*x^2292

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(12345678901234567890)),␣
˓→implementation= NTL , names=( x ,)); (x,) = R._first_ngens(1)>>> p = x**Integer(2) + Integer(2)*x + Integer(4)>>> p.shift(Integer(0))
x^2 + 2*x + 4>>> p.shift(-Integer(1))
x + 2>>> p.shift(-Integer(5))
0>>> p.shift(Integer(2))
x^4 + 2*x^3 + 4*x^2

AUTHOR:• David Harvey (2006-08-06)
small_roots(*args, **kwds)
See sage.rings.polynomial.polynomial_modn_dense_ntl.small_roots() for the
documentation of this function.
EXAMPLES:
sage: N = 10001
sage: K = Zmod(10001)
sage: P.<x> = PolynomialRing(K, implementation= NTL )sage: f = x^3 + 10*x^2 + 5000*x - 222
sage: f.small_roots()[4]>>> from sage.all import *>>> N = Integer(10001)>>> K = Zmod(Integer(10001))>>> P = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = P._
˓→first_ngens(1)>>> f = x**Integer(3) + Integer(10)*x**Integer(2) + Integer(5000)*x -␣
˓→Integer(222)>>> f.small_roots()[4]class sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p
Bases: Polynomial_dense_mod_n
A dense polynomial over the integers modulo 𝑝, where 𝑝 is prime.
discriminant()
EXAMPLES:
sage: _.<x> = PolynomialRing(GF(19), implementation= NTL )sage: f = x^3 + 3*x - 17sage: f.discriminant()
12>>> from sage.all import *>>> _ = PolynomialRing(GF(Integer(19)), implementation= NTL , names=( x ,));␣
˓→(x,) = _._first_ngens(1)>>> f = x**Integer(3) + Integer(3)*x - Integer(17)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

293

Polynomials, Release 10.4

(continued from previous page)>>> f.discriminant()
12

gcd(right)
Return the greatest common divisor of this polynomial and other, as a monic polynomial.
INPUT:• other – a polynomial defined over the same ring as self
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(3), implementation="NTL")
sage: f, g = x + 2, x^2 - 1
sage: f.gcd(g)x + 2>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), implementation="NTL", names=( x ,));␣
˓→(x,) = R._first_ngens(1)>>> f, g = x + Integer(2), x**Integer(2) - Integer(1)>>> f.gcd(g)x + 2

resultant(other)
Return the resultant of self and other, which must lie in the same polynomial ring.
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(19), implementation= NTL )sage: f = x^3 + x + 1; g = x^3 - x - 1
sage: r = f.resultant(g); r
11
sage: r.parent() is GF(19)True>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(19)), implementation= NTL , names=( x ,));␣
˓→(x,) = R._first_ngens(1)>>> f = x**Integer(3) + x + Integer(1); g = x**Integer(3) - x - Integer(1)>>> r = f.resultant(g); r
11>>> r.parent() is GF(Integer(19))
True

xgcd(other)Compute the extended gcd of this element and other.
INPUT:• other – an element in the same polynomial ring

294

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

OUTPUT:
A tuple (r,s,t) of elements in the polynomial ring such that r = s*self + t*other.
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(3), implementation= NTL )sage: x.xgcd(x)(x, 0, 1)
sage: (x^2 - 1).xgcd(x - 1)
(x + 2, 0, 1)
sage: R.zero().xgcd(R.one())(1, 0, 1)
sage: (x^3 - 1).xgcd((x - 1)^2)(x^2 + x + 1, 0, 1)
sage: ((x - 1)*(x + 1)).xgcd(x*(x - 1))(x + 2, 1, 2)>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), implementation= NTL , names=( x ,));␣
˓→(x,) = R._first_ngens(1)>>> x.xgcd(x)(x, 0, 1)>>> (x**Integer(2) - Integer(1)).xgcd(x - Integer(1))(x + 2, 0, 1)>>> R.zero().xgcd(R.one())(1, 0, 1)>>> (x**Integer(3) - Integer(1)).xgcd((x - Integer(1))**Integer(2))(x^2 + x + 1, 0, 1)>>> ((x - Integer(1))*(x + Integer(1))).xgcd(x*(x - Integer(1)))(x + 2, 1, 2)

class
sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ
Bases: Polynomial_dense_mod_n
degree()EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(14^34), implementation= NTL )sage: f = x^4 - x - 1
sage: f.degree()4
sage: f = 14^43*x + 1
sage: f.degree()0>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(14)**Integer(34)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(4) - x - Integer(1)>>> f.degree()4>>> f = Integer(14)**Integer(43)*x + Integer(1)>>> f.degree()0

is_gen()2.1. Univariate Polynomials and Polynomial Rings

295

Polynomials, Release 10.4

list(copy=True)
quo_rem(right)
Return 𝑞 and 𝑟, with the degree of 𝑟 less than the degree of right, such that 𝑞· right +𝑟 = self.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(10^30), implementation= NTL )sage: f = x^5+1; g = (x+1)^2
sage: q, r = f.quo_rem(g)sage: qx^3 + 999999999999999999999999999998*x^2 + 3*x +␣˓→999999999999999999999999999996
sage: r
5*x + 5sage: q*g + r
x^5 + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(10)**Integer(30)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(5)+Integer(1); g = (x+Integer(1))**Integer(2)>>> q, r = f.quo_rem(g)>>> qx^3 + 999999999999999999999999999998*x^2 + 3*x +␣˓→999999999999999999999999999996>>> r
5*x + 5>>> q*g + r
x^5 + 1

reverse(degree=None)
Return the reverse of the input polynomial thought as a polynomial of degree degree.
If 𝑓 is a degree-𝑑 polynomial, its reverse is 𝑥𝑑 𝑓 (1/𝑥).
INPUT:• degree (None or an integer) – if specified, truncate or zero pad the list of coefficients to this degree
before reversing it.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(12^29), implementation= NTL )sage: f = x^4 + 2*x + 5
sage: f.reverse()
5*x^4 + 2*x^3 + 1
sage: f = x^3 + x
sage: f.reverse()x^2 + 1
sage: f.reverse(1)1sage: f.reverse(5)x^4 + x^2>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(12)**Integer(29)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)(continues on next page)

296

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = x**Integer(4) + Integer(2)*x + Integer(5)>>> f.reverse()
5*x^4 + 2*x^3 + 1>>> f = x**Integer(3) + x>>> f.reverse()x^2 + 1>>> f.reverse(Integer(1))
1>>> f.reverse(Integer(5))
x^4 + x^2

shift(n)Shift self to left by 𝑛, which is multiplication by 𝑥𝑛 , truncating if 𝑛 is negative.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(12^30), implementation= NTL )sage: f = x^7 + x + 1
sage: f.shift(1)x^8 + x^2 + x
sage: f.shift(-1)
x^6 + 1
sage: f.shift(10).shift(-10) == f
True>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(12)**Integer(30)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(7) + x + Integer(1)>>> f.shift(Integer(1))
x^8 + x^2 + x>>> f.shift(-Integer(1))
x^6 + 1>>> f.shift(Integer(10)).shift(-Integer(10)) == f
Truetruncate(n)Return this polynomial mod 𝑥𝑛 .
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(15^30), implementation= NTL )sage: f = sum(x^n for n in range(10)); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
sage: f.truncate(6)x^5 + x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(15)**Integer(30)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)>>> f = sum(x**n for n in range(Integer(10))); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1>>> f.truncate(Integer(6))
x^5 + x^4 + x^3 + x^2 + x + 1

valuation()

2.1. Univariate Polynomials and Polynomial Rings

297

Polynomials, Release 10.4

Return the valuation of self, that is, the power of the lowest non-zero monomial of self.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(10^50), implementation= NTL )sage: x.valuation()1
sage: f = x - 3; f.valuation()0
sage: f = x^99; f.valuation()99
sage: f = x - x; f.valuation()+Infinity>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(10)**Integer(50)), implementation= NTL
˓→ , names=( x ,)); (x,) = R._first_ngens(1)>>> x.valuation()1>>> f = x - Integer(3); f.valuation()0>>> f = x**Integer(99); f.valuation()99>>> f = x - x; f.valuation()+Infinity

class
sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz
Bases: Polynomial_dense_mod_n
Polynomial on Z/𝑛Z implemented via NTL.
_add_(_right)_sub_(_right)_lmul_(c)_rmul_(c)_mul_(_right)_mul_trunc_(right, n)
Return the product of self and right truncated to the given length 𝑛
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(100), implementation="NTL")
sage: f = x - 2
sage: g = x^2 - 8*x + 16
sage: f*gx^3 + 90*x^2 + 32*x + 68
sage: f._mul_trunc_(g, 42)x^3 + 90*x^2 + 32*x + 68
sage: f._mul_trunc_(g, 3)
90*x^2 + 32*x + 68
sage: f._mul_trunc_(g, 2)
32*x + 68(continues on next page)

298

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f._mul_trunc_(g, 1)
68
sage: f._mul_trunc_(g, 0)0sage: f = x^2 - 8*x + 16
sage: f._mul_trunc_(f, 2)
44*x + 56>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), implementation="NTL", names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = x - Integer(2)>>> g = x**Integer(2) - Integer(8)*x + Integer(16)>>> f*gx^3 + 90*x^2 + 32*x + 68>>> f._mul_trunc_(g, Integer(42))
x^3 + 90*x^2 + 32*x + 68>>> f._mul_trunc_(g, Integer(3))
90*x^2 + 32*x + 68>>> f._mul_trunc_(g, Integer(2))
32*x + 68>>> f._mul_trunc_(g, Integer(1))
68>>> f._mul_trunc_(g, Integer(0))
0>>> f = x**Integer(2) - Integer(8)*x + Integer(16)>>> f._mul_trunc_(f, Integer(2))
44*x + 56

degree()EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(77), implementation= NTL )sage: f = x^4 - x - 1
sage: f.degree()4
sage: f = 77*x + 1
sage: f.degree()0>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(77)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(4) - x - Integer(1)>>> f.degree()4>>> f = Integer(77)*x + Integer(1)>>> f.degree()0

int_list()
Return the coefficients of self as efficiently as possible as a list of python ints.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

299

Polynomials, Release 10.4

sage: R.<x> = PolynomialRing(Integers(100), implementation= NTL )sage: from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_
˓→dense_mod_n as poly_modn_dense
sage: f = poly_modn_dense(R,[5,0,0,1])
sage: f.int_list()[5, 0, 0, 1]
sage: [type(a) for a in f.int_list()][<... int >, <... int >, <... int >, <... int >]>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(100)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> from sage.rings.polynomial.polynomial_modn_dense_ntl import Polynomial_
˓→dense_mod_n as poly_modn_dense>>> f = poly_modn_dense(R,[Integer(5),Integer(0),Integer(0),Integer(1)])>>> f.int_list()[5, 0, 0, 1]>>> [type(a) for a in f.int_list()][<... int >, <... int >, <... int >, <... int >]is_gen()ntl_set_directly(v)quo_rem(right)
Return 𝑞 and 𝑟, with the degree of 𝑟 less than the degree of right, such that 𝑞· right + 𝑟 = self.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(125), implementation= NTL )sage: f = x^5+1; g = (x+1)^2
sage: q, r = f.quo_rem(g)sage: qx^3 + 123*x^2 + 3*x + 121
sage: r
5*x + 5sage: q*g + r
x^5 + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(125)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(5)+Integer(1); g = (x+Integer(1))**Integer(2)>>> q, r = f.quo_rem(g)>>> qx^3 + 123*x^2 + 3*x + 121>>> r
5*x + 5>>> q*g + r
x^5 + 1

reverse(degree=None)
Return the reverse of the input polynomial thought as a polynomial of degree degree.
If 𝑓 is a degree-𝑑 polynomial, its reverse is 𝑥𝑑 𝑓 (1/𝑥).
INPUT:

300

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• degree (None or an integer) – if specified, truncate or zero pad the list of coefficients to this degree
before reversing it.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(77), implementation= NTL )sage: f = x^4 - x - 1
sage: f.reverse()
76*x^4 + 76*x^3 + 1
sage: f.reverse(2)76*x^2 + 76*x
sage: f.reverse(5)76*x^5 + 76*x^4 + x
sage: g = x^3 - x
sage: g.reverse()
76*x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(77)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(4) - x - Integer(1)>>> f.reverse()
76*x^4 + 76*x^3 + 1>>> f.reverse(Integer(2))
76*x^2 + 76*x>>> f.reverse(Integer(5))
76*x^5 + 76*x^4 + x>>> g = x**Integer(3) - x>>> g.reverse()
76*x^2 + 1

shift(n)Shift self to left by 𝑛, which is multiplication by 𝑥𝑛 , truncating if 𝑛 is negative.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(77), implementation= NTL )sage: f = x^7 + x + 1
sage: f.shift(1)x^8 + x^2 + x
sage: f.shift(-1)
x^6 + 1
sage: f.shift(10).shift(-10) == f
True>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(77)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(7) + x + Integer(1)>>> f.shift(Integer(1))
x^8 + x^2 + x>>> f.shift(-Integer(1))
x^6 + 1>>> f.shift(Integer(10)).shift(-Integer(10)) == f
Truetruncate(n)Return this polynomial mod 𝑥𝑛 .
2.1. Univariate Polynomials and Polynomial Rings

301

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(77), implementation= NTL )sage: f = sum(x^n for n in range(10)); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
sage: f.truncate(6)x^5 + x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(77)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> f = sum(x**n for n in range(Integer(10))); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1>>> f.truncate(Integer(6))
x^5 + x^4 + x^3 + x^2 + x + 1

valuation()
Return the valuation of self, that is, the power of the lowest non-zero monomial of self.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(10), implementation= NTL )sage: x.valuation()1
sage: f = x-3; f.valuation()0
sage: f = x^99; f.valuation()99
sage: f = x-x; f.valuation()+Infinity>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(10)), implementation= NTL , names=( x˓→ ,)); (x,) = R._first_ngens(1)>>> x.valuation()1>>> f = x-Integer(3); f.valuation()0>>> f = x**Integer(99); f.valuation()99>>> f = x-x; f.valuation()+Infinity

sage.rings.polynomial.polynomial_modn_dense_ntl.make_element(parent, args)
sage.rings.polynomial.polynomial_modn_dense_ntl.small_roots(self, X=None, beta=1.0,
epsilon=None, **kwds)
Let 𝑁 be the characteristic of the base ring this polynomial is defined over: N = self.base_ring().
characteristic(). This method returns small roots of this polynomial modulo some factor 𝑏 of 𝑁 with theconstraint that 𝑏 >= 𝑁 𝛽 . Small in this context means that if 𝑥 is a root of 𝑓 modulo 𝑏 then |𝑥| < 𝑋. This 𝑋 iseither provided by the user or the maximum 𝑋 is chosen such that this algorithm terminates in polynomial time.
2
If 𝑋 is chosen automatically it is 𝑋 = 𝑐𝑒𝑖𝑙(1/2𝑁 𝛽 /𝛿−𝜖 ). The algorithm may also return some roots which arelarger than 𝑋. ‘This algorithm’ in this context means Coppersmith’s algorithm for finding small roots using the
LLL algorithm. The implementation of this algorithm follows Alexander May’s PhD thesis referenced below.
INPUT:• X – an absolute bound for the root (default: see above)302

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• beta – compute a root mod 𝑏 where 𝑏 is a factor of 𝑁 and 𝑏 ≥ 𝑁 𝛽 . (Default: 1.0, so 𝑏 = 𝑁 .)• epsilon – the parameter 𝜖 described above. (Default: 𝛽/8)
• **kwds – passed through to method Matrix_integer_dense.LLL().
EXAMPLES:First consider a small example:
sage: N = 10001
sage: K = Zmod(10001)
sage: P.<x> = PolynomialRing(K, implementation= NTL )sage: f = x^3 + 10*x^2 + 5000*x - 222>>> from sage.all import *>>> N = Integer(10001)>>> K = Zmod(Integer(10001))>>> P = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = P._first_
˓→ngens(1)>>> f = x**Integer(3) + Integer(10)*x**Integer(2) + Integer(5000)*x - Integer(222)This polynomial has no roots without modular reduction (i.e. over Z):
sage: f.change_ring(ZZ).roots()[]>>> from sage.all import *>>> f.change_ring(ZZ).roots()[]

To compute its roots we need to factor the modulus 𝑁 and use the Chinese remainder theorem:
sage: p, q = N.prime_divisors()
sage: f.change_ring(GF(p)).roots()[(4, 1)]
sage: f.change_ring(GF(q)).roots()[(4, 1)]
sage: crt(4, 4, p, q)
4>>> from sage.all import *>>> p, q = N.prime_divisors()>>> f.change_ring(GF(p)).roots()[(4, 1)]>>> f.change_ring(GF(q)).roots()[(4, 1)]>>> crt(Integer(4), Integer(4), p, q)
4This root is quite small compared to 𝑁 , so we can attempt to recover it without factoring 𝑁 using Coppersmith’ssmall root method:
sage: f.small_roots()[4]

2.1. Univariate Polynomials and Polynomial Rings

303

Polynomials, Release 10.4>>> from sage.all import *>>> f.small_roots()[4]

An application of this method is to consider RSA. We are using 512-bit RSA with public exponent 𝑒 = 3 to encrypta 56-bit DES key. Because it would be easy to attack this setting if no padding was used we pad the key 𝐾 with 1s
to get a large number:sage: Nbits, Kbits = 512, 56
sage: e = 3>>> from sage.all import *>>> Nbits, Kbits = Integer(512), Integer(56)>>> e = Integer(3)We choose two primes of size 256-bit each:sage: p = 2^256 + 2^8 + 2^5 + 2^3 + 1
sage: q = 2^256 + 2^8 + 2^5 + 2^3 + 2^2 + 1
sage: N = p*q
sage: ZmodN = Zmod( N )>>> from sage.all import *>>> p = Integer(2)**Integer(256) + Integer(2)**Integer(8) +␣˓→Integer(2)**Integer(5) + Integer(2)**Integer(3) + Integer(1)>>> q = Integer(2)**Integer(256) + Integer(2)**Integer(8) +␣˓→Integer(2)**Integer(5) + Integer(2)**Integer(3) + Integer(2)**Integer(2) +␣˓→Integer(1)>>> N = p*q>>> ZmodN = Zmod( N )We choose a random key:
sage: K = ZZ.random_element(0, 2^Kbits)>>> from sage.all import *>>> K = ZZ.random_element(Integer(0), Integer(2)**Kbits)

and pad it with 512 − 56 = 456 1s:sage: Kdigits = K.digits(2)sage: M = [0]*Kbits + [1]*(Nbits-Kbits)
sage: for i in range(len(Kdigits)): M[i] = Kdigits[i]sage: M = ZZ(M, 2)>>> from sage.all import *>>> Kdigits = K.digits(Integer(2))>>> M = [Integer(0)]*Kbits + [Integer(1)]*(Nbits-Kbits)>>> for i in range(len(Kdigits)): M[i] = Kdigits[i]>>> M = ZZ(M, Integer(2))

Now we encrypt the resulting message:

304

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: C = ZmodN(M)^e>>> from sage.all import *>>> C = ZmodN(M)**e

To recover 𝐾 we consider the following polynomial modulo 𝑁 :sage: P.<x> = PolynomialRing(ZmodN, implementation= NTL )sage: f = (2^Nbits - 2^Kbits + x)^e - C>>> from sage.all import *>>> P = PolynomialRing(ZmodN, implementation= NTL , names=( x ,)); (x,) = P._
˓→first_ngens(1)>>> f = (Integer(2)**Nbits - Integer(2)**Kbits + x)**e - C

and recover its small roots:
sage: Kbar = f.small_roots()[0]sage: K == Kbar
True>>> from sage.all import *>>> Kbar = f.small_roots()[Integer(0)]>>> K == Kbar
True

The same algorithm can be used to factor 𝑁 = 𝑝𝑞 if partial knowledge about 𝑞 is available. This example is from
the Magma handbook:
First, we set up 𝑝, 𝑞 and 𝑁 :sage: length = 512
sage: hidden = 110
sage: p = next_prime(2^int(round(length/2)))
sage: q = next_prime(round(pi.n()*p))˓→needs sage.symbolic
sage: N = p*q
˓→needs sage.symbolic>>> from sage.all import *>>> length = Integer(512)>>> hidden = Integer(110)>>> p = next_prime(Integer(2)**int(round(length/Integer(2))))>>> q = next_prime(round(pi.n()*p))˓→needs sage.symbolic>>> N = p*q
˓→needs sage.symbolic

#␣
#␣

#␣
#␣

Now we disturb the low 110 bits of 𝑞:
sage: qbar = q + ZZ.random_element(0, 2^hidden - 1)
˓→needs sage.symbolic>>> from sage.all import *>>> qbar = q + ZZ.random_element(Integer(0), Integer(2)**hidden - Integer(1))˓→# needs sage.symbolic

2.1. Univariate Polynomials and Polynomial Rings

#␣

␣

305

Polynomials, Release 10.4

And try to recover 𝑞 from it:
sage: F.<x> = PolynomialRing(Zmod(N), implementation= NTL )˓→needs sage.symbolic
sage: f = x - qbar
˓→needs sage.symbolic#␣#␣>>> from sage.all import *>>> F = PolynomialRing(Zmod(N), implementation= NTL , names=( x ,)); (x,) = F._˓→first_ngens(1)# needs sage.symbolic>>> f = x - qbar
#␣˓→needs sage.symbolic

We know that the error is ≤ 2hidden − 1 and that the modulus we are looking for is ≥√𝑁:

sage: from sage.misc.verbose import set_verbose
sage: set_verbose(2)sage: d = f.small_roots(X=2^hidden-1, beta=0.5)[0] # time random
˓→needs sage.symbolic
verbose 2 (<module>) m = 4
verbose 2 (<module>) t = 4
verbose 2 (<module>) X = 1298074214633706907132624082305023
verbose 1 (<module>) LLL of 8x8 matrix (algorithm fpLLL:wrapper)
verbose 1 (<module>) LLL finished (time = 0.006998)
sage: q == qbar - d
˓→needs sage.symbolicTrue>>> from sage.all import *>>> from sage.misc.verbose import set_verbose>>> set_verbose(Integer(2))>>> d = f.small_roots(X=Integer(2)**hidden-Integer(1), beta=RealNumber( 0.5
˓→ ))[Integer(0)]# time random# needs sage.symbolic
verbose 2 (<module>) m = 4
verbose 2 (<module>) t = 4
verbose 2 (<module>) X = 1298074214633706907132624082305023
verbose 1 (<module>) LLL of 8x8 matrix (algorithm fpLLL:wrapper)
verbose 1 (<module>) LLL finished (time = 0.006998)>>> q == qbar - d
˓→needs sage.symbolic
True

#␣

#␣

#␣

REFERENCES:
Don Coppersmith. Finding a small root of a univariate modular equation. In Advances in Cryptology, EuroCrypt
1996, volume 1070 of Lecture Notes in Computer Science, p. 155–165. Springer, 1996. http://cr.yp.to/bib/2001/
coppersmith.pdf
Alexander May. New RSA Vulnerabilities Using Lattice Reduction Methods. PhD thesis, University of Paderborn,
2003. http://www.cs.uni-paderborn.de/uploads/tx_sibibtex/bp.pdf

306

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

2.1.12 Dense univariate polynomials over R, implemented using MPFR
class sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
Bases: Polynomialchange_ring(R)EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [-2, 0, 1.5])
sage: f.change_ring(QQ)
3/2*x^2 - 2
sage: f.change_ring(RealField(10))
1.5*x^2 - 2.0
sage: f.change_ring(RealField(100))
1.5000000000000000000000000000*x^2 - 2.0000000000000000000000000000>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [-Integer(2), Integer(0), RealNumber( 1.5
˓→ )])>>> f.change_ring(QQ)
3/2*x^2 - 2>>> f.change_ring(RealField(Integer(10)))
1.5*x^2 - 2.0>>> f.change_ring(RealField(Integer(100)))
1.5000000000000000000000000000*x^2 - 2.0000000000000000000000000000

degree()Return the degree of the polynomial.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [1, 2, 3]); f
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
sage: f.degree()2>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [Integer(1), Integer(2), Integer(3)]); f
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000>>> f.degree()2

integral()
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [3, pi, 1])#␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

307

Polynomials, Release 10.4

(continued from previous page)needs sage.symbolic
sage: f.integral()˓→needs sage.symbolic
0.333333333333333*x^3 + 1.57079632679490*x^2 + 3.00000000000000*x˓→>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [Integer(3), pi, Integer(1)])˓→# needs sage.symbolic>>> f.integral()˓→needs sage.symbolic
0.333333333333333*x^3 + 1.57079632679490*x^2 + 3.00000000000000*x

#␣

␣
#␣

list(copy=True)
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [1, 0, -2]); f-2.00000000000000*x^2 + 1.00000000000000
sage: f.list()[1.00000000000000, 0.000000000000000, -2.00000000000000]>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [Integer(1), Integer(0), -Integer(2)]); f-2.00000000000000*x^2 + 1.00000000000000>>> f.list()[1.00000000000000, 0.000000000000000, -2.00000000000000]

quo_rem(other)
Return the quotient with remainder of self by other.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [-2, 0, 1])
sage: g = PolynomialRealDense(RR[ x ], [5, 1])
sage: q, r = f.quo_rem(g)sage: qx - 5.00000000000000
sage: r23.0000000000000
sage: q*g + r == f
True
sage: fg = f*g
sage: fg.quo_rem(f)(x + 5.00000000000000, 0)
sage: fg.quo_rem(g)(x^2 - 2.00000000000000, 0)
sage: # needs sage.symbolic
sage: f = PolynomialRealDense(RR[ x ], range(5))(continues on next page)

308

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: g = PolynomialRealDense(RR[ x ], [pi,3000,4])
sage: q, r = f.quo_rem(g)sage: g*q + r == f
True>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [-Integer(2), Integer(0), Integer(1)])>>> g = PolynomialRealDense(RR[ x ], [Integer(5), Integer(1)])>>> q, r = f.quo_rem(g)>>> qx - 5.00000000000000>>> r
23.0000000000000>>> q*g + r == f
True>>> fg = f*g>>> fg.quo_rem(f)(x + 5.00000000000000, 0)>>> fg.quo_rem(g)(x^2 - 2.00000000000000, 0)>>> # needs sage.symbolic>>> f = PolynomialRealDense(RR[ x ], range(Integer(5)))>>> g = PolynomialRealDense(RR[ x ], [pi,Integer(3000),Integer(4)])>>> q, r = f.quo_rem(g)>>> g*q + r == f
Truereverse(degree=None)
Return reverse of the input polynomial thought as a polynomial of degree degree.
If 𝑓 is a degree-𝑑 polynomial, its reverse is 𝑥𝑑 𝑓 (1/𝑥).
INPUT:• degree (None or an integer) – if specified, truncate or zero pad the list of coefficients to this degree
before reversing it.
EXAMPLES:
sage: # needs sage.symbolic
sage: f = RR[ x ]([-3, pi, 0, 1])
sage: f.reverse()-3.00000000000000*x^3 + 3.14159265358979*x^2 + 1.00000000000000
sage: f.reverse(2)-3.00000000000000*x^2 + 3.14159265358979*x
sage: f.reverse(5)-3.00000000000000*x^5 + 3.14159265358979*x^4 + x^2>>> from sage.all import *>>> # needs sage.symbolic>>> f = RR[ x ]([-Integer(3), pi, Integer(0), Integer(1)])>>> f.reverse()-3.00000000000000*x^3 + 3.14159265358979*x^2 + 1.00000000000000>>> f.reverse(Integer(2))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

309

Polynomials, Release 10.4

(continued from previous page)-3.00000000000000*x^2 + 3.14159265358979*x>>> f.reverse(Integer(5))-3.00000000000000*x^5 + 3.14159265358979*x^4 + x^2

shift(n)Returns this polynomial multiplied by the power 𝑥𝑛 . If 𝑛 is negative, terms below 𝑥𝑛 will be discarded. Does
not change this polynomial.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RR[ x ], [1, 2, 3]); f
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
sage: f.shift(10)3.00000000000000*x^12 + 2.00000000000000*x^11 + x^10
sage: f.shift(-1)
3.00000000000000*x + 2.00000000000000
sage: f.shift(-10)
0>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RR[ x ], [Integer(1), Integer(2), Integer(3)]); f
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000>>> f.shift(Integer(10))
3.00000000000000*x^12 + 2.00000000000000*x^11 + x^10>>> f.shift(-Integer(1))
3.00000000000000*x + 2.00000000000000>>> f.shift(-Integer(10))
0truncate(n)Returns the polynomial of degree < 𝑛 which is equivalent to self modulo 𝑥𝑛 .
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RealField(10)[ x ], [1, 2, 4, 8])
sage: f.truncate(3)4.0*x^2 + 2.0*x + 1.0
sage: f.truncate(100)8.0*x^3 + 4.0*x^2 + 2.0*x + 1.0
sage: f.truncate(1)1.0sage: f.truncate(0)0>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RealField(Integer(10))[ x ], [Integer(1),␣
˓→Integer(2), Integer(4), Integer(8)])>>> f.truncate(Integer(3))(continues on next page)

310

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

4.0*x^2 + 2.0*x + 1.0>>> f.truncate(Integer(100))8.0*x^3 + 4.0*x^2 + 2.0*x + 1.0>>> f.truncate(Integer(1))
1.0>>> f.truncate(Integer(0))
0truncate_abs(bound)
Truncate all high order coefficients below bound.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense
sage: f = PolynomialRealDense(RealField(10)[ x ], [10^-k for k in range(10)])sage: f1.0e-9*x^9 + 1.0e-8*x^8 + 1.0e-7*x^7 + 1.0e-6*x^6 + 0.000010*x^5+ 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0
sage: f.truncate_abs(0.5e-6)
1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.
˓→0
sage: f.truncate_abs(10.0)0
sage: f.truncate_abs(1e-100) == f
True>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import␣
˓→PolynomialRealDense>>> f = PolynomialRealDense(RealField(Integer(10))[ x ], [Integer(10)**-k for␣
˓→k in range(Integer(10))])>>> f
1.0e-9*x^9 + 1.0e-8*x^8 + 1.0e-7*x^7 + 1.0e-6*x^6 + 0.000010*x^5+ 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.0>>> f.truncate_abs(RealNumber( 0.5e-6 ))1.0e-6*x^6 + 0.000010*x^5 + 0.00010*x^4 + 0.0010*x^3 + 0.010*x^2 + 0.10*x + 1.
˓→0>>> f.truncate_abs(RealNumber( 10.0 ))0>>> f.truncate_abs(RealNumber( 1e-100 )) == f
Truesage.rings.polynomial.polynomial_real_mpfr_dense.make_PolynomialRealDense(parent,
data)
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_real_mpfr_dense import make_˓→PolynomialRealDense
sage: make_PolynomialRealDense(RR[ x ], [1,2,3])3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_real_mpfr_dense import make_(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

311

Polynomials, Release 10.4

(continued from previous page)

PolynomialRealDense>>> make_PolynomialRealDense(RR[ x ], [Integer(1),Integer(2),Integer(3)])
3.00000000000000*x^2 + 2.00000000000000*x + 1.00000000000000
˓→

2.1.13 Polynomial Interfaces to Singular
AUTHORS:• Martin Albrecht <malb@informatik.uni-bremen.de> (2006-04-21)• Robert Bradshaw: Re-factor to avoid multiple inheritance vs. Cython (2007-09)• Syed Ahmad Lavasani: Added function field to _singular_init_ (2011-12-16); Added non-prime finite fields to_singular_init_ (2012-1-22)class sage.rings.polynomial.polynomial_singular_interface.
PolynomialRing_singular_repr
Bases: object
Implements methods to convert polynomial rings to Singular.
This class is a base class for all univariate and multivariate polynomial rings which support conversion from and to
Singular rings.
class
sage.rings.polynomial.polynomial_singular_interface.Polynomial_singular_repr
Bases: object
Implements coercion of polynomials to Singular polynomials.
This class is a base class for all (univariate and multivariate) polynomial classes which support conversion from andto Singular polynomials.
Due to the incompatibility of Python extension classes and multiple inheritance, this just defers to module-level
functions.
sage.rings.polynomial.polynomial_singular_interface.can_convert_to_singular(R)Return True if this ring’s base field or ring can be represented in Singular, and the polynomial ring has at least
one generator.
The following base rings are supported: finite fields, rationals, number fields, and real and complex fields.
EXAMPLES:
sage: from sage.rings.polynomial.polynomial_singular_interface import can_convert_
˓→to_singularsage: can_convert_to_singular(PolynomialRing(QQ, names=[ x ]))Truesage: can_convert_to_singular(PolynomialRing(ZZ, names=[ x ]))Truesage: can_convert_to_singular(PolynomialRing(QQ, names=[]))
False>>> from sage.all import *>>> from sage.rings.polynomial.polynomial_singular_interface import can_convert_
˓→to_singular(continues on next page)

312

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> can_convert_to_singular(PolynomialRing(QQ, names=[ x ]))True>>> can_convert_to_singular(PolynomialRing(ZZ, names=[ x ]))True>>> can_convert_to_singular(PolynomialRing(QQ, names=[]))
False

2.1.14 Base class for generic 𝑝-adic polynomials
This provides common functionality for all 𝑝-adic polynomials, such as printing and factoring.
AUTHORS:• Jeroen Demeyer (2013-11-22): initial version, split off from other files, made Polynomial_padic the common baseclass for all p-adic polynomials.
class sage.rings.polynomial.padics.polynomial_padic.Polynomial_padic(parent,
x=None,check=True,is_gen=False,
construct=False)
Bases: Polynomial
content()
Compute the content of this polynomial.
OUTPUT:
If this is the zero polynomial, return the constant coefficient. Otherwise, since the content is only defined up
to a unit, return the content as 𝜋 𝑘 with maximal precision where 𝑘 is the minimal valuation of any of thecoefficients.
EXAMPLES:
sage: # needs sage.libs.ntl
sage: K = Zp(13,7)
sage: R.<t> = K[]
sage: f = 13^7*t^3 + K(169,4)*t - 13^4sage: f.content()
13^2 + O(13^9)sage: R(0).content()
0
sage: f = R(K(0,3)); fO(13^3)sage: f.content()
O(13^3)sage: # needs sage.libs.ntl
sage: P.<x> = ZZ[]
sage: f = x + 2
sage: f.content()
1
sage: fp = f.change_ring(pAdicRing(2, 10))sage: fp
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

313

Polynomials, Release 10.4

(continued from previous page)(1 + O(2^10))*x + 2 + O(2^11)
sage: fp.content()
1 + O(2^10)sage: (2*fp).content()
2 + O(2^11)>>> from sage.all import *>>> # needs sage.libs.ntl>>> K = Zp(Integer(13),Integer(7))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(13)**Integer(7)*t**Integer(3) + K(Integer(169),Integer(4))*t ˓→ Integer(13)**Integer(4)>>> f.content()
13^2 + O(13^9)>>> R(Integer(0)).content()0>>> f = R(K(Integer(0),Integer(3))); fO(13^3)>>> f.content()
O(13^3)>>> # needs sage.libs.ntl>>> P = ZZ[ x ]; (x,) = P._first_ngens(1)>>> f = x + Integer(2)>>> f.content()
1>>> fp = f.change_ring(pAdicRing(Integer(2), Integer(10)))>>> fp(1 + O(2^10))*x + 2 + O(2^11)>>> fp.content()
1 + O(2^10)>>> (Integer(2)*fp).content()
2 + O(2^11)

Over a field it would be sufficient to return only zero or one, as the content is only defined up to multiplication
with a unit. However, we return 𝜋 𝑘 where 𝑘 is the minimal valuation of any coefficient:sage: # needs sage.libs.ntl
sage: K = Qp(13,7)
sage: R.<t> = K[]
sage: f = 13^7*t^3 + K(169,4)*t - 13^-4sage: f.content()
13^-4 + O(13^3)sage: f = R.zero()sage: f.content()
0
sage: f = R(K(0,3))
sage: f.content()
O(13^3)sage: f = 13*t^3 + K(0,1)*t
sage: f.content()
13 + O(13^8)>>> from sage.all import *>>> # needs sage.libs.ntl>>> K = Qp(Integer(13),Integer(7))(continues on next page)

314

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(13)**Integer(7)*t**Integer(3) + K(Integer(169),Integer(4))*t ˓→ Integer(13)**-Integer(4)>>> f.content()
13^-4 + O(13^3)>>> f = R.zero()>>> f.content()0>>> f = R(K(Integer(0),Integer(3)))>>> f.content()
O(13^3)>>> f = Integer(13)*t**Integer(3) + K(Integer(0),Integer(1))*t>>> f.content()
13 + O(13^8)

factor()Return the factorization of this polynomial.
EXAMPLES:
sage: # needs sage.libs.ntl
sage: R.<t> = PolynomialRing(Qp(3, 3, print_mode= terse , print_pos=False))
sage: pol = t^8 - 1
sage: for p,e in pol.factor():....:print("{} {}".format(e, p))
1 (1 + O(3^3))*t + 1 + O(3^3)
1 (1 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + (5 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + (-5 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + O(3^3)*t + 1 + O(3^3)
sage: R.<t> = PolynomialRing(Qp(5, 6, print_mode= terse , print_pos=False))
sage: pol = 100 * (5*t - 1) * (t - 5); pol(500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^9)
sage: pol.factor()(500 + O(5^9)) * ((1 + O(5^5))*t - 1/5 + O(5^5)) * ((1 + O(5^6))*t - 5 + O(5^˓→6))
sage: pol.factor().value()(500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^8)>>> from sage.all import *>>> # needs sage.libs.ntl>>> R = PolynomialRing(Qp(Integer(3), Integer(3), print_mode= terse , print_
˓→pos=False), names=( t ,)); (t,) = R._first_ngens(1)>>> pol = t**Integer(8) - Integer(1)>>> for p,e in pol.factor():...
print("{} {}".format(e, p))
1 (1 + O(3^3))*t + 1 + O(3^3)
1 (1 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + (5 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + (-5 + O(3^3))*t - 1 + O(3^3)
1 (1 + O(3^3))*t^2 + O(3^3)*t + 1 + O(3^3)>>> R = PolynomialRing(Qp(Integer(5), Integer(6), print_mode= terse , print_
˓→pos=False), names=( t ,)); (t,) = R._first_ngens(1)>>> pol = Integer(100) * (Integer(5)*t - Integer(1)) * (t - Integer(5)); pol(500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^9)>>> pol.factor()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

315

Polynomials, Release 10.4

(continued from previous page)(500 + O(5^9)) * ((1 + O(5^5))*t - 1/5 + O(5^5)) * ((1 + O(5^6))*t - 5 + O(5^˓→6))>>> pol.factor().value()(500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^8)

The same factorization over Z𝑝 . In this case, the “unit” part is a 𝑝-adic unit and the power of 𝑝 is considered
to be a factor:
sage: # needs sage.libs.ntl
sage: R.<t> = PolynomialRing(Zp(5, 6, print_mode= terse , print_pos=False))
sage: pol = 100 * (5*t - 1) * (t - 5); pol(500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^9)
sage: pol.factor()(4 + O(5^6)) * (5 + O(5^7))^2 * ((1 + O(5^6))*t - 5 + O(5^6)) * ((5 + O(5^˓→6))*t - 1 + O(5^6))sage: pol.factor().value()(500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^8)>>> from sage.all import *>>> # needs sage.libs.ntl>>> R = PolynomialRing(Zp(Integer(5), Integer(6), print_mode= terse , print_
˓→pos=False), names=( t ,)); (t,) = R._first_ngens(1)>>> pol = Integer(100) * (Integer(5)*t - Integer(1)) * (t - Integer(5)); pol(500 + O(5^9))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^9)>>> pol.factor()(4 + O(5^6)) * (5 + O(5^7))^2 * ((1 + O(5^6))*t - 5 + O(5^6)) * ((5 + O(5^˓→6))*t - 1 + O(5^6))>>> pol.factor().value()(500 + O(5^8))*t^2 + (-2600 + O(5^8))*t + 500 + O(5^8)

In the following example, the discriminant is zero, so the 𝑝-adic factorization is not well defined:
sage: factor(t^2)˓→needs sage.libs.ntl
Traceback (most recent call last):...
PrecisionError: p-adic factorization not well-defined since
the discriminant is zero up to the requestion p-adic precision>>> from sage.all import *>>> factor(t**Integer(2))˓→# needs sage.libs.ntl
Traceback (most recent call last):...
PrecisionError: p-adic factorization not well-defined since
the discriminant is zero up to the requestion p-adic precision#␣␣

An example of factoring a constant polynomial (see Issue #26669):
sage: R.<x> = Qp(5)[]˓→needs sage.libs.ntl
sage: R(2).factor()˓→needs sage.libs.ntl
2 + O(5^20)

316

#␣
#␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = Qp(Integer(5))[ x ]; (x,) = R._first_ngens(1)# needs sage.libs.ntl>>> R(Integer(2)).factor()˓→# needs sage.libs.ntl
2 + O(5^20)

␣More examples over Z𝑝 :sage: R.<w> = PolynomialRing(Zp(5, prec=6, type= capped-abs , print_mode= val˓→unit ))sage: f = w^5 - 1
sage: f.factor()#␣˓→needs sage.libs.ntl((1 + O(5^6))*w + 3124 + O(5^6))* ((1 + O(5^6))*w^4 + (12501 + O(5^6))*w^3 + (9376 + O(5^6))*w^2+ (6251 + O(5^6))*w + 3126 + O(5^6))>>> from sage.all import *>>> R = PolynomialRing(Zp(Integer(5), prec=Integer(6), type= capped-abs ,␣˓→print_mode= val-unit ), names=( w ,)); (w,) = R._first_ngens(1)>>> f = w**Integer(5) - Integer(1)>>> f.factor()#␣˓→needs sage.libs.ntl((1 + O(5^6))*w + 3124 + O(5^6))* ((1 + O(5^6))*w^4 + (12501 + O(5^6))*w^3 + (9376 + O(5^6))*w^2+ (6251 + O(5^6))*w + 3126 + O(5^6))

See Issue #4038:
sage: # needs sage.libs.ntl sage.schemes
sage: E = EllipticCurve( 37a1 )sage: K = Qp(7,10)
sage: EK = E.base_extend(K)sage: g = EK.division_polynomial_0(3)sage: g.factor()(3 + O(7^10))* ((1 + O(7^10))*x+ 1 + 2*7 + 4*7^2 + 2*7^3 + 5*7^4 + 7^5 + 5*7^6 + 3*7^7 + 5*7^8 + 3*7^9␣
˓→+ O(7^10))* ((1 + O(7^10))*x^3+ (6 + 4*7 + 2*7^2 + 4*7^3 + 7^4 + 5*7^5+ 7^6 + 3*7^7 + 7^8 + 3*7^9 + O(7^10))*x^2+ (6 + 3*7 + 5*7^2 + 2*7^4 + 7^5 + 7^6 + 2*7^8 + 3*7^9 + O(7^10))*x+ 2 + 5*7 + 4*7^2 + 2*7^3 + 6*7^4 + 3*7^5 + 7^6 + 4*7^7 + O(7^10))>>> from sage.all import *>>> # needs sage.libs.ntl sage.schemes>>> E = EllipticCurve( 37a1 )>>> K = Qp(Integer(7),Integer(10))>>> EK = E.base_extend(K)>>> g = EK.division_polynomial_0(Integer(3))>>> g.factor()(3 + O(7^10))* ((1 + O(7^10))*x+ 1 + 2*7 + 4*7^2 + 2*7^3 + 5*7^4 + 7^5 + 5*7^6 + 3*7^7 + 5*7^8 + 3*7^9␣
˓→+ O(7^10))* ((1 + O(7^10))*x^3(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

317

Polynomials, Release 10.4

(continued from previous page)+ (6 + 4*7 + 2*7^2 + 4*7^3 + 7^4 + 5*7^5+ 7^6 + 3*7^7 + 7^8 + 3*7^9 + O(7^10))*x^2+ (6 + 3*7 + 5*7^2 + 2*7^4 + 7^5 + 7^6 + 2*7^8 + 3*7^9 + O(7^10))*x+ 2 + 5*7 + 4*7^2 + 2*7^3 + 6*7^4 + 3*7^5 + 7^6 + 4*7^7 + O(7^10))

root_field(names, check_irreducible=True, **kwds)
Return the 𝑝-adic extension field generated by the roots of the irreducible polynomial self.
INPUT:• names – name of the generator of the extension• check_irreducible – check whether the polynomial is irreducible• kwds – see sage.rings.padics.padic_generic.pAdicGeneric.extension()
EXAMPLES:
sage: R.<x> = Qp(3,5,print_mode= digits )[]˓→needs sage.libs.ntl
sage: f = x^2 - 3
˓→needs sage.libs.ntl
sage: f.root_field( x )˓→needs sage.libs.ntl
3-adic Eisenstein Extension Field in x defined by x^2 - 3

#␣
#␣
#␣

>>> from sage.all import *>>> R = Qp(Integer(3),Integer(5),print_mode= digits )[ x ]; (x,) = R._first_
˓→ngens(1)# needs sage.libs.ntl>>> f = x**Integer(2) - Integer(3)␣˓→# needs sage.libs.ntl>>> f.root_field( x )#␣˓→needs sage.libs.ntl
3-adic Eisenstein Extension Field in x defined by x^2 - 3
sage: R.<x> = Qp(5,5,print_mode= digits )[]˓→needs sage.libs.ntl
sage: f = x^2 - 3
˓→needs sage.libs.ntl
sage: f.root_field( x , print_mode= bars )˓→needs sage.libs.ntl
5-adic Unramified Extension Field in x defined by x^2 - 3

#␣
#␣
#␣

>>> from sage.all import *>>> R = Qp(Integer(5),Integer(5),print_mode= digits )[ x ]; (x,) = R._first_
˓→ngens(1)# needs sage.libs.ntl>>> f = x**Integer(2) - Integer(3)␣˓→# needs sage.libs.ntl>>> f.root_field( x , print_mode= bars )#␣˓→needs sage.libs.ntl
5-adic Unramified Extension Field in x defined by x^2 - 3
sage: R.<x> = Qp(11,5,print_mode= digits )[]˓→needs sage.libs.ntl
sage: f = x^2 - 3
˓→needs sage.libs.ntl#␣#␣
(continues on next page)

318

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.root_field( x , print_mode= bars )˓→needs sage.libs.ntl
Traceback (most recent call last):...
ValueError: polynomial must be irreducible#␣>>> from sage.all import *>>> R = Qp(Integer(11),Integer(5),print_mode= digits )[ x ]; (x,) = R._first_
˓→ngens(1)# needs sage.libs.ntl>>> f = x**Integer(2) - Integer(3)␣˓→# needs sage.libs.ntl>>> f.root_field( x , print_mode= bars )#␣˓→needs sage.libs.ntl
Traceback (most recent call last):...
ValueError: polynomial must be irreducible

2.1.15 p-adic Capped Relative Dense Polynomials

class sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_

Bases: Polynomial_generic_cdv, Polynomial_padic
degree(secure=False)
Return the degree of self.
INPUT:• secure – a boolean (default: False)
If secure is True and the degree of this polynomial is not determined (because the leading coefficient is
indistinguishable from 0), an error is raised.
If secure is False, the returned value is the largest 𝑛 so that the coefficient of 𝑥𝑛 does not compare equal
to 0.
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

319

Polynomials, Release 10.4

(continued from previous page)(1 + O(3^10))*T + 2 + O(3^10)sage: f.degree()1
sage: (f-T).degree()0
sage: (f-T).degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0
sage: x = O(3^5)
sage: li = [3^i * x for i in range(0,5)]; li[O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)]sage: f = R(li); fO(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5)
sage: f.degree()-1
sage: f.degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.degree()1>>> (f-T).degree()0>>> (f-T).degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0>>> x = O(Integer(3)**Integer(5))>>> li = [Integer(3)**i * x for i in range(Integer(0),Integer(5))]; li[O(3^5), O(3^6), O(3^7), O(3^8), O(3^9)]>>> f = R(li); fO(3^9)*T^4 + O(3^8)*T^3 + O(3^7)*T^2 + O(3^6)*T + O(3^5)>>> f.degree()-1>>> f.degree(secure=True)
Traceback (most recent call last):...
PrecisionError: the leading coefficient is indistinguishable from 0

disc()
factor_mod()Return the factorization of self modulo 𝑝.
is_eisenstein(secure=False)
Return True if this polynomial is an Eisenstein polynomial.
EXAMPLES:
320

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 5*t + t^4
sage: f.is_eisenstein()True>>> from sage.all import *>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(5)*t + t**Integer(4)>>> f.is_eisenstein()
True

AUTHOR:• Xavier Caruso (2013-03)
lift()
Return an integer polynomial congruent to this one modulo the precision of each coefficient.
Note: The lift that is returned will not necessarily be the same for polynomials with the same coefficients(i.e. same values and precisions): it will depend on how the polynomials are created.
EXAMPLES:
sage: K = Qp(13,7)
sage: R.<t> = K[]
sage: a = 13^7*t^3 + K(169,4)*t - 13^4sage: a.lift()
62748517*t^3 + 169*t - 28561>>> from sage.all import *>>> K = Qp(Integer(13),Integer(7))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> a = Integer(13)**Integer(7)*t**Integer(3) + K(Integer(169),Integer(4))*t ˓→ Integer(13)**Integer(4)>>> a.lift()
62748517*t^3 + 169*t - 28561

list(copy=True)
Return a list of coefficients of self.
Note: The length of the list returned may be greater than expected since it includes any leading zeros thathave finite absolute precision.
EXAMPLES:
sage: K = Qp(13,7)
sage: R.<t> = K[]
sage: a = 2*t^3 + 169*t - 1
sage: a(2 + O(13^7))*t^3 + (13^2 + O(13^9))*t + 12 + 12*13 + 12*13^2 + 12*13^3 +␣
˓→12*13^4 + 12*13^5 + 12*13^6 + O(13^7)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

321

Polynomials, Release 10.4

(continued from previous page)

sage: a.list()[12 + 12*13 + 12*13^2 + 12*13^3 + 12*13^4 + 12*13^5 + 12*13^6 + O(13^7),
13^2 + O(13^9),
0,
2 + O(13^7)]>>> from sage.all import *>>> K = Qp(Integer(13),Integer(7))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> a = Integer(2)*t**Integer(3) + Integer(169)*t - Integer(1)>>> a(2 + O(13^7))*t^3 + (13^2 + O(13^9))*t + 12 + 12*13 + 12*13^2 + 12*13^3 +␣
˓→12*13^4 + 12*13^5 + 12*13^6 + O(13^7)>>> a.list()[12 + 12*13 + 12*13^2 + 12*13^3 + 12*13^4 + 12*13^5 + 12*13^6 + O(13^7),
13^2 + O(13^9),
0,
2 + O(13^7)]

lshift_coeffs(shift, no_list=False)
Return a new polynomials whose coefficients are multiplied by p^shift.
EXAMPLES:
sage: K = Qp(13, 4)
sage: R.<t> = K[]
sage: a = t + 52
sage: a.lshift_coeffs(3)(13^3 + O(13^7))*t + 4*13^4 + O(13^8)>>> from sage.all import *>>> K = Qp(Integer(13), Integer(4))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> a = t + Integer(52)>>> a.lshift_coeffs(Integer(3))(13^3 + O(13^7))*t + 4*13^4 + O(13^8)

newton_polygon()
Return the Newton polygon of this polynomial.
Note: If some coefficients have not enough precision an error is raised.
OUTPUT:• a NewtonPolygon
EXAMPLES:
sage: K = Qp(2, prec=5)
sage: P.<x> = K[]
sage: f = x^4 + 2^3*x^3 + 2^13*x^2 + 2^21*x + 2^37
sage: f.newton_polygon()˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 37), (1, 21), (3, 3), (4, 0)#␣(continues on next page)

322

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_polygon()˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)>>> from sage.all import *>>> K = Qp(Integer(2), prec=Integer(5))>>> P = K[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(4) + Integer(2)**Integer(3)*x**Integer(3) +␣˓→Integer(2)**Integer(13)*x**Integer(2) + Integer(2)**Integer(21)*x +␣˓→Integer(2)**Integer(37)>>> f.newton_polygon()˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 37), (1, 21), (3, 3), (4, 0)#␣#␣>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_polygon()#␣˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0), (10, 2)

Here is an example where the computation fails because precision is not sufficient:sage: g = f + K(0,0)*t^4; g(5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21)
sage: g.newton_polygon()˓→needs sage.geometry.polyhedronTraceback (most recent call last):...
PrecisionError: The coefficient of t^4 has not enough precision>>> from sage.all import *>>> g = f + K(Integer(0),Integer(0))*t**Integer(4); g(5^2 + O(5^22))*t^10 + O(5^0)*t^4 + (3 + O(5^20))*t + 5 + O(5^21)>>> g.newton_polygon()˓→needs sage.geometry.polyhedronTraceback (most recent call last):...
PrecisionError: The coefficient of t^4 has not enough precision#␣#␣

AUTHOR:• Xavier Caruso (2013-03-20)
newton_slopes(repetition=True)
Return a list of the Newton slopes of this polynomial.
These are the valuations of the roots of this polynomial.
If repetition is True, each slope is repeated a number of times equal to its multiplicity. Otherwise it
appears only one time.
INPUT:• repetition – boolean (default True)

2.1. Univariate Polynomials and Polynomial Rings

323

Polynomials, Release 10.4

OUTPUT:• a list of rationals
EXAMPLES:
sage: K = Qp(5)sage: R.<t> = K[]
sage: f = 5 + 3*t + t^4 + 25*t^10
sage: f.newton_polygon()˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0),(10, 2)sage: f.newton_slopes()
˓→needs sage.geometry.polyhedron[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]#␣#␣

sage: f.newton_slopes(repetition=False)
˓→needs sage.geometry.polyhedron[1, 0, -1/3]#␣>>> from sage.all import *>>> K = Qp(Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = Integer(5) + Integer(3)*t + t**Integer(4) + Integer(25)*t**Integer(10)>>> f.newton_polygon()#␣˓→needs sage.geometry.polyhedron
Finite Newton polygon with 4 vertices: (0, 1), (1, 0), (4, 0),(10, 2)>>> f.newton_slopes()#␣˓→needs sage.geometry.polyhedron[1, 0, 0, 0, -1/3, -1/3, -1/3, -1/3, -1/3, -1/3]>>> f.newton_slopes(repetition=False)
˓→needs sage.geometry.polyhedron[1, 0, -1/3]#␣

AUTHOR:• Xavier Caruso (2013-03-20)
prec_degree()Return the largest 𝑛 so that precision information is stored about the coefficient of 𝑥𝑛 .
Always greater than or equal to degree.
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.prec_degree()1>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(continues on next page)

324

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(1 + O(3^10))*T + 2 + O(3^10)>>> f.prec_degree()1

precision_absolute(n=None)
Return absolute precision information about self.
INPUT:• self – a p-adic polynomial• n – None or an integer (default None).
OUTPUT:
If n is None, returns a list of absolute precisions of coefficients. Otherwise, returns the absolute precision of
the coefficient of 𝑥𝑛 .
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.precision_absolute()[10, 10]>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.precision_absolute()[10, 10]precision_relative(n=None)
Return relative precision information about self.
INPUT:• self – a p-adic polynomial• n – None or an integer (default None).
OUTPUT:
If n is None, returns a list of relative precisions of coefficients. Otherwise, returns the relative precision of
the coefficient of 𝑥𝑛 .
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.precision_relative()[10, 10]2.1. Univariate Polynomials and Polynomial Rings

325

Polynomials, Release 10.4>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.precision_relative()[10, 10]

quo_rem(right, secure=False)
Return the quotient and remainder in division of self by right.
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2
sage: g = T**4 + 3*T+22
sage: g.quo_rem(f)((1 + O(3^10))*T^3 + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7␣
˓→+ 2*3^8 + 2*3^9 + O(3^10))*T^2 + (1 + 3 + O(3^10))*T + 1 + 3 + 2*3^2 + 2*3^
˓→3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10),
2 + 3 + 3^3 + O(3^10))>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2)>>> g = T**Integer(4) + Integer(3)*T+Integer(22)>>> g.quo_rem(f)((1 + O(3^10))*T^3 + (1 + 2*3 + 2*3^2 + 2*3^3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7␣
˓→+ 2*3^8 + 2*3^9 + O(3^10))*T^2 + (1 + 3 + O(3^10))*T + 1 + 3 + 2*3^2 + 2*3^
˓→3 + 2*3^4 + 2*3^5 + 2*3^6 + 2*3^7 + 2*3^8 + 2*3^9 + O(3^10),
2 + 3 + 3^3 + O(3^10))

rescale(a)Return 𝑓 (𝑎 · 𝑥).
Todo: Need to write this function for integer polynomials before this works.
EXAMPLES:
sage: K = Zp(13, 5)
sage: R.<t> = K[]
sage: f = t^3 + K(13, 3) * t
sage: f.rescale(2) # not implemented>>> from sage.all import *>>> K = Zp(Integer(13), Integer(5))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + K(Integer(13), Integer(3)) * t>>> f.rescale(Integer(2)) # not implemented

reverse(degree=None)
Return the reverse of the input polynomial, thought as a polynomial of degree degree.
If 𝑓 is a degree-𝑑 polynomial, its reverse is 𝑥𝑑 𝑓 (1/𝑥).
326

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

INPUT:• degree (None or an integer) – if specified, truncate or zero pad the list of coefficients to this degree
before reversing it.
EXAMPLES:
sage: K = Qp(13,7)
sage: R.<t> = K[]
sage: f = t^3 + 4*t; f(1 + O(13^7))*t^3 + (4 + O(13^7))*t
sage: f.reverse()
0*t^3 + (4 + O(13^7))*t^2 + 1 + O(13^7)sage: f.reverse(3)0*t^3 + (4 + O(13^7))*t^2 + 1 + O(13^7)sage: f.reverse(2)0*t^2 + (4 + O(13^7))*t
sage: f.reverse(4)0*t^4 + (4 + O(13^7))*t^3 + (1 + O(13^7))*t
sage: f.reverse(6)0*t^6 + (4 + O(13^7))*t^5 + (1 + O(13^7))*t^3>>> from sage.all import *>>> K = Qp(Integer(13),Integer(7))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> f = t**Integer(3) + Integer(4)*t; f(1 + O(13^7))*t^3 + (4 + O(13^7))*t>>> f.reverse()
0*t^3 + (4 + O(13^7))*t^2 + 1 + O(13^7)>>> f.reverse(Integer(3))
0*t^3 + (4 + O(13^7))*t^2 + 1 + O(13^7)>>> f.reverse(Integer(2))
0*t^2 + (4 + O(13^7))*t>>> f.reverse(Integer(4))
0*t^4 + (4 + O(13^7))*t^3 + (1 + O(13^7))*t>>> f.reverse(Integer(6))
0*t^6 + (4 + O(13^7))*t^5 + (1 + O(13^7))*t^3

rshift_coeffs(shift, no_list=False)
Return a new polynomial whose coefficients are p-adically shifted to the right by shift.
Note: Type Qp(5)(0).__rshift__? for more information.
EXAMPLES:
sage: K = Zp(13, 4)
sage: R.<t> = K[]
sage: a = t^2 + K(13,3)*t + 169; a(1 + O(13^4))*t^2 + (13 + O(13^3))*t + 13^2 + O(13^6)sage: b = a.rshift_coeffs(1); b
O(13^3)*t^2 + (1 + O(13^2))*t + 13 + O(13^5)sage: b.list()[13 + O(13^5), 1 + O(13^2), O(13^3)]sage: b = a.rshift_coeffs(2); b
O(13^2)*t^2 + O(13)*t + 1 + O(13^4)sage: b.list()[1 + O(13^4), O(13), O(13^2)]

2.1. Univariate Polynomials and Polynomial Rings

327

Polynomials, Release 10.4>>> from sage.all import *>>> K = Zp(Integer(13), Integer(4))>>> R = K[ t ]; (t,) = R._first_ngens(1)>>> a = t**Integer(2) + K(Integer(13),Integer(3))*t + Integer(169); a(1 + O(13^4))*t^2 + (13 + O(13^3))*t + 13^2 + O(13^6)>>> b = a.rshift_coeffs(Integer(1)); b
O(13^3)*t^2 + (1 + O(13^2))*t + 13 + O(13^5)>>> b.list()[13 + O(13^5), 1 + O(13^2), O(13^3)]>>> b = a.rshift_coeffs(Integer(2)); b
O(13^2)*t^2 + O(13)*t + 1 + O(13^4)>>> b.list()[1 + O(13^4), O(13), O(13^2)]

valuation(val_of_var=None)
Return the valuation of self.
INPUT:• self – a p-adic polynomial• val_of_var – None or a rational (default None).
OUTPUT:If val_of_var is None, returns the largest power of the variable dividing self. Otherwise, returns thevaluation of self where the variable is assigned valuation val_of_var
EXAMPLES:
sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.valuation()0>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.valuation()0valuation_of_coefficient(n=None)
Return valuation information about self’s coefficients.
INPUT:• self – a p-adic polynomial• n – None or an integer (default None).
OUTPUT:
If n is None, returns a list of valuations of coefficients. Otherwise, returns the valuation of the coefficient of
𝑥𝑛 .
EXAMPLES:

328

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: K = Qp(3,10)
sage: R.<T> = K[]
sage: f = T + 2; f
(1 + O(3^10))*T + 2 + O(3^10)sage: f.valuation_of_coefficient(1)0>>> from sage.all import *>>> K = Qp(Integer(3),Integer(10))>>> R = K[ T ]; (T,) = R._first_ngens(1)>>> f = T + Integer(2); f(1 + O(3^10))*T + 2 + O(3^10)>>> f.valuation_of_coefficient(Integer(1))
0sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.make_padic_poly(parent,x,
version)

2.1.16 p-adic Flat Polynomials
class sage.rings.polynomial.padics.polynomial_padic_flat.Polynomial_padic_flat(parent,
x=None,check=True,is_gen=False,
construct=False,
absprec=None)
Bases: Polynomial_generic_dense, Polynomial_padic

2.1.17 Univariate Polynomials over GF(p^e) via NTL’s ZZ_pEX
AUTHOR:• Yann Laigle-Chapuy (2010-01) initial implementation• Lorenz Panny (2023-01): minpoly_mod()• Giacomo Pope (2023-08): reverse(), inverse_series_trunc()
class sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
Bases: Polynomial_template
Univariate Polynomials over F𝑝𝑛 via NTL’s ZZ_pEX.
EXAMPLES:
sage: K.<a> = GF(next_prime(2**60)**3)
sage: R.<x> = PolynomialRing(K, implementation= NTL )sage: (x^3 + a*x^2 + 1) * (x + a)x^4 + 2*a*x^3 + a^2*x^2 + x + a

2.1. Univariate Polynomials and Polynomial Rings

329

Polynomials, Release 10.4>>> from sage.all import *>>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=( a ,)); (a,) =␣
˓→K._first_ngens(1)>>> R = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> (x**Integer(3) + a*x**Integer(2) + Integer(1)) * (x + a)x^4 + 2*a*x^3 + a^2*x^2 + x + a

inverse_series_trunc(prec)
Compute and return the inverse of self modulo 𝑥𝑝𝑟𝑒𝑐 .
The constant term of self must be invertible.
EXAMPLES:
sage: R.<x> = GF(101^2)[]sage: z2 = R.base_ring().gen()sage: f = (3*z2 + 57)*x^3 + (13*z2 + 94)*x^2 + (7*z2 + 2)*x + 66*z2 + 15
sage: f.inverse_series_trunc(1)51*z2 + 92
sage: f.inverse_series_trunc(2)(30*z2 + 30)*x + 51*z2 + 92
sage: f.inverse_series_trunc(3)(42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92
sage: f.inverse_series_trunc(4)(99*z2 + 96)*x^3 + (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92>>> from sage.all import *>>> R = GF(Integer(101)**Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> z2 = R.base_ring().gen()>>> f = (Integer(3)*z2 + Integer(57))*x**Integer(3) + (Integer(13)*z2 +␣˓→Integer(94))*x**Integer(2) + (Integer(7)*z2 + Integer(2))*x +␣˓→Integer(66)*z2 + Integer(15)>>> f.inverse_series_trunc(Integer(1))
51*z2 + 92>>> f.inverse_series_trunc(Integer(2))(30*z2 + 30)*x + 51*z2 + 92>>> f.inverse_series_trunc(Integer(3))(42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92>>> f.inverse_series_trunc(Integer(4))(99*z2 + 96)*x^3 + (42*z2 + 94)*x^2 + (30*z2 + 30)*x + 51*z2 + 92

is_irreducible(algorithm='fast_when_false', iter=1)
Return True precisely when self is irreducible over its base ring.
INPUT:• algorithm – a string (default "fast_when_false"), there are 3 available algorithms:"fast_when_true", "fast_when_false", and "probabilistic".
• iter – (default: 1) if the algorithm is "probabilistic", defines the number of iterations. The
error probability is bounded by 𝑞 -iter for polynomials in F𝑞 [𝑥].
EXAMPLES:
sage: K.<a> = GF(next_prime(2**60)**3)
sage: R.<x> = PolynomialRing(K, implementation= NTL )sage: P = x^3 + (2-a)*x + 1(continues on next page)

330

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: P.is_irreducible(algorithm="fast_when_false")
True
sage: P.is_irreducible(algorithm="fast_when_true")Truesage: P.is_irreducible(algorithm="probabilistic")Truesage: Q = (x^2+a)*(x+a^3)
sage: Q.is_irreducible(algorithm="fast_when_false")
False
sage: Q.is_irreducible(algorithm="fast_when_true")
False
sage: Q.is_irreducible(algorithm="probabilistic")
False>>> from sage.all import *>>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=( a ,)); (a,˓→) = K._first_ngens(1)>>> R = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> P = x**Integer(3) + (Integer(2)-a)*x + Integer(1)>>> P.is_irreducible(algorithm="fast_when_false")
True>>> P.is_irreducible(algorithm="fast_when_true")
True>>> P.is_irreducible(algorithm="probabilistic")
True>>> Q = (x**Integer(2)+a)*(x+a**Integer(3))>>> Q.is_irreducible(algorithm="fast_when_false")
False>>> Q.is_irreducible(algorithm="fast_when_true")
False>>> Q.is_irreducible(algorithm="probabilistic")
False

list(copy=True)
Return the list of coefficients.
EXAMPLES:
sage: K.<a> = GF(5^3)
sage: P = PolynomialRing(K, x )sage: f = P.random_element(100)sage: f.list() == [f[i] for i in range(f.degree()+1)]
True
sage: P.0.list()[0, 1]>>> from sage.all import *>>> K = GF(Integer(5)**Integer(3), names=( a ,)); (a,) = K._first_ngens(1)>>> P = PolynomialRing(K, x )>>> f = P.random_element(Integer(100))>>> f.list() == [f[i] for i in range(f.degree()+Integer(1))]
True>>> P.gen(0).list()[0, 1]

minpoly_mod(other)
2.1. Univariate Polynomials and Polynomial Rings

331

Polynomials, Release 10.4

Compute the minimal polynomial of this polynomial modulo another polynomial in the same ring.
ALGORITHM:
NTL’s MinPolyMod(), which uses Shoup’s algorithm [Sho1999].
EXAMPLES:
sage: R.<x> = GF(101^2)[]sage: f = x^17 + x^2 - 1
sage: (x^2).minpoly_mod(f)x^17 + 100*x^2 + 2*x + 100>>> from sage.all import *>>> R = GF(Integer(101)**Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(17) + x**Integer(2) - Integer(1)>>> (x**Integer(2)).minpoly_mod(f)x^17 + 100*x^2 + 2*x + 100

resultant(other)
Return the resultant of self and other, which must lie in the same polynomial ring.
INPUT:• other – a polynomial
OUTPUT: an element of the base ring of the polynomial ring
EXAMPLES:
sage: K.<a> = GF(next_prime(2**60)**3)
sage: R.<x> = PolynomialRing(K, implementation= NTL )sage: f = (x-a)*(x-a**2)*(x+1)
sage: g = (x-a**3)*(x-a**4)*(x+a)
sage: r = f.resultant(g)sage: r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots())
True>>> from sage.all import *>>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=( a ,)); (a,˓→) = K._first_ngens(1)>>> R = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = (x-a)*(x-a**Integer(2))*(x+Integer(1))>>> g = (x-a**Integer(3))*(x-a**Integer(4))*(x+a)>>> r = f.resultant(g)>>> r == prod(u - v for (u,eu) in f.roots() for (v,ev) in g.roots())
Truereverse(degree=None)
Return the polynomial obtained by reversing the coefficients of this polynomial. If degree is set then thisfunction behaves as if this polynomial has degree degree.
EXAMPLES:
sage: R.<x> = GF(101^2)[]sage: f = x^13 + 11*x^10 + 32*x^6 + 4
sage: f.reverse()(continues on next page)

332

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

4*x^13 + 32*x^7 + 11*x^3 + 1
sage: f.reverse(degree=15)
4*x^15 + 32*x^9 + 11*x^5 + x^2
sage: f.reverse(degree=2)
4*x^2>>> from sage.all import *>>> R = GF(Integer(101)**Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(13) + Integer(11)*x**Integer(10) +␣˓→Integer(32)*x**Integer(6) + Integer(4)>>> f.reverse()
4*x^13 + 32*x^7 + 11*x^3 + 1>>> f.reverse(degree=Integer(15))
4*x^15 + 32*x^9 + 11*x^5 + x^2>>> f.reverse(degree=Integer(2))
4*x^2shift(n)EXAMPLES:
sage: K.<a> = GF(next_prime(2**60)**3)
sage: R.<x> = PolynomialRing(K, implementation= NTL )sage: f = x^3 + x^2 + 1
sage: f.shift(1)x^4 + x^3 + x
sage: f.shift(-1)
x^2 + x>>> from sage.all import *>>> K = GF(next_prime(Integer(2)**Integer(60))**Integer(3), names=( a ,)); (a,˓→) = K._first_ngens(1)>>> R = PolynomialRing(K, implementation= NTL , names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> f = x**Integer(3) + x**Integer(2) + Integer(1)>>> f.shift(Integer(1))
x^4 + x^3 + x>>> f.shift(-Integer(1))
x^2 + xclass sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
Bases: Polynomial
Template for interfacing to external C / C++ libraries for implementations of polynomials.
AUTHORS:• Robert Bradshaw (2008-10): original idea for templating• Martin Albrecht (2008-10): initial implementation
This file implements a simple templating engine for linking univariate polynomials to their C/C++ library implementations. It requires a ‘linkage’ file which implements the celement_ functions (see sage.libs.ntl.
ntl_GF2X_linkage for an example). Both parts are then plugged together by inclusion of the linkage filewhen inheriting from this class. See sage.rings.polynomial.polynomial_gf2x for an example.
We illustrate the generic glueing using univariate polynomials over GF(2).

2.1. Univariate Polynomials and Polynomial Rings

333

Polynomials, Release 10.4

Note: Implementations using this template MUST implement coercion from base ring elements and get_unsafe(). See Polynomial_GF2X for an example.
degree()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.degree()1
sage: P(1).degree()0
sage: P(0).degree()-1>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.degree()1>>> P(Integer(1)).degree()0>>> P(Integer(0)).degree()-1gcd(other)
Return the greatest common divisor of self and other.
EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x*(x+1)
sage: f.gcd(x+1)
x + 1
sage: f.gcd(x^2)
x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.gcd(x+Integer(1))
x + 1>>> f.gcd(x**Integer(2))
xget_cparent()
is_gen()EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_gen()True
sage: (x+1).is_gen()
False

334

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.is_gen()True>>> (x+Integer(1)).is_gen()
False

is_one()EXAMPLES:
sage: P.<x> = GF(2)[]sage: P(1).is_one()True>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> P(Integer(1)).is_one()True

is_zero()
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.is_zero()
False>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.is_zero()
False

list(copy=True)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: x.list()[0, 1]
sage: list(x)[0, 1]>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> x.list()[0, 1]>>> list(x)[0, 1]

quo_rem(right)
EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^2 + x + 1
sage: f.quo_rem(x + 1)
(x, 1)

2.1. Univariate Polynomials and Polynomial Rings

335

Polynomials, Release 10.4>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(2) + x + Integer(1)>>> f.quo_rem(x + Integer(1))(x, 1)

shift(n)EXAMPLES:
sage: P.<x> = GF(2)[]sage: f = x^3 + x^2 + 1
sage: f.shift(1)x^4 + x^3 + x
sage: f.shift(-1)
x^2 + x>>> from sage.all import *>>> P = GF(Integer(2))[ x ]; (x,) = P._first_ngens(1)>>> f = x**Integer(3) + x**Integer(2) + Integer(1)>>> f.shift(Integer(1))
x^4 + x^3 + x>>> f.shift(-Integer(1))
x^2 + xtruncate(n)Returns this polynomial mod 𝑥𝑛 .
EXAMPLES:
sage: R.<x> =GF(2)[]sage: f = sum(x^n for n in range(10)); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1
sage: f.truncate(6)x^5 + x^4 + x^3 + x^2 + x + 1>>> from sage.all import *>>> R = GF(Integer(2))[ x ]; (x,) = R._first_ngens(1)>>> f = sum(x**n for n in range(Integer(10))); fx^9 + x^8 + x^7 + x^6 + x^5 + x^4 + x^3 + x^2 + x + 1>>> f.truncate(Integer(6))
x^5 + x^4 + x^3 + x^2 + x + 1

If the precision is higher than the degree of the polynomial then the polynomial itself is returned:
sage: f.truncate(10) is f
True>>> from sage.all import *>>> f.truncate(Integer(10)) is f
True

If the precision is negative, the zero polynomial is returned:
sage: f.truncate(-1)
0336

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> f.truncate(-Integer(1))
0xgcd(other)Computes extended gcd of self and other.
EXAMPLES:
sage: P.<x> = GF(7)[]sage: f = x*(x+1)
sage: f.xgcd(x+1)(x + 1, 0, 1)
sage: f.xgcd(x^2)(x, 1, 6)>>> from sage.all import *>>> P = GF(Integer(7))[ x ]; (x,) = P._first_ngens(1)>>> f = x*(x+Integer(1))>>> f.xgcd(x+Integer(1))(x + 1, 0, 1)>>> f.xgcd(x**Integer(2))(x, 1, 6)

sage.rings.polynomial.polynomial_zz_pex.make_element(parent, args)

2.1.18 Isolate Real Roots of Real Polynomials
AUTHOR:• Carl Witty (2007-09-19): initial version
This is an implementation of real root isolation. That is, given a polynomial with exact real coefficients, we computeisolating intervals for the real roots of the polynomial. (Polynomials with integer, rational, or algebraic real coefficientsare supported.)
We convert the polynomials into the Bernstein basis, and then use de Casteljau’s algorithm and Descartes’ rule of signs
on the Bernstein basis polynomial (using interval arithmetic) to locate the roots. The algorithm is similar to that in“A Descartes Algorithm for Polynomials with Bit-Stream Coefficients”, by Eigenwillig, Kettner, Krandick, Mehlhorn,
Schmitt, and Wolpert, but has three crucial optimizations over the algorithm in that paper:• Precision reduction: at certain points in the computation, we discard the low-order bits of the coefficients, widening
the intervals.
• Degree reduction: at certain points in the computation, we find lower-degree polynomials that are approximately
equal to our high-degree polynomial over the region of interest.
• When the intervals are too wide to continue (either because of a too-low initial precision, or because of precision or
degree reduction), and we need to restart with higher precision, we recall which regions have already been provennot to have any roots and do not examine them again.
The best description of the algorithms used (other than this source code itself) is in the slides for my Sage Days 4 talk,currently available from https://wiki.sagemath.org/days4schedule .
exception sage.rings.polynomial.real_roots.PrecisionError
Bases: ValueError

2.1. Univariate Polynomials and Polynomial Rings

337

Polynomials, Release 10.4

sage.rings.polynomial.real_roots.bernstein_down(d1, d2, s)Given polynomial degrees d1 and d2 (where d1 < d2), and a number of samples s, computes a matrix bd.
If you have a Bernstein polynomial of formal degree d2, and select s of its coefficients (according to subsample_vec),and multiply the resulting vector by bd, then you get the coefficients of a Bernstein polynomial of formal degree
d1, where this second polynomial is a good approximation to the first polynomial over the region of the Bernsteinbasis.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bernstein_down(3, 8, 5)[ 612/245 -348/245-37/49 338/245 -172/245][-724/441
132/49 395/441 -290/147 452/441][ 452/441 -290/147 395/441
132/49 -724/441][-172/245 338/245-37/49 -348/245 612/245]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bernstein_down(Integer(3), Integer(8), Integer(5))[ 612/245 -348/245-37/49 338/245 -172/245][-724/441
132/49 395/441 -290/147 452/441][ 452/441 -290/147 395/441
132/49 -724/441][-172/245 338/245-37/49 -348/245 612/245]

sage.rings.polynomial.real_roots.bernstein_expand(c, d2)
Given an integer vector representing a Bernstein polynomial p, and a degree d2, compute the representation of p
as a Bernstein polynomial of formal degree d2.
This is similar to multiplying by the result of bernstein_up, but should be faster for large d2 (this has about thesame number of multiplies, but in this version all the multiplies are by single machine words).
This returns a pair consisting of the expanded polynomial, and the maximum error E. (So if an element of the
returned polynomial is a, and the true value of that coefficient is b, then a <= b < a + E.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: c = vector(ZZ, [1000, 2000, -3000])
sage: bernstein_expand(c, 3)((1000, 1666, 333, -3000), 1)
sage: bernstein_expand(c, 4)((1000, 1500, 1000, -500, -3000), 1)
sage: bernstein_expand(c, 20)((1000, 1100, 1168, 1205, 1210, 1184, 1126, 1036, 915, 763, 578, 363, 115, -164, ˓→474, -816, -1190, -1595, -2032, -2500, -3000), 1)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> c = vector(ZZ, [Integer(1000), Integer(2000), -Integer(3000)])>>> bernstein_expand(c, Integer(3))((1000, 1666, 333, -3000), 1)>>> bernstein_expand(c, Integer(4))((1000, 1500, 1000, -500, -3000), 1)>>> bernstein_expand(c, Integer(20))((1000, 1100, 1168, 1205, 1210, 1184, 1126, 1036, 915, 763, 578, 363, 115, -164, ˓→474, -816, -1190, -1595, -2032, -2500, -3000), 1)

338

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4class sage.rings.polynomial.real_roots.bernstein_polynomial_factory
Bases: object
An abstract base class for bernstein_polynomial factories. That is, elements of subclasses represent Bernsteinpolynomials (exactly), and are responsible for creating interval_bernstein_polynomial_integer approximations atarbitrary precision.
Supports four methods, coeffs_bitsize(), bernstein_polynomial(), lsign(), and usign(). The coeffs_bitsize() method
gives an integer approximation to the log2 of the max of the absolute values of the Bernstein coefficients. The
bernstein_polynomial(scale_log2) method gives an approximation where the maximum coefficient has approximately coeffs_bitsize() - scale_log2 bits. The lsign() and usign() methods give the (exact) sign of the first and lastcoefficient, respectively.
lsign()
Return the sign of the first coefficient of this Bernstein polynomial.
usign()
Return the sign of the last coefficient of this Bernstein polynomial.
class sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ar(poly, neg)
Bases: bernstein_polynomial_factoryThis class holds an exact Bernstein polynomial (represented as a list of algebraic real coefficients), and returns
arbitrarily-precise interval approximations of this polynomial on demand.
bernstein_polynomial(scale_log2)
Compute an interval_bernstein_polynomial_integer that approximates this polynomial, using the given
scale_log2. (Smaller scale_log2 values give more accurate approximations.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(AA)sage: p = (x - 1) * (x - sqrt(AA(2))) * (x - 2)sage: bpf = bernstein_polynomial_factory_ar(p, False)
sage: print(bpf.bernstein_polynomial(0))
degree 3 IBP with 2-bit coefficientssage: bpf.bernstein_polynomial(-20)<IBP: ((-2965821, 2181961, -1542880, 1048576) + [0 .. 1)) * 2^-20>
sage: bpf = bernstein_polynomial_factory_ar(p, True)
sage: bpf.bernstein_polynomial(-20)<IBP: ((-2965821, -2181962, -1542880, -1048576) + [0 .. 1)) * 2^-20>
sage: p = x^2 - 1
sage: bpf = bernstein_polynomial_factory_ar(p, False)
sage: bpf.bernstein_polynomial(-10)<IBP: ((-1024, 0, 1024) + [0 .. 1)) * 2^-10>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(AA)>>> p = (x - Integer(1)) * (x - sqrt(AA(Integer(2)))) * (x - Integer(2))>>> bpf = bernstein_polynomial_factory_ar(p, False)>>> print(bpf.bernstein_polynomial(Integer(0)))
degree 3 IBP with 2-bit coefficients>>> bpf.bernstein_polynomial(-Integer(20))<IBP: ((-2965821, 2181961, -1542880, 1048576) + [0 .. 1)) * 2^-20>>>> bpf = bernstein_polynomial_factory_ar(p, True)>>> bpf.bernstein_polynomial(-Integer(20))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

339

Polynomials, Release 10.4

(continued from previous page)<IBP: ((-2965821, -2181962, -1542880, -1048576) + [0 .. 1)) * 2^-20>>>> p = x**Integer(2) - Integer(1)>>> bpf = bernstein_polynomial_factory_ar(p, False)>>> bpf.bernstein_polynomial(-Integer(10))<IBP: ((-1024, 0, 1024) + [0 .. 1)) * 2^-10>

coeffs_bitsize()
Computes the approximate log2 of the maximum of the absolute values of the coefficients.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(AA)sage: p = (x - 1) * (x - sqrt(AA(2))) * (x - 2)sage: bernstein_polynomial_factory_ar(p, False).coeffs_bitsize()1>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(AA)>>> p = (x - Integer(1)) * (x - sqrt(AA(Integer(2)))) * (x - Integer(2))>>> bernstein_polynomial_factory_ar(p, False).coeffs_bitsize()
1class sage.rings.polynomial.real_roots.bernstein_polynomial_factory_intlist(coeffs)
Bases: bernstein_polynomial_factoryThis class holds an exact Bernstein polynomial (represented as a list of integer coefficients), and returns
arbitrarily-precise interval approximations of this polynomial on demand.
bernstein_polynomial(scale_log2)
Compute an interval_bernstein_polynomial_integer that approximates this polynomial, using the given
scale_log2. (Smaller scale_log2 values give more accurate approximations.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bpf = bernstein_polynomial_factory_intlist([10, -20, 30, -40])
sage: print(bpf.bernstein_polynomial(0))
degree 3 IBP with 6-bit coefficientssage: bpf.bernstein_polynomial(20)<IBP: ((0, -1, 0, -1) + [0 .. 1)) * 2^20; lsign 1>
sage: bpf.bernstein_polynomial(0)<IBP: (10, -20, 30, -40) + [0 .. 1)>
sage: bpf.bernstein_polynomial(-20)<IBP: ((10485760, -20971520, 31457280, -41943040) + [0 .. 1)) * 2^-20>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bpf = bernstein_polynomial_factory_intlist([Integer(10), -Integer(20),␣
˓→Integer(30), -Integer(40)])>>> print(bpf.bernstein_polynomial(Integer(0)))
degree 3 IBP with 6-bit coefficients>>> bpf.bernstein_polynomial(Integer(20))<IBP: ((0, -1, 0, -1) + [0 .. 1)) * 2^20; lsign 1>(continues on next page)

340

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> bpf.bernstein_polynomial(Integer(0))<IBP: (10, -20, 30, -40) + [0 .. 1)>>>> bpf.bernstein_polynomial(-Integer(20))<IBP: ((10485760, -20971520, 31457280, -41943040) + [0 .. 1)) * 2^-20>

coeffs_bitsize()
Computes the approximate log2 of the maximum of the absolute values of the coefficients.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bernstein_polynomial_factory_intlist([1, 2, 3, -60000]).coeffs_bitsize()
16>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bernstein_polynomial_factory_intlist([Integer(1), Integer(2), Integer(3),␣
˓→-Integer(60000)]).coeffs_bitsize()
16class sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ratlist(coeffs)
Bases: bernstein_polynomial_factoryThis class holds an exact Bernstein polynomial (represented as a list of rational coefficients), and returns
arbitrarily-precise interval approximations of this polynomial on demand.
bernstein_polynomial(scale_log2)
Compute an interval_bernstein_polynomial_integer that approximates this polynomial, using the given
scale_log2. (Smaller scale_log2 values give more accurate approximations.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bpf = bernstein_polynomial_factory_ratlist([1/3, -22/7, 193/71, -140/
˓→99])
sage: print(bpf.bernstein_polynomial(0))
degree 3 IBP with 3-bit coefficientssage: bpf.bernstein_polynomial(20)<IBP: ((0, -1, 0, -1) + [0 .. 1)) * 2^20; lsign 1>
sage: bpf.bernstein_polynomial(0)<IBP: (0, -4, 2, -2) + [0 .. 1); lsign 1>
sage: bpf.bernstein_polynomial(-20)<IBP: ((349525, -3295525, 2850354, -1482835) + [0 .. 1)) * 2^-20>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bpf = bernstein_polynomial_factory_ratlist([Integer(1)/Integer(3), ˓→Integer(22)/Integer(7), Integer(193)/Integer(71), -Integer(140)/
˓→Integer(99)])>>> print(bpf.bernstein_polynomial(Integer(0)))
degree 3 IBP with 3-bit coefficients>>> bpf.bernstein_polynomial(Integer(20))<IBP: ((0, -1, 0, -1) + [0 .. 1)) * 2^20; lsign 1>>>> bpf.bernstein_polynomial(Integer(0))<IBP: (0, -4, 2, -2) + [0 .. 1); lsign 1>(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

341

Polynomials, Release 10.4

(continued from previous page)>>> bpf.bernstein_polynomial(-Integer(20))<IBP: ((349525, -3295525, 2850354, -1482835) + [0 .. 1)) * 2^-20>

coeffs_bitsize()
Computes the approximate log2 of the maximum of the absolute values of the coefficients.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bernstein_polynomial_factory_ratlist([1, 2, 3, -60000]).coeffs_bitsize()
15
sage: bernstein_polynomial_factory_ratlist([65535/65536]).coeffs_bitsize()-1
sage: bernstein_polynomial_factory_ratlist([65536/65535]).coeffs_bitsize()1>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bernstein_polynomial_factory_ratlist([Integer(1), Integer(2), Integer(3),␣
˓→-Integer(60000)]).coeffs_bitsize()15>>> bernstein_polynomial_factory_ratlist([Integer(65535)/Integer(65536)]).
˓→coeffs_bitsize()-1>>> bernstein_polynomial_factory_ratlist([Integer(65536)/Integer(65535)]).
˓→coeffs_bitsize()1sage.rings.polynomial.real_roots.bernstein_up(d1, d2, s=None)
Given polynomial degrees d1 and d2, where d1 < d2, compute a matrix bu.
If you have a Bernstein polynomial of formal degree d1, and multiply its coefficient vector by bu, then the result isthe coefficient vector of the same polynomial represented as a Bernstein polynomial of formal degree d2.
If s is not None, then it represents a number of samples; then the product only gives s of the coefficients of the newBernstein polynomial, selected according to subsample_vec.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bernstein_down(3, 7, 4)[ 12/5-4
3-2/5][-13/15
16/3
-4
8/15]
[ 8/15-4
16/3 -13/15][ -2/53-4
12/5]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bernstein_down(Integer(3), Integer(7), Integer(4))[ 12/5-4
3-2/5][-13/15
16/3
-4
8/15]
[ 8/15-4
16/3 -13/15][ -2/53-4
12/5]

sage.rings.polynomial.real_roots.bitsize_doctest(n)342Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.real_roots.cl_maximum_root(cl)Given a polynomial represented by a list of its coefficients (as RealIntervalFieldElements), compute an upper boundon its largest real root.
Uses two algorithms of Akritas, Strzebo'nski, and Vigklas, and picks the better result.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: cl_maximum_root([RIF(-1), RIF(0), RIF(1)])
1.00000000000000>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> cl_maximum_root([RIF(-Integer(1)), RIF(Integer(0)), RIF(Integer(1))])1.00000000000000

sage.rings.polynomial.real_roots.cl_maximum_root_first_lambda(cl)Given a polynomial represented by a list of its coefficients (as RealIntervalFieldElements), compute an upper boundon its largest real root.
Uses the first-lambda algorithm from “Implementations of a New Theorem for Computing Bounds for Positive
Roots of Polynomials”, by Akritas, Strzebo'nski, and Vigklas.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: cl_maximum_root_first_lambda([RIF(-1), RIF(0), RIF(1)])
1.00000000000000>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> cl_maximum_root_first_lambda([RIF(-Integer(1)), RIF(Integer(0)),␣
˓→RIF(Integer(1))])1.00000000000000

sage.rings.polynomial.real_roots.cl_maximum_root_local_max(cl)Given a polynomial represented by a list of its coefficients (as RealIntervalFieldElements), compute an upper boundon its largest real root.
Uses the local-max algorithm from “Implementations of a New Theorem for Computing Bounds for Positive Rootsof Polynomials”, by Akritas, Strzebo'nski, and Vigklas.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: cl_maximum_root_local_max([RIF(-1), RIF(0), RIF(1)])
1.41421356237310>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> cl_maximum_root_local_max([RIF(-Integer(1)), RIF(Integer(0)),␣
˓→RIF(Integer(1))])1.41421356237310

class sage.rings.polynomial.real_roots.context
Bases: object

2.1. Univariate Polynomials and Polynomial Rings

343

Polynomials, Release 10.4

A simple context class, which is passed through parts of the real root isolation algorithm to avoid global variables.
Holds logging information, a random number generator, and the target machine wordsize.
get_be_log()
get_dc_log()
sage.rings.polynomial.real_roots.de_casteljau_doublevec(c, x)
Given a polynomial in Bernstein form with floating-point coefficients over the region [0 .. 1], and a split point x,
use de Casteljau’s algorithm to give polynomials in Bernstein form over [0 .. x] and [x .. 1].
This function will work for an arbitrary rational split point x, as long as 0 < x < 1; but it has a specialized code pathfor x==1/2.
INPUT:• c – vector of coefficients of polynomial in Bernstein form
• x – rational splitting point; 0 < x < 1
OUTPUT:• c1 – coefficients of polynomial over range [0 .. x]• c2 – coefficients of polynomial over range [x .. 1]• err_inc – number of half-ulps by which error intervals widened
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: c = vector(RDF, [0.7, 0, 0, 0, 0, 0])
sage: de_casteljau_doublevec(c, 1/2)((0.7, 0.35, 0.175, 0.0875, 0.04375, 0.021875), (0.021875, 0.0, 0.0, 0.0, 0.0, 0.
˓→0), 5)sage: de_casteljau_doublevec(c, 1/3) # rel tol((0.7, 0.4666666666666667, 0.31111111111111117, 0.20740740740740746, 0.
˓→13827160493827165, 0.09218106995884777), (0.09218106995884777, 0.0, 0.0, 0.0, 0.
˓→0, 0.0), 15)
sage: de_casteljau_doublevec(c, 7/22) # rel tol((0.7, 0.4772727272727273, 0.3254132231404959, 0.22187265214124724, 0.
˓→15127680827812312, 0.10314327837144759), (0.10314327837144759, 0.0, 0.0, 0.0, 0.
˓→0, 0.0), 15)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> c = vector(RDF, [RealNumber( 0.7 ), Integer(0), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0)])>>> de_casteljau_doublevec(c, Integer(1)/Integer(2))((0.7, 0.35, 0.175, 0.0875, 0.04375, 0.021875), (0.021875, 0.0, 0.0, 0.0, 0.0, 0.
˓→0), 5)>>> de_casteljau_doublevec(c, Integer(1)/Integer(3)) # rel tol((0.7, 0.4666666666666667, 0.31111111111111117, 0.20740740740740746, 0.
˓→13827160493827165, 0.09218106995884777), (0.09218106995884777, 0.0, 0.0, 0.0, 0.
˓→0, 0.0), 15)>>> de_casteljau_doublevec(c, Integer(7)/Integer(22)) # rel tol((0.7, 0.4772727272727273, 0.3254132231404959, 0.22187265214124724, 0.
˓→15127680827812312, 0.10314327837144759), (0.10314327837144759, 0.0, 0.0, 0.0, 0.
˓→0, 0.0), 15)344

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.real_roots.de_casteljau_intvec(c, c_bitsize, x, use_ints)
Given a polynomial in Bernstein form with integer coefficients over the region [0 .. 1], and a split point x, use deCasteljau’s algorithm to give polynomials in Bernstein form over [0 .. x] and [x .. 1].
This function will work for an arbitrary rational split point x, as long as 0 < x < 1; but it has specialized code paths
that make some values of x faster than others. If x == a/(a + b), there are special efficient cases for a==1, b==1,
a+b fits in a machine word, a+b is a power of 2, a fits in a machine word, b fits in a machine word. The mostefficient case is x==1/2.
Given split points x == a/(a + b) and y == c/(c + d), where min(a, b) and min(c, d) fit in the same number ofmachine words and a+b and c+d are both powers of two, then x and y should be equally fast split points.
If use_ints is nonzero, then instead of checking whether numerators and denominators fit in machine words, wecheck whether they fit in ints (32 bits, even on 64-bit machines). This slows things down, but allows for identicalresults across machines.
INPUT:• c – vector of coefficients of polynomial in Bernstein form
• c_bitsize – approximate size of coefficients in c (in bits)• x – rational splitting point; 0 < x < 1
OUTPUT:• c1 – coefficients of polynomial over range [0 .. x]• c2 – coefficients of polynomial over range [x .. 1]• err_inc – amount by which error intervals widened
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: c = vector(ZZ, [1048576, 0, 0, 0, 0, 0])
sage: de_casteljau_intvec(c, 20, 1/2, 1)((1048576, 524288, 262144, 131072, 65536, 32768), (32768, 0, 0, 0, 0, 0), 1)
sage: de_casteljau_intvec(c, 20, 1/3, 1)((1048576, 699050, 466033, 310689, 207126, 138084), (138084, 0, 0, 0, 0, 0), 1)
sage: de_casteljau_intvec(c, 20, 7/22, 1)((1048576, 714938, 487457, 332357, 226607, 154505), (154505, 0, 0, 0, 0, 0), 1)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> c = vector(ZZ, [Integer(1048576), Integer(0), Integer(0), Integer(0),␣
˓→Integer(0), Integer(0)])>>> de_casteljau_intvec(c, Integer(20), Integer(1)/Integer(2), Integer(1))((1048576, 524288, 262144, 131072, 65536, 32768), (32768, 0, 0, 0, 0, 0), 1)>>> de_casteljau_intvec(c, Integer(20), Integer(1)/Integer(3), Integer(1))((1048576, 699050, 466033, 310689, 207126, 138084), (138084, 0, 0, 0, 0, 0), 1)>>> de_casteljau_intvec(c, Integer(20), Integer(7)/Integer(22), Integer(1))((1048576, 714938, 487457, 332357, 226607, 154505), (154505, 0, 0, 0, 0, 0), 1)

sage.rings.polynomial.real_roots.degree_reduction_next_size(n)Given n (a polynomial degree), returns either a smaller integer or None. This defines the sequence of degrees
followed by our degree reduction implementation.
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

345

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: degree_reduction_next_size(1000)
30
sage: degree_reduction_next_size(20)15sage: degree_reduction_next_size(3)2sage: degree_reduction_next_size(2) is None
True>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> degree_reduction_next_size(Integer(1000))30>>> degree_reduction_next_size(Integer(20))
15>>> degree_reduction_next_size(Integer(3))
2>>> degree_reduction_next_size(Integer(2)) is None
True

sage.rings.polynomial.real_roots.dprod_imatrow_vec(m, v, k)Computes the dot product of row k of the matrix m with the vector v (that is, compute one element of the productm*v).
If v has more elements than m has columns, then elements of v are selected using subsample_vec.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: m = matrix(3, range(9))
sage: dprod_imatrow_vec(m, vector(ZZ, [1, 0, 0, 0]), 1)0
sage: dprod_imatrow_vec(m, vector(ZZ, [0, 1, 0, 0]), 1)
3
sage: dprod_imatrow_vec(m, vector(ZZ, [0, 0, 1, 0]), 1)
4
sage: dprod_imatrow_vec(m, vector(ZZ, [0, 0, 0, 1]), 1)
5
sage: dprod_imatrow_vec(m, vector(ZZ, [1, 0, 0]), 1)
3
sage: dprod_imatrow_vec(m, vector(ZZ, [0, 1, 0]), 1)
4
sage: dprod_imatrow_vec(m, vector(ZZ, [0, 0, 1]), 1)
5
sage: dprod_imatrow_vec(m, vector(ZZ, [1, 2, 3]), 1)
26>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> m = matrix(Integer(3), range(Integer(9)))>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(1), Integer(0), Integer(0),␣
˓→Integer(0)]), Integer(1))
0>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(0), Integer(1), Integer(0),␣
˓→Integer(0)]), Integer(1))
3(continues on next page)

346

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(0), Integer(0), Integer(1),␣
˓→Integer(0)]), Integer(1))
4>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(0), Integer(0), Integer(0),␣
˓→Integer(1)]), Integer(1))
5>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(1), Integer(0), Integer(0)]),␣
˓→Integer(1))
3>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(0), Integer(1), Integer(0)]),␣
˓→Integer(1))
4>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(0), Integer(0), Integer(1)]),␣
˓→Integer(1))
5>>> dprod_imatrow_vec(m, vector(ZZ, [Integer(1), Integer(2), Integer(3)]),␣
˓→Integer(1))
26

sage.rings.polynomial.real_roots.get_realfield_rndu(n)A simple cache for RealField fields (with rounding set to round-to-positive-infinity).
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: get_realfield_rndu(20)Real Field with 20 bits of precision and rounding RNDU
sage: get_realfield_rndu(53)Real Field with 53 bits of precision and rounding RNDU
sage: get_realfield_rndu(20)Real Field with 20 bits of precision and rounding RNDU>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> get_realfield_rndu(Integer(20))
Real Field with 20 bits of precision and rounding RNDU>>> get_realfield_rndu(Integer(53))
Real Field with 53 bits of precision and rounding RNDU>>> get_realfield_rndu(Integer(20))
Real Field with 20 bits of precision and rounding RNDU

class sage.rings.polynomial.real_roots.interval_bernstein_polynomial
Bases: object
An interval_bernstein_polynomial is an approximation to an exact polynomial. This approximation is in the formof a Bernstein polynomial (a polynomial given as coefficients over a Bernstein basis) with interval coefficients.
The Bernstein basis of degree n over the region [a .. b] is the set of polynomials(︂ )︂
𝑛(𝑥 − 𝑎)𝑘 (𝑏 − 𝑥)𝑛−𝑘 /(𝑏 − 𝑎)𝑛𝑘
for 0 ≤ 𝑘 ≤ 𝑛.
A degree-n interval Bernstein polynomial P with its region [a .. b] can represent an exact polynomial p in two
different ways: it can “contain” the polynomial or it can “bound” the polynomial.

2.1. Univariate Polynomials and Polynomial Rings

347

Polynomials, Release 10.4

We say that P contains p if, when p is represented as a degree-n Bernstein polynomial over [a .. b], its coefficientsare contained in the corresponding interval coefficients of P. For instance, [0.9 .. 1.1]*x^2 (which is a degree-2
interval Bernstein polynomial over [0 .. 1]) contains x^2.
We say that P bounds p if, for all a <= x <= b, there exists a polynomial p’ contained in P such that p(x) == p’(x).
For instance, [0 .. 1]*x is a degree-1 interval Bernstein polynomial which bounds x^2 over [0 .. 1].
If P contains p, then P bounds p; but the converse is not necessarily true. In particular, if n < m, it is possible for adegree-n interval Bernstein polynomial to bound a degree-m polynomial; but it cannot contain the polynomial.
In the case where P bounds p, we maintain extra information, the “slope error”. We say that P (over [a .. b]) bounds
p with a slope error of E (where E is an interval) if there is a polynomial p’ contained in P such that the derivativeof (p - p’) is bounded by E in the range [a .. b]. If P bounds p with a slope error of 0 then P contains p.
(Note that “contains” and “bounds” are not standard terminology; I just made them up.)
Interval Bernstein polynomials are useful in finding real roots because of the following properties:• Given an exact real polynomial p, we can compute an interval Bernstein polynomial over an arbitrary region
containing p.
• Given an interval Bernstein polynomial P over [a .. c], where a < b < c, we can compute interval Bernsteinpolynomials P1 over [a .. b] and P2 over [b .. c], where P1 and P2 contain (or bound) all polynomials that P
contains (or bounds).
• Given a degree-n interval Bernstein polynomial P over [a .. b], and m < n, we can compute a degree-m intervalBernstein polynomial P’ over [a .. b] that bounds all polynomials that P bounds.
• It is sometimes possible to prove that no polynomial bounded by P over [a .. b] has any roots in [a .. b].
(Roughly, this is possible when no polynomial contained by P has any complex roots near the line segment [a.. b], where “near” is defined relative to the length b-a.)• It is sometimes possible to prove that every polynomial bounded by P over [a .. b] with slope error E has
exactly one root in [a .. b]. (Roughly, this is possible when every polynomial contained by P over [a .. b]
has exactly one root in [a .. b], there are no other complex roots near the line segment [a .. b], and every
polynomial contained in P has a derivative which is bounded away from zero over [a .. b] by an amount whichis large relative to E.)• Starting from a sufficiently precise interval Bernstein polynomial, it is always possible to split it into polynomials which provably have 0 or 1 roots (as long as your original polynomial has no multiple real roots).
So a rough outline of a family of algorithms would be:• Given a polynomial p, compute a region [a .. b] in which any real roots must lie.
• Compute an interval Bernstein polynomial P containing p over [a .. b].
• Keep splitting P until you have isolated all the roots. Optionally, reduce the degree or the precision of theinterval Bernstein polynomials at intermediate stages (to reduce computation time). If this seems not to beworking, go back and try again with higher precision.
Obviously, there are many details to be worked out to turn this into a full algorithm, like:• What initial precision is selected for computing P?
• How do you decide when to reduce the degree of intermediate polynomials?
• How do you decide when to reduce the precision of intermediate polynomials?
• How do you decide where to split the interval Bernstein polynomial regions?
• How do you decide when to give up and start over with higher precision?

348

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Each set of answers to these questions gives a different algorithm (potentially with very different performance characteristics), but all of them can use this interval_bernstein_polynomial class as their basic building
block.
To save computation time, all coefficients in an interval_bernstein_polynomial share the same interval
width. (There is one exception: when creating an interval_bernstein_polynomial, the first and lastcoefficients can be marked as “known positive” or “known negative”. This has some of the same effect as having a(potentially) smaller interval width for these two coefficients, although it does not affect de Casteljau splitting.) To
allow for widely varying coefficient magnitudes, all coefficients in an interval_bernstein_polynomial are scaled by
2𝑛 (where 𝑛 may be positive, negative, or zero).
There are two representations for interval_bernstein_polynomials, integer and floating-point. These are the two
subclasses of this class; interval_bernstein_polynomial itself is an abstract class.
interval_bernstein_polynomial and its subclasses are not expected to be used outside this file.
region()region_width()try_rand_split(ctx, logging_note)
Compute a random split point r (using the random number generator embedded in ctx). We require 1/4 <= r
< 3/4 (to ensure that recursive algorithms make progress).
Then, try doing a de Casteljau split of this polynomial at r, resulting in polynomials p1 and p2. If we see thatthe sign of this polynomial is determined at r, then return (p1, p2, r); otherwise, return None.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([50, 20, -90, -70, 200], error=5)
sage: bp1, bp2, _ = bp.try_rand_split(mk_context(), None)sage: bp1
<IBP: (50, 29, -27, -56, -11) + [0 .. 6) over [0 .. 43/64]>
sage: bp2
<IBP: (-11, 10, 49, 111, 200) + [0 .. 6) over [43/64 .. 1]>
sage: bp1, bp2, _ = bp.try_rand_split(mk_context(seed=42), None)sage: bp1
<IBP: (50, 32, -11, -41, -29) + [0 .. 6) over [0 .. 583/1024]>
sage: bp2
<IBP: (-29, -20, 13, 83, 200) + [0 .. 6) over [583/1024 .. 1]>
sage: bp = mk_ibpf([0.5, 0.2, -0.9, -0.7, 0.99], neg_err=-0.1, pos_err=0.01)
sage: bp1, bp2, _ = bp.try_rand_split(mk_context(), None)sage: bp1 # rel tol<IBP: (0.5, 0.2984375, -0.2642578125, -0.5511661529541015, -0.
˓→3145806974172592) + [-0.10000000000000069 .. 0.010000000000000677] over [0 .
˓→. 43/64]>
sage: bp2 # rel tol<IBP: (-0.3145806974172592, -0.19903896331787108, 0.04135986328125002, 0.
˓→43546875, 0.99) + [-0.10000000000000069 .. 0.010000000000000677] over [43/
˓→64 .. 1]>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(50), Integer(20), -Integer(90), -Integer(70),␣
˓→Integer(200)], error=Integer(5))>>> bp1, bp2, _ = bp.try_rand_split(mk_context(), None)>>> bp1<IBP: (50, 29, -27, -56, -11) + [0 .. 6) over [0 .. 43/64]>(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

349

Polynomials, Release 10.4

(continued from previous page)>>> bp2<IBP: (-11, 10, 49, 111, 200) + [0 .. 6) over [43/64 .. 1]>>>> bp1, bp2, _ = bp.try_rand_split(mk_context(seed=Integer(42)), None)>>> bp1<IBP: (50, 32, -11, -41, -29) + [0 .. 6) over [0 .. 583/1024]>>>> bp2<IBP: (-29, -20, 13, 83, 200) + [0 .. 6) over [583/1024 .. 1]>>>> bp = mk_ibpf([RealNumber( 0.5 ), RealNumber( 0.2 ), -RealNumber( 0.9 ), ˓→RealNumber( 0.7 ), RealNumber( 0.99 )], neg_err=-RealNumber( 0.1 ), pos_
˓→err=RealNumber( 0.01 ))>>> bp1, bp2, _ = bp.try_rand_split(mk_context(), None)>>> bp1 # rel tol<IBP: (0.5, 0.2984375, -0.2642578125, -0.5511661529541015, -0.
˓→3145806974172592) + [-0.10000000000000069 .. 0.010000000000000677] over [0 .
˓→. 43/64]>>>> bp2 # rel tol<IBP: (-0.3145806974172592, -0.19903896331787108, 0.04135986328125002, 0.
˓→43546875, 0.99) + [-0.10000000000000069 .. 0.010000000000000677] over [43/
˓→64 .. 1]>

try_split(ctx, logging_note)
Try doing a de Casteljau split of this polynomial at 1/2, resulting in polynomials p1 and p2. If we see that thesign of this polynomial is determined at 1/2, then return (p1, p2, 1/2); otherwise, return None.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([50, 20, -90, -70, 200], error=5)
sage: bp1, bp2, _ = bp.try_split(mk_context(), None)sage: bp1
<IBP: (50, 35, 0, -29, -31) + [0 .. 6) over [0 .. 1/2]>
sage: bp2
<IBP: (-31, -33, -8, 65, 200) + [0 .. 6) over [1/2 .. 1]>
sage: bp = mk_ibpf([0.5, 0.2, -0.9, -0.7, 0.99], neg_err=-0.1, pos_err=0.01)
sage: bp1, bp2, _ = bp.try_split(mk_context(), None)sage: bp1
<IBP: (0.5, 0.35, 0.0, -0.2875, -0.369375) + [-0.10000000000000023 .. 0.
˓→010000000000000226] over [0 .. 1/2]>
sage: bp2
<IBP: (-0.369375, -0.45125, -0.3275, 0.14500000000000002, 0.99) + [-0.
˓→10000000000000023 .. 0.010000000000000226] over [1/2 .. 1]>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(50), Integer(20), -Integer(90), -Integer(70),␣
˓→Integer(200)], error=Integer(5))>>> bp1, bp2, _ = bp.try_split(mk_context(), None)>>> bp1<IBP: (50, 35, 0, -29, -31) + [0 .. 6) over [0 .. 1/2]>>>> bp2<IBP: (-31, -33, -8, 65, 200) + [0 .. 6) over [1/2 .. 1]>>>> bp = mk_ibpf([RealNumber( 0.5 ), RealNumber( 0.2 ), -RealNumber( 0.9 ), ˓→RealNumber( 0.7 ), RealNumber( 0.99 )], neg_err=-RealNumber( 0.1 ), pos_
˓→err=RealNumber( 0.01 ))>>> bp1, bp2, _ = bp.try_split(mk_context(), None)>>> bp1(continues on next page)

350

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)<IBP: (0.5, 0.35, 0.0, -0.2875, -0.369375) + [-0.10000000000000023 .. 0.
˓→010000000000000226] over [0 .. 1/2]>>>> bp2<IBP: (-0.369375, -0.45125, -0.3275, 0.14500000000000002, 0.99) + [-0.
˓→10000000000000023 .. 0.010000000000000226] over [1/2 .. 1]>

variations()
Consider a polynomial (written in either the normal power basis or the Bernstein basis). Take its list ofcoefficients, omitting zeroes. Count the number of positions in the list where the sign of one coefficient is
opposite the sign of the next coefficient.
This count is the number of sign variations of the polynomial. According to Descartes’ rule of signs, thenumber of real roots of the polynomial (counted with multiplicity) in a certain interval is always less than orequal to the number of sign variations, and the difference is always even. (If the polynomial is written in the
power basis, the region is the positive reals; if the polynomial is written in the Bernstein basis over a particularregion, then we count roots in that region.)
In particular, a polynomial with no sign variations has no real roots in the region, and a polynomial with one
sign variation has one real root in the region.
In an interval Bernstein polynomial, we do not necessarily know the signs of the coefficients (if some of thecoefficient intervals contain zero), so the polynomials contained by this interval polynomial may not all havethe same number of sign variations. However, we can compute a range of possible numbers of sign variations.
This function returns the range, as a 2-tuple of integers.
class sage.rings.polynomial.real_roots.interval_bernstein_polynomial_float
Bases: interval_bernstein_polynomial
This is the subclass of interval_bernstein_polynomial where polynomial coefficients are represented
using floating-point numbers.
In the floating-point representation, each coefficient is represented as an IEEE double-precision float A, and the(shared) lower and upper interval widths E1 and E2. These represent the coefficients (A+E1)*2^n <= c <=(A+E2)*2^n.
Note that we always have E1 <= 0 <= E2. Also, each floating-point coefficient has absolute value less than one.
(Note that mk_ibpf() is a simple helper function for creating elements of interval_bernstein_polynomial_float in doctests.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpf([0.1, 0.2, 0.3], pos_err=0.5); print(bp)degree 2 IBP with floating-point coefficientssage: bp
<IBP: (0.1, 0.2, 0.3) + [0.0 .. 0.5]>
sage: bp.variations()(0, 0)
sage: bp = mk_ibpf([-0.3, -0.1, 0.1, -0.1, -0.3, -0.1],
˓→needs sage.symbolic....:
lower=1, upper=5/4, usign=1, pos_err=0.2,....:
scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp)degree 5 IBP with floating-point coefficientssage: bp
˓→needs sage.symbolic<IBP: ((-0.3, -0.1, 0.1, -0.1, -0.3, -0.1) + [0.0 .. 0.2]) * 2^-3#␣#␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

351

Polynomials, Release 10.4

(continued from previous page)

over [1 .. 5/4]; usign 1; level 2; slope_err 3.141592653589794?>
sage: bp.variations()
˓→needs sage.symbolic(3, 3)#␣>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpf([RealNumber( 0.1 ), RealNumber( 0.2 ), RealNumber( 0.3 )], pos_
˓→err=RealNumber( 0.5 )); print(bp)degree 2 IBP with floating-point coefficients>>> bp<IBP: (0.1, 0.2, 0.3) + [0.0 .. 0.5]>>>> bp.variations()(0, 0)>>> bp = mk_ibpf([-RealNumber( 0.3 ), -RealNumber( 0.1 ), RealNumber( 0.1 ), ˓→RealNumber( 0.1 ), -RealNumber( 0.3 ), -RealNumber( 0.1 )],␣˓→# needs sage.symbolic...
lower=Integer(1), upper=Integer(5)/Integer(4), usign=Integer(1),␣
˓→pos_err=RealNumber( 0.2 ),...
scale_log2=-Integer(3), level=Integer(2), slope_err=RIF(pi));␣
˓→print(bp)degree 5 IBP with floating-point coefficients>>> bp#␣˓→needs sage.symbolic<IBP: ((-0.3, -0.1, 0.1, -0.1, -0.3, -0.1) + [0.0 .. 0.2]) * 2^-3over [1 .. 5/4]; usign 1; level 2; slope_err 3.141592653589794?>>>> bp.variations()#␣˓→needs sage.symbolic(3, 3)

as_float()de_casteljau(ctx, mid, msign=0)
Uses de Casteljau’s algorithm to compute the representation of this polynomial in a Bernstein basis over new
regions.
INPUT:• mid – where to split the Bernstein basis region; 0 < mid < 1• msign – default 0 (unknown); the sign of this polynomial at mid
OUTPUT:• bp1, bp2 – the new interval Bernstein polynomials• ok – a boolean; True if the sign of the original polynomial at mid is known
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: ctx = mk_context()
sage: bp = mk_ibpf([0.5, 0.2, -0.9, -0.7, 0.99], neg_err=-0.1, pos_err=0.01)
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 1/2)
sage: bp1
<IBP: (0.5, 0.35, 0.0, -0.2875, -0.369375) + [-0.10000000000000023 .. 0.
˓→010000000000000226] over [0 .. 1/2]>
sage: bp2
(continues on next page)352

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)<IBP: (-0.369375, -0.45125, -0.3275, 0.14500000000000002, 0.99) + [-0.
˓→10000000000000023 .. 0.010000000000000226] over [1/2 .. 1]>
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 2/3)
sage: bp1 # rel tol 2e-16<IBP: (0.5, 0.30000000000000004, -0.2555555555555555, -0.5444444444444444, -0.
˓→32172839506172846) + [-0.10000000000000069 .. 0.010000000000000677] over [0␣˓→.. 2/3]>
sage: bp2 # rel tol 3e-15<IBP: (-0.32172839506172846, -0.21037037037037046, 0.028888888888888797, 0.
˓→4266666666666666, 0.99) + [-0.10000000000000069 .. 0.010000000000000677]␣
˓→over [2/3 .. 1]>
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 7/39)
sage: bp1 # rel tol<IBP: (0.5, 0.4461538461538461, 0.36653517422748183, 0.27328680523946786, 0.
˓→1765692706232836) + [-0.10000000000000069 .. 0.010000000000000677] over [0 .
˓→. 7/39]>
sage: bp2 # rel tol<IBP: (0.1765692706232836, -0.26556803047927313, -0.7802038132807364, -0.
˓→3966666666666666, 0.99) + [-0.10000000000000069 .. 0.010000000000000677]␣
˓→over [7/39 .. 1]>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> ctx = mk_context()>>> bp = mk_ibpf([RealNumber( 0.5 ), RealNumber( 0.2 ), -RealNumber( 0.9 ), ˓→RealNumber( 0.7 ), RealNumber( 0.99 )], neg_err=-RealNumber( 0.1 ), pos_
˓→err=RealNumber( 0.01 ))>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(1)/Integer(2))>>> bp1<IBP: (0.5, 0.35, 0.0, -0.2875, -0.369375) + [-0.10000000000000023 .. 0.
˓→010000000000000226] over [0 .. 1/2]>>>> bp2<IBP: (-0.369375, -0.45125, -0.3275, 0.14500000000000002, 0.99) + [-0.
˓→10000000000000023 .. 0.010000000000000226] over [1/2 .. 1]>>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(2)/Integer(3))>>> bp1 # rel tol 2e-16<IBP: (0.5, 0.30000000000000004, -0.2555555555555555, -0.5444444444444444, -0.
˓→32172839506172846) + [-0.10000000000000069 .. 0.010000000000000677] over [0␣˓→.. 2/3]>>>> bp2 # rel tol 3e-15<IBP: (-0.32172839506172846, -0.21037037037037046, 0.028888888888888797, 0.
˓→4266666666666666, 0.99) + [-0.10000000000000069 .. 0.010000000000000677]␣
˓→over [2/3 .. 1]>>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(7)/Integer(39))>>> bp1 # rel tol<IBP: (0.5, 0.4461538461538461, 0.36653517422748183, 0.27328680523946786, 0.
˓→1765692706232836) + [-0.10000000000000069 .. 0.010000000000000677] over [0 .
˓→. 7/39]>>>> bp2 # rel tol<IBP: (0.1765692706232836, -0.26556803047927313, -0.7802038132807364, -0.
˓→3966666666666666, 0.99) + [-0.10000000000000069 .. 0.010000000000000677]␣
˓→over [7/39 .. 1]>

get_msb_bit()
Return an approximation of the log2 of the maximum of the absolute values of the coefficients, as an integer.
slope_range()
2.1. Univariate Polynomials and Polynomial Rings

353

Polynomials, Release 10.4

Compute a bound on the derivative of this polynomial, over its region.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpf([0.5, 0.2, -0.9, -0.7, 0.99], neg_err=-0.1, pos_err=0.01)
sage: bp.slope_range().str(style= brackets )[-4.8400000000000017 .. 7.2000000000000011]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpf([RealNumber( 0.5 ), RealNumber( 0.2 ), -RealNumber( 0.9 ), ˓→RealNumber( 0.7 ), RealNumber( 0.99 )], neg_err=-RealNumber( 0.1 ), pos_
˓→err=RealNumber( 0.01 ))>>> bp.slope_range().str(style= brackets )[-4.8400000000000017 .. 7.2000000000000011]

class sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer
Bases: interval_bernstein_polynomial
This is the subclass of interval_bernstein_polynomial where polynomial coefficients are represented
using integers.
In this integer representation, each coefficient is represented by a GMP arbitrary-precision integer A, and a (shared)
interval width E (which is a machine integer). These represent the coefficients A*2^n <= c < (A+E)*2^n.
(Note that mk_ibpi is a simple helper() function for creating elements of interval_bernstein_polynomial_integer in doctests.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([1, 2, 3], error=5); print(bp)degree 2 IBP with 2-bit coefficientssage: bp
<IBP: (1, 2, 3) + [0 .. 5)>
sage: bp.variations()(0, 0)
sage: bp = mk_ibpi([-3, -1, 1, -1, -3, -1], lower=1, upper=5/4, usign=1,#␣˓→needs sage.symbolic....:
error=2, scale_log2=-3, level=2, slope_err=RIF(pi)); print(bp)degree 5 IBP with 2-bit coefficientssage: bp#␣˓→needs sage.symbolic<IBP: ((-3, -1, 1, -1, -3, -1) + [0 .. 2)) * 2^-3 over [1 .. 5/4]; usign 1;
level 2; slope_err 3.141592653589794?>
sage: bp.variations()#␣˓→needs sage.symbolic(3, 3)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(1), Integer(2), Integer(3)], error=Integer(5));␣
˓→print(bp)degree 2 IBP with 2-bit coefficients>>> bp<IBP: (1, 2, 3) + [0 .. 5)>>>> bp.variations()(continues on next page)354

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(0, 0)>>> bp = mk_ibpi([-Integer(3), -Integer(1), Integer(1), -Integer(1), -Integer(3),␣
˓→-Integer(1)], lower=Integer(1), upper=Integer(5)/Integer(4), usign=Integer(1), ␣˓→# needs sage.symbolic...
error=Integer(2), scale_log2=-Integer(3), level=Integer(2),␣
˓→slope_err=RIF(pi)); print(bp)degree 5 IBP with 2-bit coefficients>>> bp#␣˓→needs sage.symbolic<IBP: ((-3, -1, 1, -1, -3, -1) + [0 .. 2)) * 2^-3 over [1 .. 5/4]; usign 1;
level 2; slope_err 3.141592653589794?>>>> bp.variations()#␣˓→needs sage.symbolic(3, 3)

as_float()
Compute an interval_bernstein_polynomial_float which contains (or bounds) all the polynomials this interval
polynomial contains (or bounds).
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([50, 20, -90, -70, 200], error=5)
sage: print(bp.as_float())
degree 4 IBP with floating-point coefficientssage: bp.as_float()<IBP: ((0.1953125, 0.078125, -0.3515625, -0.2734375, 0.78125) + [-1.
˓→1275702593849246e-16 .. 0.01953125000000017]) * 2^8>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(50), Integer(20), -Integer(90), -Integer(70),␣
˓→Integer(200)], error=Integer(5))>>> print(bp.as_float())
degree 4 IBP with floating-point coefficients>>> bp.as_float()<IBP: ((0.1953125, 0.078125, -0.3515625, -0.2734375, 0.78125) + [-1.
˓→1275702593849246e-16 .. 0.01953125000000017]) * 2^8>de_casteljau(ctx, mid, msign=0)
Uses de Casteljau’s algorithm to compute the representation of this polynomial in a Bernstein basis over new
regions.
INPUT:• mid – where to split the Bernstein basis region; 0 < mid < 1• msign – default 0 (unknown); the sign of this polynomial at mid
OUTPUT:• bp1, bp2 – the new interval Bernstein polynomials• ok – a boolean; True if the sign of the original polynomial at mid is known
EXAMPLES:

2.1. Univariate Polynomials and Polynomial Rings

355

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([50, 20, -90, -70, 200], error=5)
sage: ctx = mk_context()
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 1/2)
sage: bp1
<IBP: (50, 35, 0, -29, -31) + [0 .. 6) over [0 .. 1/2]>
sage: bp2
<IBP: (-31, -33, -8, 65, 200) + [0 .. 6) over [1/2 .. 1]>
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 2/3)
sage: bp1
<IBP: (50, 30, -26, -55, -13) + [0 .. 6) over [0 .. 2/3]>
sage: bp2
<IBP: (-13, 8, 47, 110, 200) + [0 .. 6) over [2/3 .. 1]>
sage: bp1, bp2, ok = bp.de_casteljau(ctx, 7/39)
sage: bp1
<IBP: (50, 44, 36, 27, 17) + [0 .. 6) over [0 .. 7/39]>
sage: bp2
<IBP: (17, -26, -75, -22, 200) + [0 .. 6) over [7/39 .. 1]>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(50), Integer(20), -Integer(90), -Integer(70),␣
˓→Integer(200)], error=Integer(5))>>> ctx = mk_context()>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(1)/Integer(2))>>> bp1<IBP: (50, 35, 0, -29, -31) + [0 .. 6) over [0 .. 1/2]>>>> bp2<IBP: (-31, -33, -8, 65, 200) + [0 .. 6) over [1/2 .. 1]>>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(2)/Integer(3))>>> bp1<IBP: (50, 30, -26, -55, -13) + [0 .. 6) over [0 .. 2/3]>>>> bp2<IBP: (-13, 8, 47, 110, 200) + [0 .. 6) over [2/3 .. 1]>>>> bp1, bp2, ok = bp.de_casteljau(ctx, Integer(7)/Integer(39))>>> bp1<IBP: (50, 44, 36, 27, 17) + [0 .. 6) over [0 .. 7/39]>>>> bp2<IBP: (17, -26, -75, -22, 200) + [0 .. 6) over [7/39 .. 1]>

down_degree(ctx, max_err, exp_err_shift)Compute an interval_bernstein_polynomial_integer which bounds all the polynomials this interval polynomial
bounds, but is of lesser degree.
During the computation, we find an “expected error” expected_err, which is the error inherent in our approach(this depends on the degrees involved, and is proportional to the error of the current polynomial).
We require that the error of the new interval polynomial be bounded both by max_err, and by expected_err<< exp_err_shift. If we find such a polynomial p, then we return a pair of p and some debugging/logging
information. Otherwise, we return the pair (None, None).
If the resulting polynomial would have error more than 2^17, then it is downscaled before returning.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([0, 100, 400, 903], error=2)
sage: ctx = mk_context()(continues on next page)

356

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: bp
<IBP: (0, 100, 400, 903) + [0 .. 2)>
sage: dbp, _ = bp.down_degree(ctx, 10, 32)
sage: dbp
<IBP: (-1, 148, 901) + [0 .. 4); level 1; slope_err 0.?e2>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(0), Integer(100), Integer(400), Integer(903)],␣
˓→error=Integer(2))>>> ctx = mk_context()>>> bp<IBP: (0, 100, 400, 903) + [0 .. 2)>>>> dbp, _ = bp.down_degree(ctx, Integer(10), Integer(32))>>> dbp<IBP: (-1, 148, 901) + [0 .. 4); level 1; slope_err 0.?e2>

down_degree_iter(ctx, max_scale)Compute a degree-reduced version of this interval polynomial, by iterating down_degree.
We stop when degree reduction would give a polynomial which is too inaccurate, meaning that either we think
the current polynomial may have more roots in its region than the degree of the reduced polynomial, or thatthe least significant accurate bit in the result (on the absolute scale) would be larger than 1 << max_scale.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([0, 100, 400, 903, 1600, 2500], error=2)
sage: ctx = mk_context()
sage: bp
<IBP: (0, 100, 400, 903, 1600, 2500) + [0 .. 2)>
sage: rbp = bp.down_degree_iter(ctx, 6)
sage: rbp
<IBP: (-4, 249, 2497) + [0 .. 9); level 2; slope_err 0.?e3>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(0), Integer(100), Integer(400), Integer(903),␣
˓→Integer(1600), Integer(2500)], error=Integer(2))>>> ctx = mk_context()>>> bp<IBP: (0, 100, 400, 903, 1600, 2500) + [0 .. 2)>>>> rbp = bp.down_degree_iter(ctx, Integer(6))>>> rbp<IBP: (-4, 249, 2497) + [0 .. 9); level 2; slope_err 0.?e3>

downscale(bits)
Compute an interval_bernstein_polynomial_integer which contains (or bounds) all the polynomials this interval polynomial contains (or bounds), but uses “bits” fewer bits.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([0, 100, 400, 903], error=2)
sage: bp.downscale(5)<IBP: ((0, 3, 12, 28) + [0 .. 1)) * 2^5>

2.1. Univariate Polynomials and Polynomial Rings

357

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(0), Integer(100), Integer(400), Integer(903)],␣
˓→error=Integer(2))>>> bp.downscale(Integer(5))<IBP: ((0, 3, 12, 28) + [0 .. 1)) * 2^5>

get_msb_bit()
Return an approximation of the log2 of the maximum of the absolute values of the coefficients, as an integer.
slope_range()
Compute a bound on the derivative of this polynomial, over its region.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([0, 100, 400, 903], error=2)
sage: bp.slope_range().str(style= brackets )[294.00000000000000 .. 1515.0000000000000]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(0), Integer(100), Integer(400), Integer(903)],␣
˓→error=Integer(2))>>> bp.slope_range().str(style= brackets )[294.00000000000000 .. 1515.0000000000000]

sage.rings.polynomial.real_roots.intvec_to_doublevec(b, err)
Given a vector of integers A = [a1, …, an], and an integer error bound E, returns a vector of floating-point numbers
B = [b1, …, bn], lower and upper error bounds F1 and F2, and a scaling factor d, such that(𝑏𝑘 + 𝐹 1) * 2𝑑 ≤ 𝑎𝑘
and𝑎𝑘 + 𝐸 ≤ (𝑏𝑘 + 𝐹 2) * 2𝑑
If bj is the element of B with largest absolute value, then 0.5 <= abs(bj) < 1.0 .
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: intvec_to_doublevec(vector(ZZ, [1, 2, 3, 4, 5]), 3)((0.125, 0.25, 0.375, 0.5, 0.625), -1.1275702593849246e-16, 0.37500000000000017,␣
˓→3)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> intvec_to_doublevec(vector(ZZ, [Integer(1), Integer(2), Integer(3),␣
˓→Integer(4), Integer(5)]), Integer(3))((0.125, 0.25, 0.375, 0.5, 0.625), -1.1275702593849246e-16, 0.37500000000000017,␣
˓→3)class sage.rings.polynomial.real_roots.island
Bases: object
This implements the island portion of my ocean-island root isolation algorithm. See the documentation for classocean, for more information on the overall algorithm.
358

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Island root refinement starts with a Bernstein polynomial whose region is the whole island (or perhaps slightly morethan the island in certain cases). There are two subalgorithms; one when looking at a Bernstein polynomial covering
a whole island (so we know that there are gaps on the left and right), and one when looking at a Bernstein polynomial
covering the left segment of an island (so we know that there is a gap on the left, but the right is in the middle ofan island). An important invariant of the left-segment subalgorithm over the region [l .. r] is that it always finds a
gap [r0 .. r] ending at its right endpoint.
Ignoring degree reduction, downscaling (precision reduction), and failures to split, the algorithm is roughly:
Whole island:
1. If the island definitely has exactly one root, then return.
2. Split the island in (approximately) half.
3. If both halves definitely have no roots, then remove this island from its doubly-linked list (merging its left andright gaps) and return.
4. If either half definitely has no roots, then discard that half and call the whole-island algorithm with the other
half, then return.
5. If both halves may have roots, then call the left-segment algorithm on the left half.
6. We now know that there is a gap immediately to the left of the right half, so call the whole-island algorithm
on the right half, then return.
Left segment:
1. Split the left segment in (approximately) half.
2. If both halves definitely have no roots, then extend the left gap over the segment and return.
3. If the left half definitely has no roots, then extend the left gap over this half and call the left-segment algorithm
on the right half, then return.
4. If the right half definitely has no roots, then split the island in two, creating a new gap. Call the whole-island
algorithm on the left half, then return.
5. Both halves may have roots. Call the left-segment algorithm on the left half.
6. We now know that there is a gap immediately to the left of the right half, so call the left-segment algorithm
on the right half, then return.
Degree reduction complicates this picture only slightly. Basically, we use heuristics to decide when degree reduction
might be likely to succeed and be helpful; whenever this is the case, we attempt degree reduction.
Precision reduction and split failure add more complications. The algorithm maintains a stack of different-precision
representations of the interval Bernstein polynomial. The base of the stack is at the highest (currently known)
precision; each stack entry has approximately half the precision of the entry below it. When we do a split, we pop off
the top of the stack, split it, then push whichever half we’re interested in back on the stack (so the different Bernsteinpolynomials may be over different regions). When we push a polynomial onto the stack, we may heuristically decideto push further lower-precision versions of the same polynomial onto the stack.
In the algorithm above, whenever we say “split in (approximately) half”, we attempt to split the top-of-stack polynomial using try_split() and try_rand_split(). However, these will fail if the sign of the polynomial at the chosen
split point is unknown (if the polynomial is not known to high enough precision, or if the chosen split point actually
happens to be a root of the polynomial). If this fails, then we discard the top-of-stack polynomial, and try again
with the next polynomial down (which has approximately twice the precision). This next polynomial may not be
over the same region; if not, we split it using de Casteljau’s algorithm to get a polynomial over (approximately) thesame region first.
If we run out of higher-precision polynomials (if we empty out the entire stack), then we give up on root refinement
for this island. The ocean class will notice this, provide the island with a higher-precision polynomial, and restart

2.1. Univariate Polynomials and Polynomial Rings

359

Polynomials, Release 10.4

root refinement. Basically the only information kept in that case is the lower and upper bounds on the island. Since
these are updated whenever we discover a “half” (of an island or a segment) that definitely contains no roots, wenever need to re-examine these gaps. (We could keep more information. For example, we could keep a record ofsplit points that succeeded and failed. However, a split point that failed at lower precision is likely to succeed at
higher precision, so it’s not worth avoiding. It could be useful to select split points that are known to succeed, but
starting from a new Bernstein polynomial over a slightly different region, hitting such split points would require deCasteljau splits with non-power-of-two denominators, which are much much slower.)
bp_done(bp)Examine the given Bernstein polynomial to see if it is known to have exactly one root in its region. (Inaddition, we require that the polynomial region not include 0 or 1. This makes things work if the user gives
explicit bounds to real_roots(), where the lower or upper bound is a root of the polynomial. real_roots() deals
with this by explicitly detecting it, dividing out the appropriate linear polynomial, and adding the root to thereturned list of roots; but then if the island considers itself “done” with a region including 0 or 1, the returnedroot regions can overlap with each other.)done(ctx)
Check to see if the island is known to contain zero roots or is known to contain one root.
has_root()
Assuming that the island is done (has either 0 or 1 roots), reports whether the island has a root.
less_bits(ancestors, bp)
Heuristically pushes lower-precision polynomials on the polynomial stack. See the class documentation forclass island for more information.
more_bits(ctx, ancestors, bp, rightmost)Find a Bernstein polynomial on the “ancestors” stack with more precision than bp; if it is over a different
region, then shrink its region to (approximately) match that of bp. (If this is rightmost – if bp covers thewhole island – then we only require that the new region cover the whole island fairly tightly; if this is not
rightmost, then the new region will have exactly the same right boundary as bp, although the left boundary
may vary slightly.)refine(ctx)
Attempts to shrink and/or split this island into sub-island that each definitely contain exactly one root.
refine_recurse(ctx, bp, ancestors, history, rightmost)This implements the root isolation algorithm described in the class documentation for class island. This is theimplementation of both the whole-island and the left-segment algorithms; if the flag rightmost is True, thenit is the whole-island algorithm, otherwise the left-segment algorithm.
The precision-reduction stack is (ancestors + [bp]); that is, the top-of-stack is maintained separately.
reset_root_width(target_width)
Modify the criteria for this island to require that it is not “done” until its width is less than or equal to target_width.
shrink_bp(ctx)
If the island’s Bernstein polynomial covers a region much larger than the island itself (in particular, if either
the island’s left gap or right gap are totally contained in the polynomial’s region) then shrink the polynomial
down to cover the island more tightly.
class sage.rings.polynomial.real_roots.linear_map(lower, upper)
Bases: object
A simple class to map linearly between original coordinates (ranging from [lower .. upper]) and ocean coordinates(ranging from [0 .. 1]).

360

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

from_ocean(region)
to_ocean(region)
sage.rings.polynomial.real_roots.max_abs_doublevec(c)Given a floating-point vector, return the maximum of the absolute values of its elements.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: max_abs_doublevec(vector(RDF, [0.1, -0.767, 0.3, 0.693]))
0.767>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> max_abs_doublevec(vector(RDF, [RealNumber( 0.1 ), -RealNumber( 0.767 ),␣
˓→RealNumber( 0.3 ), RealNumber( 0.693 )]))
0.767

sage.rings.polynomial.real_roots.max_bitsize_intvec_doctest(b)sage.rings.polynomial.real_roots.maximum_root_first_lambda(p)Given a polynomial with real coefficients, computes an upper bound on its largest real root.
This is using the first-lambda algorithm from “Implementations of a New Theorem for Computing Bounds for
Positive Roots of Polynomials”, by Akritas, Strzebo'nski, and Vigklas.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: maximum_root_first_lambda((x-1)*(x-2)*(x-3))
6.00000000000001
sage: maximum_root_first_lambda((x+1)*(x+2)*(x+3))0.000000000000000
sage: maximum_root_first_lambda(x^2 - 1)
1.00000000000000>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> maximum_root_first_lambda((x-Integer(1))*(x-Integer(2))*(x-Integer(3)))
6.00000000000001>>> maximum_root_first_lambda((x+Integer(1))*(x+Integer(2))*(x+Integer(3)))
0.000000000000000>>> maximum_root_first_lambda(x**Integer(2) - Integer(1))
1.00000000000000

sage.rings.polynomial.real_roots.maximum_root_local_max(p)Given a polynomial with real coefficients, computes an upper bound on its largest real root, using the local-max
algorithm from “Implementations of a New Theorem for Computing Bounds for Positive Roots of Polynomials”,
by Akritas, Strzebo'nski, and Vigklas.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: maximum_root_local_max((x-1)*(x-2)*(x-3))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

361

Polynomials, Release 10.4

(continued from previous page)

12.0000000000001
sage: maximum_root_local_max((x+1)*(x+2)*(x+3))0.000000000000000
sage: maximum_root_local_max(x^2 - 1)
1.41421356237310>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> maximum_root_local_max((x-Integer(1))*(x-Integer(2))*(x-Integer(3)))
12.0000000000001>>> maximum_root_local_max((x+Integer(1))*(x+Integer(2))*(x+Integer(3)))
0.000000000000000>>> maximum_root_local_max(x**Integer(2) - Integer(1))
1.41421356237310

sage.rings.polynomial.real_roots.min_max_delta_intvec(a, b)Given two integer vectors a and b (of equal, nonzero length), return a pair of the minimum and maximum values
taken on by a[i] - b[i].
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: a = vector(ZZ, [10, -30])
sage: b = vector(ZZ, [15, -60])
sage: min_max_delta_intvec(a, b)(30, -5)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> a = vector(ZZ, [Integer(10), -Integer(30)])>>> b = vector(ZZ, [Integer(15), -Integer(60)])>>> min_max_delta_intvec(a, b)(30, -5)sage.rings.polynomial.real_roots.min_max_diff_doublevec(c)Given a floating-point vector b = (b0, …, bn), compute the minimum and maximum values of b_{j+1} - b_j.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: min_max_diff_doublevec(vector(RDF, [1, 7, -2]))(-9.0, 6.0)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> min_max_diff_doublevec(vector(RDF, [Integer(1), Integer(7), -Integer(2)]))(-9.0, 6.0)

sage.rings.polynomial.real_roots.min_max_diff_intvec(b)Given an integer vector b = (b0, …, bn), compute the minimum and maximum values of b_{j+1} - b_j.
EXAMPLES:

362

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: min_max_diff_intvec(vector(ZZ, [1, 7, -2]))(-9, 6)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> min_max_diff_intvec(vector(ZZ, [Integer(1), Integer(7), -Integer(2)]))(-9, 6)sage.rings.polynomial.real_roots.mk_context(do_logging=False, seed=0, wordsize=32)
A simple wrapper for creating context objects with coercions, defaults, etc.
For use in doctests.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: mk_context(do_logging=True, seed=3, wordsize=64)
root isolation context: seed=3; do_logging=True; wordsize=64>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> mk_context(do_logging=True, seed=Integer(3), wordsize=Integer(64))
root isolation context: seed=3; do_logging=True; wordsize=64

sage.rings.polynomial.real_roots.mk_ibpf(coeffs, lower=0, upper=1, lsign=0, usign=0, neg_err=0,
pos_err=0, scale_log2=0, level=0, slope_err=None)
A simple wrapper for creating interval_bernstein_polynomial_float objects with coercions, defaults, etc.
For use in doctests.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: print(mk_ibpf([0.5, 0.2, -0.9, -0.7, 0.99], pos_err=0.1, neg_err=-0.01))
degree 4 IBP with floating-point coefficients>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> print(mk_ibpf([RealNumber( 0.5 ), RealNumber( 0.2 ), -RealNumber( 0.9 ), ˓→RealNumber( 0.7 ), RealNumber( 0.99 )], pos_err=RealNumber( 0.1 ), neg_err=˓→RealNumber( 0.01 )))degree 4 IBP with floating-point coefficientssage.rings.polynomial.real_roots.mk_ibpi(coeffs, lower=0, upper=1, lsign=0, usign=0, error=1,
scale_log2=0, level=0, slope_err=None)
A simple wrapper for creating interval_bernstein_polynomial_integer objects with coercions, defaults, etc.
For use in doctests.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: print(mk_ibpi([50, 20, -90, -70, 200], error=5))
degree 4 IBP with 8-bit coefficients2.1. Univariate Polynomials and Polynomial Rings

363

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> print(mk_ibpi([Integer(50), Integer(20), -Integer(90), -Integer(70),␣
˓→Integer(200)], error=Integer(5)))
degree 4 IBP with 8-bit coefficientsclass sage.rings.polynomial.real_roots.ocean
Bases: object
Given the tools we’ve defined so far, there are many possible root isolation algorithms that differ on where to selectsplit points, what precision to work at when, and when to attempt degree reduction.
Here we implement one particular algorithm, which I call the ocean-island algorithm. We start with an intervalBernstein polynomial defined over the region [0 .. 1]. This region is the “ocean”. Using de Casteljau’s algorithm
and Descartes’ rule of signs, we divide this region into subregions which may contain roots, and subregions which
are guaranteed not to contain roots. Subregions which may contain roots are “islands”; subregions known not to
contain roots are “gaps”.
All the real root isolation work happens in class island. See the documentation of that class for more information.
An island can be told to refine itself until it contains only a single root. This may not succeed, if the island’s intervalBernstein polynomial does not have enough precision. The ocean basically loops, refining each of its islands, thenincreasing the precision of islands which did not succeed in isolating a single root; until all islands are done.
Increasing the precision of unsuccessful islands is done in a single pass using split_for_target(); this means it ispossible to share work among multiple islands.
all_done()
Return True iff all islands are known to contain exactly one root.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc.all_done()False
sage: oc.find_roots()
sage: oc.all_done()True>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> oc.all_done()
False>>> oc.find_roots()>>> oc.all_done()
True

approx_bp(scale_log2)
Return an approximation to our Bernstein polynomial with the given scale_log2.
EXAMPLES:

364

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc.approx_bp(0)<IBP: (0, -4, 2, -2) + [0 .. 1); lsign 1>
sage: oc.approx_bp(-20)<IBP: ((349525, -3295525, 2850354, -1482835) + [0 .. 1)) * 2^-20>>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> oc.approx_bp(Integer(0))<IBP: (0, -4, 2, -2) + [0 .. 1); lsign 1>>>> oc.approx_bp(-Integer(20))<IBP: ((349525, -3295525, 2850354, -1482835) + [0 .. 1)) * 2^-20>

find_roots()
Isolate all roots in this ocean.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc
ocean with precision 120 and 1 island(s)sage: oc.find_roots()
sage: oc
ocean with precision 120 and 3 island(s)sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1, 0, ˓→1111/2, 0, 11108889/14, 0, 0, 0, 0, -1]), lmap)
sage: oc.find_roots()
sage: oc
ocean with precision 240 and 3 island(s)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> ococean with precision 120 and 1 island(s)>>> oc.find_roots()>>> ococean with precision 120 and 3 island(s)>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1),˓→ Integer(0), -Integer(1111)/Integer(2), Integer(0), Integer(11108889)/
˓→Integer(14), Integer(0), Integer(0), Integer(0), Integer(0), -Integer(1)]),␣
˓→lmap)>>> oc.find_roots()>>> ococean with precision 240 and 3 island(s)increase_precision()
Increase the precision of the interval Bernstein polynomial held by any islands which are not done. (In normal
2.1. Univariate Polynomials and Polynomial Rings

365

Polynomials, Release 10.4

use, calls to this function are separated by calls to self.refine_all().)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc
ocean with precision 120 and 1 island(s)sage: oc.increase_precision()sage: oc.increase_precision()sage: oc.increase_precision()sage: oc
ocean with precision 960 and 1 island(s)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> ococean with precision 120 and 1 island(s)>>> oc.increase_precision()>>> oc.increase_precision()>>> oc.increase_precision()>>> ococean with precision 960 and 1 island(s)refine_all()Refine all islands which are not done (which are not known to contain exactly one root).
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc
ocean with precision 120 and 1 island(s)sage: oc.refine_all()sage: oc
ocean with precision 120 and 3 island(s)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> ococean with precision 120 and 1 island(s)>>> oc.refine_all()>>> ococean with precision 120 and 3 island(s)reset_root_width(isle_num, target_width)
Require that the isle_num island have a width at most target_width.
If this is followed by a call to find_roots(), then the corresponding root will be refined to the specified width.
EXAMPLES:
366

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([-1, -1,␣˓→1]), lmap)
sage: oc.find_roots()
sage: oc.roots()[(1/2, 3/4)]
sage: oc.reset_root_width(0, 1/2^200)
sage: oc.find_roots()
sage: oc
ocean with precision 240 and 1 island(s)sage: RR(RealIntervalField(300)(oc.roots()[0]).absolute_diameter()).log2()-232.668979560890>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([˓→Integer(1), -Integer(1), Integer(1)]), lmap)>>> oc.find_roots()>>> oc.roots()[(1/2, 3/4)]>>> oc.reset_root_width(Integer(0), Integer(1)/Integer(2)**Integer(200))>>> oc.find_roots()>>> ococean with precision 240 and 1 island(s)>>> RR(RealIntervalField(Integer(300))(oc.roots()[Integer(0)]).absolute_
˓→diameter()).log2()-232.668979560890

roots()
Return the locations of all islands in this ocean. (If run after find_roots(), this is the location of all roots inthe ocean.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1/3, -22/
˓→7, 193/71, -140/99]), lmap)
sage: oc.find_roots()
sage: oc.roots()[(1/32, 1/16), (1/2, 5/8), (3/4, 7/8)]
sage: oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([1, 0, ˓→1111/2, 0, 11108889/14, 0, 0, 0, 0, -1]), lmap)
sage: oc.find_roots()
sage: oc.roots()[(95761241267509487747625/9671406556917033397649408, 191522482605387719863145/
˓→19342813113834066795298816), (1496269395904347376805/
˓→151115727451828646838272, 374067366568272936175/37778931862957161709568),␣
˓→(31/32, 63/64)]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1)/˓→Integer(3), -Integer(22)/Integer(7), Integer(193)/Integer(71), ˓→Integer(140)/Integer(99)]), lmap)>>> oc.find_roots()>>> oc.roots()[(1/32, 1/16), (1/2, 5/8), (3/4, 7/8)](continues on next page)2.1. Univariate Polynomials and Polynomial Rings

367

Polynomials, Release 10.4

(continued from previous page)>>> oc = ocean(mk_context(), bernstein_polynomial_factory_ratlist([Integer(1),˓→ Integer(0), -Integer(1111)/Integer(2), Integer(0), Integer(11108889)/
˓→Integer(14), Integer(0), Integer(0), Integer(0), Integer(0), -Integer(1)]),␣
˓→lmap)>>> oc.find_roots()>>> oc.roots()[(95761241267509487747625/9671406556917033397649408, 191522482605387719863145/
˓→19342813113834066795298816), (1496269395904347376805/
˓→151115727451828646838272, 374067366568272936175/37778931862957161709568),␣
˓→(31/32, 63/64)]

sage.rings.polynomial.real_roots.precompute_degree_reduction_cache(n)Compute and cache the matrices used for degree reduction, starting from degree n.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: precompute_degree_reduction_cache(5)sage: dr_cache[5]([121/126
8/63-1/9-2/63 11/126-2/63]
[
-3/7
37/42
16/21
1/21
-3/7
1/6]
[
1/6
-3/7
1/21
16/21
37/42
-3/7]
3, [ -2/63 11/126
-2/63
-1/9
8/63 121/126], 2,([121 16 -14 -4 11 -4][-54 111 96
6 -54 21]
[ 21 -54
6 96 111 -54]
[ -4 11 -4 -14 16 121], 126))>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> precompute_degree_reduction_cache(Integer(5))>>> dr_cache[Integer(5)]([121/126
8/63-1/9-2/63 11/126-2/63]
[
-3/7
37/42
16/21
1/21
-3/7
1/6]
[
1/6
-3/7
1/21
16/21
37/42
-3/7]
3, [ -2/63 11/126
-2/63
-1/9
8/63 121/126], 2,<BLANKLINE>([121 16 -14 -4 11 -4][-54 111 96
6 -54 21]
[ 21 -54
6 96 111 -54]
[ -4 11 -4 -14 16 121], 126))

sage.rings.polynomial.real_roots.pseudoinverse(m)sage.rings.polynomial.real_roots.rational_root_bounds(p)Given a polynomial p with real coefficients, computes rationals a and b, such that for every real root r of p, a < r< b. We try to find rationals which bound the roots somewhat tightly, yet are simple (have small numerators anddenominators).
EXAMPLES:

368

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: rational_root_bounds((x-1)*(x-2)*(x-3))(0, 7)
sage: rational_root_bounds(x^2)(-1/2, 1/2)
sage: rational_root_bounds(x*(x+1))(-3/2, 1/2)
sage: rational_root_bounds((x+2)*(x-3))(-3, 6)sage: rational_root_bounds(x^995 * (x^2 - 9999) - 1)(-100, 1000/7)
sage: rational_root_bounds(x^995 * (x^2 - 9999) + 1)(-142, 213/2)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> rational_root_bounds((x-Integer(1))*(x-Integer(2))*(x-Integer(3)))(0, 7)>>> rational_root_bounds(x**Integer(2))(-1/2, 1/2)>>> rational_root_bounds(x*(x+Integer(1)))(-3/2, 1/2)>>> rational_root_bounds((x+Integer(2))*(x-Integer(3)))(-3, 6)>>> rational_root_bounds(x**Integer(995) * (x**Integer(2) - Integer(9999)) -␣˓→Integer(1))(-100, 1000/7)>>> rational_root_bounds(x**Integer(995) * (x**Integer(2) - Integer(9999)) +␣˓→Integer(1))(-142, 213/2)

If we can see that the polynomial has no real roots, return None.
sage: rational_root_bounds(x^2 + 7) is None Truesage.rings.polynomial.real_roots.real_roots(p, bounds=None, seed=None,skip_squarefree=False, do_logging=False,wordsize=32, retval='rational', strategy=None,
max_diameter=None)
Compute the real roots of a given polynomial with exact coefficients (integer, rational, and algebraic real coefficientsare supported).
This returns a list of pairs of a root and its multiplicity.
The root itself can be returned in one of three different ways. If retval==’rational’, then it is returned as a pair ofrationals that define a region that includes exactly one root. If retval==’interval’, then it is returned as a RealIntervalFieldElement that includes exactly one root. If retval==’algebraic_real’, then it is returned as an AlgebraicReal.
In the former two cases, all the intervals are disjoint.
An alternate high-level algorithm can be used by selecting strategy=’warp’. This affects the conversion into Bernstein polynomial form, but still uses the same ocean-island algorithm as the default algorithm. The ‘warp’ algorithm
performs the conversion into Bernstein polynomial form much more quickly, but performs the rest of the computation slightly slower in some benchmarks. The ‘warp’ algorithm is particularly likely to be helpful for low-degree
polynomials.
Part of the algorithm is randomized; the seed parameter gives a seed for the random number generator. (By default,
2.1. Univariate Polynomials and Polynomial Rings

369

Polynomials, Release 10.4

the same seed is used for every call, so that results are repeatable.) The random seed may affect the running time,or the exact intervals returned, but the results are correct regardless of the seed used.
The bounds parameter lets you find roots in some proper subinterval of the reals; it takes a pair of a rational lower
and upper bound and only roots within this bound will be found. Currently, specifying bounds does not work if
you select strategy=’warp’, or if you use a polynomial with algebraic real coefficients.
By default, the algorithm will do a squarefree decomposition to get squarefree polynomials. The skip_squarefreeparameter lets you skip this step. (If this step is skipped, and the polynomial has a repeated real root, then thealgorithm will loop forever! However, repeated non-real roots are not a problem.)
For integer and rational coefficients, the squarefree decomposition is very fast, but it may be slow for algebraic reals.
(It may trigger exact computation, so it might be arbitrarily slow. The only other way that this algorithm might
trigger exact computation on algebraic real coefficients is that it checks the constant term of the input polynomialfor equality with zero.)Part of the algorithm works (approximately) by splitting numbers into word-size pieces (that is, pieces that fit into amachine word). For portability, this defaults to always selecting pieces suitable for a 32-bit machine; the wordsize
parameter lets you make choices suitable for a 64-bit machine instead. (This affects the running time, and theexact intervals returned, but the results are correct on both 32- and 64-bit machines even if the wordsize is chosen“wrong”.)
The precision of the results can be improved (at the expense of time, of course) by specifying the max_diameterparameter. If specified, this sets the maximum diameter() of the intervals returned. (Sage defines diameter() to be
the relative diameter for intervals that do not contain 0, and the absolute diameter for intervals containing 0.) This
directly affects the results in rational or interval return mode; in algebraic_real mode, it increases the precision of
the intervals passed to the algebraic number package, which may speed up some operations on that algebraic real.
Some logging can be enabled with do_logging=True. If logging is enabled, then the normal values are not returned;
instead, a pair of the internal context object and a list of all the roots in their internal form is returned.
ALGORITHM: We convert the polynomial into the Bernstein basis, and then use de Casteljau’s algorithm andDescartes’ rule of signs (using interval arithmetic) to locate the roots.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: real_roots(x^3 - x^2 - x - 1)[((7/4, 19/8), 1)]
sage: real_roots((x-1)*(x-2)*(x-3)*(x-5)*(x-8)*(x-13)*(x-21)*(x-34))[((11/16, 33/32), 1), ((11/8, 33/16), 1), ((11/4, 55/16), 1), ((77/16, 165/32),␣
˓→1), ((11/2, 33/4), 1), ((11, 55/4), 1), ((165/8, 341/16), 1), ((22, 44), 1)]
sage: real_roots(x^5 * (x^2 - 9999)^2 - 1)[((-29274496381311/9007199254740992, 419601125186091/2251799813685248), 1),␣
˓→((2126658450145849453951061654415153249597/
˓→21267647932558653966460912964485513216,␣
˓→4253316902721330018853696359533061621799/
˓→42535295865117307932921825928971026432), 1),␣
˓→((1063329226287740282451317352558954186101/
˓→10633823966279326983230456482242756608, 531664614358685696701445201630854654353/
˓→5316911983139663491615228241121378304), 1)]
sage: real_roots(x^5 * (x^2 - 9999)^2 - 1, seed=42)[((-123196838480289/18014398509481984, 293964743458749/9007199254740992), 1),␣
˓→((8307259573979551907841696381986376143/83076749736557242056487941267521536,␣˓→16614519150981033789137940378745325503/166153499473114484112975882535043072),␣
˓→1), ((519203723562592617581015249797434335/5192296858534827628530496329220096,␣
˓→60443268924081068060312183/604462909807314587353088), 1)]
sage: real_roots(x^5 * (x^2 - 9999)^2 - 1, wordsize=64)(continues on next page)

370

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[((-62866503803202151050003/19342813113834066795298816, 901086554512564177624143/
˓→4835703278458516698824704), 1), ((544424563237337315214990987922809050101157/
˓→5444517870735015415413993718908291383296,␣˓→1088849127096660194637118845654929064385439/
˓→10889035741470030830827987437816582766592), 1),␣
˓→((272212281929661439711063928866060007142141/
˓→2722258935367507707706996859454145691648,␣
˓→136106141275823501959100399337685485662633/
˓→1361129467683753853853498429727072845824), 1)]
sage: real_roots(x)[((-47/256, 81/512), 1)]
sage: real_roots(x * (x-1))[((-47/256, 81/512), 1), ((1/2, 1201/1024), 1)]
sage: real_roots(x-1)[((209/256, 593/512), 1)]
sage: real_roots(x*(x-1)*(x-2), bounds=(0, 2))[((0, 0), 1), ((81/128, 337/256), 1), ((2, 2), 1)]
sage: real_roots(x*(x-1)*(x-2), bounds=(0, 2), retval= algebraic_real )[(0, 1), (1, 1), (2, 1)]
sage: v = 2^40
sage: real_roots((x^2-1)^2 * (x^2 - (v+1)/v))[((-12855504354077768210885019021174120740504020581912910106032833/
˓→12855504354071922204335696738729300820177623950262342682411008, ˓→6427752177038884105442509510587059395588605840418680645585479/
˓→6427752177035961102167848369364650410088811975131171341205504), 1), ((˓→1125899906842725/1125899906842624, -562949953421275/562949953421312), 2),␣
˓→((62165404551223330269422781018352603934643403586760330761772204409982940218804935733653/
˓→62165404551223330269422781018352605012557018849668464680057997111644937126566671941632,
˓→␣
˓→3885337784451458141838923813647037871787041539340705594199885610069035709862106085785/
˓→3885337784451458141838923813647037813284813678104279042503624819477808570410416996352),
˓→ 2),␣
˓→((509258994083853105745586001837045839749063767798922046787130823804169826426726965449697819/
˓→509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344,
˓→ 25711008708155536421770038042348240136257704305733983563630791/
˓→25711008708143844408671393477458601640355247900524685364822016), 1)]
sage: real_roots(x^2 - 2)[((-3/2, -1), 1), ((1, 3/2), 1)]
sage: real_roots(x^2 - 2, retval= interval )[(-2.?, 1), (2.?, 1)]
sage: real_roots(x^2 - 2, max_diameter=1/2^30)[((˓→22506280506048041472675379598886543645348790970912519198456805737131269246430553365310109/
˓→15914343565113172548972231940698266883214596825515126958094847260581103904401068017057792,
˓→ ˓→45012561012096082945350759197773086524448972309421182031053065599548946985601579935498343/
˓→31828687130226345097944463881396533766429193651030253916189694521162207808802136034115584),
˓→ 1),␣
˓→((45012561012096082945350759197773086524448972309421182031053065599548946985601579935498343/
˓→31828687130226345097944463881396533766429193651030253916189694521162207808802136034115584,
˓→␣
˓→22506280506048041472675379598886543645348790970912519198456805737131269246430553365310109/
˓→15914343565113172548972231940698266883214596825515126958094847260581103904401068017057792),
˓→ 1)]
sage: real_roots(x^2 - 2, retval= interval , max_diameter=1/2^500)[(-1.
˓→4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

371

Polynomials, Release 10.4

(continued from previous page), 1), (1.
˓→4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276
˓→, 1)]
sage: ar_rts = real_roots(x^2 - 2, retval= algebraic_real ); ar_rts[(-1.414213562373095?, 1), (1.414213562373095?, 1)]
sage: ar_rts[0][0]^2 - 2 == 0
True
sage: v = 2^40
sage: real_roots((x-1) * (x-(v+1)/v), retval= interval )[(1.000000000000?, 1), (1.000000000001?, 1)]
sage: v = 2^60
sage: real_roots((x-1) * (x-(v+1)/v), retval= interval )[(1.000000000000000000?, 1), (1.000000000000000001?, 1)]
sage: real_roots((x-1) * (x-2), strategy= warp )[((499/525, 1173/875), 1), ((337/175, 849/175), 1)]
sage: real_roots((x+3)*(x+1)*x*(x-1)*(x-2), strategy= warp )[((-1713/335, -689/335), 1), ((-2067/2029, -689/1359), 1), ((0, 0), 1), ((499/525,
˓→ 1173/875), 1), ((337/175, 849/175), 1)]
sage: real_roots((x+3)*(x+1)*x*(x-1)*(x-2), strategy= warp , retval= algebraic_
˓→real )[(-3.000000000000000?, 1), (-1.000000000000000?, 1), (0, 1), (1.000000000000000?,␣
˓→1), (2.000000000000000?, 1)]
sage: ar_rts = real_roots(x-1, retval= algebraic_real )sage: ar_rts[0][0] == 1
True˓→>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> real_roots(x**Integer(3) - x**Integer(2) - x - Integer(1))[((7/4, 19/8), 1)]>>> real_roots((x-Integer(1))*(x-Integer(2))*(x-Integer(3))*(x-Integer(5))*(x˓→Integer(8))*(x-Integer(13))*(x-Integer(21))*(x-Integer(34)))[((11/16, 33/32), 1), ((11/8, 33/16), 1), ((11/4, 55/16), 1), ((77/16, 165/32),␣
˓→1), ((11/2, 33/4), 1), ((11, 55/4), 1), ((165/8, 341/16), 1), ((22, 44), 1)]>>> real_roots(x**Integer(5) * (x**Integer(2) - Integer(9999))**Integer(2) -␣˓→Integer(1))[((-29274496381311/9007199254740992, 419601125186091/2251799813685248), 1),␣
˓→((2126658450145849453951061654415153249597/
˓→21267647932558653966460912964485513216,␣
˓→4253316902721330018853696359533061621799/
˓→42535295865117307932921825928971026432), 1),␣
˓→((1063329226287740282451317352558954186101/
˓→10633823966279326983230456482242756608, 531664614358685696701445201630854654353/
˓→5316911983139663491615228241121378304), 1)]>>> real_roots(x**Integer(5) * (x**Integer(2) - Integer(9999))**Integer(2) -␣˓→Integer(1), seed=Integer(42))[((-123196838480289/18014398509481984, 293964743458749/9007199254740992), 1),␣
˓→((8307259573979551907841696381986376143/83076749736557242056487941267521536,␣˓→16614519150981033789137940378745325503/166153499473114484112975882535043072),␣
˓→1), ((519203723562592617581015249797434335/5192296858534827628530496329220096,␣
˓→60443268924081068060312183/604462909807314587353088), 1)]>>> real_roots(x**Integer(5) * (x**Integer(2) - Integer(9999))**Integer(2) -␣˓→Integer(1), wordsize=Integer(64))[((-62866503803202151050003/19342813113834066795298816, 901086554512564177624143/
˓→4835703278458516698824704), 1), ((544424563237337315214990987922809050101157/(continues on next page)372

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)5444517870735015415413993718908291383296,␣˓→1088849127096660194637118845654929064385439/
˓→10889035741470030830827987437816582766592), 1),␣
˓→((272212281929661439711063928866060007142141/
˓→2722258935367507707706996859454145691648,␣
˓→136106141275823501959100399337685485662633/
˓→1361129467683753853853498429727072845824), 1)]>>> real_roots(x)[((-47/256, 81/512), 1)]>>> real_roots(x * (x-Integer(1)))[((-47/256, 81/512), 1), ((1/2, 1201/1024), 1)]>>> real_roots(x-Integer(1))[((209/256, 593/512), 1)]>>> real_roots(x*(x-Integer(1))*(x-Integer(2)), bounds=(Integer(0), Integer(2)))[((0, 0), 1), ((81/128, 337/256), 1), ((2, 2), 1)]>>> real_roots(x*(x-Integer(1))*(x-Integer(2)), bounds=(Integer(0), Integer(2)),␣
˓→retval= algebraic_real )[(0, 1), (1, 1), (2, 1)]>>> v = Integer(2)**Integer(40)>>> real_roots((x**Integer(2)-Integer(1))**Integer(2) * (x**Integer(2) -␣˓→(v+Integer(1))/v))[((-12855504354077768210885019021174120740504020581912910106032833/
˓→12855504354071922204335696738729300820177623950262342682411008, ˓→6427752177038884105442509510587059395588605840418680645585479/
˓→6427752177035961102167848369364650410088811975131171341205504), 1), ((˓→1125899906842725/1125899906842624, -562949953421275/562949953421312), 2),␣
˓→((62165404551223330269422781018352603934643403586760330761772204409982940218804935733653/
˓→62165404551223330269422781018352605012557018849668464680057997111644937126566671941632,
˓→␣
˓→3885337784451458141838923813647037871787041539340705594199885610069035709862106085785/
˓→3885337784451458141838923813647037813284813678104279042503624819477808570410416996352),
˓→ 2),␣
˓→((509258994083853105745586001837045839749063767798922046787130823804169826426726965449697819/
˓→509258994083621521567111422102344540262867098416484062659035112338595324940834176545849344,
˓→ 25711008708155536421770038042348240136257704305733983563630791/
˓→25711008708143844408671393477458601640355247900524685364822016), 1)]>>> real_roots(x**Integer(2) - Integer(2))[((-3/2, -1), 1), ((1, 3/2), 1)]>>> real_roots(x**Integer(2) - Integer(2), retval= interval )[(-2.?, 1), (2.?, 1)]>>> real_roots(x**Integer(2) - Integer(2), max_diameter=Integer(1)/˓→Integer(2)**Integer(30))[((˓→22506280506048041472675379598886543645348790970912519198456805737131269246430553365310109/
˓→15914343565113172548972231940698266883214596825515126958094847260581103904401068017057792,
˓→ ˓→45012561012096082945350759197773086524448972309421182031053065599548946985601579935498343/
˓→31828687130226345097944463881396533766429193651030253916189694521162207808802136034115584),
˓→ 1),␣
˓→((45012561012096082945350759197773086524448972309421182031053065599548946985601579935498343/
˓→31828687130226345097944463881396533766429193651030253916189694521162207808802136034115584,
˓→␣
˓→22506280506048041472675379598886543645348790970912519198456805737131269246430553365310109/
˓→15914343565113172548972231940698266883214596825515126958094847260581103904401068017057792),
˓→ 1)]>>> real_roots(x**Integer(2) - Integer(2), retval= interval , max_
˓→diameter=Integer(1)/Integer(2)**Integer(500))
˓→(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

373

Polynomials, Release 10.4

(continued from previous page)[(-1.
˓→4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276
˓→, 1), (1.
˓→4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276
˓→, 1)]>>> ar_rts = real_roots(x**Integer(2) - Integer(2), retval= algebraic_real ); ar_˓→rts[(-1.414213562373095?, 1), (1.414213562373095?, 1)]>>> ar_rts[Integer(0)][Integer(0)]**Integer(2) - Integer(2) == Integer(0)True>>> v = Integer(2)**Integer(40)>>> real_roots((x-Integer(1)) * (x-(v+Integer(1))/v), retval= interval )[(1.000000000000?, 1), (1.000000000001?, 1)]>>> v = Integer(2)**Integer(60)>>> real_roots((x-Integer(1)) * (x-(v+Integer(1))/v), retval= interval )[(1.000000000000000000?, 1), (1.000000000000000001?, 1)]>>> real_roots((x-Integer(1)) * (x-Integer(2)), strategy= warp )[((499/525, 1173/875), 1), ((337/175, 849/175), 1)]>>> real_roots((x+Integer(3))*(x+Integer(1))*x*(x-Integer(1))*(x-Integer(2)),␣
˓→strategy= warp )[((-1713/335, -689/335), 1), ((-2067/2029, -689/1359), 1), ((0, 0), 1), ((499/525,
˓→ 1173/875), 1), ((337/175, 849/175), 1)]>>> real_roots((x+Integer(3))*(x+Integer(1))*x*(x-Integer(1))*(x-Integer(2)),␣
˓→strategy= warp , retval= algebraic_real )[(-3.000000000000000?, 1), (-1.000000000000000?, 1), (0, 1), (1.000000000000000?,␣
˓→1), (2.000000000000000?, 1)]>>> ar_rts = real_roots(x-Integer(1), retval= algebraic_real )>>> ar_rts[Integer(0)][Integer(0)] == Integer(1)True

If the polynomial has no real roots, we get an empty list.
sage: (x^2 + 1).real_root_intervals()[]>>> from sage.all import *>>> (x**Integer(2) + Integer(1)).real_root_intervals()[]

We can compute Conway’s constant (see http://mathworld.wolfram.com/ConwaysConstant.html) to arbitrary precision.
sage: p = x^71 - x^69 - 2*x^68 - x^67 + 2*x^66 + 2*x^65 + x^64 - x^63 - x^62 - x^
˓→61 - x^60 - x^59 + 2*x^58 + 5*x^57 + 3*x^56 - 2*x^55 - 10*x^54 - 3*x^53 - 2*x^
˓→52 + 6*x^51 + 6*x^50 + x^49 + 9*x^48 - 3*x^47 - 7*x^46 - 8*x^45 - 8*x^44 + 10*x^
˓→43 + 6*x^42 + 8*x^41 - 5*x^40 - 12*x^39 + 7*x^38 - 7*x^37 + 7*x^36 + x^35 - 3*x^
˓→34 + 10*x^33 + x^32 - 6*x^31 - 2*x^30 - 10*x^29 - 3*x^28 + 2*x^27 + 9*x^26 -␣
˓→3*x^25 + 14*x^24 - 8*x^23 - 7*x^21 + 9*x^20 + 3*x^19 - 4*x^18 - 10*x^17 - 7*x^
˓→16 + 12*x^15 + 7*x^14 + 2*x^13 - 12*x^12 - 4*x^11 - 2*x^10 + 5*x^9 + x^7 - 7*x^
˓→6 + 7*x^5 - 4*x^4 + 12*x^3 - 6*x^2 + 3*x - 6
sage: cc = real_roots(p, retval= algebraic_real )[2][0] # long time
sage: RealField(180)(cc)# long time
1.3035772690342963912570991121525518907307025046594049>>> from sage.all import *>>> p = x**Integer(71) - x**Integer(69) - Integer(2)*x**Integer(68) -␣(continues on next page)

374

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x**Integer(67) + Integer(2)*x**Integer(66) + Integer(2)*x**Integer(65) +␣˓→x**Integer(64) - x**Integer(63) - x**Integer(62) - x**Integer(61) -␣˓→x**Integer(60) - x**Integer(59) + Integer(2)*x**Integer(58) +␣˓→Integer(5)*x**Integer(57) + Integer(3)*x**Integer(56) -␣˓→Integer(2)*x**Integer(55) - Integer(10)*x**Integer(54) -␣˓→Integer(3)*x**Integer(53) - Integer(2)*x**Integer(52) +␣˓→Integer(6)*x**Integer(51) + Integer(6)*x**Integer(50) + x**Integer(49) +␣˓→Integer(9)*x**Integer(48) - Integer(3)*x**Integer(47) -␣˓→Integer(7)*x**Integer(46) - Integer(8)*x**Integer(45) -␣˓→Integer(8)*x**Integer(44) + Integer(10)*x**Integer(43) +␣˓→Integer(6)*x**Integer(42) + Integer(8)*x**Integer(41) -␣˓→Integer(5)*x**Integer(40) - Integer(12)*x**Integer(39) +␣˓→Integer(7)*x**Integer(38) - Integer(7)*x**Integer(37) +␣˓→Integer(7)*x**Integer(36) + x**Integer(35) - Integer(3)*x**Integer(34) +␣˓→Integer(10)*x**Integer(33) + x**Integer(32) - Integer(6)*x**Integer(31) -␣˓→Integer(2)*x**Integer(30) - Integer(10)*x**Integer(29) -␣˓→Integer(3)*x**Integer(28) + Integer(2)*x**Integer(27) +␣˓→Integer(9)*x**Integer(26) - Integer(3)*x**Integer(25) +␣˓→Integer(14)*x**Integer(24) - Integer(8)*x**Integer(23) -␣˓→Integer(7)*x**Integer(21) + Integer(9)*x**Integer(20) +␣˓→Integer(3)*x**Integer(19) - Integer(4)*x**Integer(18) -␣˓→Integer(10)*x**Integer(17) - Integer(7)*x**Integer(16) +␣˓→Integer(12)*x**Integer(15) + Integer(7)*x**Integer(14) +␣˓→Integer(2)*x**Integer(13) - Integer(12)*x**Integer(12) -␣˓→Integer(4)*x**Integer(11) - Integer(2)*x**Integer(10) +␣˓→Integer(5)*x**Integer(9) + x**Integer(7) - Integer(7)*x**Integer(6) +␣˓→Integer(7)*x**Integer(5) - Integer(4)*x**Integer(4) + Integer(12)*x**Integer(3)␣
˓→- Integer(6)*x**Integer(2) + Integer(3)*x - Integer(6)>>> cc = real_roots(p, retval= algebraic_real )[Integer(2)][Integer(0)] # long␣˓→time>>> RealField(Integer(180))(cc)# long time
1.3035772690342963912570991121525518907307025046594049
˓→

Now we play with algebraic real coefficients.
sage: x = polygen(AA)sage: p = (x - 1) * (x - sqrt(AA(2))) * (x - 2)sage: real_roots(p)[((499/525, 2171/1925), 1), ((1173/875, 2521/1575), 1), ((337/175, 849/175), 1)]
sage: ar_rts = real_roots(p, retval= algebraic_real ); ar_rts[(1.000000000000000?, 1), (1.414213562373095?, 1), (2.000000000000000?, 1)]
sage: ar_rts[1][0]^2 == 2
True
sage: ar_rts = real_roots(x*(x-1), retval= algebraic_real )sage: ar_rts[0][0] == 0
True
sage: p2 = p * (p - 1/100); p2x^6 - 8.82842712474619?*x^5 + 31.97056274847714?*x^4 - 60.77955262170047?*x^3 +␣
˓→63.98526763257801?*x^2 - 35.37613490585595?*x + 8.028284271247462?
sage: real_roots(p2, retval= interval )[(1.00?, 1), (1.1?, 1), (1.38?, 1), (1.5?, 1), (2.00?, 1), (2.1?, 1)]
sage: p = (x - 1) * (x - sqrt(AA(2)))^2 * (x - 2)^3 * sqrt(AA(3))
sage: real_roots(p, retval= interval )[(1.000000000000000?, 1), (1.414213562373095?, 2), (2.000000000000000?, 3)]>>> from sage.all import *(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

375

Polynomials, Release 10.4

(continued from previous page)>>> x = polygen(AA)>>> p = (x - Integer(1)) * (x - sqrt(AA(Integer(2)))) * (x - Integer(2))>>> real_roots(p)[((499/525, 2171/1925), 1), ((1173/875, 2521/1575), 1), ((337/175, 849/175), 1)]>>> ar_rts = real_roots(p, retval= algebraic_real ); ar_rts[(1.000000000000000?, 1), (1.414213562373095?, 1), (2.000000000000000?, 1)]>>> ar_rts[Integer(1)][Integer(0)]**Integer(2) == Integer(2)True>>> ar_rts = real_roots(x*(x-Integer(1)), retval= algebraic_real )>>> ar_rts[Integer(0)][Integer(0)] == Integer(0)True>>> p2 = p * (p - Integer(1)/Integer(100)); p2x^6 - 8.82842712474619?*x^5 + 31.97056274847714?*x^4 - 60.77955262170047?*x^3 +␣
˓→63.98526763257801?*x^2 - 35.37613490585595?*x + 8.028284271247462?
>>> real_roots(p2, retval= interval )[(1.00?, 1), (1.1?, 1), (1.38?, 1), (1.5?, 1), (2.00?, 1), (2.1?, 1)]>>> p = (x - Integer(1)) * (x - sqrt(AA(Integer(2))))**Integer(2) * (x -␣˓→Integer(2))**Integer(3) * sqrt(AA(Integer(3)))>>> real_roots(p, retval= interval )[(1.000000000000000?, 1), (1.414213562373095?, 2), (2.000000000000000?, 3)]

sage.rings.polynomial.real_roots.relative_bounds(a, b)
INPUT:• (al, ah) – pair of rationals• (bl, bh) – pair of rationals
OUTPUT:• (cl, ch) – pair of rationals
Computes the linear transformation that maps (al, ah) to (0, 1); then applies this transformation to (bl, bh) andreturns the result.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: relative_bounds((1/7, 1/4), (1/6, 1/5))(2/9, 8/15)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> relative_bounds((Integer(1)/Integer(7), Integer(1)/Integer(4)), (Integer(1)/˓→Integer(6), Integer(1)/Integer(5)))(2/9, 8/15)

sage.rings.polynomial.real_roots.reverse_intvec(c)Given a vector of integers, reverse the vector (like the reverse() method on lists).
Modifies the input vector; has no return value.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: v = vector(ZZ, [1, 2, 3, 4]); v(1, 2, 3, 4)
sage: reverse_intvec(v)(continues on next page)

376

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: v
(4, 3, 2, 1)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> v = vector(ZZ, [Integer(1), Integer(2), Integer(3), Integer(4)]); v(1, 2, 3, 4)>>> reverse_intvec(v)>>> v(4, 3, 2, 1)

sage.rings.polynomial.real_roots.root_bounds(p)Given a polynomial with real coefficients, computes a lower and upper bound on its real roots. Uses algorithms of
Akritas, Strzebo'nski, and Vigklas.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: root_bounds((x-1)*(x-2)*(x-3))(0.545454545454545, 6.00000000000001)
sage: root_bounds(x^2)(0.000000000000000, 0.000000000000000)
sage: root_bounds(x*(x+1))(-1.00000000000000, 0.000000000000000)
sage: root_bounds((x+2)*(x-3))(-2.44948974278317, 3.46410161513776)
sage: root_bounds(x^995 * (x^2 - 9999) - 1)(-99.9949998749937, 141.414284992713)
sage: root_bounds(x^995 * (x^2 - 9999) + 1)(-141.414284992712, 99.9949998749938)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> root_bounds((x-Integer(1))*(x-Integer(2))*(x-Integer(3)))(0.545454545454545, 6.00000000000001)>>> root_bounds(x**Integer(2))(0.000000000000000, 0.000000000000000)>>> root_bounds(x*(x+Integer(1)))(-1.00000000000000, 0.000000000000000)>>> root_bounds((x+Integer(2))*(x-Integer(3)))(-2.44948974278317, 3.46410161513776)>>> root_bounds(x**Integer(995) * (x**Integer(2) - Integer(9999)) - Integer(1))(-99.9949998749937, 141.414284992713)>>> root_bounds(x**Integer(995) * (x**Integer(2) - Integer(9999)) + Integer(1))(-141.414284992712, 99.9949998749938)

If we can see that the polynomial has no real roots, return None.
sage: root_bounds(x^2 + 1) is None
True>>> from sage.all import *>>> root_bounds(x**Integer(2) + Integer(1)) is NoneTrue

2.1. Univariate Polynomials and Polynomial Rings

377

Polynomials, Release 10.4class sage.rings.polynomial.real_roots.rr_gap
Bases: object
A simple class representing the gaps between islands, in my ocean-island root isolation algorithm. Named “rr_gap”
for “real roots gap”, because “gap” seemed too short and generic.
region()sage.rings.polynomial.real_roots.scale_intvec_var(c, k)Given a vector of integers c of length n+1, and a rational k == kn / kd, multiplies each element c[i] by(kd^i)*(kn^(n-i)).
Modifies the input vector; has no return value.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: v = vector(ZZ, [1, 1, 1, 1])
sage: scale_intvec_var(v, 3/4)
sage: v
(64, 48, 36, 27)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> v = vector(ZZ, [Integer(1), Integer(1), Integer(1), Integer(1)])>>> scale_intvec_var(v, Integer(3)/Integer(4))>>> v(64, 48, 36, 27)

sage.rings.polynomial.real_roots.split_for_targets(ctx, bp, target_list, precise=False)
Given an interval Bernstein polynomial over a particular region (assumed to be a (not necessarily proper) subregionof [0 .. 1]), and a list of targets, uses de Casteljau’s method to compute representations of the Bernstein polynomial
over each target. Uses degree reduction as often as possible while maintaining the requested precision.
Each target is of the form (lgap, ugap, b). Suppose lgap.region() is (l1, l2), and ugap.region() is (u1, u2). Thenwe will compute an interval Bernstein polynomial over a region [l .. u], where l1 <= l <= l2 and u1 <= u <= u2.
(split_for_targets() is free to select arbitrary region endpoints within these bounds; it picks endpoints which makethe computation easier.) The third component of the target, b, is the maximum allowed scale_log2 of the result;
this is used to decide when degree reduction is allowed.
The pair (l1, l2) can be replaced by None, meaning [-infinity .. 0]; or, (u1, u2) can be replaced by None, meaning[1 .. infinity].
There is another constraint on the region endpoints selected by split_for_targets() for a target ((l1, l2), (u1, u2),b). We set a size goal g, such that (u - l) <= g * (u1 - l2). Normally g is 256/255, but if precise is True, then g is65536/65535.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: bp = mk_ibpi([1000000, -2000000, 3000000, -4000000, -5000000, -6000000])
sage: ctx = mk_context()
sage: bps = split_for_targets(ctx, bp, [(rr_gap(1/1234567893, 1/1234567892, 1),␣˓→rr_gap(1/1234567891, 1/1234567890, 1), 12), (rr_gap(1/3, 1/2, -1), rr_gap(2/3,␣
˓→3/4, -1), 6)])sage: bps[0]<IBP: (999992, 999992, 999992) + [0 .. 15) over [8613397477114467984778830327/
˓→10633823966279326983230456482242756608 ..␣
˓→591908168025934394813836527495938294787/(continues on next page)

378

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)730750818665451459101842416358141509827966271488]; level 2; slope_err 0.?e12>
sage: bps[1]<IBP: (-1562500, -1875001, -2222223, -2592593, -2969137, -3337450) + [0 .. 4)␣
˓→over [1/2 .. 2863311531/4294967296]>˓→>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> bp = mk_ibpi([Integer(1000000), -Integer(2000000), Integer(3000000), ˓→Integer(4000000), -Integer(5000000), -Integer(6000000)])>>> ctx = mk_context()>>> bps = split_for_targets(ctx, bp, [(rr_gap(Integer(1)/Integer(1234567893),␣
˓→Integer(1)/Integer(1234567892), Integer(1)), rr_gap(Integer(1)/˓→Integer(1234567891), Integer(1)/Integer(1234567890), Integer(1)), Integer(12)),␣
˓→(rr_gap(Integer(1)/Integer(3), Integer(1)/Integer(2), -Integer(1)), rr_
˓→gap(Integer(2)/Integer(3), Integer(3)/Integer(4), -Integer(1)), Integer(6))])>>> bps[Integer(0)]<IBP: (999992, 999992, 999992) + [0 .. 15) over [8613397477114467984778830327/
˓→10633823966279326983230456482242756608 ..␣
˓→591908168025934394813836527495938294787/
˓→730750818665451459101842416358141509827966271488]; level 2; slope_err 0.?e12>>>> bps[Integer(1)]<IBP: (-1562500, -1875001, -2222223, -2592593, -2969137, -3337450) + [0 .. 4)␣
˓→over [1/2 .. 2863311531/4294967296]>

sage.rings.polynomial.real_roots.subsample_vec_doctest(a, slen, llen)
sage.rings.polynomial.real_roots.taylor_shift1_intvec(c)Given a vector of integers c of length d+1, representing the coefficients of a degree-d polynomial p, modify thevector to perform a Taylor shift by 1 (that is, p becomes p(x+1)).
This is the straightforward algorithm, which is not asymptotically optimal.
Modifies the input vector; has no return value.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: p = (x-1)*(x-2)*(x-3)
sage: v = vector(ZZ, p.list())
sage: p, v
(x^3 - 6*x^2 + 11*x - 6, (-6, 11, -6, 1))
sage: taylor_shift1_intvec(v)sage: p(x+1), v(x^3 - 3*x^2 + 2*x, (0, 2, -3, 1))>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> p = (x-Integer(1))*(x-Integer(2))*(x-Integer(3))>>> v = vector(ZZ, p.list())>>> p, v(x^3 - 6*x^2 + 11*x - 6, (-6, 11, -6, 1))>>> taylor_shift1_intvec(v)>>> p(x+Integer(1)), v(x^3 - 3*x^2 + 2*x, (0, 2, -3, 1))

2.1. Univariate Polynomials and Polynomial Rings

379

Polynomials, Release 10.4

sage.rings.polynomial.real_roots.to_bernstein(p, low=0, high=1, degree=None)
Given a polynomial p with integer coefficients, and rational bounds low and high, compute the exact rational Bernstein coefficients of p over the region [low .. high]. The optional parameter degree can be used to give a formal
degree higher than the actual degree.
The return value is a pair (c, scale); c represents the same polynomial as p*scale. (If you only care about the rootsof the polynomial, then of course scale can be ignored.)
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: to_bernstein(x)([0, 1], 1)
sage: to_bernstein(x, degree=5)([0, 1/5, 2/5, 3/5, 4/5, 1], 1)
sage: to_bernstein(x^3 + x^2 - x - 1, low=-3, high=3)([-16, 24, -32, 32], 1)
sage: to_bernstein(x^3 + x^2 - x - 1, low=3, high=22/7)([296352, 310464, 325206, 340605], 9261)>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> to_bernstein(x)([0, 1], 1)>>> to_bernstein(x, degree=Integer(5))([0, 1/5, 2/5, 3/5, 4/5, 1], 1)>>> to_bernstein(x**Integer(3) + x**Integer(2) - x - Integer(1), low=-Integer(3),␣
˓→high=Integer(3))([-16, 24, -32, 32], 1)>>> to_bernstein(x**Integer(3) + x**Integer(2) - x - Integer(1), low=Integer(3),␣
˓→high=Integer(22)/Integer(7))([296352, 310464, 325206, 340605], 9261)

sage.rings.polynomial.real_roots.to_bernstein_warp(p)Given a polynomial p with rational coefficients, compute the exact rational Bernstein coefficients of p(x/(x+1)).
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: x = polygen(ZZ)
sage: to_bernstein_warp(1 + x + x^2 + x^3 + x^4 + x^5)
[1, 1/5, 1/10, 1/10, 1/5, 1]>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> x = polygen(ZZ)>>> to_bernstein_warp(Integer(1) + x + x**Integer(2) + x**Integer(3) +␣˓→x**Integer(4) + x**Integer(5))[1, 1/5, 1/10, 1/10, 1/5, 1]class sage.rings.polynomial.real_roots.warp_map(neg)Bases: object
A class to map between original coordinates and ocean coordinates. If neg is False, then the original->oceantransform is x -> x/(x+1), and the ocean->original transform is x/(1-x); this maps between [0 .. infinity] and [0380

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4.. 1]. If neg is True, then the original->ocean transform is x -> -x/(1-x), and the ocean->original transform is thesame thing: -x/(1-x). This maps between [0 .. -infinity] and [0 .. 1].
from_ocean(region)
to_ocean(region)
sage.rings.polynomial.real_roots.wordsize_rational(a, b, wordsize)
Given rationals a and b, select a de Casteljau split point r between a and b.
An attempt is made to select an efficient split point (according to the criteria mentioned in the documentation forde_casteljau_intvec), with a bias towards split points near a.
In full detail:This takes as input two rationals, a and b, such that 0<=a<=1, 0<=b<=1, and a!=b. This returns rational r, such thata<=r<=b or b<=r<=a. The denominator of r is a power of 2. Let m be min(r, 1-r), nm be numerator(m), and dml
be log2(denominator(m)). The return value r is taken from the first of the following classes to have any members
between a and b (except that if a <= 1/8, or 7/8 <= a, then class 2 is preferred to class 1).
1. dml < wordsize
2. bitsize(nm) <= wordsize
3. bitsize(nm) <= 2*wordsize
4. bitsize(nm) <= 3*wordsize…
k. bitsize(nm) <= (k-1)*wordsize
From the first class to have members between a and b, r is chosen as the element of the class which is closest to a.
EXAMPLES:
sage: from sage.rings.polynomial.real_roots import *sage: wordsize_rational(1/5, 1/7, 32)
429496729/2147483648
sage: wordsize_rational(1/7, 1/5, 32)
306783379/2147483648
sage: wordsize_rational(1/5, 1/7, 64)
1844674407370955161/9223372036854775808
sage: wordsize_rational(1/7, 1/5, 64)
658812288346769701/4611686018427387904
sage: wordsize_rational(1/17, 1/19, 32)252645135/4294967296
sage: wordsize_rational(1/17, 1/19, 64)
1085102592571150095/18446744073709551616
sage: wordsize_rational(1/1234567890, 1/1234567891, 32)
933866427/1152921504606846976
sage: wordsize_rational(1/1234567890, 1/1234567891, 64)
4010925763784056541/4951760157141521099596496896>>> from sage.all import *>>> from sage.rings.polynomial.real_roots import *>>> wordsize_rational(Integer(1)/Integer(5), Integer(1)/Integer(7), Integer(32))
429496729/2147483648>>> wordsize_rational(Integer(1)/Integer(7), Integer(1)/Integer(5), Integer(32))
306783379/2147483648>>> wordsize_rational(Integer(1)/Integer(5), Integer(1)/Integer(7), Integer(64))(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

381

Polynomials, Release 10.4

(continued from previous page)

1844674407370955161/9223372036854775808>>> wordsize_rational(Integer(1)/Integer(7), Integer(1)/Integer(5), Integer(64))
658812288346769701/4611686018427387904>>> wordsize_rational(Integer(1)/Integer(17), Integer(1)/Integer(19), Integer(32))
252645135/4294967296>>> wordsize_rational(Integer(1)/Integer(17), Integer(1)/Integer(19), Integer(64))
1085102592571150095/18446744073709551616>>> wordsize_rational(Integer(1)/Integer(1234567890), Integer(1)/˓→Integer(1234567891), Integer(32))
933866427/1152921504606846976>>> wordsize_rational(Integer(1)/Integer(1234567890), Integer(1)/˓→Integer(1234567891), Integer(64))
4010925763784056541/4951760157141521099596496896

2.1.19 Isolate Complex Roots of Polynomials
AUTHOR:• Carl Witty (2007-11-18): initial version
This is an implementation of complex root isolation. That is, given a polynomial with exact complex coefficients, we
compute isolating intervals for the complex roots of the polynomial. (Polynomials with integer, rational, Gaussian rational,or algebraic coefficients are supported.)
We use a simple algorithm. First, we compute a squarefree decomposition of the input polynomial; the resulting polynomials have no multiple roots. Then, we find the roots numerically, using NumPy (at low precision) or Pari (at highprecision). Then, we verify the roots using interval arithmetic.
EXAMPLES:
sage: x = polygen(ZZ)
sage: (x^5 - x - 1).roots(ring=CIF)[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]>>> from sage.all import *>>> x = polygen(ZZ)>>> (x**Integer(5) - x - Integer(1)).roots(ring=CIF)[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]

sage.rings.polynomial.complex_roots.complex_roots(p, skip_squarefree=False, retval='interval',
min_prec=0)
Compute the complex roots of a given polynomial with exact coefficients (integer, rational, Gaussian rational, andalgebraic coefficients are supported). Returns a list of pairs of a root and its multiplicity.
Roots are returned as a ComplexIntervalFieldElement; each interval includes exactly one root, and the intervals are
disjoint.

382

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

By default, the algorithm will do a squarefree decomposition to get squarefree polynomials. The skip_squarefreeparameter lets you skip this step. (If this step is skipped, and the polynomial has a repeated root, then the algorithm
will loop forever!)You can specify retval=’interval’ (the default) to get roots as complex intervals. The other options are retval=’algebraic’ to get elements of QQbar, or retval=’algebraic_real’ to get only the real roots, and to get them as elementsof AA.
EXAMPLES:
sage: from sage.rings.polynomial.complex_roots import complex_roots
sage: x = polygen(ZZ)
sage: complex_roots(x^5 - x - 1)[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]
sage: v = complex_roots(x^2 + 27*x + 181)>>> from sage.all import *>>> from sage.rings.polynomial.complex_roots import complex_roots>>> x = polygen(ZZ)>>> complex_roots(x**Integer(5) - x - Integer(1))[(1.167303978261419?, 1),(-0.764884433600585? - 0.352471546031727?*I, 1),(-0.764884433600585? + 0.352471546031727?*I, 1),(0.181232444469876? - 1.083954101317711?*I, 1),(0.181232444469876? + 1.083954101317711?*I, 1)]>>> v = complex_roots(x**Integer(2) + Integer(27)*x + Integer(181))

Unfortunately due to numerical noise there can be a small imaginary part to each root depending on CPU, compiler,
etc, and that affects the printing order. So we verify the real part of each root and check that the imaginary part issmall in both cases:
sage: v # random[(-14.61803398874990?..., 1), (-12.3819660112501...? + 0.?e-27*I, 1)]
sage: sorted((v[0][0].real(),v[1][0].real()))[-14.61803398874989?, -12.3819660112501...?]
sage: v[0][0].imag().upper() < 1e25
True
sage: v[1][0].imag().upper() < 1e25
True
sage: K.<im> = QuadraticField(-1)
sage: eps = 1/2^100
sage: x = polygen(K)sage: p = (x-1)*(x-1-eps)*(x-1+eps)*(x-1-eps*im)*(x-1+eps*im)>>> from sage.all import *>>> v # random[(-14.61803398874990?..., 1), (-12.3819660112501...? + 0.?e-27*I, 1)]>>> sorted((v[Integer(0)][Integer(0)].real(),v[Integer(1)][Integer(0)].real()))[-14.61803398874989?, -12.3819660112501...?]>>> v[Integer(0)][Integer(0)].imag().upper() < RealNumber( 1e25 )True>>> v[Integer(1)][Integer(0)].imag().upper() < RealNumber( 1e25 )(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

383

Polynomials, Release 10.4

(continued from previous page)

True>>> K = QuadraticField(-Integer(1), names=( im ,)); (im,) = K._first_ngens(1)>>> eps = Integer(1)/Integer(2)**Integer(100)>>> x = polygen(K)>>> p = (x-Integer(1))*(x-Integer(1)-eps)*(x-Integer(1)+eps)*(x-Integer(1)˓→eps*im)*(x-Integer(1)+eps*im)

This polynomial actually has all-real coefficients, and is very, very close to (x-1)^5:
sage: [RR(QQ(a)) for a in list(p - (x-1)^5)][3.87259191484932e-121, -3.87259191484932e-121]
sage: rts = complex_roots(p)sage: [ComplexIntervalField(10)(rt[0] - 1) for rt in rts][-7.8887?e-31, 0, 7.8887?e-31, -7.8887?e-31*I, 7.8887?e-31*I]>>> from sage.all import *>>> [RR(QQ(a)) for a in list(p - (x-Integer(1))**Integer(5))][3.87259191484932e-121, -3.87259191484932e-121]>>> rts = complex_roots(p)>>> [ComplexIntervalField(Integer(10))(rt[Integer(0)] - Integer(1)) for rt in rts][-7.8887?e-31, 0, 7.8887?e-31, -7.8887?e-31*I, 7.8887?e-31*I]

We can get roots either as intervals, or as elements of QQbar or AA.
sage: p = (x^2 + x - 1)sage: p = p * p(x*im)
sage: p-x^4 + (im - 1)*x^3 + im*x^2 + (-im - 1)*x + 1>>> from sage.all import *>>> p = (x**Integer(2) + x - Integer(1))>>> p = p * p(x*im)>>> p-x^4 + (im - 1)*x^3 + im*x^2 + (-im - 1)*x + 1

Two of the roots have a zero real component; two have a zero imaginary component. These zero components
will be found slightly inaccurately, and the exact values returned are very sensitive to the (non-portable) results of
NumPy. So we post-process the roots for printing, to get predictable doctest results.
sage: def tiny(x):....:return x.contains_zero() and x.absolute_diameter() < 1e-14
sage: def smash(x):....:x = CIF(x[0]) # discard multiplicity....:
if tiny(x.imag()): return x.real()....:
if tiny(x.real()): return CIF(0, x.imag())
sage: rts = complex_roots(p); type(rts[0][0]), sorted(map(smash, rts))(<class sage.rings.complex_interval.ComplexIntervalFieldElement >,[-1.618033988749895?, -0.618033988749895?*I,
1.618033988749895?*I, 0.618033988749895?])
sage: rts = complex_roots(p, retval= algebraic ); type(rts[0][0]),␣
˓→sorted(map(smash, rts))(<class sage.rings.qqbar.AlgebraicNumber >,[-1.618033988749895?, -0.618033988749895?*I,
1.618033988749895?*I, 0.618033988749895?])
sage: rts = complex_roots(p, retval= algebraic_real ); type(rts[0][0]), rts(continues on next page)384

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(<class sage.rings.qqbar.AlgebraicReal >,[(-1.618033988749895?, 1), (0.618033988749895?, 1)])>>> from sage.all import *>>> def tiny(x):...
return x.contains_zero() and x.absolute_diameter() < RealNumber( 1e-14 )>>> def smash(x):...
x = CIF(x[Integer(0)]) # discard multiplicity...
if tiny(x.imag()): return x.real()...
if tiny(x.real()): return CIF(Integer(0), x.imag())>>> rts = complex_roots(p); type(rts[Integer(0)][Integer(0)]), sorted(map(smash,␣˓→rts))(<class sage.rings.complex_interval.ComplexIntervalFieldElement >,[-1.618033988749895?, -0.618033988749895?*I,
1.618033988749895?*I, 0.618033988749895?])>>> rts = complex_roots(p, retval= algebraic ); type(rts[Integer(0)][Integer(0)]),˓→ sorted(map(smash, rts))(<class sage.rings.qqbar.AlgebraicNumber >,[-1.618033988749895?, -0.618033988749895?*I,
1.618033988749895?*I, 0.618033988749895?])>>> rts = complex_roots(p, retval= algebraic_real );␣
˓→type(rts[Integer(0)][Integer(0)]), rts(<class sage.rings.qqbar.AlgebraicReal >,[(-1.618033988749895?, 1), (0.618033988749895?, 1)])sage.rings.polynomial.complex_roots.interval_roots(p, rts, prec)
We are given a squarefree polynomial p, a list of estimated roots, and a precision.
We attempt to verify that the estimated roots are in fact distinct roots of the polynomial, using interval arithmeticof precision prec. If we succeed, we return a list of intervals bounding the roots; if we fail, we return None.
EXAMPLES:
sage: x = polygen(ZZ)
sage: p = x^3 - 1
sage: rts = [CC.zeta(3)^i for i in range(0, 3)]
sage: from sage.rings.polynomial.complex_roots import interval_roots
sage: interval_roots(p, rts, 53)[1, -0.500000000000000? + 0.866025403784439?*I,-0.500000000000000? - 0.866025403784439?*I]
sage: interval_roots(p, rts, 200)
[1, -0.500000000000000000000000000000000000000000000000000000000000?
+ 0.866025403784438646763723170752936183471402626905190314027904?*I,-0.500000000000000000000000000000000000000000000000000000000000?
- 0.866025403784438646763723170752936183471402626905190314027904?*I]>>> from sage.all import *>>> x = polygen(ZZ)>>> p = x**Integer(3) - Integer(1)>>> rts = [CC.zeta(Integer(3))**i for i in range(Integer(0), Integer(3))]>>> from sage.rings.polynomial.complex_roots import interval_roots>>> interval_roots(p, rts, Integer(53))[1, -0.500000000000000? + 0.866025403784439?*I,-0.500000000000000? - 0.866025403784439?*I]>>> interval_roots(p, rts, Integer(200))[1, -0.500000000000000000000000000000000000000000000000000000000000?
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

385

Polynomials, Release 10.4

(continued from previous page)+ 0.866025403784438646763723170752936183471402626905190314027904?*I,-0.500000000000000000000000000000000000000000000000000000000000?
- 0.866025403784438646763723170752936183471402626905190314027904?*I]

sage.rings.polynomial.complex_roots.intervals_disjoint(intvs)
Given a list of complex intervals, check whether they are pairwise disjoint.
EXAMPLES:
sage: from sage.rings.polynomial.complex_roots import intervals_disjoint
sage: a = CIF(RIF(0, 3), 0)
sage: b = CIF(0, RIF(1, 3))
sage: c = CIF(RIF(1, 2), RIF(1, 2))
sage: d = CIF(RIF(2, 3), RIF(2, 3))
sage: intervals_disjoint([a,b,c,d])
False
sage: d2 = CIF(RIF(2, 3), RIF(2.001, 3))
sage: intervals_disjoint([a,b,c,d2])
True>>> from sage.all import *>>> from sage.rings.polynomial.complex_roots import intervals_disjoint>>> a = CIF(RIF(Integer(0), Integer(3)), Integer(0))>>> b = CIF(Integer(0), RIF(Integer(1), Integer(3)))>>> c = CIF(RIF(Integer(1), Integer(2)), RIF(Integer(1), Integer(2)))>>> d = CIF(RIF(Integer(2), Integer(3)), RIF(Integer(2), Integer(3)))>>> intervals_disjoint([a,b,c,d])
False>>> d2 = CIF(RIF(Integer(2), Integer(3)), RIF(RealNumber( 2.001 ), Integer(3)))>>> intervals_disjoint([a,b,c,d2])
True

2.1.20 Refine polynomial roots using Newton–Raphson
This is an implementation of the Newton–Raphson algorithm to approximate roots of complex polynomials. The implementation is based on interval arithmetic
AUTHORS:• Carl Witty (2007-11-18): initial version
sage.rings.polynomial.refine_root.refine_root(ip, ipd, irt, fld)
We are given a polynomial and its derivative (with complex interval coefficients), an estimated root, and a complex
interval field to use in computations. We use interval arithmetic to refine the root and prove that we have in fact
isolated a unique root.
If we succeed, we return the isolated root; if we fail, we return None.
EXAMPLES:
sage: # needs sage.symbolic
sage: from sage.rings.polynomial.refine_root import refine_root
sage: x = polygen(ZZ)
sage: p = x^9 - 1
sage: ip = CIF[ x ](p); ipx^9 - 1
(continues on next page)

386

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: ipd = CIF[ x ](p.derivative()); ipd
9*x^8
sage: irt = CIF(CC(cos(2*pi/9), sin(2*pi/9))); irt
0.76604444311897802? + 0.64278760968653926?*I
sage: ip(irt)0.?e-14 + 0.?e-14*I
sage: ipd(irt)
6.89439998807080? - 5.78508848717885?*I
sage: refine_root(ip, ipd, irt, CIF)
0.766044443118978? + 0.642787609686540?*I>>> from sage.all import *>>> # needs sage.symbolic>>> from sage.rings.polynomial.refine_root import refine_root>>> x = polygen(ZZ)>>> p = x**Integer(9) - Integer(1)>>> ip = CIF[ x ](p); ipx^9 - 1>>> ipd = CIF[ x ](p.derivative()); ipd
9*x^8>>> irt = CIF(CC(cos(Integer(2)*pi/Integer(9)), sin(Integer(2)*pi/Integer(9))));␣
˓→irt
0.76604444311897802? + 0.64278760968653926?*I>>> ip(irt)0.?e-14 + 0.?e-14*I>>> ipd(irt)
6.89439998807080? - 5.78508848717885?*I>>> refine_root(ip, ipd, irt, CIF)
0.766044443118978? + 0.642787609686540?*I

2.1.21 Ideals in Univariate Polynomial Rings
AUTHORS:• David Roe (2009-12-14) – initial version.
class sage.rings.polynomial.ideal.Ideal_1poly_field(ring, gens, coerce=True, **kwds)
Bases: Ideal_pid
An ideal in a univariate polynomial ring over a field.
change_ring(R)Coerce an ideal into a new ring.
EXAMPLES:
sage: R.<q> = QQ[]
sage: I = R.ideal([q^2 + q - 1])sage: I.change_ring(RR[ q ])˓→needs sage.rings.real_mpfr
Principal ideal (q^2 + q - 1.00000000000000) of
Univariate Polynomial Ring in q over Real Field with 53 bits of precision#␣>>> from sage.all import *>>> R = QQ[ q ]; (q,) = R._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

387

Polynomials, Release 10.4

(continued from previous page)>>> I = R.ideal([q**Integer(2) + q - Integer(1)])>>> I.change_ring(RR[ q ])#␣˓→needs sage.rings.real_mpfr
Principal ideal (q^2 + q - 1.00000000000000) of
Univariate Polynomial Ring in q over Real Field with 53 bits of precisiongroebner_basis(algorithm=None)
Return a Gröbner basis for this ideal.
The Gröbner basis has 1 element, namely the generator of the ideal. This trivial method exists for compatibility
with multi-variate polynomial rings.
INPUT:• algorithm – ignored
EXAMPLES:
sage: R.<x> = QQ[]
sage: I = R.ideal([x^2 - 1, x^3 - 1])sage: G = I.groebner_basis(); G[x - 1]
sage: type(G)<class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_
˓→generic >sage: list(G)[x - 1]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> I = R.ideal([x**Integer(2) - Integer(1), x**Integer(3) - Integer(1)])>>> G = I.groebner_basis(); G[x - 1]>>> type(G)<class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_
˓→generic >>>> list(G)[x - 1]residue_class_degree()Return the degree of the generator of this ideal.
This function is included for compatibility with ideals in rings of integers of number fields.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: P = R.ideal(t^4 + t + 1)
sage: P.residue_class_degree()4>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> P = R.ideal(t**Integer(4) + t + Integer(1))>>> P.residue_class_degree()
4388

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

residue_field(names=None, check=True)
If this ideal is 𝑃 ⊂ 𝐹𝑝 [𝑡], return the quotient 𝐹𝑝 [𝑡]/𝑃 .
EXAMPLES:
sage: R.<t> = GF(17)[]; P = R.ideal(t^3 + 2*t + 9)
sage: k.<a> = P.residue_field(); k˓→needs sage.rings.finite_rings
Residue field in a of Principal ideal (t^3 + 2*t + 9) of
Univariate Polynomial Ring in t over Finite Field of size 17#␣>>> from sage.all import *>>> R = GF(Integer(17))[ t ]; (t,) = R._first_ngens(1); P = R.
˓→ideal(t**Integer(3) + Integer(2)*t + Integer(9))>>> k = P.residue_field(names=( a ,)); (a,) = k._first_ngens(1); k˓→# needs sage.rings.finite_rings
Residue field in a of Principal ideal (t^3 + 2*t + 9) of
Univariate Polynomial Ring in t over Finite Field of size 17␣

2.1.22 Quotients of Univariate Polynomial Rings
EXAMPLES:
sage: R.<x> = QQ[]
sage: S = R.quotient(x**3 - 3*x + 1,
sage: S.gen()**2 in S
True
sage: x in S
True
sage: S.gen() in R
False
sage: 1 in S
Truealpha )>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(3)*x + Integer(1),>>> S.gen()**Integer(2) in S
True>>> x in S
True>>> S.gen() in R
False>>> Integer(1) in S
Truealpha )

classsage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRingFactory
Bases: UniqueFactory
Create a quotient of a polynomial ring.
INPUT:• ring – a univariate polynomial ring
• polynomial – an element of ring with a unit leading coefficient
2.1. Univariate Polynomials and Polynomial Rings

389

Polynomials, Release 10.4

• names – (optional) name for the variable
OUTPUT: Creates the quotient ring 𝑅/𝐼, where 𝑅 is the ring and 𝐼 is the principal ideal generated by polynomial.
EXAMPLES:
We create the quotient ring Z[𝑥]/(𝑥3 + 7), and demonstrate many basic functions with it:
sage: Z = IntegerRing()sage: R = PolynomialRing(Z, x ); x = R.gen()sage: S = R.quotient(x^3 + 7, a ); a = S.gen()sage: S
Univariate Quotient Polynomial Ring in aover Integer Ring with modulus x^3 + 7
sage: a^3
-7
sage: S.is_field()
False
sage: a in S
True
sage: x in S
True
sage: a in R
False
sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Integer Ringsage: S.modulus()x^3 + 7sage: S.degree()3>>> from sage.all import *>>> Z = IntegerRing()>>> R = PolynomialRing(Z, x ); x = R.gen()>>> S = R.quotient(x**Integer(3) + Integer(7), a ); a = S.gen()>>> S
Univariate Quotient Polynomial Ring in aover Integer Ring with modulus x^3 + 7>>> a**Integer(3)-7>>> S.is_field()
False>>> a in S
True>>> x in S
True>>> a in R
False>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Integer Ring>>> S.modulus()x^3 + 7>>> S.degree()3

We create the “iterated” polynomial ring quotient
𝑅 = (F2 [𝑦]/(𝑦 2 + 𝑦 + 1))[𝑥]/(𝑥3 − 5).

390

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.libs.ntl
sage: A.<y> = PolynomialRing(GF(2)); A
Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X)
sage: B = A.quotient(y^2 + y + 1, y2 ); B
Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2
with modulus y^2 + y + 1
sage: C = PolynomialRing(B, x ); x = C.gen(); C
Univariate Polynomial Ring in x
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
sage: R = C.quotient(x^3 - 5); R
Univariate Quotient Polynomial Ring in xbar
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
with modulus x^3 + 1>>> from sage.all import *>>> # needs sage.libs.ntl>>> A = PolynomialRing(GF(Integer(2)), names=( y ,)); (y,) = A._first_ngens(1); A
Univariate Polynomial Ring in y over Finite Field of size 2 (using GF2X)>>> B = A.quotient(y**Integer(2) + y + Integer(1), y2 ); B
Univariate Quotient Polynomial Ring in y2 over Finite Field of size 2
with modulus y^2 + y + 1>>> C = PolynomialRing(B, x ); x = C.gen(); C
Univariate Polynomial Ring in x
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1>>> R = C.quotient(x**Integer(3) - Integer(5)); R
Univariate Quotient Polynomial Ring in xbar
over Univariate Quotient Polynomial Ring in y2
over Finite Field of size 2 with modulus y^2 + y + 1
with modulus x^3 + 1

Next we create a number field, but viewed as a quotient of a polynomial ring over:sage: R = PolynomialRing(RationalField(), x ); x = R.gen()sage: S = R.quotient(x^3 + 2*x - 5, a ); S
Univariate Quotient Polynomial Ring in a over Rational Field
with modulus x^3 + 2*x - 5
sage: S.is_field()True
sage: S.degree()3>>> from sage.all import *>>> R = PolynomialRing(RationalField(), x ); x = R.gen()>>> S = R.quotient(x**Integer(3) + Integer(2)*x - Integer(5),Univariate Quotient Polynomial Ring in a over Rational Field
with modulus x^3 + 2*x - 5>>> S.is_field()
True>>> S.degree()3a ); S

There are conversion functions for easily going back and forth between quotients of polynomial rings overnumber fields:

2.1. Univariate Polynomials and Polynomial Rings

and

391

Polynomials, Release 10.4

sage: K = S.number_field(); K˓→needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + 2*x - 5
sage: K.polynomial_quotient_ring()
˓→needs sage.rings.number_field
Univariate Quotient Polynomial Ring in aover Rational Field with modulus x^3 + 2*x - 5>>> from sage.all import *>>> K = S.number_field(); K˓→needs sage.rings.number_field
Number Field in a with defining polynomial x^3 + 2*x - 5>>> K.polynomial_quotient_ring()
˓→needs sage.rings.number_field
Univariate Quotient Polynomial Ring in aover Rational Field with modulus x^3 + 2*x - 5

#␣

#␣

#␣

#␣

The leading coefficient must be a unit (but need not be 1).
sage: R = PolynomialRing(Integers(9), x ); x = R.gen()sage: S = R.quotient(2*x^4 + 2*x^3 + x + 2, a )sage: S = R.quotient(3*x^4 + 2*x^3 + x + 2, a )Traceback (most recent call last):...
TypeError: polynomial must have unit leading coefficient>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(9)), x ); x = R.gen()>>> S = R.quotient(Integer(2)*x**Integer(4) + Integer(2)*x**Integer(3) + x +␣˓→Integer(2),a )>>> S = R.quotient(Integer(3)*x**Integer(4) + Integer(2)*x**Integer(3) + x +␣˓→Integer(2),a )Traceback (most recent call last):...
TypeError: polynomial must have unit leading coefficient

Another example:
sage: R.<x> = PolynomialRing(IntegerRing())
sage: f = x^2 + 1
sage: R.quotient(f)Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(IntegerRing(), names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1)>>> R.quotient(f)Univariate Quotient Polynomial Ring in xbar over Integer Ring with modulus x^2 + 1

This shows that the issue at Issue #5482 is solved:
sage: R.<x> = PolynomialRing(QQ)
sage: f = x^2 - 1
sage: R.quotient_by_principal_ideal(f)Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 ˓→ 1

392

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(2) - Integer(1)>>> R.quotient_by_principal_ideal(f)Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus x^2 ˓→ 1

create_key(ring, polynomial, names=None)
Return a unique description of the quotient ring specified by the arguments.
EXAMPLES:
sage: R.<x> = QQ[]
sage: PolynomialQuotientRing.create_key(R, x + 1)
(Univariate Polynomial Ring in x over Rational Field, x + 1, ( xbar ,))>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> PolynomialQuotientRing.create_key(R, x + Integer(1))(Univariate Polynomial Ring in x over Rational Field, x + 1, ( xbar ,))create_object(version, key)
Return the quotient ring specified by key.
EXAMPLES:
sage: R.<x> = QQ[]
sage: PolynomialQuotientRing.create_object((8, 0, 0),....:(R, x^2 - 1, ( xbar )))Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus␣˓→x^2 - 1>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> PolynomialQuotientRing.create_object((Integer(8), Integer(0), Integer(0)),...
(R, x**Integer(2) - Integer(1), (˓→ xbar )))Univariate Quotient Polynomial Ring in xbar over Rational Field with modulus␣˓→x^2 - 1class
sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_coercion
Bases: DefaultConvertMap_uniqueA coercion map from a PolynomialQuotientRing to a PolynomialQuotientRing that restricts tothe coercion map on the underlying ring of constants.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: S.<x> = QQ[]
sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1)); f
Coercion map:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ringwith modulus x^2 + 1
To:
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1

2.1. Univariate Polynomials and Polynomial Rings

393

Polynomials, Release 10.4>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = QQ[ x ]; (x,) = S._first_ngens(1)>>> f = S.quo(x**Integer(2) + Integer(1)).coerce_map_from(R.quo(x**Integer(2) +␣˓→Integer(1))); f
Coercion map:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ringwith modulus x^2 + 1
To:
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1

is_injective()
Return whether this coercion is injective.
EXAMPLES:
If the modulus of the domain and the codomain is the same and the leading coefficient is a unit in the domain,then the map is injective if the underlying map on the constants is:
sage: R.<x> = ZZ[]
sage: S.<x> = QQ[]
sage: f = S.quo(x^2 + 1).coerce_map_from(R.quo(x^2 + 1))
sage: f.is_injective()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = QQ[ x ]; (x,) = S._first_ngens(1)>>> f = S.quo(x**Integer(2) + Integer(1)).coerce_map_from(R.quo(x**Integer(2)␣
˓→+ Integer(1)))>>> f.is_injective()
True

is_surjective()
Return whether this coercion is surjective.
EXAMPLES:
If the underlying map on constants is surjective, then this coercion is surjective since the modulus of thecodomain divides the modulus of the domain:
sage: R.<x> = ZZ[]
sage: f = R.quo(x).coerce_map_from(R.quo(x^2))
sage: f.is_surjective()
True>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> f = R.quo(x).coerce_map_from(R.quo(x**Integer(2)))>>> f.is_surjective()
True

If the modulus of the domain and the codomain is the same, then the map is surjective iff the underlying map
on the constants is:
sage: # needs sage.rings.padics
sage: A.<a> = ZqCA(9)(continues on next page)394

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: R.<x> = A[]
sage: S.<x> = A.fraction_field()[]sage: f = S.quo(x^2 + 2).coerce_map_from(R.quo(x^2 + 2))
sage: f.is_surjective()
False>>> from sage.all import *>>> # needs sage.rings.padics>>> A = ZqCA(Integer(9), names=( a ,)); (a,) = A._first_ngens(1)>>> R = A[ x ]; (x,) = R._first_ngens(1)>>> S = A.fraction_field()[ x ]; (x,) = S._first_ngens(1)>>> f = S.quo(x**Integer(2) + Integer(2)).coerce_map_from(R.quo(x**Integer(2)␣
˓→+ Integer(2)))>>> f.is_surjective()
False

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_domain(ring,
polynomial,
name=None
category=None
Bases: PolynomialQuotientRing_generic, IntegralDomain
EXAMPLES:
sage: R.<x> = PolynomialRing(ZZ)
sage: S.<xbar> = R.quotient(x^2 + 1)
sage: S
Univariate Quotient Polynomial Ring in xbar
over Integer Ring with modulus x^2 + 1
sage: loads(S.dumps()) == S
True
sage: loads(xbar.dumps()) == xbar
True>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) + Integer(1), names=( xbar ,)); (xbar,) = S._
˓→first_ngens(1)>>> S
Univariate Quotient Polynomial Ring in xbar
over Integer Ring with modulus x^2 + 1>>> loads(S.dumps()) == S
True>>> loads(xbar.dumps()) == xbar
Truefield_extension(names)
Take a polynomial quotient ring, and return a tuple with three elements: the NumberField defined by
the same polynomial quotient ring, a homomorphism from its parent to the NumberField sending thegenerators to one another, and the inverse isomorphism.
OUTPUT:2.1. Univariate Polynomials and Polynomial Rings

395

Polynomials, Release 10.4

• field• homomorphism from self to field• homomorphism from field to self
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(Rationals())
sage: S.<alpha> = R.quotient(x^3 - 2)sage: F.<b>, f, g = S.field_extension()sage: F
Number Field in b with defining polynomial x^3 - 2
sage: a = F.gen()sage: f(alpha)bsage: g(a)alpha>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(Rationals(), names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(2), names=( alpha ,)); (alpha,) =␣
˓→S._first_ngens(1)>>> F, f, g = S.field_extension(names=( b ,)); (b,) = F._first_ngens(1)>>> F
Number Field in b with defining polynomial x^3 - 2>>> a = F.gen()>>> f(alpha)b>>> g(a)alphaNote that the parent ring must be an integral domain:
sage: R.<x> = GF(25, f25 )[ x ]˓→needs sage.rings.finite_rings
sage: S.<a> = R.quo(x^3 - 2)
˓→needs sage.rings.finite_rings
sage: F, g, h = S.field_extension( b )˓→needs sage.rings.finite_rings
Traceback (most recent call last):...
AttributeError: PolynomialQuotientRing_generic_with_category
˓→attribute
field_extension ...

#␣
#␣
#␣

object has no␣>>> from sage.all import *>>> R = GF(Integer(25), f25 )[ x ]; (x,) = R._first_ngens(1)# needs sage.
˓→rings.finite_rings>>> S = R.quo(x**Integer(3) - Integer(2), names=( a ,)); (a,) = S._first_
˓→ngens(1)# needs sage.rings.finite_rings>>> F, g, h = S.field_extension( b )#␣˓→needs sage.rings.finite_rings
Traceback (most recent call last):...
AttributeError: PolynomialQuotientRing_generic_with_category object has no␣˓→attribute
field_extension ...

396

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Over a finite field, the corresponding field extension is not a number field:
sage: # needs sage.modules sage.rings.finite_rings
sage: R.<x> = GF(25, a )[ x ]sage: S.<a> = R.quo(x^3 + 2*x + 1)
sage: F, g, h = S.field_extension( b )sage: h(F.0^2 + 3)a^2 + 3sage: g(x^2 + 2)b^2 + 2>>> from sage.all import *>>> # needs sage.modules sage.rings.finite_rings>>> R = GF(Integer(25), a )[ x ]; (x,) = R._first_ngens(1)>>> S = R.quo(x**Integer(3) + Integer(2)*x + Integer(1), names=( a ,)); (a,)␣
˓→= S._first_ngens(1)>>> F, g, h = S.field_extension( b )>>> h(F.gen(0)**Integer(2) + Integer(3))
a^2 + 3>>> g(x**Integer(2) + Integer(2))
b^2 + 2

We do an example involving a relative number field:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[ x ]sage: K.<a> = NumberField(x^3 - 2)sage: S.<X> = K[ X ]sage: Q.<b> = S.quo(X^3 + 2*X + 1)
sage: Q.field_extension( b )(Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field,
˓→ ...
Defn: b |--> b, Relative number field morphism:
From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its␣˓→base fieldTo:
Univariate Quotient Polynomial Ring in b over Number Field in a with␣
˓→defining polynomial x^3 - 2 with modulus X^3 + 2*X + 1
Defn: b |--> ba |--> a)>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(3) - Integer(2), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> S = K[ X ]; (X,) = S._first_ngens(1)>>> Q = S.quo(X**Integer(3) + Integer(2)*X + Integer(1), names=( b ,)); (b,)␣
˓→= Q._first_ngens(1)>>> Q.field_extension( b )(Number Field in b with defining polynomial X^3 + 2*X + 1 over its base field,
˓→ ...
Defn: b |--> b, Relative number field morphism:
From: Number Field in b with defining polynomial X^3 + 2*X + 1 over its␣˓→base fieldTo:
Univariate Quotient Polynomial Ring in b over Number Field in a with␣
˓→defining polynomial x^3 - 2 with modulus X^3 + 2*X + 1
Defn: b |--> ba |--> a)2.1. Univariate Polynomials and Polynomial Rings

397

Polynomials, Release 10.4

We slightly change the example above so it works.
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[ x ]sage: K.<a> = NumberField(x^3 - 2)sage: S.<X> = K[ X ]sage: f = (X+a)^3 + 2*(X+a) + 1
sage: fX^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3
sage: Q.<z> = S.quo(f)sage: F.<w>, g, h = Q.field_extension()sage: c = g(z)sage: f(c)0sage: h(g(z))
zsage: g(h(w))
w>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(3) - Integer(2), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> S = K[ X ]; (X,) = S._first_ngens(1)>>> f = (X+a)**Integer(3) + Integer(2)*(X+a) + Integer(1)>>> fX^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3>>> Q = S.quo(f, names=( z ,)); (z,) = Q._first_ngens(1)>>> F, g, h = Q.field_extension(names=( w ,)); (w,) = F._first_ngens(1)>>> c = g(z)>>> f(c)0>>> h(g(z))
z>>> g(h(w))
w

AUTHORS:• Craig Citro (2006-08-07)• William Stein (2006-08-06)

class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field(ring,
polynomial,
name=None,
category=None)
Bases: PolynomialQuotientRing_domain, Field
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(QQ)(continues on next page)

398

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: S.<xbar> = R.quotient(x^2 + 1)
sage: S
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1
sage: loads(S.dumps()) == S
True
sage: loads(xbar.dumps()) == xbar
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) + Integer(1), names=( xbar ,)); (xbar,) = S._
˓→first_ngens(1)>>> S
Univariate Quotient Polynomial Ring in xbar over Rational Field
with modulus x^2 + 1>>> loads(S.dumps()) == S
True>>> loads(xbar.dumps()) == xbar
Truebase_field()
Alias for base_ring(), when we’re defined over a field.
complex_embeddings(prec=53)
Return all homomorphisms of this ring into the approximate complex field with precision prec.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: f = x^5 + x + 17
sage: k = R.quotient(f)sage: v = k.complex_embeddings(100)sage: [phi(k.0^2) for phi in v][2.9757207403766761469671194565,-2.4088994371613850098316292196 + 1.9025410530350528612407363802*I,-2.4088994371613850098316292196 - 1.9025410530350528612407363802*I,
0.92103906697304693634806949137 - 3.0755331188457794473265418086*I,
0.92103906697304693634806949137 + 3.0755331188457794473265418086*I]>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = x**Integer(5) + x + Integer(17)>>> k = R.quotient(f)>>> v = k.complex_embeddings(Integer(100))>>> [phi(k.gen(0)**Integer(2)) for phi in v][2.9757207403766761469671194565,-2.4088994371613850098316292196 + 1.9025410530350528612407363802*I,-2.4088994371613850098316292196 - 1.9025410530350528612407363802*I,
0.92103906697304693634806949137 - 3.0755331188457794473265418086*I,
0.92103906697304693634806949137 + 3.0755331188457794473265418086*I]

2.1. Univariate Polynomials and Polynomial Rings

399

Polynomials, Release 10.4class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic(ring,
polynomial,
name=No
category=Non
Bases: QuotientRing_generic
Quotient of a univariate polynomial ring by an ideal.
EXAMPLES:
sage: R.<x> = PolynomialRing(Integers(8)); R
Univariate Polynomial Ring in x over Ring of integers modulo 8
sage: S.<xbar> = R.quotient(x^2 + 1); S
Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8
with modulus x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(8)), names=( x ,)); (x,) = R._first_
˓→ngens(1); R
Univariate Polynomial Ring in x over Ring of integers modulo 8>>> S = R.quotient(x**Integer(2) + Integer(1), names=( xbar ,)); (xbar,) = S._
˓→first_ngens(1); S
Univariate Quotient Polynomial Ring in xbar over Ring of integers modulo 8
with modulus x^2 + 1

We demonstrate object persistence.
sage: loads(S.dumps()) == S
True
sage: loads(xbar.dumps()) == xbar
True>>> from sage.all import *>>> loads(S.dumps()) == S
True>>> loads(xbar.dumps()) == xbar
True

We create some sample homomorphisms;
sage: R.<x> = PolynomialRing(ZZ)
sage: S = R.quo(x^2 - 4)sage: f = S.hom([2])
sage: fRing morphism:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ringwith modulus x^2 - 4
To:
Integer Ring
Defn: xbar |--> 2
sage: f(x)2sage: f(x^2 - 4)0(continues on next page)

400

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f(x^2)
4>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quo(x**Integer(2) - Integer(4))>>> f = S.hom([Integer(2)])>>> fRing morphism:
From: Univariate Quotient Polynomial Ring in xbar over Integer Ringwith modulus x^2 - 4
To:
Integer Ring
Defn: xbar |--> 2>>> f(x)2>>> f(x**Integer(2) - Integer(4))
0>>> f(x**Integer(2))
4Element
alias of PolynomialQuotientRingElement
S_class_group(S, proof=True)
If self is an étale algebra 𝐷 over a number field 𝐾 (i.e. a quotient of 𝐾[𝑥] by a squarefree polynomial) and
𝑆 is a finite set of places of 𝐾, return a list of generators of the 𝑆-class group of 𝐷.
NOTE:
Since the ideal function behaves differently over number fields than over polynomial quotient rings (thequotient does not even know its ring of integers), we return a set of pairs (gen, order), where gen is atuple of generators of an ideal 𝐼 and order is the order of 𝐼 in the 𝑆-class group.
INPUT:• S – a set of primes of the coefficient ring
• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of generators of the 𝑆-class group, in the form (gen, order), where gen is a tuple of elements
generating a fractional ideal 𝐼 and order is the order of 𝐼 in the 𝑆-class group.
EXAMPLES:
A trivial algebra over√( −5) has the same class group as its base:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x)sage: S.S_class_group([])[((2, -a + 1), 2)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

401

Polynomials, Release 10.4

(continued from previous page)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x, names=( xbar ,)); (xbar,) = S._first_ngens(1)>>> S.S_class_group([])[((2, -a + 1), 2)]

When we include the prime (2, −𝑎 + 1), the 𝑆-class group becomes trivial:sage: S.S_class_group([K.ideal(2, -a+1)])
˓→needs sage.rings.number_field[]#␣>>> from sage.all import *>>> S.S_class_group([K.ideal(Integer(2), -a+Integer(1))])˓→# needs sage.rings.number_field[]␣Here is an example where the base and the extension both contribute to the class group:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: K.class_group()Class group of order 2 with structure C2 of Number Field in awith defining polynomial x^2 + 5 with a = 2.236067977499790?*I
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x^2 + 23)
sage: S.S_class_group([])[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]
sage: S.S_class_group([K.ideal(3, a-1)])[]
sage: S.S_class_group([K.ideal(2, a+1)])[]
sage: S.S_class_group([K.ideal(a)])[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> K.class_group()Class group of order 2 with structure C2 of Number Field in awith defining polynomial x^2 + 5 with a = 2.236067977499790?*I>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) + Integer(23), names=( xbar ,)); (xbar,) = S.
˓→_first_ngens(1)>>> S.S_class_group([])[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]>>> S.S_class_group([K.ideal(Integer(3), a-Integer(1))])[]>>> S.S_class_group([K.ideal(Integer(2), a+Integer(1))])[]>>> S.S_class_group([K.ideal(a)])[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]

Now we take an example over a nontrivial base with two factors, each contributing to the class group:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)(continues on next page)402

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: R.<x> = K[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 31))
sage: S.S_class_group([])# not tested[((1/4*xbar^2 + 31/4,(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4,(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),2)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) +␣˓→Integer(31)), names=( xbar ,)); (xbar,) = S._first_ngens(1)>>> S.S_class_group([])# not tested[((1/4*xbar^2 + 31/4,(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4,(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),2)]

By using the ideal (𝑎), we cut the part of the class group coming from 𝑥2 + 31 from 12 to 2, i.e. we lose agenerator of order 6 (this was fixed in Issue #14489):
sage: S.S_class_group([K.ideal(a)]) # representation varies# not␣
˓→tested, needs sage.rings.number_field[((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
2)]

2.1. Univariate Polynomials and Polynomial Rings

403

Polynomials, Release 10.4>>> from sage.all import *>>> S.S_class_group([K.ideal(a)]) # representation varies# not␣
˓→tested, needs sage.rings.number_field[((1/4*xbar^2 + 31/4, (-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4, (1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
2)]Note that all the returned values live where we expect them to:sage: # needs sage.rings.number_fieldsage: CG = S.S_class_group([])
sage: type(CG[0][0][1])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→generic_with_category.element_class >sage: type(CG[0][1])<class sage.rings.integer.Integer >>>> from sage.all import *>>> # needs sage.rings.number_field>>> CG = S.S_class_group([])>>> type(CG[Integer(0)][Integer(0)][Integer(1)])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→generic_with_category.element_class >>>> type(CG[Integer(0)][Integer(1)])<class sage.rings.integer.Integer >S_units(S, proof=True)
If self is an étale algebra 𝐷 over a number field 𝐾 (i.e. a quotient of 𝐾[𝑥] by a squarefree polynomial) and
𝑆 is a finite set of places of 𝐾, return a list of generators of the group of 𝑆-units of 𝐷.
INPUT:• S – a set of primes of the base field• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of generators of the 𝑆-unit group, in the form (gen, order), where gen is a unit of order order.
EXAMPLES:
sage: K.<a> = QuadraticField(-3)˓→needs sage.rings.number_fieldsage: K.unit_group()
˓→needs sage.rings.number_field
Unit group with structure C6 of Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*I#␣#␣

sage: # needs sage.rings.number_fieldsage: x = polygen(ZZ, x )sage: K.<a> = QQ[ x ].quotient(x^2 + 3)
sage: u, o = K.S_units([])[0]; o6(continues on next page)404

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: 2*u - 1 in {a, -a}
True
sage: u^6
1sage: u^3
-1
sage: 2*u^2 + 1 in {a, -a}
True>>> from sage.all import *>>> K = QuadraticField(-Integer(3), names=( a ,)); (a,) = K._first_ngens(1)#␣
˓→needs sage.rings.number_field>>> K.unit_group()#␣˓→needs sage.rings.number_field
Unit group with structure C6 of Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*I>>> # needs sage.rings.number_field>>> x = polygen(ZZ, x )>>> K = QQ[ x ].quotient(x**Integer(2) + Integer(3), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> u, o = K.S_units([])[Integer(0)]; o
6>>> Integer(2)*u - Integer(1) in {a, -a}
True>>> u**Integer(6)1>>> u**Integer(3)-1>>> Integer(2)*u**Integer(2) + Integer(1) in {a, -a}
True
sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-3)
sage: y = polygen(K)sage: L.<b> = K[ y ].quotient(y^3 + 5); L
Univariate Quotient Polynomial Ring in b over Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*Iwith modulus y^3 + 5
sage: [u for u, o in L.S_units([]) if o is Infinity][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: [u for u, o in L.S_units([K.ideal(1/2*a - 3/2)])....: if o is Infinity][(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a,(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: [u for u, o in L.S_units([K.ideal(2)]) if o is Infinity][(1/2*a - 1/2)*b^2 + (a + 1)*b + 3,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2,(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]>>> from sage.all import *>>> # needs sage.rings.number_field

2.1. Univariate Polynomials and Polynomial Rings(continues on next page)405

Polynomials, Release 10.4

(continued from previous page)>>> K = QuadraticField(-Integer(3), names=( a ,)); (a,) = K._first_ngens(1)>>> y = polygen(K)>>> L = K[ y ].quotient(y**Integer(3) + Integer(5), names=( b ,)); (b,) = L._˓→first_ngens(1); L
Univariate Quotient Polynomial Ring in b over Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*Iwith modulus y^3 + 5>>> [u for u, o in L.S_units([]) if o is Infinity][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]>>> [u for u, o in L.S_units([K.ideal(Integer(1)/Integer(2)*a - Integer(3)/˓→Integer(2))])... if o is Infinity][(-1/6*a - 1/2)*b^2 + (1/3*a - 1)*b + 4/3*a,(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]>>> [u for u, o in L.S_units([K.ideal(Integer(2))]) if o is Infinity][(1/2*a - 1/2)*b^2 + (a + 1)*b + 3,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a + 1/2,
(1/6*a + 1/2)*b^2 + (-1/3*a + 1)*b - 5/6*a - 1/2,(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]

Note that all the returned values live where we expect them to:sage: # needs sage.rings.number_fieldsage: U = L.S_units([])
sage: type(U[0][0])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→field_with_category.element_class >sage: type(U[0][1])<class sage.rings.integer.Integer >sage: type(U[1][1])<class sage.rings.infinity.PlusInfinity >>>> from sage.all import *>>> # needs sage.rings.number_field>>> U = L.S_units([])>>> type(U[Integer(0)][Integer(0)])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→field_with_category.element_class >>>> type(U[Integer(0)][Integer(1)])<class sage.rings.integer.Integer >>>> type(U[Integer(1)][Integer(1)])<class sage.rings.infinity.PlusInfinity >ambient()
base_ring()
Return the base ring of the polynomial ring, of which this ring is a quotient.
EXAMPLES:
The base ring of Z[𝑧]/(𝑧 3 + 𝑧 2 + 𝑧 + 1) is Z.
sage: R.<z> = PolynomialRing(ZZ)
sage: S.<beta> = R.quo(z^3 + z^2 + z + 1)
(continues on next page)

406

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: S.base_ring()
Integer Ring>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( z ,)); (z,) = R._first_ngens(1)>>> S = R.quo(z**Integer(3) + z**Integer(2) + z + Integer(1), names=( beta ,˓→)); (beta,) = S._first_ngens(1)>>> S.base_ring()
Integer Ring

Next we make a polynomial quotient ring over 𝑆 and ask for its base ring.
sage: T.<t> = PolynomialRing(S)sage: W = T.quotient(t^99 + 99)
sage: W.base_ring()
Univariate Quotient Polynomial Ring in beta
over Integer Ring with modulus z^3 + z^2 + z + 1>>> from sage.all import *>>> T = PolynomialRing(S, names=( t ,)); (t,) = T._first_ngens(1)>>> W = T.quotient(t**Integer(99) + Integer(99))>>> W.base_ring()
Univariate Quotient Polynomial Ring in beta
over Integer Ring with modulus z^3 + z^2 + z + 1

cardinality()
Return the number of elements of this quotient ring.
order is an alias of cardinality.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R.quo(1).cardinality()1sage: R.quo(x^3 - 2).cardinality()+Infinity
sage: R.quo(1).order()1sage: R.quo(x^3 - 2).order()+Infinity>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R.quo(Integer(1)).cardinality()1>>> R.quo(x**Integer(3) - Integer(2)).cardinality()+Infinity>>> R.quo(Integer(1)).order()1>>> R.quo(x**Integer(3) - Integer(2)).order()+Infinity

2.1. Univariate Polynomials and Polynomial Rings

407

Polynomials, Release 10.4

sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(9, a )[]sage: R.quo(2*x^3 + x + 1).cardinality()729
sage: GF(9, a ).extension(2*x^3 + x + 1).cardinality()729
sage: R.quo(2).cardinality()1>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(9), a )[ x ]; (x,) = R._first_ngens(1)>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()729>>> GF(Integer(9), a ).extension(Integer(2)*x**Integer(3) + x + Integer(1)).
˓→cardinality()729>>> R.quo(Integer(2)).cardinality()
1characteristic()
Return the characteristic of this quotient ring.
This is always the same as the characteristic of the base ring.
EXAMPLES:
sage: R.<z> = PolynomialRing(ZZ)
sage: S.<a> = R.quo(z - 19)sage: S.characteristic()
0
sage: R.<x> = PolynomialRing(GF(9,˓→needs sage.rings.finite_rings
sage: S = R.quotient(x^3 + 1)
˓→needs sage.rings.finite_rings
sage: S.characteristic()
˓→needs sage.rings.finite_rings
3

a ))

#␣
#␣
#␣

>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( z ,)); (z,) = R._first_ngens(1)>>> S = R.quo(z - Integer(19), names=( a ,)); (a,) = S._first_ngens(1)>>> S.characteristic()
0>>> R = PolynomialRing(GF(Integer(9), a ), names=( x ,)); (x,) = R._first_
˓→ngens(1)# needs sage.rings.finite_rings>>> S = R.quotient(x**Integer(3) + Integer(1))␣˓→# needs sage.rings.finite_rings>>> S.characteristic()#␣˓→needs sage.rings.finite_rings
3

class_group(proof=True)
If self is a quotient ring of a polynomial ring over a number field 𝐾, by a polynomial of nonzero discriminant, return a list of generators of the class group.
NOTE:

408

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Since the ideal function behaves differently over number fields than over polynomial quotient rings (thequotient does not even know its ring of integers), we return a set of pairs (gen, order), where gen is atuple of generators of an ideal 𝐼 and order is the order of 𝐼 in the class group.
INPUT:• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of pairs (gen, order), where gen is a tuple of elements generating a fractional ideal and orderis the order of 𝐼 in the class group.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-3)
sage: K.class_group()Class group of order 1 of Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*I
sage: x = polygen(QQ, x )sage: K.<a> = QQ[ x ].quotient(x^2 + 3)
sage: K.class_group()[]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(3), names=( a ,)); (a,) = K._first_ngens(1)>>> K.class_group()Class group of order 1 of Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*I>>> x = polygen(QQ, x )>>> K = QQ[ x ].quotient(x**Integer(2) + Integer(3), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> K.class_group()[]

A trivial algebra over√( −5) has the same class group as its base:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x)sage: S.class_group()[((2, -a + 1), 2)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x, names=( xbar ,)); (xbar,) = S._first_ngens(1)>>> S.class_group()[((2, -a + 1), 2)]

The same algebra constructed in a different way:sage: x = polygen(ZZ, x )sage: K.<a> = QQ[ x ].quotient(x^2 + 5)
sage: K.class_group(())#␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

409

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field[((2, a + 1), 2)]˓→>>> from sage.all import *>>> x = polygen(ZZ, x )>>> K = QQ[ x ].quotient(x**Integer(2) + Integer(5), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> K.class_group(())#␣˓→needs sage.rings.number_field[((2, a + 1), 2)]Here is an example where the base and the extension both contribute to the class group:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: K.class_group()Class group of order 2 with structure C2 of Number Field in awith defining polynomial x^2 + 5 with a = 2.236067977499790?*I
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient(x^2 + 23)
sage: S.class_group()[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> K.class_group()Class group of order 2 with structure C2 of Number Field in awith defining polynomial x^2 + 5 with a = 2.236067977499790?*I>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) + Integer(23), names=( xbar ,)); (xbar,) = S.
˓→_first_ngens(1)>>> S.class_group()[((2, -a + 1, 1/2*xbar + 1/2, -1/2*a*xbar + 1/2*a + 1), 6)]

Here is an example of a product of number fields, both of which contribute to the class group:sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 47))
sage: S.class_group()[((1/12*xbar^2 + 47/12,
1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48),
3),((-1/12*xbar^2 - 23/12,-1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48),
5)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) +␣˓→Integer(47)), names=( xbar ,)); (xbar,) = S._first_ngens(1)>>> S.class_group()[((1/12*xbar^2 + 47/12,(continues on next page)

410

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

1/48*xbar^3 - 1/48*xbar^2 + 47/48*xbar - 47/48),
3),((-1/12*xbar^2 - 23/12,-1/48*xbar^3 - 1/48*xbar^2 - 23/48*xbar - 23/48),
5)]

Now we take an example over a nontrivial base with two factors, each contributing to the class group:sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: R.<x> = K[]
sage: S.<xbar> = R.quotient((x^2 + 23) * (x^2 + 31))
sage: S.class_group()# not tested[((1/4*xbar^2 + 31/4,(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4,(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),2)]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient((x**Integer(2) + Integer(23)) * (x**Integer(2) +␣˓→Integer(31)), names=( xbar ,)); (xbar,) = S._first_ngens(1)>>> S.class_group()# not tested[((1/4*xbar^2 + 31/4,(-1/8*a + 1/8)*xbar^2 - 31/8*a + 31/8,
1/16*xbar^3 + 1/16*xbar^2 + 31/16*xbar + 31/16,-1/16*a*xbar^3 + (1/16*a + 1/8)*xbar^2 - 31/16*a*xbar + 31/16*a + 31/8),
6),((-1/4*xbar^2 - 23/4,(1/8*a - 1/8)*xbar^2 + 23/8*a - 23/8,-1/16*xbar^3 - 1/16*xbar^2 - 23/16*xbar - 23/16,
1/16*a*xbar^3 + (-1/16*a - 1/8)*xbar^2 + 23/16*a*xbar - 23/16*a - 23/8),
6),((-5/4*xbar^2 - 115/4,
1/4*a*xbar^2 + 23/4*a,-1/16*xbar^3 - 7/16*xbar^2 - 23/16*xbar - 161/16,
1/16*a*xbar^3 - 1/16*a*xbar^2 + 23/16*a*xbar - 23/16*a),2)]Note that all the returned values live where we expect them to:sage: # needs sage.rings.number_fieldsage: CG = S.class_group()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

411

Polynomials, Release 10.4

(continued from previous page)

sage: type(CG[0][0][1])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→generic_with_category.element_class >sage: type(CG[0][1])<class sage.rings.integer.Integer >>>> from sage.all import *>>> # needs sage.rings.number_field>>> CG = S.class_group()>>> type(CG[Integer(0)][Integer(0)][Integer(1)])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→generic_with_category.element_class >>>> type(CG[Integer(0)][Integer(1)])<class sage.rings.integer.Integer >construction()
Functorial construction of self
EXAMPLES:
sage: P.<t> = ZZ[]
sage: Q = P.quo(5 + t^2)
sage: F, R = Q.construction()sage: F(R) == Q
True
sage: P.<t> = GF(3)[]sage: Q = P.quo([2 + t^2])
sage: F, R = Q.construction()sage: F(R) == Q
True>>> from sage.all import *>>> P = ZZ[ t ]; (t,) = P._first_ngens(1)>>> Q = P.quo(Integer(5) + t**Integer(2))>>> F, R = Q.construction()>>> F(R) == Q
True>>> P = GF(Integer(3))[ t ]; (t,) = P._first_ngens(1)>>> Q = P.quo([Integer(2) + t**Integer(2)])>>> F, R = Q.construction()>>> F(R) == Q
True

AUTHOR:– Simon King (2010-05)
cover_ring()
Return the polynomial ring of which this ring is the quotient.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

412

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) - Integer(2))>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

degree()Return the degree of this quotient ring. The degree is the degree of the polynomial that we quotiented out
by.
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(3))
sage: S = R.quotient(x^2005 + 1)
sage: S.degree()2005>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2005) + Integer(1))>>> S.degree()2005

discriminant(v=None)
Return the discriminant of this ring over the base ring. This is by definition the discriminant of the polynomialthat we quotiented out by.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^3 + x^2 + x + 1)
sage: S.discriminant()-16
sage: S = R.quotient((x + 1) * (x + 1))
sage: S.discriminant()
0>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) + x**Integer(2) + x + Integer(1))>>> S.discriminant()-16>>> S = R.quotient((x + Integer(1)) * (x + Integer(1)))>>> S.discriminant()0

The discriminant of the quotient polynomial ring need not equal the discriminant of the corresponding number
field, since the discriminant of a number field is by definition the discriminant of the ring of integers of thenumber field:
sage: S = R.quotient(x^2 - 8)sage: S.number_field().discriminant()
˓→needs sage.rings.number_field8
sage: S.discriminant()
32

2.1. Univariate Polynomials and Polynomial Rings

#␣

413

Polynomials, Release 10.4>>> from sage.all import *>>> S = R.quotient(x**Integer(2) - Integer(8))>>> S.number_field().discriminant()
˓→needs sage.rings.number_field
8>>> S.discriminant()32#␣gen(n=0)
Return the generator of this quotient ring. This is the equivalence class of the image of the generator of thepolynomial ring.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 8, gamma )sage: S.gen()gamma>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) - Integer(8), gamma )>>> S.gen()gamma

is_field(proof=True)
Return whether or not this quotient ring is a field.
EXAMPLES:
sage: R.<z> = PolynomialRing(ZZ)
sage: S = R.quo(z^2 - 2)sage: S.is_field()
False
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)sage: S.is_field()True>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( z ,)); (z,) = R._first_ngens(1)>>> S = R.quo(z**Integer(2) - Integer(2))>>> S.is_field()
False>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) - Integer(2))>>> S.is_field()
True

If proof is True, requires the is_irreducible method of the modulus to be implemented:
sage: # needs sage.rings.padics
sage: R1.<x> = Qp(2)[]sage: F1 = R1.quotient_ring(x^2 + x + 1)
sage: R2.<x> = F1[]
sage: F2 = R2.quotient_ring(x^2 + x + 1)
(continues on next page)

414

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: F2.is_field()
Traceback (most recent call last):...
NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in
xbar over 2-adic Field with capped relative precision 20 with modulus(1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ringsage: F2.is_field(proof = False)
False>>> from sage.all import *>>> # needs sage.rings.padics>>> R1 = Qp(Integer(2))[ x ]; (x,) = R1._first_ngens(1)>>> F1 = R1.quotient_ring(x**Integer(2) + x + Integer(1))>>> R2 = F1[ x ]; (x,) = R2._first_ngens(1)>>> F2 = R2.quotient_ring(x**Integer(2) + x + Integer(1))>>> F2.is_field()
Traceback (most recent call last):...
NotImplementedError: cannot rewrite Univariate Quotient Polynomial Ring in
xbar over 2-adic Field with capped relative precision 20 with modulus(1 + O(2^20))*x^2 + (1 + O(2^20))*x + 1 + O(2^20) as an isomorphic ring>>> F2.is_field(proof = False)
False

is_finite()
Return whether or not this quotient ring is finite.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R.quo(1).is_finite()True
sage: R.quo(x^3 - 2).is_finite()
False>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R.quo(Integer(1)).is_finite()
True>>> R.quo(x**Integer(3) - Integer(2)).is_finite()
False
sage: R.<x> = GF(9, a )[]˓→needs sage.rings.finite_rings
sage: R.quo(2*x^3 + x + 1).is_finite()
˓→needs sage.rings.finite_rings
True
sage: R.quo(2).is_finite()
˓→needs sage.rings.finite_rings
True

#␣
#␣

#␣

>>> from sage.all import *>>> R = GF(Integer(9), a )[ x ]; (x,) = R._first_ngens(1)# needs sage.rings.
˓→finite_rings>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).is_finite()␣(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

415

Polynomials, Release 10.4

(continued from previous page)˓→# needs sage.rings.finite_rings

True>>> R.quo(Integer(2)).is_finite()˓→# needs sage.rings.finite_ringsTrue␣

sage: P.<v> = GF(2)[]sage: P.quotient(v^2 - v).is_finite()True>>> from sage.all import *>>> P = GF(Integer(2))[ v ]; (v,) = P._first_ngens(1)>>> P.quotient(v**Integer(2) - v).is_finite()True

is_integral_domain(proof=True)
Return whether or not this quotient ring is an integral domain.
EXAMPLES:
sage: R.<z> = PolynomialRing(ZZ)
sage: S = R.quotient(z^2 - z)sage: S.is_integral_domain()
False
sage: T = R.quotient(z^2 + 1)
sage: T.is_integral_domain()Truesage: U = R.quotient(-1)
sage: U.is_integral_domain()
False
sage: # needs sage.libs.singularsage: R2.<y> = PolynomialRing(R)sage: S2 = R2.quotient(z^2 - y^3)
sage: S2.is_integral_domain()Truesage: S3 = R2.quotient(z^2 - 2*y*z + y^2)
sage: S3.is_integral_domain()
False
sage: R.<z> = PolynomialRing(ZZ.quotient(4))
sage: S = R.quotient(z - 1)sage: S.is_integral_domain()False>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( z ,)); (z,) = R._first_ngens(1)>>> S = R.quotient(z**Integer(2) - z)>>> S.is_integral_domain()
False>>> T = R.quotient(z**Integer(2) + Integer(1))>>> T.is_integral_domain()
True>>> U = R.quotient(-Integer(1))(continues on next page)

416

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> U.is_integral_domain()
False>>> # needs sage.libs.singular>>> R2 = PolynomialRing(R, names=( y ,)); (y,) = R2._first_ngens(1)>>> S2 = R2.quotient(z**Integer(2) - y**Integer(3))>>> S2.is_integral_domain()
True>>> S3 = R2.quotient(z**Integer(2) - Integer(2)*y*z + y**Integer(2))>>> S3.is_integral_domain()
False>>> R = PolynomialRing(ZZ.quotient(Integer(4)), names=( z ,)); (z,) = R._
˓→first_ngens(1)>>> S = R.quotient(z - Integer(1))>>> S.is_integral_domain()Falsekrull_dimension()
Return the Krull dimension.
This is the Krull dimension of the base ring, unless the quotient is zero.
EXAMPLES:
sage: x = polygen(ZZ, x )sage: R = PolynomialRing(ZZ,
sage: R.krull_dimension()1
sage: R = PolynomialRing(ZZ,
sage: R.krull_dimension()-1>>> from sage.all import *>>> x = polygen(ZZ, x )>>> R = PolynomialRing(ZZ,>>> R.krull_dimension()1>>> R = PolynomialRing(ZZ,>>> R.krull_dimension()-1x ).quotient(x**6 - 1)x ).quotient(1)x ).quotient(x**Integer(6) - Integer(1))

x ).quotient(Integer(1))

lift(x)Return an element of the ambient ring mapping to the given argument.
EXAMPLES:
sage: P.<x> = QQ[]
sage: Q = P.quotient(x^2 + 2)
sage: Q.lift(Q.0^3)-2*x
sage: Q(-2*x)-2*xbarsage: Q.0^3-2*xbar2.1. Univariate Polynomials and Polynomial Rings

417

Polynomials, Release 10.4>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> Q = P.quotient(x**Integer(2) + Integer(2))>>> Q.lift(Q.gen(0)**Integer(3))-2*x>>> Q(-Integer(2)*x)-2*xbar>>> Q.gen(0)**Integer(3)-2*xbarmodulus()Return the polynomial modulus of this quotient ring.
EXAMPLES:
sage: R.<x> = PolynomialRing(GF(3))
sage: S = R.quotient(x^2 - 2)sage: S.modulus()x^2 + 1>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) - Integer(2))>>> S.modulus()x^2 + 1

ngens()
Return the number of generators of this quotient ring over the base ring. This function always returns 1.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<y> = PolynomialRing(R)sage: T.<z> = S.quotient(y + x)
sage: T
Univariate Quotient Polynomial Ring in z over
Univariate Polynomial Ring in x over Rational Field with modulus y + x
sage: T.ngens()
1>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( y ,)); (y,) = S._first_ngens(1)>>> T = S.quotient(y + x, names=( z ,)); (z,) = T._first_ngens(1)>>> T
Univariate Quotient Polynomial Ring in z over
Univariate Polynomial Ring in x over Rational Field with modulus y + x>>> T.ngens()
1

number_field()
Return the number field isomorphic to this quotient polynomial ring, if possible.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(QQ)(continues on next page)

418

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: S.<alpha> = R.quotient(x^29 - 17*x - 1)sage: K = S.number_field(); K
Number Field in alpha with defining polynomial x^29 - 17*x - 1
sage: alpha = K.gen()sage: alpha^29
17*alpha + 1>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(29) - Integer(17)*x - Integer(1), names=( alpha˓→ ,)); (alpha,) = S._first_ngens(1)>>> K = S.number_field(); K
Number Field in alpha with defining polynomial x^29 - 17*x - 1>>> alpha = K.gen()>>> alpha**Integer(29)17*alpha + 1

order()
Return the number of elements of this quotient ring.
order is an alias of cardinality.
EXAMPLES:
sage: R.<x> = ZZ[]
sage: R.quo(1).cardinality()1sage: R.quo(x^3 - 2).cardinality()+Infinity
sage: R.quo(1).order()1sage: R.quo(x^3 - 2).order()+Infinity>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> R.quo(Integer(1)).cardinality()1>>> R.quo(x**Integer(3) - Integer(2)).cardinality()+Infinity>>> R.quo(Integer(1)).order()1>>> R.quo(x**Integer(3) - Integer(2)).order()+Infinity
sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(9, a )[]sage: R.quo(2*x^3 + x + 1).cardinality()729
sage: GF(9, a ).extension(2*x^3 + x + 1).cardinality()729
sage: R.quo(2).cardinality()1

2.1. Univariate Polynomials and Polynomial Rings

419

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(9), a )[ x ]; (x,) = R._first_ngens(1)>>> R.quo(Integer(2)*x**Integer(3) + x + Integer(1)).cardinality()729>>> GF(Integer(9), a ).extension(Integer(2)*x**Integer(3) + x + Integer(1)).
˓→cardinality()729>>> R.quo(Integer(2)).cardinality()1polynomial_ring()
Return the polynomial ring of which this ring is the quotient.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S = R.quotient(x^2 - 2)sage: S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) - Integer(2))>>> S.polynomial_ring()
Univariate Polynomial Ring in x over Rational Field

random_element(degree=None, *args, **kwds)
Return a random element of this quotient ring.
INPUT:• degree – Optional argument: either an integer for fixing the degree, or a tuple of the minimum andmaximum degree. By default the degree is n - 1 with n the degree of the polynomial ring. Note thatthe degree of the polynomial is fixed before the modulo calculation. So when 𝑑𝑒𝑔𝑟𝑒𝑒 is bigger than the
degree of the polynomial ring, the degree of the returned polynomial would be lower than 𝑑𝑒𝑔𝑟𝑒𝑒.
• *args, **kwds – Arguments for randomization that are passed on to the random_element methodof the polynomial ring, and from there to the base ring
OUTPUT:
Element of this quotient ring
EXAMPLES:
sage: # needs sage.modules sage.rings.finite_rings
sage: F1.<a> = GF(2^7)
sage: P1.<x> = F1[]
sage: F2 = F1.extension(x^2 + x + 1, u )sage: F2.random_element().parent() is F2
True>>> from sage.all import *>>> # needs sage.modules sage.rings.finite_rings>>> F1 = GF(Integer(2)**Integer(7), names=( a ,)); (a,) = F1._first_ngens(1)>>> P1 = F1[ x ]; (x,) = P1._first_ngens(1)>>> F2 = F1.extension(x**Integer(2) + x + Integer(1), u )(continues on next page)

420

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> F2.random_element().parent() is F2
True

retract(x)Return the coercion of x into this polynomial quotient ring.
The rings that coerce into the quotient ring canonically are:• this ring
• any canonically isomorphic ring
• anything that coerces into the ring of which this is the quotient
selmer_generators(S, m, proof=True)
If self is an étale algebra 𝐷 over a number field 𝐾 (i.e. a quotient of 𝐾[𝑥] by a squarefree polynomial) and** 𝑚
𝑆 is a finite set of places of 𝐾, compute√ the Selmer group 𝐷(𝑆, 𝑚). This is the subgroup of 𝐷 /(𝐷 )𝑚consisting of elements 𝑎 such that 𝐷( 𝑎)/𝐷 is unramified at all primes of 𝐷 lying above a place outside of𝑆.
INPUT:• S – A set of primes of the coefficient ring (which is a number field).
• m – a positive integer• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of generators of 𝐷(𝑆, 𝑚).
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: R.<x> = K[]
sage: D.<T> = R.quotient(x)sage: D.selmer_generators((), 2)[-1, 2]sage: D.selmer_generators([K.ideal(2, -a + 1)], 2)[2, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2)[2, a + 1, -1]
sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4)[2, a + 1, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 3)[2]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3)[2, a + 1]
sage: D.selmer_generators([K.ideal(2, -a + 1),....:
K.ideal(3, a + 1),....:
K.ideal(a)], 3)[2, a + 1, -a]>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> D = R.quotient(x, names=( T ,)); (T,) = D._first_ngens(1)(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

421

Polynomials, Release 10.4

(continued from previous page)>>> D.selmer_generators((), Integer(2))[-1, 2]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(2))[2, -1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))], Integer(2))[2, a + 1, -1]>>> D.selmer_generators((K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))), Integer(4))[2, a + 1, -1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(3))[2]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))], Integer(3))[2, a + 1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)),...
K.ideal(Integer(3), a + Integer(1)),...
K.ideal(a)], Integer(3))[2, a + 1, -a]selmer_group(S, m, proof=True)
If self is an étale algebra 𝐷 over a number field 𝐾 (i.e. a quotient of 𝐾[𝑥] by a squarefree polynomial) and
𝑆 is a finite set of places of 𝐾, compute
the Selmer group 𝐷(𝑆, 𝑚). This is the subgroup of 𝐷* /(𝐷* )𝑚√consisting of elements 𝑎 such that 𝐷( 𝑚 𝑎)/𝐷 is unramified at all primes of 𝐷 lying above a place outside of𝑆.
INPUT:• S – A set of primes of the coefficient ring (which is a number field).
• m – a positive integer• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of generators of 𝐷(𝑆, 𝑚).
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-5)
sage: R.<x> = K[]
sage: D.<T> = R.quotient(x)sage: D.selmer_generators((), 2)[-1, 2]sage: D.selmer_generators([K.ideal(2, -a + 1)], 2)[2, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 2)[2, a + 1, -1]
sage: D.selmer_generators((K.ideal(2, -a + 1), K.ideal(3, a + 1)), 4)[2, a + 1, -1]
sage: D.selmer_generators([K.ideal(2, -a + 1)], 3)[2]
sage: D.selmer_generators([K.ideal(2, -a + 1), K.ideal(3, a + 1)], 3)[2, a + 1]
sage: D.selmer_generators([K.ideal(2, -a + 1),....:
K.ideal(3, a + 1),(continues on next page)422

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)....:[2, a + 1, -a]K.ideal(a)], 3)>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(5), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> D = R.quotient(x, names=( T ,)); (T,) = D._first_ngens(1)>>> D.selmer_generators((), Integer(2))[-1, 2]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(2))[2, -1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))], Integer(2))[2, a + 1, -1]>>> D.selmer_generators((K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))), Integer(4))[2, a + 1, -1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1))], Integer(3))[2]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)), K.
˓→ideal(Integer(3), a + Integer(1))], Integer(3))[2, a + 1]>>> D.selmer_generators([K.ideal(Integer(2), -a + Integer(1)),...
K.ideal(Integer(3), a + Integer(1)),...
K.ideal(a)], Integer(3))[2, a + 1, -a]units(proof=True)
If this quotient ring is over a number field K, by a polynomial of nonzero discriminant, returns a list ofgenerators of the units.
INPUT:• proof – if False, assume the GRH in computing the class group
OUTPUT:
A list of generators of the unit group, in the form (gen, order), where gen is a unit of order order.
EXAMPLES:
sage: K.<a> = QuadraticField(-3)˓→needs sage.rings.number_fieldsage: K.unit_group()
˓→needs sage.rings.number_field
Unit group with structure C6 of
Number Field in a with defining polynomial x^2 + 3 with a = 1.
˓→732050807568878?*I#␣#␣

sage: # needs sage.rings.number_fieldsage: x = polygen(ZZ, x )sage: K.<a> = QQ[ x ].quotient(x^2 + 3)
sage: u = K.units()[0][0]sage: 2*u - 1 in {a, -a}
True
sage: u^6
1
(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

423

Polynomials, Release 10.4

(continued from previous page)

sage: u^3
-1
sage: 2*u^2 + 1 in {a, -a}
True
sage: x = polygen(ZZ, x )sage: K.<a> = QQ[ x ].quotient(x^2 + 5)
sage: K.units(())[(-1, 2)]>>> from sage.all import *>>> K = QuadraticField(-Integer(3), names=( a ,)); (a,) = K._first_ngens(1)#␣
˓→needs sage.rings.number_field>>> K.unit_group()#␣˓→needs sage.rings.number_field
Unit group with structure C6 of
Number Field in a with defining polynomial x^2 + 3 with a = 1.
˓→732050807568878?*I>>> # needs sage.rings.number_field>>> x = polygen(ZZ, x )>>> K = QQ[ x ].quotient(x**Integer(2) + Integer(3), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> u = K.units()[Integer(0)][Integer(0)]>>> Integer(2)*u - Integer(1) in {a, -a}
True>>> u**Integer(6)1>>> u**Integer(3)-1>>> Integer(2)*u**Integer(2) + Integer(1) in {a, -a}True>>> x = polygen(ZZ, x )>>> K = QQ[ x ].quotient(x**Integer(2) + Integer(5), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> K.units(())[(-1, 2)]sage: # needs sage.rings.number_fieldsage: K.<a> = QuadraticField(-3)
sage: y = polygen(K)sage: L.<b> = K[ y ].quotient(y^3 + 5); L
Univariate Quotient Polynomial Ring in b over Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*Iwith modulus y^3 + 5
sage: [u for u, o in L.units() if o is Infinity][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]
sage: L.<b> = K.extension(y^3 + 5)
sage: L.unit_group()
Unit group with structure C6 x Z x Z of
Number Field in b with defining polynomial x^3 + 5 over its base fieldsage: L.unit_group().gens()# abstract generators(u0, u1, u2)
sage: L.unit_group().gens_values()[1:][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]

424

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QuadraticField(-Integer(3), names=( a ,)); (a,) = K._first_ngens(1)>>> y = polygen(K)>>> L = K[ y ].quotient(y**Integer(3) + Integer(5), names=( b ,)); (b,) = L._˓→first_ngens(1); L
Univariate Quotient Polynomial Ring in b over Number Field in awith defining polynomial x^2 + 3 with a = 1.732050807568878?*Iwith modulus y^3 + 5>>> [u for u, o in L.units() if o is Infinity][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]>>> L = K.extension(y**Integer(3) + Integer(5), names=( b ,)); (b,) = L._˓→first_ngens(1)>>> L.unit_group()
Unit group with structure C6 x Z x Z of
Number Field in b with defining polynomial x^3 + 5 over its base field>>> L.unit_group().gens()# abstract generators(u0, u1, u2)>>> L.unit_group().gens_values()[Integer(1):][(-1/3*a - 1)*b^2 - 4/3*a*b - 5/6*a + 7/2,
2/3*a*b^2 + (2/3*a - 2)*b - 5/6*a - 7/2]

Note that all the returned values live where we expect them to:sage: # needs sage.rings.number_fieldsage: L.<b> = K[ y ].quotient(y^3 + 5)
sage: U = L.units()
sage: type(U[0][0])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→field_with_category.element_class >sage: type(U[0][1])<class sage.rings.integer.Integer >sage: type(U[1][1])<class sage.rings.infinity.PlusInfinity >>>> from sage.all import *>>> # needs sage.rings.number_field>>> L = K[ y ].quotient(y**Integer(3) + Integer(5), names=( b ,)); (b,) = L._˓→first_ngens(1)>>> U = L.units()>>> type(U[Integer(0)][Integer(0)])<class sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_
˓→field_with_category.element_class >>>> type(U[Integer(0)][Integer(1)])<class sage.rings.integer.Integer >>>> type(U[Integer(1)][Integer(1)])<class sage.rings.infinity.PlusInfinity >sage.rings.polynomial.polynomial_quotient_ring.is_PolynomialQuotientRing(x)2.1. Univariate Polynomials and Polynomial Rings

425

Polynomials, Release 10.4

2.1.23 Elements of Quotients of Univariate Polynomial Rings
EXAMPLES: We create a quotient of a univariate polynomial ring over Z.
sage: R.<x> = ZZ[]
sage: S.<a> = R.quotient(x^3 + 3*x - 1)sage: 2 * a^3-6*a + 2>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) + Integer(3)*x - Integer(1), names=( a ,)); (a,) = S.
˓→_first_ngens(1)>>> Integer(2) * a**Integer(3)-6*a + 2

Next we make a univariate polynomial ring over Z[𝑥]/(𝑥3 + 3𝑥 − 1).
sage: S1.<y> = S[]>>> from sage.all import *>>> S1 = S[ y ]; (y,) = S1._first_ngens(1)And, we quotient out that by 𝑦 2 + 𝑎.
sage: T.<z> = S1.quotient(y^2 + a)>>> from sage.all import *>>> T = S1.quotient(y**Integer(2) + a, names=( z ,)); (z,) = T._first_ngens(1)In the quotient 𝑧 2 is −𝑎.
sage: z^2-a>>> from sage.all import *>>> z**Integer(2)-aAnd since 𝑎3 = −3𝑥 + 1, we have:sage: z^6
3*a - 1>>> from sage.all import *>>> z**Integer(6)3*a - 1
sage: R.<x> = PolynomialRing(Integers(9))
sage: S.<a> = R.quotient(x^4 + 2*x^3 + x + 2)
sage: a^100
7*a^3 + 8*a + 7>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(9)), names=( x ,)); (x,) = R._first_ngens(1)(continues on next page)

426

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> S = R.quotient(x**Integer(4) + Integer(2)*x**Integer(3) + x + Integer(2), names=(
˓→ a ,)); (a,) = S._first_ngens(1)>>> a**Integer(100)7*a^3 + 8*a + 7
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 - 2)sage: aasage: a^3
2>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(2), names=( a ,)); (a,) = S._first_ngens(1)>>> aa>>> a**Integer(3)2For the purposes of comparison in Sage the quotient element 𝑎3 is equal to 𝑥3 . This is because when the comparison is
performed, the right element is coerced into the parent of the left element, and 𝑥3 coerces to 𝑎3 .
sage: a == x
True
sage: a^3 == x^3
True
sage: x^3
x^3
sage: S(x^3)
2>>> from sage.all import *>>> a == x
True>>> a**Integer(3) == x**Integer(3)True>>> x**Integer(3)x^3>>> S(x**Integer(3))
2

AUTHORS:• William Steinclass sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement(

Bases: Polynomial_singular_repr, CommutativeRingElement
Element of a quotient of a polynomial ring.
EXAMPLES:
2.1. Univariate Polynomials and Polynomial Rings

427

Polynomials, Release 10.4

sage: P.<x> = QQ[]
sage: Q.<xi> = P.quo([(x^2 + 1)])
sage: xi^2
-1
sage: singular(xi)˓→needs sage.libs.singularxi
sage: (singular(xi)*singular(xi)).NF( std(0) )˓→needs sage.libs.singular
-1

#␣

#␣

>>> from sage.all import *>>> P = QQ[ x ]; (x,) = P._first_ngens(1)>>> Q = P.quo([(x**Integer(2) + Integer(1))], names=( xi ,)); (xi,) = Q._first_
˓→ngens(1)>>> xi**Integer(2)-1>>> singular(xi)#␣˓→needs sage.libs.singularxi>>> (singular(xi)*singular(xi)).NF( std(0) )#␣˓→needs sage.libs.singular-1charpoly(var)The characteristic polynomial of this element, which is by definition the characteristic polynomial of rightmultiplication by this element.
INPUT:• var – string; the variable name
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quo(x^3 -389*x^2 + 2*x - 5)sage: a.charpoly( X )˓→needs sage.modulesX^3 - 389*X^2 + 2*X - 5#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quo(x**Integer(3) -Integer(389)*x**Integer(2) + Integer(2)*x -␣
˓→Integer(5), names=( a ,)); (a,) = S._first_ngens(1)>>> a.charpoly( X )#␣˓→needs sage.modulesX^3 - 389*X^2 + 2*X - 5

fcp(var='x')
Return the factorization of the characteristic polynomial of this element.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 -389*x^2 + 2*x - 5)sage: a.fcp( x )˓→needs sage.modules#␣(continues on next page)

428

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x^3 - 389*x^2 + 2*x - 5
sage: S(1).fcp( y )˓→needs sage.modules(y - 1)^3#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) -Integer(389)*x**Integer(2) + Integer(2)*x -␣
˓→Integer(5), names=( a ,)); (a,) = S._first_ngens(1)>>> a.fcp( x )#␣˓→needs sage.modulesx^3 - 389*x^2 + 2*x - 5>>> S(Integer(1)).fcp( y )␣˓→# needs sage.modules(y - 1)^3

field_extension(names)
Given a polynomial with base ring a quotient ring, return a 3-tuple: a number field defined by the samepolynomial, a homomorphism from its parent to the number field sending the generators to one another, andthe inverse isomorphism.
INPUT:• names – name of generator of output field
OUTPUT:• field• homomorphism from self to field• homomorphism from field to self
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x> = PolynomialRing(QQ)
sage: S.<alpha> = R.quotient(x^3 - 2)sage: F.<a>, f, g = alpha.field_extension()sage: F
Number Field in a with defining polynomial x^3 - 2
sage: a = F.gen()sage: f(alpha)asage: g(a)alpha>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(2), names=( alpha ,)); (alpha,) =␣
˓→S._first_ngens(1)>>> F, f, g = alpha.field_extension(names=( a ,)); (a,) = F._first_ngens(1)>>> F
Number Field in a with defining polynomial x^3 - 2>>> a = F.gen()>>> f(alpha)a(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

429

Polynomials, Release 10.4

(continued from previous page)>>> g(a)alphaOver a finite field, the corresponding field extension is not a number field:
sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(25, b )[ x ]sage: S.<a> = R.quo(x^3 + 2*x + 1)
sage: F.<b>, g, h = a.field_extension()sage: h(b^2 + 3)a^2 + 3sage: g(x^2 + 2)b^2 + 2>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(25), b )[ x ]; (x,) = R._first_ngens(1)>>> S = R.quo(x**Integer(3) + Integer(2)*x + Integer(1), names=( a ,)); (a,)␣
˓→= S._first_ngens(1)>>> F, g, h = a.field_extension(names=( b ,)); (b,) = F._first_ngens(1)>>> h(b**Integer(2) + Integer(3))
a^2 + 3>>> g(x**Integer(2) + Integer(2))
b^2 + 2

We do an example involving a relative number field:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[ x ]sage: K.<a> = NumberField(x^3 - 2)sage: S.<X> = K[ X ]sage: Q.<b> = S.quo(X^3 + 2*X + 1)
sage: F, g, h = b.field_extension( c )>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(3) - Integer(2), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> S = K[ X ]; (X,) = S._first_ngens(1)>>> Q = S.quo(X**Integer(3) + Integer(2)*X + Integer(1), names=( b ,)); (b,)␣
˓→= Q._first_ngens(1)>>> F, g, h = b.field_extension( c )Another more awkward example:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[ x ]sage: K.<a> = NumberField(x^3 - 2)sage: S.<X> = K[ X ]sage: f = (X+a)^3 + 2*(X+a) + 1
sage: fX^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3
sage: Q.<z> = S.quo(f)sage: F.<w>, g, h = z.field_extension()sage: c = g(z)(continues on next page)

430

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f(c)0sage: h(g(z))
zsage: g(h(w))
w>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(3) - Integer(2), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> S = K[ X ]; (X,) = S._first_ngens(1)>>> f = (X+a)**Integer(3) + Integer(2)*(X+a) + Integer(1)>>> fX^3 + 3*a*X^2 + (3*a^2 + 2)*X + 2*a + 3>>> Q = S.quo(f, names=( z ,)); (z,) = Q._first_ngens(1)>>> F, g, h = z.field_extension(names=( w ,)); (w,) = F._first_ngens(1)>>> c = g(z)>>> f(c)0>>> h(g(z))
z>>> g(h(w))
w

AUTHORS:• Craig Citro (2006-08-06)• William Stein (2006-08-06)
is_unit()
Return True if self is invertible.
Warning: Only implemented when the base ring is a field.
EXAMPLES:
sage: R.<x> = QQ[]
sage: S.<y> = R.quotient(x^2 + 2*x + 1)
sage: (2*y).is_unit()
True
sage: (y + 1).is_unit()
False>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(2) + Integer(2)*x + Integer(1), names=( y ,));␣
˓→(y,) = S._first_ngens(1)>>> (Integer(2)*y).is_unit()True>>> (y + Integer(1)).is_unit()
False

2.1. Univariate Polynomials and Polynomial Rings

431

Polynomials, Release 10.4

lift()
Return lift of this polynomial quotient ring element to the unique equivalent polynomial of degree less thanthe modulus.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 - 2)sage: b = a^2 - 3
sage: ba^2 - 3sage: b.lift()x^2 - 3>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(2), names=( a ,)); (a,) = S._first_
˓→ngens(1)>>> b = a**Integer(2) - Integer(3)>>> ba^2 - 3>>> b.lift()x^2 - 3list(copy=True)
Return list of the elements of self, of length the same as the degree of the quotient polynomial ring.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 + 2*x - 5)sage: a^10
-134*a^2 - 35*a + 300
sage: (a^10).list()[300, -35, -134]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) + Integer(2)*x - Integer(5), names=( a ,));␣
˓→(a,) = S._first_ngens(1)>>> a**Integer(10)-134*a^2 - 35*a + 300>>> (a**Integer(10)).list()[300, -35, -134]

matrix()The matrix of right multiplication by this element on the power basis for the quotient ring.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 + 2*x - 5)sage: a.matrix()
˓→needs sage.modules[ 0 1 0][ 0 0 1]
[ 5 -2 0]432#␣Chapter 2. Univariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) + Integer(2)*x - Integer(5), names=( a ,));␣
˓→(a,) = S._first_ngens(1)>>> a.matrix()#␣˓→needs sage.modules[ 0 1 0][ 0 0 1]
[ 5 -2 0]

minpoly()
The minimal polynomial of this element, which is by definition the minimal polynomial of the matrix()of this element.
ALGORITHM: Use minpoly_mod() if possible, otherwise compute the minimal polynomial of the matrix().
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 + 2*x - 5)sage: (a + 123).minpoly()
˓→needs sage.modulesx^3 - 369*x^2 + 45389*x - 1861118
sage: (a + 123).matrix().minpoly()
˓→needs sage.modulesx^3 - 369*x^2 + 45389*x - 1861118#␣#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) + Integer(2)*x - Integer(5), names=( a ,));␣
˓→(a,) = S._first_ngens(1)>>> (a + Integer(123)).minpoly()␣˓→# needs sage.modulesx^3 - 369*x^2 + 45389*x - 1861118>>> (a + Integer(123)).matrix().minpoly()␣˓→# needs sage.modulesx^3 - 369*x^2 + 45389*x - 1861118

One useful application of this function is to compute a minimal polynomial of a finite-field element over anintermediate extension, rather than the absolute minimal polynomial over the prime field:
sage: # needs sage.rings.finite_rings
sage: F2.<i> = GF((431,2), modulus=[1,0,1])
sage: F6.<u> = F2.extension(3)sage: (u + 1).minpoly()
˓→needs sage.modulesx^6 + 425*x^5 + 19*x^4 + 125*x^3 + 189*x^2 + 239*x + 302
sage: ext = F6.over(F2)˓→needs sage.modules
sage: ext(u + 1).minpoly() # indirect doctest
˓→needs sage.modules # randomx^3 + (396*i + 428)*x^2 + (80*i + 39)*x + 9*i + 178

#␣

#␣
#␣

>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F2 = GF((Integer(431),Integer(2)), modulus=[Integer(1),Integer(0),(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

433

Polynomials, Release 10.4

(continued from previous page)

Integer(1)], names=( i ,)); (i,) = F2._first_ngens(1)>>> F6 = F2.extension(Integer(3), names=( u ,)); (u,) = F6._first_ngens(1)>>> (u + Integer(1)).minpoly()␣˓→# needs sage.modulesx^6 + 425*x^5 + 19*x^4 + 125*x^3 + 189*x^2 + 239*x + 302>>> ext = F6.over(F2)#␣˓→needs sage.modules>>> ext(u + Integer(1)).minpoly() # indirect doctest␣˓→# needs sage.modules # randomx^3 + (396*i + 428)*x^2 + (80*i + 39)*x + 9*i + 178˓→norm()The norm of this element, which is the determinant of the matrix of right multiplication by this element.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 - 389*x^2 + 2*x - 5)sage: a.norm()
˓→needs sage.modules5#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(389)*x**Integer(2) + Integer(2)*x ˓→ Integer(5), names=( a ,)); (a,) = S._first_ngens(1)>>> a.norm()#␣˓→needs sage.modules
5

rational_reconstruction(*args, **kwargs)
Compute a rational reconstruction of this polynomial quotient ring element to its cover ring.
This method is a thin convenience wrapper around Polynomial.rational_reconstruction().
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: R.<x> = GF(65537)[]
sage: m = (x^11 + 25345*x^10 + 10956*x^9 + 13873*x^8 + 23962*x^7....:+ 17496*x^6 + 30348*x^5 + 7440*x^4 + 65438*x^3 + 7676*x^2....:+ 54266*x + 47805)
sage: f = (20437*x^10 + 62630*x^9 + 63241*x^8 + 12820*x^7 + 42171*x^6....:+ 63091*x^5 + 15288*x^4 + 32516*x^3 + 2181*x^2 + 45236*x + 2447)
sage: f_mod_m = R.quotient(m)(f)sage: f_mod_m.rational_reconstruction()(51388*x^5 + 29141*x^4 + 59341*x^3 + 7034*x^2 + 14152*x + 23746,
x^5 + 15208*x^4 + 19504*x^3 + 20457*x^2 + 11180*x + 28352)>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(65537))[ x ]; (x,) = R._first_ngens(1)>>> m = (x**Integer(11) + Integer(25345)*x**Integer(10) +␣˓→Integer(10956)*x**Integer(9) + Integer(13873)*x**Integer(8) +␣˓→Integer(23962)*x**Integer(7)...
+ Integer(17496)*x**Integer(6) + Integer(30348)*x**Integer(5) +␣
(continues on next page)

434

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(7440)*x**Integer(4) + Integer(65438)*x**Integer(3) +␣˓→Integer(7676)*x**Integer(2)...
+ Integer(54266)*x + Integer(47805))>>> f = (Integer(20437)*x**Integer(10) + Integer(62630)*x**Integer(9) +␣˓→Integer(63241)*x**Integer(8) + Integer(12820)*x**Integer(7) +␣˓→Integer(42171)*x**Integer(6)...
+ Integer(63091)*x**Integer(5) + Integer(15288)*x**Integer(4) +␣˓→Integer(32516)*x**Integer(3) + Integer(2181)*x**Integer(2) +␣˓→Integer(45236)*x + Integer(2447))>>> f_mod_m = R.quotient(m)(f)>>> f_mod_m.rational_reconstruction()(51388*x^5 + 29141*x^4 + 59341*x^3 + 7034*x^2 + 14152*x + 23746,
x^5 + 15208*x^4 + 19504*x^3 + 20457*x^2 + 11180*x + 28352)
˓→

trace()The trace of this element, which is the trace of the matrix of right multiplication by this element.
EXAMPLES:
sage: R.<x> = PolynomialRing(QQ)
sage: S.<a> = R.quotient(x^3 - 389*x^2 + 2*x - 5)sage: a.trace()
˓→needs sage.modules389#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> S = R.quotient(x**Integer(3) - Integer(389)*x**Integer(2) + Integer(2)*x ˓→ Integer(5), names=( a ,)); (a,) = S._first_ngens(1)>>> a.trace()#␣˓→needs sage.modules389

2.1.24 Polynomial Compilers
AUTHORS:• Tom Boothby, initial design & implementation• Robert Bradshaw, bug fixes / suggested & assisted with significant design improvements
class sage.rings.polynomial.polynomial_compiled.CompiledPolynomialFunction
Bases: object
Builds a reasonably optimized directed acyclic graph representation for a given polynomial. A CompiledPolynomialFunction is callable from python, though it is a little faster to call the eval function from pyrex.
This class is not intended to be called by a user, rather, it is intended to improve the performance of immutable
polynomial objects.
Todo:• Recursive calling• Faster casting of coefficients / argument• Multivariate polynomials
2.1. Univariate Polynomials and Polynomial Rings

435

Polynomials, Release 10.4

• Cython implementation of Pippenger’s Algorithm that doesn’t depend heavily upon dicts.
• Computation of parameter sequence suggested by Pippenger• Univariate exponentiation can use Brauer’s method to improve extremely sparse polynomials of very highdegreeclass sage.rings.polynomial.polynomial_compiled.abc_pd
Bases: binary_pd
class sage.rings.polynomial.polynomial_compiled.add_pd
Bases: binary_pd
class sage.rings.polynomial.polynomial_compiled.binary_pd
Bases: generic_pd
class sage.rings.polynomial.polynomial_compiled.coeff_pd
Bases: generic_pd
class sage.rings.polynomial.polynomial_compiled.dummy_pd
Bases: generic_pd
class sage.rings.polynomial.polynomial_compiled.generic_pd
Bases: object
class sage.rings.polynomial.polynomial_compiled.mul_pd
Bases: binary_pd
class sage.rings.polynomial.polynomial_compiled.pow_pd
Bases: unary_pd
class sage.rings.polynomial.polynomial_compiled.sqr_pd
Bases: unary_pd
class sage.rings.polynomial.polynomial_compiled.unary_pd
Bases: generic_pd
class sage.rings.polynomial.polynomial_compiled.univar_pd
Bases: generic_pd
class sage.rings.polynomial.polynomial_compiled.var_pd
Bases: generic_pd

2.1.25 Polynomial multiplication by Kronecker substitution
2.1.26 Integer-valued polynomial rings
AUTHORS:• Frédéric Chapoton (2023-03): Initial version
class sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing(R)Bases: UniqueRepresentation, Parent
The integer-valued polynomial ring over a base ring 𝑅.
Integer-valued polynomial rings are commutative and associative algebras, with a basis indexed by non-negative
integers.
436

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

There are two natural bases, made of the sequence(︀𝑥+𝑛)︀
for 𝑛 ≥ 0 (the shifted basis).
𝑛

(︀𝑥)︀
𝑛

for 𝑛 ≥ 0 (the binomial basis) and of the other sequence

These two bases are available as follows:
sage: B = IntegerValuedPolynomialRing(QQ).Binomial()
sage: S = IntegerValuedPolynomialRing(QQ).Shifted()>>> from sage.all import *>>> B = IntegerValuedPolynomialRing(QQ).Binomial()>>> S = IntegerValuedPolynomialRing(QQ).Shifted()or by using the shortcuts:
sage: B = IntegerValuedPolynomialRing(QQ).B()
sage: S = IntegerValuedPolynomialRing(QQ).S()>>> from sage.all import *>>> B = IntegerValuedPolynomialRing(QQ).B()>>> S = IntegerValuedPolynomialRing(QQ).S()

There is a conversion formula between the two bases:(︂ )︂ ∑︁(︂ )︂(︂
)︂
𝑖
𝑥
𝑖
𝑥+𝑘
=
(−1)𝑖−𝑘𝑖𝑘𝑘𝑘=0with inverse:
(︂

)︂ ∑︁
𝑖 (︂ )︂(︂ )︂
𝑥+𝑖
𝑖
𝑥
=
.
𝑖
𝑘
𝑘
𝑘=0

REFERENCES:• Wikipedia article Integer-valued polynomialBalias of Binomialclass Bases(parent_with_realization)
Bases: Category_realization_of_parent
class ElementMethods
Bases: object
content()
Return the content of self.
This is the gcd of the coefficients.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: B = F.basis()
sage: (3*B[4]+6*B[7]).content()
3

2.1. Univariate Polynomials and Polynomial Rings

437

Polynomials, Release 10.4>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()>>> B = F.basis()>>> (Integer(3)*B[Integer(4)]+Integer(6)*B[Integer(7)]).content()3

polynomial()
Convert to a polynomial in 𝑥.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: B = F.gen()sage: (B+1).polynomial()x + 2
sage: F = IntegerValuedPolynomialRing(ZZ).B()
sage: B = F.gen()sage: (B+1).polynomial()
x + 1>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()>>> B = F.gen()>>> (B+Integer(1)).polynomial()
x + 2>>> F = IntegerValuedPolynomialRing(ZZ).B()>>> B = F.gen()>>> (B+Integer(1)).polynomial()
x + 1

shift(j=1)
Shift all indices by 𝑗.
INPUT:• 𝑗 – integer (default: 1)
In the binomial basis, the shift by 1 corresponds to a summation operator from 0 to 𝑥.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).B()
sage: B = F.gen()sage: (B+1).shift()B[1] + B[2]sage: (B+1).shift(3)B[3] + B[4]>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).B()>>> B = F.gen()>>> (B+Integer(1)).shift()B[1] + B[2]>>> (B+Integer(1)).shift(Integer(3))
B[3] + B[4]sum_of_coefficients()

438

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Return the sum of coefficients.
In the shifted basis, this is the evaluation at 𝑥 = 0.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: B = F.basis()
sage: (B[2]*B[4]).sum_of_coefficients()
1>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()>>> B = F.basis()>>> (B[Integer(2)]*B[Integer(4)]).sum_of_coefficients()
1class ParentMethods
Bases: object
algebra_generators()
Return the generators of this algebra.
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S(); A
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis
sage: A.algebra_generators()
Family (S[1],)>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S(); A
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis>>> A.algebra_generators()
Family (S[1],)degree_on_basis(m)Return the degree of the basis element indexed by m.
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(QQ).S()
sage: A.degree_on_basis(4)4>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(QQ).S()>>> A.degree_on_basis(Integer(4))
4from_polynomial(p)Convert a polynomial into the ring of integer-valued polynomials.
This raises a ValueError if this is not possible.
INPUT:
2.1. Univariate Polynomials and Polynomial Rings

439

Polynomials, Release 10.4

• p – a polynomial in one variable
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: S = A.basis()
sage: S[5].polynomial()
1/120*x^5 + 1/8*x^4 + 17/24*x^3 + 15/8*x^2 + 137/60*x + 1
sage: A.from_polynomial(_)
S[5]sage: x = polygen(QQ, x )sage: A.from_polynomial(x)-S[0] + S[1]sage: A = IntegerValuedPolynomialRing(ZZ).B()
sage: B = A.basis()
sage: B[5].polynomial()
1/120*x^5 - 1/12*x^4 + 7/24*x^3 - 5/12*x^2 + 1/5*x
sage: A.from_polynomial(_)
B[5]sage: x = polygen(QQ, x )sage: A.from_polynomial(x)B[1]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> S = A.basis()>>> S[Integer(5)].polynomial()
1/120*x^5 + 1/8*x^4 + 17/24*x^3 + 15/8*x^2 + 137/60*x + 1>>> A.from_polynomial(_)
S[5]>>> x = polygen(QQ, x )>>> A.from_polynomial(x)-S[0] + S[1]>>> A = IntegerValuedPolynomialRing(ZZ).B()>>> B = A.basis()>>> B[Integer(5)].polynomial()
1/120*x^5 - 1/12*x^4 + 7/24*x^3 - 5/12*x^2 + 1/5*x>>> A.from_polynomial(_)
B[5]>>> x = polygen(QQ, x )>>> A.from_polynomial(x)B[1]gen(i=0)
Return the generator of this algebra.
The optional argument is ignored.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).B()
sage: F.gen()B[1]>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).B()(continues on next page)

440

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> F.gen()B[1]gens()
Return the generators of this algebra.
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S(); A
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis
sage: A.algebra_generators()
Family (S[1],)>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S(); A
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis>>> A.algebra_generators()
Family (S[1],)one_basis()
Return the number 0, which index the unit of this algebra.
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(QQ).S()
sage: A.one_basis()0
sage: A.one()S[0]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(QQ).S()>>> A.one_basis()0>>> A.one()S[0]super_categories()
Return the super-categories of self.
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(QQ); A
Integer-Valued Polynomial Ring over Rational Field
sage: C = A.Bases(); C
Category of bases of Integer-Valued Polynomial Ringover Rational Field
sage: C.super_categories()[Category of realizations of Integer-Valued Polynomial Ringover Rational Field,
Join of Category of algebras with basis over Rational Field andCategory of filtered algebras over Rational Field andCategory of commutative algebras over Rational Field andCategory of realizations of unital magmas]

2.1. Univariate Polynomials and Polynomial Rings

441

Polynomials, Release 10.4>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(QQ); A
Integer-Valued Polynomial Ring over Rational Field>>> C = A.Bases(); C
Category of bases of Integer-Valued Polynomial Ringover Rational Field>>> C.super_categories()[Category of realizations of Integer-Valued Polynomial Ringover Rational Field,
Join of Category of algebras with basis over Rational Field andCategory of filtered algebras over Rational Field andCategory of commutative algebras over Rational Field andCategory of realizations of unital magmas]

class Binomial(A)Bases: CombinatorialFreeModule, BindableClass
The integer-valued polynomial ring in the binomial basis.
(︀ )︀
The basis used here is given by 𝐵[𝑖] = 𝑥𝑖 for 𝑖 ∈ N.
Assuming 𝑛1 ≤ 𝑛2 , the product of two monomials 𝐵[𝑛1 ] · 𝐵[𝑛2 ] is given by the sum)︂𝑛1 (︂ )︂(︂∑︁𝑛1𝑛1 + 𝑛2 − 𝑘𝐵[𝑛1 + 𝑛2 − 𝑘].
𝑘
𝑛1
𝑘=0

The product of two monomials is therefore a positive linear combination of monomials.
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(QQ).B(); F
Integer-Valued Polynomial Ring over Rational Fieldin the binomial basis
sage: F.gen()B[1]sage: S = IntegerValuedPolynomialRing(ZZ).B(); S
Integer-Valued Polynomial Ring over Integer Ringin the binomial basis
sage: S.base_ring()
Integer Ringsage: G = IntegerValuedPolynomialRing(S).B(); GInteger-Valued Polynomial Ring over Integer-Valued Polynomial Ringover Integer Ring in the binomial basis in the binomial basis
sage: G.base_ring()
Integer-Valued Polynomial Ring over Integer Ringin the binomial basis>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(QQ).B(); F
Integer-Valued Polynomial Ring over Rational Fieldin the binomial basis>>> F.gen()B[1](continues on next page)

442

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> S = IntegerValuedPolynomialRing(ZZ).B(); S
Integer-Valued Polynomial Ring over Integer Ringin the binomial basis>>> S.base_ring()
Integer Ring>>> G = IntegerValuedPolynomialRing(S).B(); GInteger-Valued Polynomial Ring over Integer-Valued Polynomial Ringover Integer Ring in the binomial basis in the binomial basis>>> G.base_ring()
Integer-Valued Polynomial Ring over Integer Ringin the binomial basis

Integer-valued polynomial rings commute with their base ring:sage: K = IntegerValuedPolynomialRing(QQ).B()
sage: a = K.gen()sage: K.is_commutative()
True
sage: L = IntegerValuedPolynomialRing(K).B()
sage: c = L.gen()sage: L.is_commutative()
True
sage: s = a * c^3; s
B[1]*B[1] + 6*B[1]*B[2] + 6*B[1]*B[3]sage: parent(s)Integer-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Rational Field in the binomial basis in the binomial basis>>> from sage.all import *>>> K = IntegerValuedPolynomialRing(QQ).B()>>> a = K.gen()>>> K.is_commutative()
True>>> L = IntegerValuedPolynomialRing(K).B()>>> c = L.gen()>>> L.is_commutative()
True>>> s = a * c**Integer(3); s
B[1]*B[1] + 6*B[1]*B[2] + 6*B[1]*B[3]>>> parent(s)Integer-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Rational Field in the binomial basis in the binomial basis

Integer-valued polynomial rings are commutative:
sage: c^3 * a == c * a * c * cTrue>>> from sage.all import *>>> c**Integer(3) * a == c * a * c * cTrue

We can also manipulate elements in the basis:

2.1. Univariate Polynomials and Polynomial Rings

443

Polynomials, Release 10.4

sage: F = IntegerValuedPolynomialRing(QQ).B()
sage: B = F.basis()
sage: B[2] * B[3]3*B[3] + 12*B[4] + 10*B[5]sage: 1 - B[2] * B[2] / 2
B[0] - 1/2*B[2] - 3*B[3] - 3*B[4]>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(QQ).B()>>> B = F.basis()>>> B[Integer(2)] * B[Integer(3)]3*B[3] + 12*B[4] + 10*B[5]>>> Integer(1) - B[Integer(2)] * B[Integer(2)] / Integer(2)B[0] - 1/2*B[2] - 3*B[3] - 3*B[4]and coerce elements from our base field:
sage: F(4/3)
4/3*B[0]>>> from sage.all import *>>> F(Integer(4)/Integer(3))
4/3*B[0]class Element
Bases: IndexedFreeModuleElement
variable_shift(k=1)
Return the image by the shift of variables.
On polynomials, the action is the shift on variables 𝑥 ↦→ 𝑥 + 𝑘.
INPUT:• 𝑘 – integer (default: 1)
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).B()
sage: B = A.basis()
sage: B[5].variable_shift()B[4] + B[5]sage: B[5].variable_shift(-1)-B[0] + B[1] - B[2] + B[3] - B[4] + B[5]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).B()>>> B = A.basis()>>> B[Integer(5)].variable_shift()B[4] + B[5]>>> B[Integer(5)].variable_shift(-Integer(1))-B[0] + B[1] - B[2] + B[3] - B[4] + B[5]product_on_basis(n1, n2)
Return the product of basis elements n1 and n2.
INPUT:• n1, n2 – integers
EXAMPLES:
444

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: A = IntegerValuedPolynomialRing(QQ).B()
sage: A.product_on_basis(0, 1)B[1]sage: A.product_on_basis(1, 2)
2*B[2] + 3*B[3]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(QQ).B()>>> A.product_on_basis(Integer(0), Integer(1))
B[1]>>> A.product_on_basis(Integer(1), Integer(2))
2*B[2] + 3*B[3]S
alias of Shiftedclass Shifted(A)Bases: CombinatorialFreeModule, BindableClass
The integer-valued polynomial ring in the shifted basis.
(︀ )︀
The basis used here is given by 𝑆[𝑖] = 𝑖+𝑥
for 𝑖 ∈ N.
𝑖
Assuming 𝑛1 ≤ 𝑛2 , the product of two monomials 𝑆[𝑛1 ] · 𝑆[𝑛2 ] is given by the sum
𝑛1
∑︁
𝑘=0

(−1)𝑘

(︂

𝑛1
𝑘

)︂(︂

)︂
𝑛1 + 𝑛2 − 𝑘𝑆[𝑛1 + 𝑛2 − 𝑘].
𝑛1

EXAMPLES:
sage: F = IntegerValuedPolynomialRing(QQ).S(); F
Integer-Valued Polynomial Ring over Rational Fieldin the shifted basis
sage: F.gen()S[1]sage: S = IntegerValuedPolynomialRing(ZZ).S(); S
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis
sage: S.base_ring()
Integer Ringsage: G = IntegerValuedPolynomialRing(S).S(); GInteger-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Integer Ring in the shifted basis in the shifted basis
sage: G.base_ring()
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(QQ).S(); F
Integer-Valued Polynomial Ring over Rational Fieldin the shifted basis>>> F.gen()S[1](continues on next page)2.1. Univariate Polynomials and Polynomial Rings

445

Polynomials, Release 10.4

(continued from previous page)>>> S = IntegerValuedPolynomialRing(ZZ).S(); S
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis>>> S.base_ring()
Integer Ring>>> G = IntegerValuedPolynomialRing(S).S(); GInteger-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Integer Ring in the shifted basis in the shifted basis>>> G.base_ring()
Integer-Valued Polynomial Ring over Integer Ringin the shifted basis

Integer-valued polynomial rings commute with their base ring:sage: K = IntegerValuedPolynomialRing(QQ).S()
sage: a = K.gen()sage: K.is_commutative()
True
sage: L = IntegerValuedPolynomialRing(K).S()
sage: c = L.gen()sage: L.is_commutative()
True
sage: s = a * c^3; sS[1]*S[1] + (-6*S[1])*S[2] + 6*S[1]*S[3]sage: parent(s)Integer-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Rational Field in the shifted basis in the shifted basis>>> from sage.all import *>>> K = IntegerValuedPolynomialRing(QQ).S()>>> a = K.gen()>>> K.is_commutative()
True>>> L = IntegerValuedPolynomialRing(K).S()>>> c = L.gen()>>> L.is_commutative()
True>>> s = a * c**Integer(3); sS[1]*S[1] + (-6*S[1])*S[2] + 6*S[1]*S[3]>>> parent(s)Integer-Valued Polynomial Ring over Integer-Valued Polynomial
Ring over Rational Field in the shifted basis in the shifted basis

Integer-valued polynomial rings are commutative:
sage: c^3 * a == c * a * c * cTrue>>> from sage.all import *>>> c**Integer(3) * a == c * a * c * cTrue

We can also manipulate elements in the basis and coerce elements from our base field:

446

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage: F = IntegerValuedPolynomialRing(QQ).S()
sage: S = F.basis()
sage: S[2] * S[3]3*S[3] - 12*S[4] + 10*S[5]sage: 1 - S[2] * S[2] / 2
S[0] - 1/2*S[2] + 3*S[3] - 3*S[4]>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(QQ).S()>>> S = F.basis()>>> S[Integer(2)] * S[Integer(3)]3*S[3] - 12*S[4] + 10*S[5]>>> Integer(1) - S[Integer(2)] * S[Integer(2)] / Integer(2)S[0] - 1/2*S[2] + 3*S[3] - 3*S[4]class Element
Bases: IndexedFreeModuleElement
delta()
Return the image by the difference operator Δ.
The operator Δ is defined on polynomials by𝑓 ↦→ 𝑓 (𝑥 + 1) − 𝑓 (𝑥).
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: S = F.basis()
sage: S[5].delta()
S[0] + S[1] + S[2] + S[3] + S[4]>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()>>> S = F.basis()>>> S[Integer(5)].delta()
S[0] + S[1] + S[2] + S[3] + S[4]derivative_at_minus_one()
Return the derivative at −1.
This is sometimes useful when −1 is a root.
See also:
umbra()
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: B = F.gen()sage: (B+1).derivative_at_minus_one()1>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()>>> B = F.gen()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

447

Polynomials, Release 10.4

(continued from previous page)>>> (B+Integer(1)).derivative_at_minus_one()1

fraction()
Return the generating series of values as a fraction.
In the case of Ehrhart polynomials, this is known as the Ehrhart series.
See also:
h_vector(), h_polynomial()
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: ex = A.monomial(4)sage: f = ex.fraction();f1/(-t^5 + 5*t^4 - 10*t^3 + 10*t^2 - 5*t + 1)
sage: F = LazyPowerSeriesRing(QQ, t )sage: F(f)1 + 5*t + 15*t^2 + 35*t^3 + 70*t^4 + 126*t^5 + 210*t^6 + O(t^7)
sage: poly = ex.polynomial()
sage: [poly(i) for i in range(6)][1, 5, 15, 35, 70, 126]
sage: y = polygen(QQ, y )sage: penta = A.from_polynomial(7/2*y^2 + 7/2*y + 1)
sage: penta.fraction()(t^2 + 5*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> ex = A.monomial(Integer(4))>>> f = ex.fraction();f1/(-t^5 + 5*t^4 - 10*t^3 + 10*t^2 - 5*t + 1)>>> F = LazyPowerSeriesRing(QQ, t )>>> F(f)
1 + 5*t + 15*t^2 + 35*t^3 + 70*t^4 + 126*t^5 + 210*t^6 + O(t^7)>>> poly = ex.polynomial()>>> [poly(i) for i in range(Integer(6))][1, 5, 15, 35, 70, 126]>>> y = polygen(QQ, y )>>> penta = A.from_polynomial(Integer(7)/Integer(2)*y**Integer(2) +␣˓→Integer(7)/Integer(2)*y + Integer(1))>>> penta.fraction()(t^2 + 5*t + 1)/(-t^3 + 3*t^2 - 3*t + 1)

h_polynomial()
Return the ℎ-vector as a polynomial.
See also:
h_vector(), fraction()

448

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: x = polygen(QQ, x )sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: ex = A.from_polynomial((1+x)**3)
sage: ex.h_polynomial()z^2 + 4*z + 1>>> from sage.all import *>>> x = polygen(QQ, x )>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> ex = A.from_polynomial((Integer(1)+x)**Integer(3))>>> ex.h_polynomial()z^2 + 4*z + 1

h_vector()
Return the numerator of the generating series of values.
If self is an Ehrhart polynomial, this is the ℎ-vector.
See also:h_polynomial(), fraction()
EXAMPLES:
sage: x = polygen(QQ, x )sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: ex = A.from_polynomial((1+x)**3)
sage: ex.h_vector()(0, 1, 4, 1)>>> from sage.all import *>>> x = polygen(QQ, x )>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> ex = A.from_polynomial((Integer(1)+x)**Integer(3))>>> ex.h_vector()(0, 1, 4, 1)

umbra()
Return the Bernoulli umbra.
This is the derivative at −1 of the shift by one.
This is related to Bernoulli numbers.
See also:
derivative_at_minus_one()
EXAMPLES:
sage: F = IntegerValuedPolynomialRing(ZZ).S()
sage: B = F.gen()sage: (B+1).umbra()
3/2>>> from sage.all import *>>> F = IntegerValuedPolynomialRing(ZZ).S()(continues on next page)2.1. Univariate Polynomials and Polynomial Rings

449

Polynomials, Release 10.4

(continued from previous page)>>> B = F.gen()>>> (B+Integer(1)).umbra()
3/2

variable_shift(k=1)
Return the image by the shift of variables.
On polynomials, the action is the shift on variables 𝑥 ↦→ 𝑥 + 𝑘.
INPUT:• 𝑘 – integer (default: 1)
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: S = A.basis()
sage: S[5].variable_shift()
S[0] + S[1] + S[2] + S[3] + S[4] + S[5]sage: S[5].variable_shift(-1)-S[4] + S[5]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> S = A.basis()>>> S[Integer(5)].variable_shift()
S[0] + S[1] + S[2] + S[3] + S[4] + S[5]>>> S[Integer(5)].variable_shift(-Integer(1))-S[4] + S[5]from_h_vector(h)Convert from some ℎ-vector.
INPUT:• h – a tuple or vector
See also:
Element.h_vector()
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(ZZ).S()
sage: S = A.basis()
sage: ex = S[2]+S[4]sage: A.from_h_vector(ex.h_vector())
S[2] + S[4]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(ZZ).S()>>> S = A.basis()>>> ex = S[Integer(2)]+S[Integer(4)]>>> A.from_h_vector(ex.h_vector())
S[2] + S[4]product_on_basis(n1, n2)
Return the product of basis elements n1 and n2.
INPUT:
450

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

• n1, n2 – integers
EXAMPLES:
sage: A = IntegerValuedPolynomialRing(QQ).S()
sage: A.product_on_basis(0, 1)S[1]sage: A.product_on_basis(1, 2)-2*S[2] + 3*S[3]>>> from sage.all import *>>> A = IntegerValuedPolynomialRing(QQ).S()>>> A.product_on_basis(Integer(0), Integer(1))
S[1]>>> A.product_on_basis(Integer(1), Integer(2))-2*S[2] + 3*S[3]a_realization()
Return a default realization.
The Binomial realization is chosen.
EXAMPLES:
sage: IntegerValuedPolynomialRing(QQ).a_realization()
Integer-Valued Polynomial Ring over Rational Fieldin the binomial basis>>> from sage.all import *>>> IntegerValuedPolynomialRing(QQ).a_realization()
Integer-Valued Polynomial Ring over Rational Fieldin the binomial basis

2.2 Generic Convolution
Asymptotically fast convolution of lists over any commutative ring in which the multiply-by-two map is injective. (Moreprecisely, if 𝑥 ∈ 𝑅, and 𝑥 = 2𝑘 * 𝑦 for some 𝑘 ≥ 0, we require that 𝑅(𝑥/2𝑘 ) returns 𝑦.)
The main function to be exported is convolution().
EXAMPLES:
sage: convolution([1, 2, 3, 4, 5], [6, 7])[6, 19, 32, 45, 58, 35]>>> from sage.all import *>>> convolution([Integer(1), Integer(2), Integer(3), Integer(4), Integer(5)],␣
˓→[Integer(6), Integer(7)])[6, 19, 32, 45, 58, 35]

The convolution function is reasonably fast, even though it is written in pure Python. For example, the following takes
less than a second:sage: v = convolution(list(range(1000)), list(range(1000)))

2.2. Generic Convolution

451

Polynomials, Release 10.4>>> from sage.all import *>>> v = convolution(list(range(Integer(1000))), list(range(Integer(1000))))ALGORITHM:
Converts the problem to multiplication in the ring 𝑆[𝑥]/(𝑥𝑀 − 1), where 𝑆 = 𝑅[𝑦]/(𝑦 𝐾 + 1) (where 𝑅 is the original
base ring). Performs FFT with respect to the roots of unity 1, 𝑦, 𝑦 2 , . . . , 𝑦 2𝐾−1 in 𝑆. The FFT/IFFT are accomplishedwith just additions and subtractions and rotating python lists. (I think this algorithm is essentially due to Schonhage, notcompletely sure.) The pointwise multiplications are handled recursively, switching to a classical algorithm at some point.
Complexity is O(n log(n) log(log(n))) additions/subtractions in R and O(n log(n)) multiplications in R.
AUTHORS:• David Harvey (2007-07): first implementation• William Stein: editing the docstrings for inclusion in Sage.
sage.rings.polynomial.convolution.convolution(L1, L2)
Return convolution of non-empty lists L1 and L2.
L1 and L2 may have arbitrary lengths.
EXAMPLES:
sage: convolution([1, 2, 3], [4, 5, 6, 7])[4, 13, 28, 34, 32, 21]>>> from sage.all import *>>> convolution([Integer(1), Integer(2), Integer(3)], [Integer(4), Integer(5),␣
˓→Integer(6), Integer(7)])[4, 13, 28, 34, 32, 21]

2.3 Fast calculation of cyclotomic polynomials
This module provides a function cyclotomic_coeffs(), which calculates the coefficients of cyclotomic polynomials. This is not intended to be invoked directly by the user, but it is called by the method cyclotomic_polynomial() method of univariate polynomial ring objects and the top-level cyclotomic_polynomial() function.
sage.rings.polynomial.cyclotomic.bateman_bound(nn)Reference:
Bateman, P. T.; Pomerance, C.; Vaughan, R. C. On the size of the coefficients of the cyclotomic polynomial.
EXAMPLES:
sage: from sage.rings.polynomial.cyclotomic import bateman_boundsage: bateman_bound(2**8 * 1234567893377)
˓→needs sage.libs.pari
66944986927>>> from sage.all import *>>> from sage.rings.polynomial.cyclotomic import bateman_bound>>> bateman_bound(Integer(2)**Integer(8) * Integer(1234567893377))˓→# needs sage.libs.pari
66944986927

452

#␣

␣

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.cyclotomic.cyclotomic_coeffs(nn, sparse=None)
Return the coefficients of the 𝑛-th cyclotomic polynomial by using the formula∏︁Φ𝑛 (𝑥) =(1 − 𝑥𝑛/𝑑 )𝜇(𝑑)𝑑|𝑛where 𝜇(𝑑) is the Möbius function that is 1 if 𝑑 has an even number of distinct prime divisors, −1 if it has an odd
number of distinct prime divisors, and 0 if 𝑑 is not squarefree.
Multiplications and divisions by polynomials of the form 1 − 𝑥𝑛 can be done very quickly in a single pass.
If sparse is True, the result is returned as a dictionary of the non-zero entries, otherwise the result is returned
as a list of python ints.
EXAMPLES:
sage: from sage.rings.polynomial.cyclotomic import cyclotomic_coeffs
sage: cyclotomic_coeffs(30)[1, 1, 0, -1, -1, -1, 0, 1, 1]
sage: cyclotomic_coeffs(10^5){0: 1, 10000: -1, 20000: 1, 30000: -1, 40000: 1}
sage: R = QQ[ x ]sage: R(cyclotomic_coeffs(30))
x^8 + x^7 - x^5 - x^4 - x^3 + x + 1>>> from sage.all import *>>> from sage.rings.polynomial.cyclotomic import cyclotomic_coeffs>>> cyclotomic_coeffs(Integer(30))[1, 1, 0, -1, -1, -1, 0, 1, 1]>>> cyclotomic_coeffs(Integer(10)**Integer(5)){0: 1, 10000: -1, 20000: 1, 30000: -1, 40000: 1}>>> R = QQ[ x ]>>> R(cyclotomic_coeffs(Integer(30)))x^8 + x^7 - x^5 - x^4 - x^3 + x + 1

Check that it has the right degree:
sage: euler_phi(30)˓→needs sage.libs.pari8
sage: R(cyclotomic_coeffs(14)).factor()˓→needs sage.libs.parix^6 - x^5 + x^4 - x^3 + x^2 - x + 1>>> from sage.all import *>>> euler_phi(Integer(30))˓→# needs sage.libs.pari
8>>> R(cyclotomic_coeffs(Integer(14))).factor()˓→# needs sage.libs.parix^6 - x^5 + x^4 - x^3 + x^2 - x + 1

#␣

#␣

␣

␣

The coefficients are not always +/-1:
sage: cyclotomic_coeffs(105)[1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1,
0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2,-1, -1, 0, 0, 1, 1, 1]

2.3. Fast calculation of cyclotomic polynomials453

Polynomials, Release 10.4>>> from sage.all import *>>> cyclotomic_coeffs(Integer(105))[1, 1, 1, 0, 0, -1, -1, -2, -1, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1,
0, -1, 0, -1, 0, -1, 0, -1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, -1, -1, -2,-1, -1, 0, 0, 1, 1, 1]

In fact the height is not bounded by any polynomial in 𝑛 (Erdos), although takes a while just to exceed linear:sage: v = cyclotomic_coeffs(1181895)
sage: max(v)14102773>>> from sage.all import *>>> v = cyclotomic_coeffs(Integer(1181895))>>> max(v)14102773

The polynomial is a palindrome for any n:sage: n = ZZ.random_element(50000)
sage: v = cyclotomic_coeffs(n, sparse=False)
sage: v == list(reversed(v))
True>>> from sage.all import *>>> n = ZZ.random_element(Integer(50000))>>> v = cyclotomic_coeffs(n, sparse=False)>>> v == list(reversed(v))
True

AUTHORS:• Robert Bradshaw (2007-10-27): initial version (inspired by work of Andrew Arnold and Michael Monagan)
REFERENCE:• http://www.cecm.sfu.ca/ ada26/cyclotomic/
sage.rings.polynomial.cyclotomic.cyclotomic_value(n, x)
Return the value of the 𝑛-th cyclotomic polynomial evaluated at 𝑥.
INPUT:• n – an Integer, specifying which cyclotomic polynomial is to be evaluated• x – an element of a ring
OUTPUT:• the value of the cyclotomic polynomial Φ𝑛 at 𝑥
ALGORITHM:• Reduce to the case that 𝑛 is squarefree: use the identityΦ𝑛 (𝑥) = Φ𝑞 (𝑥𝑛/𝑞 )where 𝑞 is the radical of 𝑛.
• Use the identity

454

Chapter 2. Univariate Polynomials

Polynomials, Release 10.4

Φ𝑛 (𝑥) =∏︁(𝑥𝑑 − 1)𝜇(𝑛/𝑑) ,𝑑|𝑛where 𝜇 is the Möbius function.
• Handles the case that 𝑥𝑑 = 1 for some 𝑑, but not the case that 𝑥𝑑 −1 is non-invertible: in this case polynomial
evaluation is used instead.
EXAMPLES:
sage: cyclotomic_value(51, 3)
1282860140677441
sage: cyclotomic_polynomial(51)(3)
1282860140677441>>> from sage.all import *>>> cyclotomic_value(Integer(51), Integer(3))
1282860140677441>>> cyclotomic_polynomial(Integer(51))(Integer(3))
1282860140677441

It works for non-integral values as well:sage: cyclotomic_value(144, 4/3)
79148745433504023621920372161/79766443076872509863361
sage: cyclotomic_polynomial(144)(4/3)
79148745433504023621920372161/79766443076872509863361>>> from sage.all import *>>> cyclotomic_value(Integer(144), Integer(4)/Integer(3))
79148745433504023621920372161/79766443076872509863361>>> cyclotomic_polynomial(Integer(144))(Integer(4)/Integer(3))
79148745433504023621920372161/79766443076872509863361

2.3. Fast calculation of cyclotomic polynomials

455

Polynomials, Release 10.4

456

Chapter 2. Univariate Polynomials

CHAPTER

THREE

MULTIVARIATE POLYNOMIALS

3.1 Multivariate Polynomials and Polynomial Rings
Sage implements multivariate polynomial rings through several backends. The most generic implementation uses theclasses sage.rings.polynomial.polydict.PolyDict and sage.rings.polynomial.polydict.
ETuple to construct a dictionary with exponent tuples as keys and coefficients as values.
Additionally, specialized and optimized implementations over many specific coefficient rings are implemented via a sharedlibrary interface to SINGULAR; and polynomials in the boolean polynomial ringF2 [𝑥1 , ..., 𝑥𝑛 ]/⟨𝑥21 + 𝑥1 , ..., 𝑥2𝑛 + 𝑥𝑛 ⟩.
are implemented using the PolyBoRi library (cf. sage.rings.polynomial.pbori).

3.1.1 Term orders
Sage supports the following term orders:
Lexicographic (lex)𝑥𝑎 < 𝑥𝑏 if and only if there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 < 𝑏𝑖 . This term order iscalled ‘lp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: x > y
True
sage: x > y^2
Truesage: x > 1
True
sage: x^1*y^2 > y^3*z^4True
sage: x^3*y^2*z^4 < x^3*y^2*z^1
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= lex , names=( x ,˓→y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > y**Integer(2)y ,z ,)); (x,␣(continues on next page)457

Polynomials, Release 10.4

(continued from previous page)True>>> x > Integer(1)True>>> x**Integer(1)*y**Integer(2) > y**Integer(3)*z**Integer(4)True>>> x**Integer(3)*y**Integer(2)*z**Integer(4) <␣
˓→x**Integer(3)*y**Integer(2)*z**Integer(1)False

Degree reverse lexicographic (degrevlex)
Let deg(𝑥𝑎 ) = 𝑎1 + 𝑎2 + · · · + 𝑎𝑛 , then 𝑥𝑎 < 𝑥𝑏 if and only if deg(𝑥𝑎 ) < deg(𝑥𝑏 ) or deg(𝑥𝑎 ) = deg(𝑥𝑏 ) andthere exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎𝑛 = 𝑏𝑛 , . . . , 𝑎𝑖+1 = 𝑏𝑖+1 , 𝑎𝑖 > 𝑏𝑖 . This term order is called ‘dp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= degrevlex )sage: x > y
True
sage: x > y^2*z
False
sage: x > 1
True
sage: x^1*y^5*z^2 > x^4*y^1*z^3
True
sage: x^2*y*z^2 > x*y^3*z
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= degrevlex , names=( x ,˓→ (x, y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > y**Integer(2)*z
False>>> x > Integer(1)True>>> x**Integer(1)*y**Integer(5)*z**Integer(2) >␣
˓→x**Integer(4)*y**Integer(1)*z**Integer(3)True>>> x**Integer(2)*y*z**Integer(2) > x*y**Integer(3)*z
False

y ,

z ,));

Degree lexicographic (deglex)
Let deg(𝑥𝑎 ) = 𝑎1 + 𝑎2 + · · · + 𝑎𝑛 , then 𝑥𝑎 < 𝑥𝑏 if and only if deg(𝑥𝑎 ) < deg(𝑥𝑏 ) or deg(𝑥𝑎 ) = deg(𝑥𝑏 ) andthere exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 < 𝑏𝑖 . This term order is called ‘Dp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= deglex )sage: x > y
True
sage: x > y^2*z
False
sage: x > 1
True
sage: x^1*y^2*z^3 > x^3*y^2*z^0(continues on next page)

458

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True
sage: x^2*y*z^2 > x*y^3*z
True>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= deglex , names=( x ,˓→(x, y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > y**Integer(2)*z
False>>> x > Integer(1)True>>> x**Integer(1)*y**Integer(2)*z**Integer(3) >␣
˓→x**Integer(3)*y**Integer(2)*z**Integer(0)True>>> x**Integer(2)*y*z**Integer(2) > x*y**Integer(3)*z
True

y ,

z ,));␣

Inverse lexicographic (invlex)
𝑥𝑎 < 𝑥𝑏 if and only if there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎𝑛 = 𝑏𝑛 , . . . , 𝑎𝑖+1 = 𝑏𝑖+1 , 𝑎𝑖 < 𝑏𝑖 . This order is called‘rp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= invlex )sage: x > y
False
sage: y > x^2
True
sage: x > 1
True
sage: x*y > z
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= invlex , names=( x ,˓→(x, y, z,) = P._first_ngens(3)>>> x > y
False>>> y > x**Integer(2)True>>> x > Integer(1)True>>> x*y > z
False

y ,

z ,));␣

This term order only makes sense in a non-commutative setting because if P is the ring 𝑘[𝑥1 , . . . , 𝑥𝑛 ] and termorder ‘invlex’ then it is equivalent to the ring 𝑘[𝑥𝑛 , . . . , 𝑥1 ] with term order ‘lex’.
Negative lexicographic (neglex)
𝑥𝑎 < 𝑥𝑏 if and only if there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 > 𝑏𝑖 . This term order iscalled ‘ls’ in Singular.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

459

Polynomials, Release 10.4

sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= neglex )sage: x > y
False
sage: x > 1
False
sage: x^1*y^2 > y^3*z^4False
sage: x^3*y^2*z^4 < x^3*y^2*z^1True
sage: x*y > z
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= neglex , names=( x ,˓→(x, y, z,) = P._first_ngens(3)>>> x > yFalse>>> x > Integer(1)False>>> x**Integer(1)*y**Integer(2) > y**Integer(3)*z**Integer(4)False>>> x**Integer(3)*y**Integer(2)*z**Integer(4) <␣
˓→x**Integer(3)*y**Integer(2)*z**Integer(1)True>>> x*y > z
False

y ,

z ,));␣

Negative degree reverse lexicographic (negdegrevlex)
Let deg(𝑥𝑎 ) = 𝑎1 + 𝑎2 + · · · + 𝑎𝑛 , then 𝑥𝑎 < 𝑥𝑏 if and only if deg(𝑥𝑎 ) > deg(𝑥𝑏 ) or deg(𝑥𝑎 ) = deg(𝑥𝑏 ) andthere exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎𝑛 = 𝑏𝑛 , . . . , 𝑎𝑖+1 = 𝑏𝑖+1 , 𝑎𝑖 > 𝑏𝑖 . This term order is called ‘ds’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= negdegrevlex )sage: x > y
True
sage: x > x^2
True
sage: x > 1
False
sage: x^1*y^2 > y^3*z^4True
sage: x^2*y*z^2 > x*y^3*z
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= negdegrevlex , names=( x ,˓→)); (x, y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > x**Integer(2)True>>> x > Integer(1)False>>> x**Integer(1)*y**Integer(2) > y**Integer(3)*z**Integer(4)True>>> x**Integer(2)*y*z**Integer(2) > x*y**Integer(3)*z

y ,

z ,

(continues on next page)

460

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

False

Negative degree lexicographic (negdeglex)
Let deg(𝑥𝑎 ) = 𝑎1 + 𝑎2 + · · · + 𝑎𝑛 , then 𝑥𝑎 < 𝑥𝑏 if and only if deg(𝑥𝑎 ) > deg(𝑥𝑏 ) or deg(𝑥𝑎 ) = deg(𝑥𝑏 ) andthere exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 < 𝑏𝑖 . This term order is called ‘Ds’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= negdeglex )sage: x > y
True
sage: x > x^2
True
sage: x > 1
False
sage: x^1*y^2 > y^3*z^4True
sage: x^2*y*z^2 > x*y^3*z
True>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= negdeglex , names=( x ,˓→ (x, y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > x**Integer(2)True>>> x > Integer(1)False>>> x**Integer(1)*y**Integer(2) > y**Integer(3)*z**Integer(4)True>>> x**Integer(2)*y*z**Integer(2) > x*y**Integer(3)*z
True

y ,

z ,));

Weighted degree reverse lexicographic (wdegrevlex), positive integral weights
Let deg𝑤 (𝑥𝑎 ) = 𝑎1 𝑤1 + 𝑎2 𝑤2 + · · · + 𝑎𝑛 𝑤𝑛 with weights 𝑤, then 𝑥𝑎 < 𝑥𝑏 if and only if deg𝑤 (𝑥𝑎 ) < deg𝑤 (𝑥𝑏 )or deg𝑤 (𝑥𝑎 ) = deg𝑤 (𝑥𝑏 ) and there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎𝑛 = 𝑏𝑛 , . . . , 𝑎𝑖+1 = 𝑏𝑖+1 , 𝑎𝑖 > 𝑏𝑖 . This termorder is called ‘wp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder( wdegrevlex ,(1,2,3)))
sage: x > y
False
sage: x > x^2
False
sage: x > 1
True
sage: x^1*y^2 > x^2*z
True
sage: y*z > x^3*y
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order=TermOrder( wdegrevlex ,(Integer(1),˓→Integer(2),Integer(3))), names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

461

Polynomials, Release 10.4

(continued from previous page)>>> x > yFalse>>> x > x**Integer(2)False>>> x > Integer(1)True>>> x**Integer(1)*y**Integer(2) > x**Integer(2)*z
True>>> y*z > x**Integer(3)*yFalse

Weighted degree lexicographic (wdeglex), positive integral weights
Let deg𝑤 (𝑥𝑎 ) = 𝑎1 𝑤1 + 𝑎2 𝑤2 + · · · + 𝑎𝑛 𝑤𝑛 with weights 𝑤, then 𝑥𝑎 < 𝑥𝑏 if and only if deg𝑤 (𝑥𝑎 ) < deg𝑤 (𝑥𝑏 )or deg𝑤 (𝑥𝑎 ) = deg𝑤 (𝑥𝑏 ) and there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 < 𝑏𝑖 . This termorder is called ‘Wp’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder( wdeglex ,(1,2,3)))
sage: x > y
False
sage: x > x^2
False
sage: x > 1
True
sage: x^1*y^2 > x^2*z
False
sage: y*z > x^3*y
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order=TermOrder( wdeglex ,(Integer(1),˓→Integer(2),Integer(3))), names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> x > yFalse>>> x > x**Integer(2)False>>> x > Integer(1)True>>> x**Integer(1)*y**Integer(2) > x**Integer(2)*z
False>>> y*z > x**Integer(3)*yFalse

Negative weighted degree reverse lexicographic (negwdegrevlex), positive integral weights
Let deg𝑤 (𝑥𝑎 ) = 𝑎1 𝑤1 + 𝑎2 𝑤2 + · · · + 𝑎𝑛 𝑤𝑛 with weights 𝑤, then 𝑥𝑎 < 𝑥𝑏 if and only if deg𝑤 (𝑥𝑎 ) > deg𝑤 (𝑥𝑏 )or deg𝑤 (𝑥𝑎 ) = deg𝑤 (𝑥𝑏 ) and there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎𝑛 = 𝑏𝑛 , . . . , 𝑎𝑖+1 = 𝑏𝑖+1 , 𝑎𝑖 > 𝑏𝑖 . This termorder is called ‘ws’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder( negwdegrevlex ,(1,2,3)))
sage: x > y
True
sage: x > x^2
True(continues on next page)462

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: x > 1
False
sage: x^1*y^2 > x^2*z
True
sage: y*z > x^3*y
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order=TermOrder( negwdegrevlex ,˓→(Integer(1),Integer(2),Integer(3))), names=( x ,y , z ,)); (x, y, z,) = P._
˓→first_ngens(3)>>> x > yTrue>>> x > x**Integer(2)True>>> x > Integer(1)False>>> x**Integer(1)*y**Integer(2) > x**Integer(2)*z
True>>> y*z > x**Integer(3)*yFalse

Degree negative lexicographic (degneglex)
Let deg(𝑥𝑎 ) = 𝑎1 + 𝑎2 + · · · + 𝑎𝑛 , then 𝑥𝑎 < 𝑥𝑏 if and only if deg(𝑥𝑎 ) < deg(𝑥𝑏 ) or deg(𝑥𝑎 ) = deg(𝑥𝑏 )and there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 > 𝑏𝑖 . This term order is called ‘dp_asc’ in
PolyBoRi. Singular has the extra weight vector ordering (a(1:n),ls) for this purpose.
EXAMPLES:
sage: t = TermOrder( degneglex )sage: P.<x,y,z> = PolynomialRing(QQ, order=t)
sage: x*y > y*z # indirect doctest
False
sage: x*y > x
True>>> from sage.all import *>>> t = TermOrder( degneglex )>>> P = PolynomialRing(QQ, order=t, names=( x ,˓→first_ngens(3)>>> x*y > y*z # indirect doctest
False>>> x*y > x
True

y ,

z ,)); (x, y, z,) = P._

Negative weighted degree lexicographic (negwdeglex), positive integral weights
Let deg𝑤 (𝑥𝑎 ) = 𝑎1 𝑤1 + 𝑎2 𝑤2 + · · · + 𝑎𝑛 𝑤𝑛 with weights 𝑤, then 𝑥𝑎 < 𝑥𝑏 if and only if deg𝑤 (𝑥𝑎 ) > deg𝑤 (𝑥𝑏 )or deg𝑤 (𝑥𝑎 ) = deg𝑤 (𝑥𝑏 ) and there exists 1 ≤ 𝑖 ≤ 𝑛 such that 𝑎1 = 𝑏1 , . . . , 𝑎𝑖−1 = 𝑏𝑖−1 , 𝑎𝑖 < 𝑏𝑖 . This termorder is called ‘Ws’ in Singular.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order=TermOrder( negwdeglex ,(1,2,3)))
sage: x > y
True
sage: x > x^2(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

463

Polynomials, Release 10.4

(continued from previous page)True
sage: x > 1
False
sage: x^1*y^2 > x^2*z
False
sage: y*z > x^3*y
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order=TermOrder( negwdeglex ,(Integer(1),˓→Integer(2),Integer(3))), names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> x > yTrue>>> x > x**Integer(2)True>>> x > Integer(1)False>>> x**Integer(1)*y**Integer(2) > x**Integer(2)*z
False>>> y*z > x**Integer(3)*yFalse

Of these, only ‘degrevlex’, ‘deglex’, ‘degneglex’, ‘wdegrevlex’, ‘wdeglex’, ‘invlex’ and ‘lex’ are global orders.
Sage also supports matrix term order. Given a square matrix 𝐴,
𝑥𝑎 <𝐴 𝑥𝑏 if and only if 𝐴𝑎 < 𝐴𝑏
where < is the lexicographic term order.
EXAMPLES:
sage: # needs sage.modules
sage: m = matrix(2, [2,3,0,1]); m
[2 3]
[0 1]
sage: T = TermOrder(m); T
Matrix term order with matrix
[2 3]
[0 1]
sage: P.<a,b> = PolynomialRing(QQ, 2, order=T)
sage: P
Multivariate Polynomial Ring in a, b over Rational Field
sage: a > b
False
sage: a^3 < b^2
Truesage: S = TermOrder( M(2,3,0,1) )sage: T == S
True>>> from sage.all import *>>> # needs sage.modules>>> m = matrix(Integer(2), [Integer(2),Integer(3),Integer(0),Integer(1)]); m
[2 3]
[0 1]
>>> T = TermOrder(m); T(continues on next page)464

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)Matrix term order with matrix
[2 3]
[0 1]
>>> P = PolynomialRing(QQ, Integer(2), order=T, names=( a ,˓→first_ngens(2)>>> P
Multivariate Polynomial Ring in a, b over Rational Field>>> a > b
False>>> a**Integer(3) < b**Integer(2)True>>> S = TermOrder( M(2,3,0,1) )>>> T == STrueb ,)); (a, b,) = P._

Additionally all these monomial orders may be combined to product or block orders, defined as:
Let 𝑥 = (𝑥1 , 𝑥2 , . . . , 𝑥𝑛 ) and 𝑦 = (𝑦1 , 𝑦2 , . . . , 𝑦𝑚 ) be two ordered sets of variables, <1 a monomial order on 𝑘[𝑥] and<2 a monomial order on 𝑘[𝑦].
The product order (or block order) < := (<1 , <2 ) on 𝑘[𝑥, 𝑦] is defined as: 𝑥𝑎 𝑦 𝑏 < 𝑥𝐴 𝑦 𝐵 if and only if 𝑥𝑎 <1 𝑥𝐴 or(𝑥𝑎 = 𝑥𝐴 and 𝑦 𝑏 <2 𝑦 𝐵 ).
These block orders are constructed in Sage by giving a comma separated list of monomial orders with the length of eachblock attached to them.
EXAMPLES:
As an example, consider constructing a block order where the first four variables are compared using the degree reverse
lexicographical order while the last two variables in the second block are compared using negative lexicographical order.
sage: P.<a,b,c,d,e,f> = PolynomialRing(QQ, 6, order= degrevlex(4),neglex(2) )sage: a > c^4
False
sage: a > e^4
Truesage: e > f^2
False>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(6), order= degrevlex(4),neglex(2) , names=( a ,˓→ ,c , d , e , f ,)); (a, b, c, d, e, f,) = P._first_ngens(6)>>> a > c**Integer(4)False>>> a > e**Integer(4)True>>> e > f**Integer(2)
False

b

The same result can be achieved by:sage: T1 = TermOrder( degrevlex ,4)
sage: T2 = TermOrder( neglex ,2)
sage: T = T1 + T2
sage: P.<a,b,c,d,e,f> = PolynomialRing(QQ, 6, order=T)
sage: a > c^4
False(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

465

Polynomials, Release 10.4

(continued from previous page)

sage: a > e^4
True>>> from sage.all import *>>> T1 = TermOrder( degrevlex ,Integer(4))>>> T2 = TermOrder( neglex ,Integer(2))>>> T = T1 + T2>>> P = PolynomialRing(QQ, Integer(6), order=T, names=( a ,˓→)); (a, b, c, d, e, f,) = P._first_ngens(6)>>> a > c**Integer(4)False>>> a > e**Integer(4)
True

b ,

c ,

d ,

e ,

f ,

If any other unsupported term order is given the provided string can be forced to be passed through as is to Singular,
Macaulay2, and Magma. This ensures that it is for example possible to calculate a Groebner basis with respect to someterm order Singular supports but Sage doesn’t:
sage: T = TermOrder("royalorder")Traceback (most recent call last):...
ValueError: unknown term order royalordersage: T = TermOrder("royalorder", force=True)
sage: Troyalorder term ordersage: T.singular_str()
royalorder>>> from sage.all import *>>> T = TermOrder("royalorder")Traceback (most recent call last):...
ValueError: unknown term order royalorder>>> T = TermOrder("royalorder", force=True)>>> T
royalorder term order>>> T.singular_str()
royalorder

AUTHORS:• David Joyner and William Stein: initial version of multi_polynomial_ring• Kiran S. Kedlaya: added macaulay2 interface• Martin Albrecht: implemented native term orders, refactoring• Kwankyu Lee: implemented matrix and weighted degree term orders• Simon King (2011-06-06): added termorder_from_singularclass sage.rings.polynomial.term_order.TermOrder(name='lex', n=0, force=False)
Bases: SageObject
A term order.
See sage.rings.polynomial.term_order for details on supported term orders.

466

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

blocks()Return the term order blocks of self.
NOTE:
This method has been added in Issue #11316. There used to be an attribute of the same name and the samecontent. So, it is a backward incompatible syntax change.
EXAMPLES:
sage: t = TermOrder( deglex ,2) + TermOrder( lex ,2)
sage: t.blocks()(Degree lexicographic term order, Lexicographic term order)>>> from sage.all import *>>> t = TermOrder( deglex ,Integer(2)) + TermOrder( lex ,Integer(2))>>> t.blocks()(Degree lexicographic term order, Lexicographic term order)

property greater_tuple
The default greater_tuple method for this term order.
EXAMPLES:
sage: O = TermOrder()sage: O.greater_tuple.__func__ is O.greater_tuple_lex.__func__
True
sage: O = TermOrder( deglex )sage: O.greater_tuple.__func__ is O.greater_tuple_deglex.__func__
True>>> from sage.all import *>>> O = TermOrder()>>> O.greater_tuple.__func__ is O.greater_tuple_lex.__func__
True>>> O = TermOrder( deglex )>>> O.greater_tuple.__func__ is O.greater_tuple_deglex.__func__
Truegreater_tuple_block(f, g)
Return the greater exponent tuple with respect to the block order as specified when constructing this element.
This method is called by the lm/lc/lt methods of MPolynomial_polydict.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: P.<a,b,c,d,e,f> = PolynomialRing(QQbar, 6,
˓→needs sage.rings.number_field....:order= degrevlex(3),degrevlex(3) )sage: f = a + c^4; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldc^4
sage: g = a + e^4; g.lm()

#␣

#␣

#␣

(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

467

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field˓→a>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(6),# needs␣
˓→sage.rings.number_field...
order= degrevlex(3),degrevlex(3) ,␣˓→names=( a ,b , c , d , e , f ,)); (a, b, c, d, e, f,) = P._first_
˓→ngens(6)>>> f = a + c**Integer(4); f.lm() # indirect doctest␣˓→# needs sage.rings.number_fieldc^4>>> g = a + e**Integer(4); g.lm()␣˓→# needs sage.rings.number_fieldagreater_tuple_deglex(f, g)
Return the greater exponent tuple with respect to the total degree lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= deglex )˓→needs sage.rings.number_fieldsage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldx
sage: f = x + y^2*z; f.lm()
˓→needs sage.rings.number_fieldy^2*z>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= deglex , names=( x ,˓→ ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldx>>> f = x + y**Integer(2)*z; f.lm()˓→# needs sage.rings.number_field
y^2*z

#␣
#␣

#␣

y ,

z
#␣

␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_degneglex(f, g)
Return the greater exponent tuple with respect to the degree negative lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:

468

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= degneglex )˓→needs sage.rings.number_fieldsage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldysage: f = x + y^2*z; f.lm()
˓→needs sage.rings.number_fieldy^2*z>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= degneglex , names=( x ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldy>>> f = x + y**Integer(2)*z; f.lm()˓→# needs sage.rings.number_field
y^2*z

#␣
#␣

#␣

y ,
#␣

␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_degrevlex(f, g)
Return the greater exponent tuple with respect to the total degree reversed lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= degrevlex )˓→needs sage.rings.number_fieldsage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldx
sage: f = x + y^2*z; f.lm()
˓→needs sage.rings.number_fieldy^2*z>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= degrevlex , names=( x ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldx>>> f = x + y**Integer(2)*z; f.lm()˓→# needs sage.rings.number_field
y^2*z

#␣
#␣

#␣

y ,
#␣

␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_invlex(f, g)
Return the greater exponent tuple with respect to the inversed lexicographical term order.
INPUT:• f – exponent tuple

3.1. Multivariate Polynomials and Polynomial Rings

469

Polynomials, Release 10.4

• g – exponent tuple
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= invlex )˓→needs sage.rings.number_fieldsage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldysage: f = y + x^2; f.lm()
˓→needs sage.rings.number_fieldy>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= invlex , names=( x ,˓→ ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldy>>> f = y + x**Integer(2); f.lm()˓→# needs sage.rings.number_field
y

#␣
#␣

#␣

y ,

z
#␣

␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_lex(f, g)
Return the greater exponent tuple with respect to the lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= lex )˓→needs sage.rings.number_fieldsage: f = x + y^2; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldx>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= lex , names=( x , y ,˓→)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y**Integer(2); f.lm() # indirect doctest˓→# needs sage.rings.number_field
x

#␣
#␣

z ,
␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_matrix(f, g)
Return the greater exponent tuple with respect to the matrix term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
470

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y> = PolynomialRing(QQbar, 2, order= m(1,3,1,0) )˓→needs sage.rings.number_fieldsage: y > x^2 # indirect doctest
˓→needs sage.rings.number_fieldTrue
sage: y > x^3
˓→needs sage.rings.number_field
False>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= m(1,3,1,0) , names=( x ,˓→)); (x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> y > x**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> y > x**Integer(3)˓→# needs sage.rings.number_field
False

#␣
#␣

#␣

y ,
␣

␣

greater_tuple_negdeglex(f, g)
Return the greater exponent tuple with respect to the negative degree lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= negdeglex )sage: f = x + y; f.lm() # indirect doctestxsage: f = x + x^2; f.lm()xsage: f = x^2*y*z^2 + x*y^3*z; f.lm()x^2*y*z^2>>> from sage.all import *>>> # needs sage.rings.number_field>>> P = PolynomialRing(QQbar, Integer(3), order= negdeglex , names=( x ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)>>> f = x + y; f.lm() # indirect doctestx>>> f = x + x**Integer(2); f.lm()x>>> f = x**Integer(2)*y*z**Integer(2) + x*y**Integer(3)*z; f.lm()x^2*y*z^2y ,This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_negdegrevlex(f, g)
Return the greater exponent tuple with respect to the negative degree reverse lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
3.1. Multivariate Polynomials and Polynomial Rings

471

Polynomials, Release 10.4

EXAMPLES:
sage: # needs sage.rings.number_fieldsage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= negdegrevlex )sage: f = x + y; f.lm() # indirect doctestxsage: f = x + x^2; f.lm()xsage: f = x^2*y*z^2 + x*y^3*z; f.lm()x*y^3*z>>> from sage.all import *>>> # needs sage.rings.number_field>>> P = PolynomialRing(QQbar, Integer(3), order= negdegrevlex , names=( x ,˓→ ,z ,)); (x, y, z,) = P._first_ngens(3)>>> f = x + y; f.lm() # indirect doctestx>>> f = x + x**Integer(2); f.lm()x>>> f = x**Integer(2)*y*z**Integer(2) + x*y**Integer(3)*z; f.lm()x*y^3*zyThis method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_neglex(f, g)
Return the greater exponent tuple with respect to the negative lexicographical term order.
This method is called by the lm/lc/lt methods of MPolynomial_polydict.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: P.<a,b,c,d,e,f> = PolynomialRing(QQbar, 6,
˓→needs sage.rings.number_field....:order= degrevlex(3),degrevlex(3) )sage: f = a + c^4; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldc^4
sage: g = a + e^4; g.lm()
˓→needs sage.rings.number_field
a

#␣

#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(6),# needs␣
˓→sage.rings.number_field...
order= degrevlex(3),degrevlex(3) ,␣˓→names=( a ,b , c , d , e , f ,)); (a, b, c, d, e, f,) = P._first_
˓→ngens(6)>>> f = a + c**Integer(4); f.lm() # indirect doctest␣˓→# needs sage.rings.number_fieldc^4>>> g = a + e**Integer(4); g.lm()␣˓→# needs sage.rings.number_fielda472

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

greater_tuple_negwdeglex(f, g)
Return the greater exponent tuple with respect to the negative weighted degree lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: t = TermOrder( negwdeglex ,(1,2,3))
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
sage: f = x + y; f.lm() # indirect doctestxsage: f = x + x^2; f.lm()xsage: f = x^3 + z; f.lm()x^3>>> from sage.all import *>>> # needs sage.rings.number_field>>> t = TermOrder( negwdeglex ,(Integer(1),Integer(2),Integer(3)))>>> P = PolynomialRing(QQbar, Integer(3), order=t, names=( x , y ,˓→(x, y, z,) = P._first_ngens(3)>>> f = x + y; f.lm() # indirect doctestx>>> f = x + x**Integer(2); f.lm()x>>> f = x**Integer(3) + z; f.lm()x^3z ,));␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_negwdegrevlex(f, g)
Return the greater exponent tuple with respect to the negative weighted degree reverse lexicographical termorder.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: t = TermOrder( negwdegrevlex ,(1,2,3))
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
sage: f = x + y; f.lm() # indirect doctestxsage: f = x + x^2; f.lm()xsage: f = x^3 + z; f.lm()x^3>>> from sage.all import *>>> # needs sage.rings.number_field>>> t = TermOrder( negwdegrevlex ,(Integer(1),Integer(2),Integer(3)))(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

473

Polynomials, Release 10.4

(continued from previous page)>>> P = PolynomialRing(QQbar, Integer(3), order=t, names=( x ,˓→(x, y, z,) = P._first_ngens(3)>>> f = x + y; f.lm() # indirect doctestx>>> f = x + x**Integer(2); f.lm()x>>> f = x**Integer(3) + z; f.lm()
x^3

y ,

z ,));␣

This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_wdeglex(f, g)
Return the greater exponent tuple with respect to the weighted degree lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: t = TermOrder( wdeglex ,(1,2,3))
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
˓→needs sage.rings.number_fieldsage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldysage: f = x*y + z; f.lm()
˓→needs sage.rings.number_field
x*y

#␣
#␣

#␣

>>> from sage.all import *>>> t = TermOrder( wdeglex ,(Integer(1),Integer(2),Integer(3)))>>> P = PolynomialRing(QQbar, Integer(3), order=t, names=( x , y ,˓→(x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldy>>> f = x*y + z; f.lm()
˓→needs sage.rings.number_fieldx*yz ,));␣
#␣#␣This method is called by the lm/lc/lt methods of MPolynomial_polydict.
greater_tuple_wdegrevlex(f, g)
Return the greater exponent tuple with respect to the weighted degree reverse lexicographical term order.
INPUT:• f – exponent tuple• g – exponent tuple
EXAMPLES:
sage: t = TermOrder( wdegrevlex ,(1,2,3))
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order=t)
˓→needs sage.rings.number_field#␣(continues on next page)474

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldysage: f = x + y^2*z; f.lm()
˓→needs sage.rings.number_fieldy^2*z>>> from sage.all import *>>> t = TermOrder( wdegrevlex ,(Integer(1),Integer(2),Integer(3)))>>> P = PolynomialRing(QQbar, Integer(3), order=t, names=( x , y ,˓→(x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> f = x + y; f.lm() # indirect doctest
˓→needs sage.rings.number_fieldy>>> f = x + y**Integer(2)*z; f.lm()˓→# needs sage.rings.number_field
y^2*z

#␣

#␣

z ,));␣
#␣␣This method is called by the lm/lc/lt methods of MPolynomial_polydict.
is_block_order()Return True if self is a block term order.
EXAMPLES:
sage: t = TermOrder( deglex ,2) + TermOrder( lex ,2)
sage: t.is_block_order()True>>> from sage.all import *>>> t = TermOrder( deglex ,Integer(2)) + TermOrder( lex ,Integer(2))>>> t.is_block_order()True

is_global()
Return True if this term order is definitely global. Return false otherwise, which includes unknown termorders.
EXAMPLES:
sage: T = TermOrder( lex )sage: T.is_global()Truesage: T = TermOrder( degrevlex , 3) + TermOrder( degrevlex , 3)
sage: T.is_global()Truesage: T = TermOrder( degrevlex , 3) + TermOrder( negdegrevlex , 3)
sage: T.is_global()
False
sage: T = TermOrder( degneglex , 3)
sage: T.is_global()Truesage: T = TermOrder( invlex , 3)
sage: T.is_global()
True

3.1. Multivariate Polynomials and Polynomial Rings

475

Polynomials, Release 10.4>>> from sage.all import *>>> T = TermOrder( lex )>>> T.is_global()
True>>> T = TermOrder( degrevlex , Integer(3)) + TermOrder( degrevlex ,␣
˓→Integer(3))>>> T.is_global()
True>>> T = TermOrder( degrevlex , Integer(3)) + TermOrder( negdegrevlex ,␣
˓→Integer(3))>>> T.is_global()
False>>> T = TermOrder( degneglex , Integer(3))>>> T.is_global()
True>>> T = TermOrder( invlex , Integer(3))>>> T.is_global()Trueis_local()
Return True if this term order is definitely local. Return false otherwise, which includes unknown termorders.
EXAMPLES:
sage: T = TermOrder( lex )sage: T.is_local()
False
sage: T = TermOrder( negdeglex , 3) + TermOrder( negdegrevlex , 3)
sage: T.is_local()Truesage: T = TermOrder( degrevlex , 3) + TermOrder( negdegrevlex , 3)
sage: T.is_local()False>>> from sage.all import *>>> T = TermOrder( lex )>>> T.is_local()
False>>> T = TermOrder( negdeglex , Integer(3)) + TermOrder( negdegrevlex ,␣
˓→Integer(3))>>> T.is_local()True>>> T = TermOrder( degrevlex , Integer(3)) + TermOrder( negdegrevlex ,␣
˓→Integer(3))>>> T.is_local()False

is_weighted_degree_order()Return True if self is a weighted degree term order.
EXAMPLES:
sage: t = TermOrder( wdeglex ,(2,3))
sage: t.is_weighted_degree_order()
True

476

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> t = TermOrder( wdeglex ,(Integer(2),Integer(3)))>>> t.is_weighted_degree_order()Truemacaulay2_str()
Return a Macaulay2 representation of self.
Used to convert polynomial rings to their Macaulay2 representation.
EXAMPLES:
sage: P = PolynomialRing(GF(127), 8, names= x , order= degrevlex(3),lex(5) )sage: T = P.term_order()sage: T.macaulay2_str(){GRevLex => 3,Lex => 5}
sage: P._macaulay2_().options()[ MonomialOrder ]# optional - macaulay2{MonomialSize => 16 }{GRevLex => {1, 1, 1}}{Lex => 5}{Position => Up}>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(8), names= x , order=
˓→ degrevlex(3),lex(5) )>>> T = P.term_order()>>> T.macaulay2_str(){GRevLex => 3,Lex => 5}>>> P._macaulay2_().options()[ MonomialOrder ]# optional - macaulay2{MonomialSize => 16 }{GRevLex => {1, 1, 1}}{Lex => 5}{Position => Up}magma_str()
Return a MAGMA representation of self.
Used to convert polynomial rings to their MAGMA representation.
EXAMPLES:
sage: P = PolynomialRing(GF(127), 10, names= x , order= degrevlex )sage: magma(P)# optional - magma
Polynomial ring of rank 10 over GF(127)
Order: Graded Reverse Lexicographical
Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(10), names= x , order=
˓→ degrevlex )>>> magma(P)# optional - magma
Polynomial ring of rank 10 over GF(127)
Order: Graded Reverse Lexicographical
Variables: x0, x1, x2, x3, x4, x5, x6, x7, x8, x9

3.1. Multivariate Polynomials and Polynomial Rings

477

Polynomials, Release 10.4

sage: T = P.term_order()sage: T.magma_str()"grevlex">>> from sage.all import *>>> T = P.term_order()>>> T.magma_str()"grevlex"

matrix()Return the matrix defining matrix term order.
EXAMPLES:
sage: t = TermOrder("M(1,2,0,1)")
˓→needs sage.modules
sage: t.matrix()
˓→needs sage.modules
[1 2]
[0 1]

#␣
#␣

>>> from sage.all import *>>> t = TermOrder("M(1,2,0,1)")
˓→needs sage.modules>>> t.matrix()
˓→needs sage.modules
[1 2]
[0 1]

#␣
#␣

name()
EXAMPLES:
sage: TermOrder( lex ).name()lex>>> from sage.all import *>>> TermOrder( lex ).name()lexsingular_moreblocks()
Return a the number of additional blocks SINGULAR needs to allocate for handling non-native orderings
like degneglex.
EXAMPLES:
sage: P = PolynomialRing(GF(127), 10, names= x ,....:order= lex(3),deglex(5),lex(2) )sage: T = P.term_order()sage: T.singular_moreblocks()
0sage: P = PolynomialRing(GF(127), 10, names= x ,....:order= lex(3),degneglex(5),lex(2) )sage: T = P.term_order()sage: T.singular_moreblocks()
1
sage: P = PolynomialRing(GF(127), 10, names= x ,(continues on next page)

478

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)....:order= degneglex(5),degneglex(5) )sage: T = P.term_order()sage: T.singular_moreblocks()
2>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(10), names= x ,...
order= lex(3),deglex(5),lex(2) )>>> T = P.term_order()>>> T.singular_moreblocks()
0>>> P = PolynomialRing(GF(Integer(127)), Integer(10), names= x ,...
order= lex(3),degneglex(5),lex(2) )>>> T = P.term_order()>>> T.singular_moreblocks()
1>>> P = PolynomialRing(GF(Integer(127)), Integer(10), names= x ,...
order= degneglex(5),degneglex(5) )>>> T = P.term_order()>>> T.singular_moreblocks()
2

singular_str()
Return a SINGULAR representation of self.
Used to convert polynomial rings to their SINGULAR representation.
EXAMPLES:
sage: P = PolynomialRing(GF(127), 10, names= x ,....:order= lex(3),deglex(5),lex(2) )sage: T = P.term_order()sage: T.singular_str()(lp(3),Dp(5),lp(2))
sage: P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering//
coefficients: ZZ/127//
number of vars : 10//
block
1 : ordering lp//: namesx0 x1 x2//block
2 : ordering Dp//: namesx3 x4 x5 x6 x7//
block
3 : ordering lp//: names
x8 x9
//
block
4 : ordering C>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(10), names= x ,...
order= lex(3),deglex(5),lex(2) )>>> T = P.term_order()>>> T.singular_str()(lp(3),Dp(5),lp(2))>>> P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering#␣#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

479

Polynomials, Release 10.4

(continued from previous page)

//
//
//
//
//
//
//
//
//

coefficients: ZZ/127
number of vars : 10
block
1 : ordering lp: namesx0 x1 x2block
2 : ordering Dp: namesx3 x4 x5 x6 x7
block
3 : ordering lp: namesx8 x9
block
4 : ordering C

The degneglex ordering is somehow special, it looks like a block ordering in SINGULAR:
sage: T = TermOrder("degneglex", 2)
sage: P = PolynomialRing(QQ,2, names= x , order=T)
sage: T = P.term_order()sage: T.singular_str()(a(1:2),ls(2))
sage: T = TermOrder("degneglex", 2) + TermOrder("degneglex", 2)
sage: P = PolynomialRing(QQ,4, names= x , order=T)
sage: T = P.term_order()sage: T.singular_str()(a(1:2),ls(2),a(1:2),ls(2))
sage: P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering//
coefficients: QQ//
number of vars : 4//
block
1 : ordering a//: namesx0 x1//: weights
1 1
//
block
2 : ordering ls//: names
x0 x1
//
block
3 : ordering a//: namesx2 x3//: weights
1 1
//
block
4 : ordering ls//: names
x2 x3
//
block
5 : ordering C#␣>>> from sage.all import *>>> T = TermOrder("degneglex", Integer(2))>>> P = PolynomialRing(QQ,Integer(2), names= x , order=T)>>> T = P.term_order()>>> T.singular_str()(a(1:2),ls(2))>>> T = TermOrder("degneglex", Integer(2)) + TermOrder("degneglex",␣
˓→Integer(2))>>> P = PolynomialRing(QQ,Integer(4), names= x , order=T)>>> T = P.term_order()>>> T.singular_str()(a(1:2),ls(2),a(1:2),ls(2))>>> P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering#␣(continues on next page)

480

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

//
//
//
//
//
//
//
//
//
//
//
//
//

coefficients: QQ
number of vars : 4
block
1 : ordering a: namesx0 x1: weights
1 1
block
2 : ordering ls: namesx0 x1
block
3 : ordering a: namesx2 x3: weights
1 1
block
4 : ordering ls: namesx2 x3
block
5 : ordering C

The position of the ordering C block can be controlled by setting _singular_ringorder_column
attribute to an integer:
sage: T = TermOrder("degneglex", 2) + TermOrder("degneglex", 2)
sage: T._singular_ringorder_column = 0
sage: P = PolynomialRing(QQ, 4, names= x , order=T)
sage: P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering C//
block
2 : ordering a//: namesx0 x1//: weights
1 1
//
block
3 : ordering ls//: names
x0 x1
//
block
4 : ordering a//: namesx2 x3//: weights
1 1
//
block
5 : ordering ls//: namesx2 x3
sage: T._singular_ringorder_column = 1
sage: P = PolynomialRing(QQ, 4, names= y , order=T)
sage: P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering c//
block
2 : ordering a//: namesy0 y1//: weights
1 1
//
block
3 : ordering ls//: names
y0 y1
//
block
4 : ordering a//: namesy2 y3//: weights
1 1
//
block
5 : ordering ls//: namesy2 y3
sage: T._singular_ringorder_column = 2

3.1. Multivariate Polynomials and Polynomial Rings#␣#␣(continues on next page)

481

Polynomials, Release 10.4

(continued from previous page)

sage: P = PolynomialRing(QQ, 4, names= z , order=T)
sage: P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering a//: namesz0 z1//: weights
1 1
//
block
2 : ordering C//
block
3 : ordering ls//: names
z0 z1
//
block
4 : ordering a//: namesz2 z3//: weights
1 1
//
block
5 : ordering ls//: namesz2 z3#␣>>> from sage.all import *>>> T = TermOrder("degneglex", Integer(2)) + TermOrder("degneglex",␣
˓→Integer(2))>>> T._singular_ringorder_column = Integer(0)>>> P = PolynomialRing(QQ, Integer(4), names= x , order=T)>>> P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering C//
block
2 : ordering a//: namesx0 x1//: weights
1 1
//
block
3 : ordering ls//: names
x0 x1
//
block
4 : ordering a//: namesx2 x3//: weights
1 1
//
block
5 : ordering ls//: namesx2 x3>>> T._singular_ringorder_column = Integer(1)>>> P = PolynomialRing(QQ, Integer(4), names= y , order=T)>>> P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering c//
block
2 : ordering a//: namesy0 y1//: weights
1 1
//
block
3 : ordering ls//: names
y0 y1
//
block
4 : ordering a//: namesy2 y3//: weights
1 1

#␣

#␣

(continues on next page)482

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

//
//

block

5 : ordering ls: namesy2 y3>>> T._singular_ringorder_column = Integer(2)>>> P = PolynomialRing(QQ, Integer(4), names= z , order=T)>>> P._singular_()˓→needs sage.libs.singularpolynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering a//: namesz0 z1//: weights
1 1
//
block
2 : ordering C//
block
3 : ordering ls//: names
z0 z1
//
block
4 : ordering a//: namesz2 z3//: weights
1 1
//
block
5 : ordering ls//: namesz2 z3#␣property sortkey
The default sortkey method for this term order.
EXAMPLES:
sage: O = TermOrder()sage: O.sortkey.__func__ is O.sortkey_lex.__func__
True
sage: O = TermOrder( deglex )sage: O.sortkey.__func__ is O.sortkey_deglex.__func__
True>>> from sage.all import *>>> O = TermOrder()>>> O.sortkey.__func__ is O.sortkey_lex.__func__
True>>> O = TermOrder( deglex )>>> O.sortkey.__func__ is O.sortkey_deglex.__func__
Truesortkey_block(f)Return the sortkey of an exponent tuple with respect to the block order as specified when constructing thiselement.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<a,b,c,d,e,f> = PolynomialRing(QQbar, 6,
˓→needs sage.rings.number_field....:order= degrevlex(3),degrevlex(3) )sage: a > c^4 # indirect doctest
˓→needs sage.rings.number_field#␣#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

483

Polynomials, Release 10.4

(continued from previous page)

False
sage: a > e^4
˓→needs sage.rings.number_field
True

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(6),# needs␣
˓→sage.rings.number_field...
order= degrevlex(3),degrevlex(3) ,␣˓→names=( a ,b , c , d , e , f ,)); (a, b, c, d, e, f,) = P._first_
˓→ngens(6)>>> a > c**Integer(4) # indirect doctest␣˓→# needs sage.rings.number_field
False>>> a > e**Integer(4)␣˓→# needs sage.rings.number_fieldTrue

sortkey_deglex(f)Return the sortkey of an exponent tuple with respect to the degree lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= deglex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
False
sage: x > 1
˓→needs sage.rings.number_field
True

#␣
#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= deglex , names=( x ,˓→(x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x > Integer(1)˓→# needs sage.rings.number_field
Truey ,));␣␣␣

sortkey_degneglex(f)Return the sortkey of an exponent tuple with respect to the degree negative lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQbar, 3, order= degneglex )˓→needs sage.rings.number_field#␣(continues on next page)484

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: x*y > y*z # indirect doctest
˓→needs sage.rings.number_field
False
sage: x*y > x
˓→needs sage.rings.number_field
True

#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(3), order= degneglex , names=( x ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.number_field>>> x*y > y*z # indirect doctest
˓→needs sage.rings.number_field
False>>> x*y > x
˓→needs sage.rings.number_field
True

y ,
#␣

#␣

sortkey_degrevlex(f)Return the sortkey of an exponent tuple with respect to the degree reversed lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= degrevlex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
False
sage: x > 1
˓→needs sage.rings.number_field
True

#␣
#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= degrevlex , names=( x ,˓→)); (x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x > Integer(1)˓→# needs sage.rings.number_field
True

y ,
␣

␣

sortkey_invlex(f)Return the sortkey of an exponent tuple with respect to the inversed lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= invlex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest#␣#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

485

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field
False
sage: x > 1
˓→needs sage.rings.number_field
True
˓→

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= invlex , names=( x ,˓→(x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x > Integer(1)˓→# needs sage.rings.number_field
Truey ,));␣␣␣

sortkey_lex(f)Return the sortkey of an exponent tuple with respect to the lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= lex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_fieldTrue
sage: x > 1
˓→needs sage.rings.number_field
True

#␣
#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= lex , names=( x ,˓→ y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> x > Integer(1)˓→# needs sage.rings.number_field
Truey ,)); (x,␣␣sortkey_matrix(f)Return the sortkey of an exponent tuple with respect to the matrix term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= m(1,3,1,0) )˓→needs sage.rings.number_fieldsage: y > x^2 # indirect doctest
˓→needs sage.rings.number_field#␣#␣(continues on next page)

486

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True
sage: y > x^3
˓→needs sage.rings.number_field
False

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= m(1,3,1,0) , names=( x ,˓→)); (x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> y > x**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> y > x**Integer(3)˓→# needs sage.rings.number_field
False

y ,
␣

␣

sortkey_negdeglex(f)Return the sortkey of an exponent tuple with respect to the negative degree lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= negdeglex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_fieldTrue
sage: x > 1
˓→needs sage.rings.number_field
False

#␣
#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= negdeglex , names=( x ,˓→)); (x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> x > Integer(1)˓→# needs sage.rings.number_field
False

y ,
␣

␣

sortkey_negdegrevlex(f)Return the sortkey of an exponent tuple with respect to the negative degree reverse lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= negdegrevlex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
True

#␣
#␣

(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

487

Polynomials, Release 10.4

(continued from previous page)

sage: x > 1
˓→needs sage.rings.number_field
False

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= negdegrevlex , names=( x ,˓→ ,)); (x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> x > Integer(1)˓→# needs sage.rings.number_field
False

y
␣

␣

sortkey_neglex(f)Return the sortkey of an exponent tuple with respect to the negative lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQbar, 2, order= neglex )˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
False
sage: x > 1
˓→needs sage.rings.number_field
False

#␣
#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQbar, Integer(2), order= neglex , names=( x ,˓→(x, y,) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x > Integer(1)˓→# needs sage.rings.number_field
Falsey ,));␣␣␣

sortkey_negwdeglex(f)Return the sortkey of an exponent tuple with respect to the negative weighted degree lexicographical termorder.
INPUT:• f – exponent tuple
EXAMPLES:
sage: t = TermOrder( negwdeglex ,(3,2))
sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field#␣#␣(continues on next page)

488

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True
sage: x^2 > y^3
˓→needs sage.rings.number_field
True>>> from sage.all import *>>> t = TermOrder( negwdeglex ,(Integer(3),Integer(2)))>>> P = PolynomialRing(QQbar, Integer(2), order=t, names=( x ,˓→) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> x**Integer(2) > y**Integer(3)˓→# needs sage.rings.number_field
True

#␣

y ,)); (x, y,␣␣sortkey_negwdegrevlex(f)Return the sortkey of an exponent tuple with respect to the negative weighted degree reverse lexicographicalterm order.
INPUT:• f – exponent tuple
EXAMPLES:
sage: t = TermOrder( negwdegrevlex ,(3,2))
sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_fieldTrue
sage: x^2 > y^3
˓→needs sage.rings.number_field
True>>> from sage.all import *>>> t = TermOrder( negwdegrevlex ,(Integer(3),Integer(2)))>>> P = PolynomialRing(QQbar, Integer(2), order=t, names=( x ,˓→) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_fieldTrue>>> x**Integer(2) > y**Integer(3)˓→# needs sage.rings.number_field
True

#␣
#␣

#␣

y ,)); (x, y,␣␣sortkey_wdeglex(f)Return the sortkey of an exponent tuple with respect to the weighted degree lexicographical term order.
INPUT:• f – exponent tuple
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

489

Polynomials, Release 10.4

sage: t = TermOrder( wdeglex ,(3,2))
sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
False
sage: x > y
˓→needs sage.rings.number_field
True>>> from sage.all import *>>> t = TermOrder( wdeglex ,(Integer(3),Integer(2)))>>> P = PolynomialRing(QQbar, Integer(2), order=t, names=( x ,˓→) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x > y˓→needs sage.rings.number_field
True

#␣
#␣

#␣

y ,)); (x, y,␣#␣sortkey_wdegrevlex(f)Return the sortkey of an exponent tuple with respect to the weighted degree reverse lexicographical termorder.
INPUT:• f – exponent tuple
EXAMPLES:
sage: t = TermOrder( wdegrevlex ,(3,2))
sage: P.<x,y> = PolynomialRing(QQbar, 2, order=t)
˓→needs sage.rings.number_fieldsage: x > y^2 # indirect doctest
˓→needs sage.rings.number_field
False
sage: x^2 > y^3
˓→needs sage.rings.number_field
True>>> from sage.all import *>>> t = TermOrder( wdegrevlex ,(Integer(3),Integer(2)))>>> P = PolynomialRing(QQbar, Integer(2), order=t, names=( x ,˓→) = P._first_ngens(2)# needs sage.rings.number_field>>> x > y**Integer(2) # indirect doctest˓→# needs sage.rings.number_field
False>>> x**Integer(2) > y**Integer(3)˓→# needs sage.rings.number_field
True

#␣
#␣

#␣

y ,)); (x, y,␣␣

tuple_weight(f)Return the weight of tuple f.
INPUT:• f – exponent tuple

490

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: t = TermOrder( wdeglex ,(1,2,3))
sage: P.<a,b,c> = PolynomialRing(QQbar, order=t)
˓→needs sage.rings.number_fieldsage: P.term_order().tuple_weight([3,2,1])
˓→needs sage.rings.number_field
10

#␣
#␣

>>> from sage.all import *>>> t = TermOrder( wdeglex ,(Integer(1),Integer(2),Integer(3)))>>> P = PolynomialRing(QQbar, order=t, names=( a , b , c ,)); (a, b, c,) =␣
˓→P._first_ngens(3)# needs sage.rings.number_field>>> P.term_order().tuple_weight([Integer(3),Integer(2),Integer(1)])␣˓→# needs sage.rings.number_field10

weights()
Return the weights for weighted term orders.
EXAMPLES:
sage: t = TermOrder( wdeglex ,(2,3))
sage: t.weights()(2, 3)>>> from sage.all import *>>> t = TermOrder( wdeglex ,(Integer(2),Integer(3)))>>> t.weights()(2, 3)

sage.rings.polynomial.term_order.termorder_from_singular(S)Return the Sage term order of the basering in the given Singular interface
INPUT:
An instance of the Singular interface.
EXAMPLES:
sage: from sage.rings.polynomial.term_order import termorder_from_singularsage: singular.eval( ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp) )˓→needs sage.libs.singular#␣

sage: termorder_from_singular(singular)
˓→needs sage.libs.singular
Block term order with blocks:(Matrix term order with matrix[1 2][3 0],
Weighted degree reverse lexicographic term order with weights (2, 3),
Lexicographic term order of length 2)>>> from sage.all import *>>> from sage.rings.polynomial.term_order import termorder_from_singular>>> singular.eval( ring r1 = (9,x),(a,b,c,d,e,f),(M((1,2,3,0)),wp(2,3),lp) )˓→needs sage.libs.singular#␣#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

491

Polynomials, Release 10.4

(continued from previous page)>>> termorder_from_singular(singular)
˓→needs sage.libs.singular
Block term order with blocks:(Matrix term order with matrix[1 2][3 0],
Weighted degree reverse lexicographic term order with weights (2, 3),
Lexicographic term order of length 2)#␣

A term order in Singular also involves information on orders for modules. This information is reflected in _singular_ringorder_column attribute of the term order.
sage: # needs sage.libs.singularsage: singular.ring(0, (x,y,z,w) , (C,dp(2),lp(2)) )polynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering C//
block
2 : ordering dp//: names
x y
//
block
3 : ordering lp//: namesz w
sage: T = termorder_from_singular(singular)
sage: T
Block term order with blocks:(Degree reverse lexicographic term order of length 2,
Lexicographic term order of length 2)
sage: T._singular_ringorder_column
0sage: # needs sage.libs.singularsage: singular.ring(0, (x,y,z,w) , (c,dp(2),lp(2)) )polynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering c//
block
2 : ordering dp//: names
x y
//
block
3 : ordering lp//: namesz w
sage: T = termorder_from_singular(singular)
sage: T
Block term order with blocks:(Degree reverse lexicographic term order of length 2,
Lexicographic term order of length 2)
sage: T._singular_ringorder_column
1>>> from sage.all import *>>> # needs sage.libs.singular>>> singular.ring(Integer(0), (x,y,z,w) , (C,dp(2),lp(2)) )polynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering C(continues on next page)492

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

//
block
2 : ordering dp//: names
x y
//
block
3 : ordering lp//: namesz w>>> T = termorder_from_singular(singular)>>> T
Block term order with blocks:(Degree reverse lexicographic term order of length 2,
Lexicographic term order of length 2)>>> T._singular_ringorder_column
0>>> # needs sage.libs.singular>>> singular.ring(Integer(0), (x,y,z,w) , (c,dp(2),lp(2)) )polynomial ring, over a field, global ordering// coefficients: QQ// number of vars : 4//
block
1 : ordering c//
block
2 : ordering dp//: names
x y
//
block
3 : ordering lp//: namesz w>>> T = termorder_from_singular(singular)>>> T
Block term order with blocks:(Degree reverse lexicographic term order of length 2,
Lexicographic term order of length 2)>>> T._singular_ringorder_column
1

3.1.2 Base class for multivariate polynomial rings
class
sage.rings.polynomial.multi_polynomial_ring_base.BooleanPolynomialRing_base
Bases: MPolynomialRing_base
Abstract base class for BooleanPolynomialRing.
This class is defined for the purpose of isinstance tests. It should not be instantiated.
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ring_base import␣˓→BooleanPolynomialRing_base
sage: R.<x, y, z> = BooleanPolynomialRing()
˓→needs sage.rings.polynomial.pbori
sage: isinstance(R, BooleanPolynomialRing_base)˓→needs sage.rings.polynomial.pbori
True

#␣
#␣

>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring_base import␣˓→BooleanPolynomialRing_base>>> R = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)# needs sage.rings.polynomial.pbori(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

493

Polynomials, Release 10.4

(continued from previous page)>>> isinstance(R, BooleanPolynomialRing_base)˓→needs sage.rings.polynomial.pbori
True

#␣

By design, there is only one direct implementation subclass:sage: len(BooleanPolynomialRing_base.__subclasses__()) <= 1
True>>> from sage.all import *>>> len(BooleanPolynomialRing_base.__subclasses__()) <= Integer(1)Trueclass sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
Bases: CommutativeRing
Create a polynomial ring in several variables over a commutative ring.
EXAMPLES:
sage: R.<x,y> = ZZ[ x,y ]; R
Multivariate Polynomial Ring in x, y over Integer Ringsage: cat = Rings().Commutative()sage: class CR(Parent):....:
def __init__(self):....:
Parent.__init__(self, self, category=cat)....:
def __call__(self, x):....:
return Nonesage: cr = CR()
sage: cr.is_commutative()
True
sage: cr[ x,y ]Multivariate Polynomial Ring in x, y over<__main__.CR_with_category object at ...>>>> from sage.all import *>>> R = ZZ[ x,y ]; (x, y,) = R._first_ngens(2); R
Multivariate Polynomial Ring in x, y over Integer Ring>>> cat = Rings().Commutative()>>> class CR(Parent):...
def __init__(self):...
Parent.__init__(self, self, category=cat)...
def __call__(self, x):...
return None>>> cr = CR()>>> cr.is_commutative()
True>>> cr[ x,y ]Multivariate Polynomial Ring in x, y over<__main__.CR_with_category object at ...>

change_ring(base_ring=None, names=None, order=None)
Return a new multivariate polynomial ring which is isomorphic to self, but has a different ordering givenby the parameter order or names given by the parameter names.
INPUT:

494

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• base_ring – a base ring
• names – variable names• order – a term order
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(127), 3, order= lex )sage: x > y^2
Truesage: Q.<x,y,z> = P.change_ring(order= degrevlex )sage: x > y^2
False>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(3), order= lex , names=( x ,˓→ y ,z ,)); (x, y, z,) = P._first_ngens(3)>>> x > y**Integer(2)True>>> Q = P.change_ring(order= degrevlex , names=( x , y , z ,)); (x, y, z,)␣˓→= Q._first_ngens(3)>>> x > y**Integer(2)Falsecharacteristic()
Return the characteristic of this polynomial ring.
EXAMPLES:
sage: R = PolynomialRing(QQ, x , 3)
sage: R.characteristic()
0
sage: R = PolynomialRing(GF(7), x , 20)
sage: R.characteristic()
7>>> from sage.all import *>>> R = PolynomialRing(QQ, x , Integer(3))>>> R.characteristic()
0>>> R = PolynomialRing(GF(Integer(7)), x , Integer(20))>>> R.characteristic()
7

completion(names=None, prec=20, extras={}, **kwds)
Return the completion of self with respect to the ideal generated by the variable(s) names.
INPUT:• names – (optional) variable or list/tuple of variables (given either as elements of the polynomial ring or
as strings); the default is all variables of self
• prec – default precision of resulting power series ring, possibly infinite• extras – passed as keywords to PowerSeriesRing or LazyPowerSeriesRing; can also be
keyword arguments
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

495

Polynomials, Release 10.4

sage: P.<x,y,z,w> = PolynomialRing(ZZ)
sage: P.completion( w )Power Series Ring in w over Multivariate Polynomial Ring in
x, y, z over Integer Ringsage: P.completion((w,x,y))Multivariate Power Series Ring in w, x, y over
Univariate Polynomial Ring in z over Integer Ringsage: Q.<w,x,y,z> = P.completion(); Q
Multivariate Power Series Ring in w, x, y, z over Integer Ringsage: H = PolynomialRing(PolynomialRing(ZZ,3, z ),4, f ); H
Multivariate Polynomial Ring in f0, f1, f2, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ringsage: H.completion(H.gens())
Multivariate Power Series Ring in f0, f1, f2, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ringsage: H.completion(H.gens()[2])Power Series Ring in f2 overMultivariate Polynomial Ring in f0, f1, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ringsage: P.<x,y,z,w> = PolynomialRing(ZZ)
sage: P.completion(prec=oo)
˓→needs sage.combinat
Multivariate Lazy Taylor Series Ring in x, y, z, w over Integer Ringsage: P.completion((w,x,y), prec=oo)
˓→needs sage.combinat
Multivariate Lazy Taylor Series Ring in w, x, y over
Univariate Polynomial Ring in z over Integer Ring#␣#␣>>> from sage.all import *>>> P = PolynomialRing(ZZ, names=( x , y , z , w ,)); (x, y, z, w,) = P._
˓→first_ngens(4)>>> P.completion( w )Power Series Ring in w over Multivariate Polynomial Ring in
x, y, z over Integer Ring>>> P.completion((w,x,y))Multivariate Power Series Ring in w, x, y over
Univariate Polynomial Ring in z over Integer Ring>>> Q = P.completion(names=( w , x , y , z ,)); (w, x, y, z,) = Q._first_
˓→ngens(4); Q
Multivariate Power Series Ring in w, x, y, z over Integer Ring>>> H = PolynomialRing(PolynomialRing(ZZ,Integer(3), z ),Integer(4), f ); H
Multivariate Polynomial Ring in f0, f1, f2, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ring>>> H.completion(H.gens())
Multivariate Power Series Ring in f0, f1, f2, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ring>>> H.completion(H.gens()[Integer(2)])
Power Series Ring in f2 overMultivariate Polynomial Ring in f0, f1, f3 overMultivariate Polynomial Ring in z0, z1, z2 over Integer Ring
(continues on next page)

496

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> P = PolynomialRing(ZZ, names=( x , y , z , w ,)); (x, y, z, w,) = P._
˓→first_ngens(4)>>> P.completion(prec=oo)#␣˓→needs sage.combinat
Multivariate Lazy Taylor Series Ring in x, y, z, w over Integer Ring>>> P.completion((w,x,y), prec=oo)#␣˓→needs sage.combinat
Multivariate Lazy Taylor Series Ring in w, x, y over
Univariate Polynomial Ring in z over Integer Ring

construction()
Returns a functor F and base ring R such that F(R) == self.
EXAMPLES:
sage: S = ZZ[ x,y ]sage: F, R = S.construction(); R
Integer Ringsage: F
MPoly[x,y]sage: F(R) == S
True
sage: F(R) == ZZ[ x ][ y ]False>>> from sage.all import *>>> S = ZZ[ x,y ]>>> F, R = S.construction(); R
Integer Ring>>> F
MPoly[x,y]>>> F(R) == S
True>>> F(R) == ZZ[ x ][ y ]Falseflattening_morphism()
Return the flattening morphism of this polynomial ring
EXAMPLES:
sage: QQ[ a , b ][ x , y ].flattening_morphism()
Flattening morphism:
From: Multivariate Polynomial Ring in x, yover Multivariate Polynomial Ring in a, b over Rational Field
To:
Multivariate Polynomial Ring in a, b, x, y over Rational Field
sage: QQ[ x,y ].flattening_morphism()
Identity endomorphism ofMultivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> QQ[ a , b ][ x , y ].flattening_morphism()
Flattening morphism:
From: Multivariate Polynomial Ring in x, y(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

497

Polynomials, Release 10.4

(continued from previous page)To:

over Multivariate Polynomial Ring in a, b over Rational Field
Multivariate Polynomial Ring in a, b, x, y over Rational Field>>> QQ[ x,y ].flattening_morphism()
Identity endomorphism ofMultivariate Polynomial Ring in x, y over Rational Fieldgen(n=0)interpolation(bound, *args)
Create a polynomial with specified evaluations.
CALL FORMATS:
This function can be called in two ways:
1. interpolation(bound, points, values)
2. interpolation(bound, function)
INPUT:• bound – either an integer bounding the total degree or a list/tuple of integers bounding the degree ofthe variables• points – list/tuple containing the evaluation points• values – list/tuple containing the desired values at points• function – evaluable function in 𝑛 variables, where 𝑛 is the number of variables of the polynomial
ring
OUTPUT:
1. A polynomial respecting the bounds and having values as values when evaluated at points.
2. A polynomial respecting the bounds and having the same values as function at exactly so many points
so that the polynomial is unique.
EXAMPLES:
sage: def F(a,b,c):....:
return a^3*b + b + c^2 + 25....:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: R.interpolation(4, F)
˓→needs sage.modulesx^3*y + z^2 + y + 25
sage: def F(a,b,c):....:
return a^3*b + b + c^2 + 25....:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: R.interpolation([3,1,2], F)˓→needs sage.modulesx^3*y + z^2 + y + 25#␣#␣

sage: def F(a,b,c):....:
return a^3*b + b + c^2 + 25....:
sage: R.<x,y,z> = PolynomialRing(QQ)(continues on next page)

498

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: points = [(5,1,1),(7,2,2),(8,5,-1),(2,5,3),(1,4,0),(5,9,0),....: (2,7,0),(1,10,13),(0,0,1),(-1,1,0),(2,5,3),(1,1,1),(7,4,11),....: (12,1,9),(1,1,3),(4,-1,2),(0,1,5),(5,1,3),(3,1,-2),(2,11,3),....: (4,12,19),(3,1,1),(5,2,-3),(12,1,1),(2,3,4)]
sage: R.interpolation([3,1,2], points, [F(*x) for x in points])
˓→needs sage.modulesx^3*y + z^2 + y + 25>>> from sage.all import *>>> def F(a,b,c):...
return a**Integer(3)*b + b + c**Integer(2) + Integer(25)....:>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> R.interpolation(Integer(4), F)˓→# needs sage.modulesx^3*y + z^2 + y + 25>>> def F(a,b,c):...
return a**Integer(3)*b + b + c**Integer(2) + Integer(25)....:>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> R.interpolation([Integer(3),Integer(1),Integer(2)], F)˓→# needs sage.modulesx^3*y + z^2 + y + 25

#␣

␣

␣

>>> def F(a,b,c):...
return a**Integer(3)*b + b + c**Integer(2) + Integer(25)....:>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> points = [(Integer(5),Integer(1),Integer(1)),(Integer(7),Integer(2),˓→Integer(2)),(Integer(8),Integer(5),-Integer(1)),(Integer(2),Integer(5),˓→Integer(3)),(Integer(1),Integer(4),Integer(0)),(Integer(5),Integer(9),˓→Integer(0)),... (Integer(2),Integer(7),Integer(0)),(Integer(1),Integer(10),Integer(13)),
˓→(Integer(0),Integer(0),Integer(1)),(-Integer(1),Integer(1),Integer(0)),˓→(Integer(2),Integer(5),Integer(3)),(Integer(1),Integer(1),Integer(1)),
˓→(Integer(7),Integer(4),Integer(11)),... (Integer(12),Integer(1),Integer(9)),(Integer(1),Integer(1),Integer(3)),˓→(Integer(4),-Integer(1),Integer(2)),(Integer(0),Integer(1),Integer(5)),˓→(Integer(5),Integer(1),Integer(3)),(Integer(3),Integer(1),-Integer(2)),˓→(Integer(2),Integer(11),Integer(3)),... (Integer(4),Integer(12),Integer(19)),(Integer(3),Integer(1),Integer(1)),
˓→(Integer(5),Integer(2),-Integer(3)),(Integer(12),Integer(1),Integer(1)),
˓→(Integer(2),Integer(3),Integer(4))]>>> R.interpolation([Integer(3),Integer(1),Integer(2)], points, [F(*x) for x␣˓→in points])# needs sage.modulesx^3*y + z^2 + y + 25

ALGORITHM:
Solves a linear system of equations with the linear algebra module. If the points are not specified, it samples
exactly as many points as needed for a unique solution.
Note: It will only run if the base ring is a field, even though it might work otherwise as well. If your base
3.1. Multivariate Polynomials and Polynomial Rings

499

Polynomials, Release 10.4

ring is an integral domain, let it run over the fraction field.
Also, if the solution is not unique, it spits out one solution, without any notice that there are more.
Lastly, the interpolation function for univariate polynomial rings is called lagrange_polynomial().

Warning: If you don’t provide point/value pairs but just a function, it will only use as many points asneeded for a unique solution with the given bounds. In particular it will not notice or check whether the
result yields the correct evaluation for other points as well. So if you give wrong bounds, you will get awrong answer without any warning.
sage: def F(a,b,c):....:
return a^3*b + b + c^2 + 25....:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: R.interpolation(3, F)
˓→needs sage.modules
1/2*x^3 + x*y + z^2 - 1/2*x + y + 25

#␣>>> from sage.all import *>>> def F(a,b,c):...
return a**Integer(3)*b + b + c**Integer(2) + Integer(25)....:>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> R.interpolation(Integer(3), F)␣˓→# needs sage.modules
1/2*x^3 + x*y + z^2 - 1/2*x + y + 25

See also:lagrange_polynomial
irrelevant_ideal()
Return the irrelevant ideal of this multivariate polynomial ring.
This is the ideal generated by all of the indeterminate generators of this ring.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: R.irrelevant_ideal()
Ideal (x, y, z) of Multivariate Polynomial Ring in x, y, z over
Rational Field>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> R.irrelevant_ideal()
Ideal (x, y, z) of Multivariate Polynomial Ring in x, y, z over
Rational Field

is_exact()
Test whether this multivariate polynomial ring is defined over an exact base ring.
EXAMPLES:

500

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: PolynomialRing(QQ, 2, x ).is_exact()
True
sage: PolynomialRing(RDF, 2, x ).is_exact()
False>>> from sage.all import *>>> PolynomialRing(QQ, Integer(2), x ).is_exact()
True>>> PolynomialRing(RDF, Integer(2), x ).is_exact()
False

is_field(proof=True)
Test whether this multivariate polynomial ring is a field.
A polynomial ring is a field when there are no variable and the base ring is a field.
EXAMPLES:
sage: PolynomialRing(QQ, x , 2).is_field()
False
sage: PolynomialRing(QQ, x , 0).is_field()True
sage: PolynomialRing(ZZ, x , 0).is_field()
False
sage: PolynomialRing(Zmod(1), names=[ x , y ]).is_finite()True>>> from sage.all import *>>> PolynomialRing(QQ, x , Integer(2)).is_field()
False>>> PolynomialRing(QQ, x , Integer(0)).is_field()
True>>> PolynomialRing(ZZ, x , Integer(0)).is_field()
False>>> PolynomialRing(Zmod(Integer(1)), names=[ x , y ]).is_finite()True

is_integral_domain(proof=True)
EXAMPLES:
sage: ZZ[ x,y ].is_integral_domain()Truesage: Integers(8)[ x,y ].is_integral_domain()False>>> from sage.all import *>>> ZZ[ x,y ].is_integral_domain()
True>>> Integers(Integer(8))[ x,y ].is_integral_domain()
False

is_noetherian()
EXAMPLES:
sage: ZZ[ x,y ].is_noetherian()True(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

501

Polynomials, Release 10.4

(continued from previous page)

sage: Integers(8)[ x,y ].is_noetherian()True>>> from sage.all import *>>> ZZ[ x,y ].is_noetherian()
True>>> Integers(Integer(8))[ x,y ].is_noetherian()Truekrull_dimension()macaulay_resultant(*args, **kwds)
Return the Macaulay resultant.
This computes the resultant of universal polynomials as well as polynomials with constant coefficients. Thisis a project done in sage days 55. It is based on the implementation in Maple by Manfred Minimair, which inturn is based on the references listed below. It calculates the Macaulay resultant for a list of polynomials, up
to sign!
REFERENCES:• [CLO2005]• [Can1990]• [Mac1916]
AUTHORS:• Hao Chen, Solomon Vishkautsan (7-2014)
INPUT:• args – a list of 𝑛 homogeneous polynomials in 𝑛 variables. works when args[0] is the list of polynomials, or args is itself the list of polynomials
kwds:• sparse – boolean (default: False); if True, the function creates sparse matrices.
OUTPUT:• the Macaulay resultant, an element of the base ring of self
Todo: Working with sparse matrices should usually give faster results, but with the current implementation
it actually works slower. There should be a way to improve performance with regards to this.
EXAMPLES:
The number of polynomials has to match the number of variables:sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant([y, x + z])
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: number of polynomials(= 2) must equal number of variables (= 3)

502

#␣

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> R.macaulay_resultant([y, x + z])#␣˓→needs sage.modules
Traceback (most recent call last):...
TypeError: number of polynomials(= 2) must equal number of variables (= 3)The polynomials need to be all homogeneous:
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant([y, x + z, z + x^3])
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: resultant for non-homogeneous polynomials is not supported#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> R.macaulay_resultant([y, x + z, z + x**Integer(3)])␣˓→# needs sage.modules
Traceback (most recent call last):...
TypeError: resultant for non-homogeneous polynomials is not supported

All polynomials must be in the same ring:sage: S.<x,y> = PolynomialRing(QQ, 2)
sage: R.<x,y,z> = PolynomialRing(QQ,3)
sage: S.macaulay_resultant([y, z+x])
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: not all inputs are polynomials in the calling ring#␣>>> from sage.all import *>>> S = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = S._first_
˓→ngens(2)>>> R = PolynomialRing(QQ,Integer(3), names=( x , y , z ,)); (x, y, z,) = R.
˓→_first_ngens(3)>>> S.macaulay_resultant([y, z+x])#␣˓→needs sage.modules
Traceback (most recent call last):...
TypeError: not all inputs are polynomials in the calling ring

The following example recreates Proposition 2.10 in Ch.3 in [CLO2005]:
sage: K.<x,y> = PolynomialRing(ZZ, 2)
sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2])
sage: R.macaulay_resultant(flist)
˓→needs sage.modulesu2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 +u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 -#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

503

Polynomials, Release 10.4

(continued from previous page)

2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 - u1*u2*u3^2*u10 +u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10 +
u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11>>> from sage.all import *>>> K = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = K._first_
˓→ngens(2)>>> flist, R = K._macaulay_resultant_universal_polynomials([Integer(1),˓→Integer(1),Integer(2)])>>> R.macaulay_resultant(flist)#␣˓→needs sage.modulesu2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 +u1*u2*u3*u5*u7 + u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 u0*u2*u4^2*u8 - u1^2*u3*u5*u8 + u0*u1*u4*u5*u8 + u2^2*u3^2*u9 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9 - u1*u2*u3^2*u10 +u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10 +
u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11

The following example degenerates into the determinant of a 3 × 3 matrix:
sage: K.<x,y> = PolynomialRing(ZZ, 2)
sage: flist,R = K._macaulay_resultant_universal_polynomials([1,1,1])
sage: R.macaulay_resultant(flist)
˓→needs sage.modules-u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8#␣>>> from sage.all import *>>> K = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = K._first_
˓→ngens(2)>>> flist,R = K._macaulay_resultant_universal_polynomials([Integer(1),˓→Integer(1),Integer(1)])>>> R.macaulay_resultant(flist)#␣˓→needs sage.modules-u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8

The following example is by Patrick Ingram (arXiv 1310.4114):
sage: U = PolynomialRing(ZZ, y ,2); y0,y1 = U.gens()
sage: R = PolynomialRing(U, x ,3); x0,x1,x2 = R.gens()
sage: f0 = y0*x2^2 - x0^2 + 2*x1*x2
sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2
sage: f2 = x0*x1 - x2^2
sage: flist = [f0,f1,f2]
sage: R.macaulay_resultant([f0,f1,f2])
˓→needs sage.modulesy0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27>>> from sage.all import *>>> U = PolynomialRing(ZZ, y ,Integer(2)); y0,y1 = U.gens()>>> R = PolynomialRing(U, x ,Integer(3)); x0,x1,x2 = R.gens()>>> f0 = y0*x2**Integer(2) - x0**Integer(2) + Integer(2)*x1*x2>>> f1 = y1*x2**Integer(2) - x1**Integer(2) + Integer(2)*x0*x2>>> f2 = x0*x1 - x2**Integer(2)>>> flist = [f0,f1,f2]>>> R.macaulay_resultant([f0,f1,f2])#␣#␣(continues on next page)504

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.modulesy0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27
˓→A simple example with constant rational coefficients:
sage: R.<x,y,z,w> = PolynomialRing(QQ, 4)
sage: R.macaulay_resultant([w, z, y, x])
˓→needs sage.modules
1>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(4), names=( x ,˓→ w,) = R._first_ngens(4)>>> R.macaulay_resultant([w, z, y, x])
˓→needs sage.modules
1

#␣

y ,

z ,

w ,)); (x, y, z,#␣An example where the resultant vanishes:sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant([x + y, y^2, x])
˓→needs sage.modules0#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y ,˓→R._first_ngens(3)>>> R.macaulay_resultant([x + y, y**Integer(2), x])˓→# needs sage.modules
0z ,)); (x, y, z,) =␣␣An example of bad reduction at a prime 𝑝 = 5:
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant([y, x^3 + 25*y^2*x, 5*z])
˓→needs sage.libs.pari sage.modules125#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> R.macaulay_resultant([y, x**Integer(3) + Integer(25)*y**Integer(2)*x,␣
˓→Integer(5)*z])# needs sage.libs.pari sage.modules
125

The input can given as an unpacked list of polynomials:
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant(y, x^3 + 25*y^2*x, 5*z)
˓→needs sage.libs.pari sage.modules
125>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x ,˓→R._first_ngens(3)

#␣

y ,

z ,)); (x, y, z,) =␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

505

Polynomials, Release 10.4

(continued from previous page)>>> R.macaulay_resultant(y, x**Integer(3) + Integer(25)*y**Integer(2)*x,␣
˓→Integer(5)*z)# needs sage.libs.pari sage.modules
125

An example when the coefficients live in a finite field:
sage: F = FiniteField(11)sage: R.<x,y,z,w> = PolynomialRing(F, 4)
sage: R.macaulay_resultant([z, x^3, 5*y, w])
˓→needs sage.modules sage.rings.finite_rings4#␣>>> from sage.all import *>>> F = FiniteField(Integer(11))>>> R = PolynomialRing(F, Integer(4), names=( x , y , z , w ,)); (x, y, z,␣
˓→w,) = R._first_ngens(4)>>> R.macaulay_resultant([z, x**Integer(3), Integer(5)*y, w])␣˓→# needs sage.modules sage.rings.finite_rings
4

Example when the denominator in the algorithm vanishes(in this case the resultant is the constant term of thequotient of char polynomials of numerator/denominator):sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: R.macaulay_resultant([y, x + z, z^2])
˓→needs sage.libs.pari sage.modules-1#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y ,˓→R._first_ngens(3)>>> R.macaulay_resultant([y, x + z, z**Integer(2)])˓→# needs sage.libs.pari sage.modules-1z ,)); (x, y, z,) =␣␣

When there are only 2 polynomials, the Macaulay resultant degenerates to the traditional resultant:sage: R.<x> = PolynomialRing(QQ, 1)
sage: f = x^2 + 1; g = x^5 + 1
sage: fh = f.homogenize()
sage: gh = g.homogenize()
sage: RH = fh.parent()
sage: f.resultant(g) == RH.macaulay_resultant([fh, gh])˓→needs sage.modules
True

#␣

>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(1), names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1); g = x**Integer(5) + Integer(1)>>> fh = f.homogenize()>>> gh = g.homogenize()>>> RH = fh.parent()>>> f.resultant(g) == RH.macaulay_resultant([fh, gh])#␣˓→needs sage.modules
True

506

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

monomial(*exponents)
Return the monomial with given exponents.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(ZZ, 3)
sage: R.monomial(1,1,1)
x*y*z
sage: e=(1,2,3)
sage: R.monomial(*e)
x*y^2*z^3
sage: m = R.monomial(1,2,3)
sage: R.monomial(*m.degrees()) == mTrue>>> from sage.all import *>>> R = PolynomialRing(ZZ, Integer(3), names=( x , y ,˓→R._first_ngens(3)>>> R.monomial(Integer(1),Integer(1),Integer(1))
x*y*z>>> e=(Integer(1),Integer(2),Integer(3))>>> R.monomial(*e)
x*y^2*z^3>>> m = R.monomial(Integer(1),Integer(2),Integer(3))>>> R.monomial(*m.degrees()) == mTruez ,)); (x, y, z,) =␣

monomials_of_degree(degree)
Return a list of all monomials of the given total degree in this multivariate polynomial ring.
EXAMPLES:
sage: # needs sage.combinat
sage: R.<x,y,z> = ZZ[]
sage: mons = R.monomials_of_degree(2)sage: mons[z^2, y*z, x*z, y^2, x*y, x^2]
sage: P = PolynomialRing(QQ, 3, x, y, z , order=TermOrder( wdeglex , [1, 2,␣
˓→1]))
sage: P.monomials_of_degree(2)[z^2, y, x*z, x^2]
sage: P = PolynomialRing(QQ, 3, x, y, z , order= lex )sage: P.monomials_of_degree(3)[z^3, y*z^2, y^2*z, y^3, x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3]
sage: P = PolynomialRing(QQ, 3, x, y, z , order= invlex )sage: P.monomials_of_degree(3)[x^3, x^2*y, x*y^2, y^3, x^2*z, x*y*z, y^2*z, x*z^2, y*z^2, z^3]>>> from sage.all import *>>> # needs sage.combinat>>> R = ZZ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> mons = R.monomials_of_degree(Integer(2))>>> mons[z^2, y*z, x*z, y^2, x*y, x^2]>>> P = PolynomialRing(QQ, Integer(3), x, y, z , order=TermOrder( wdeglex ,␣
˓→[Integer(1), Integer(2), Integer(1)]))>>> P.monomials_of_degree(Integer(2))(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

507

Polynomials, Release 10.4

(continued from previous page)[z^2, y, x*z, x^2]>>> P = PolynomialRing(QQ, Integer(3), x, y, z , order= lex )>>> P.monomials_of_degree(Integer(3))[z^3, y*z^2, y^2*z, y^3, x*z^2, x*y*z, x*y^2, x^2*z, x^2*y, x^3]>>> P = PolynomialRing(QQ, Integer(3), x, y, z , order= invlex )>>> P.monomials_of_degree(Integer(3))[x^3, x^2*y, x*y^2, y^3, x^2*z, x*y*z, y^2*z, x*z^2, y*z^2, z^3]

The number of such monomials equals(︀𝑛+𝑘−1)︀
𝑘where 𝑛 is the number of variables and 𝑘 the degree:

sage: len(mons) == binomial(3 + 2 - 1, 2)
˓→needs sage.combinat
True

#␣

>>> from sage.all import *>>> len(mons) == binomial(Integer(3) + Integer(2) - Integer(1), Integer(2))˓→# needs sage.combinat
True␣

ngens()
random_element(degree=2, terms=None, choose_degree=False, *args, **kwargs)
Return a random polynomial of at most degree 𝑑 and at most 𝑡 terms.
First monomials are chosen uniformly random from the set of all possible monomials of degree up to 𝑑(inclusive). This means that it is more likely that a monomial of degree 𝑑 appears than a monomial of degree𝑑 − 1 because the former class is bigger.
Exactly 𝑡 distinct monomials are chosen this way and each one gets a random coefficient (possibly zero) fromthe base ring assigned.
The returned polynomial is the sum of this list of terms.
INPUT:• degree – maximal degree (likely to be reached) (default: 2)• terms – number of terms requested (default: 5). If more terms are requested than exist, then thisparameter is silently reduced to the maximum number of available terms.
• choose_degree – choose degrees of monomials randomly first rather than monomials uniformly
random.
• **kwargs – passed to the random element generator of the base ring
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: f = P.random_element(2, 5)
sage: f.degree() <= 2
Truesage: f.parent() is P
True
sage: len(list(f)) <= 5
Truesage: f = P.random_element(2, 5, choose_degree=True)
sage: f.degree() <= 2
True(continues on next page)

508

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.parent() is P
True
sage: len(list(f)) <= 5
True>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> f = P.random_element(Integer(2), Integer(5))>>> f.degree() <= Integer(2)True>>> f.parent() is P
True>>> len(list(f)) <= Integer(5)True>>> f = P.random_element(Integer(2), Integer(5), choose_degree=True)>>> f.degree() <= Integer(2)True>>> f.parent() is P
True>>> len(list(f)) <= Integer(5)True

Stacked rings:
sage: R = QQ[ x,y ]sage: S = R[ t,u ]sage: f = S._random_nonzero_element(degree=2, terms=1)
sage: len(list(f))
1sage: f.degree() <= 2
Truesage: f.parent() is S
True>>> from sage.all import *>>> R = QQ[ x,y ]>>> S = R[ t,u ]>>> f = S._random_nonzero_element(degree=Integer(2), terms=Integer(1))>>> len(list(f))
1>>> f.degree() <= Integer(2)True>>> f.parent() is S
True

Default values apply if no degree and/or number of terms is provided:
sage: # needs sage.modules
sage: M = random_matrix(QQ[ x,y,z ], 2, 2)
sage: all(a.degree() <= 2 for a in M.list())
True
sage: all(len(list(a)) <= 5 for a in M.list())
True
sage: M = random_matrix(QQ[ x,y,z ], 2, 2, terms=1, degree=2)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

509

Polynomials, Release 10.4

(continued from previous page)

sage: all(a.degree() <= 2 for a in M.list())
True
sage: all(len(list(a)) <= 1 for a in M.list())
True
sage: P.random_element(0, 1) in QQ
True
sage: P.random_element(2, 0)0sage: R.<x> = PolynomialRing(Integers(3), 1)
sage: f = R.random_element()
sage: f.degree() <= 2
Truesage: len(list(f)) <= 3
True>>> from sage.all import *>>> # needs sage.modules>>> M = random_matrix(QQ[ x,y,z ], Integer(2), Integer(2))>>> all(a.degree() <= Integer(2) for a in M.list())
True>>> all(len(list(a)) <= Integer(5) for a in M.list())
True>>> M = random_matrix(QQ[ x,y,z ], Integer(2), Integer(2), terms=Integer(1),␣
˓→degree=Integer(2))>>> all(a.degree() <= Integer(2) for a in M.list())
True>>> all(len(list(a)) <= Integer(1) for a in M.list())
True>>> P.random_element(Integer(0), Integer(1)) in QQ
True>>> P.random_element(Integer(2), Integer(0))
0>>> R = PolynomialRing(Integers(Integer(3)), Integer(1), names=( x ,)); (x,)␣
˓→= R._first_ngens(1)>>> f = R.random_element()>>> f.degree() <= Integer(2)True>>> len(list(f)) <= Integer(3)True

To produce a dense polynomial, pick terms=Infinity:
sage: P.<x,y,z> = GF(127)[]
sage: f = P.random_element(degree=2, terms=Infinity)
sage: while len(list(f)) != 10:....:
f = P.random_element(degree=2, terms=Infinity)
sage: f = P.random_element(degree=3, terms=Infinity)
sage: while len(list(f)) != 20:....:
f = P.random_element(degree=3, terms=Infinity)
sage: f = P.random_element(degree=3, terms=Infinity, choose_degree=True)(continues on next page)

510

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: while len(list(f)) != 20:....:
f = P.random_element(degree=3, terms=Infinity)>>> from sage.all import *>>> P = GF(Integer(127))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = P.random_element(degree=Integer(2), terms=Infinity)>>> while len(list(f)) != Integer(10):...
f = P.random_element(degree=Integer(2), terms=Infinity)>>> f = P.random_element(degree=Integer(3), terms=Infinity)>>> while len(list(f)) != Integer(20):...
f = P.random_element(degree=Integer(3), terms=Infinity)>>> f = P.random_element(degree=Integer(3), terms=Infinity, choose_
˓→degree=True)>>> while len(list(f)) != Integer(20):...
f = P.random_element(degree=Integer(3), terms=Infinity)

The number of terms is silently reduced to the maximum available if more terms are requested:sage: P.<x,y,z> = GF(127)[]
sage: f = P.random_element(degree=2, terms=1000)
sage: len(list(f)) <= 10
True>>> from sage.all import *>>> P = GF(Integer(127))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = P.random_element(degree=Integer(2), terms=Integer(1000))>>> len(list(f)) <= Integer(10)Trueremove_var(order=None, *var)
Remove a variable or sequence of variables from self.
If order is not specified, then the subring inherits the term order of the original ring, if possible.
EXAMPLES:
sage: P.<x,y,z,w> = PolynomialRing(ZZ)
sage: P.remove_var(z)Multivariate Polynomial Ring in x, y, w over Integer Ringsage: P.remove_var(z, x)Multivariate Polynomial Ring in y, w over Integer Ringsage: P.remove_var(y, z, x)
Univariate Polynomial Ring in w over Integer Ring>>> from sage.all import *>>> P = PolynomialRing(ZZ, names=( x , y , z , w ,)); (x, y, z, w,) = P._
˓→first_ngens(4)>>> P.remove_var(z)Multivariate Polynomial Ring in x, y, w over Integer Ring>>> P.remove_var(z, x)Multivariate Polynomial Ring in y, w over Integer Ring>>> P.remove_var(y, z, x)
Univariate Polynomial Ring in w over Integer Ring

Removing all variables results in the base ring:

3.1. Multivariate Polynomials and Polynomial Rings

511

Polynomials, Release 10.4

sage: P.remove_var(y, z, x, w)
Integer Ring>>> from sage.all import *>>> P.remove_var(y, z, x, w)
Integer Ring

If possible, the term order is kept:
sage: R.<x,y,z,w> = PolynomialRing(ZZ, order= deglex )sage: R.remove_var(y).term_order()Degree lexicographic term ordersage: R.<x,y,z,w> = PolynomialRing(ZZ, order= lex )sage: R.remove_var(y).term_order()
Lexicographic term order>>> from sage.all import *>>> R = PolynomialRing(ZZ, order= deglex , names=( x ,˓→y, z, w,) = R._first_ngens(4)>>> R.remove_var(y).term_order()Degree lexicographic term order>>> R = PolynomialRing(ZZ, order= lex , names=( x ,˓→z, w,) = R._first_ngens(4)>>> R.remove_var(y).term_order()
Lexicographic term order

y ,

y ,

z ,

z ,

w ,)); (x,␣w ,)); (x, y,␣

Be careful with block orders when removing variables:sage: R.<x,y,z,u,v> = PolynomialRing(ZZ, order= deglex(2),lex(3) )sage: R.remove_var(x, y, z)
Traceback (most recent call last):...
ValueError: impossible to use the original term order (mostlikely because it was a block order). Please specify the termorder for the subringsage: R.remove_var(x,y,z, order= degrevlex )Multivariate Polynomial Ring in u, v over Integer Ring>>> from sage.all import *>>> R = PolynomialRing(ZZ, order= deglex(2),lex(3) , names=( x ,˓→ ,v ,)); (x, y, z, u, v,) = R._first_ngens(5)>>> R.remove_var(x, y, z)
Traceback (most recent call last):...
ValueError: impossible to use the original term order (mostlikely because it was a block order). Please specify the termorder for the subring>>> R.remove_var(x,y,z, order= degrevlex )Multivariate Polynomial Ring in u, v over Integer Ring

y ,

z ,

u

repr_long()
Return structured string representation of self.
EXAMPLES:

512

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y,z> = PolynomialRing(QQ, order=TermOrder( degrevlex ,1)....:+ TermOrder( lex ,2))
sage: print(P.repr_long())
Polynomial Ring
Base Ring : Rational Field
Size : 3 Variables
Block 0 : Ordering : degrevlex
Names
: x
Block 1 : Ordering : lex
Names: y, z>>> from sage.all import *>>> P = PolynomialRing(QQ, order=TermOrder( degrevlex ,Integer(1))...
+ TermOrder( lex ,Integer(2)),␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> print(P.repr_long())
Polynomial Ring
Base Ring : Rational Field
Size : 3 Variables
Block 0 : Ordering : degrevlex
Names
: x
Block 1 : Ordering : lex
Names: y, zsome_elements()
Return a list of polynomials.
This is typically used for running generic tests.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: R.some_elements()[x, y, x + y, x^2 + x*y, 0, 1]>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> R.some_elements()[x, y, x + y, x^2 + x*y, 0, 1]

term_order()univariate_ring(x)Return a univariate polynomial ring whose base ring comprises all but one variables of self.
INPUT:• x – a variable of self.
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.univariate_ring(y)Univariate Polynomial Ring in yover Multivariate Polynomial Ring in x, z over Rational Field

3.1. Multivariate Polynomials and Polynomial Rings

513

Polynomials, Release 10.4>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.univariate_ring(y)Univariate Polynomial Ring in yover Multivariate Polynomial Ring in x, z over Rational Field

variable_names_recursive(depth=None)
Return the list of variable names of this and its base rings, as if it were a single multi-variate polynomial.
EXAMPLES:
sage: R = QQ[ x,y ][ z,w ]sage: R.variable_names_recursive()( x , y , z , w )sage: R.variable_names_recursive(3)( y , z , w )>>> from sage.all import *>>> R = QQ[ x,y ][ z,w ]>>> R.variable_names_recursive()( x , y , z , w )>>> R.variable_names_recursive(Integer(3))( y , z , w )weyl_algebra()
Return the Weyl algebra generated from self.
EXAMPLES:
sage: R = QQ[ x,y,z ]sage: W = R.weyl_algebra(); W˓→needs sage.modules
Differential Weyl algebra of polynomials in x, y, z over Rational Field
sage: W.polynomial_ring() == R
˓→needs sage.modules
True>>> from sage.all import *>>> R = QQ[ x,y,z ]>>> W = R.weyl_algebra(); W˓→needs sage.modules
Differential Weyl algebra of polynomials in x, y, z over Rational Field>>> W.polynomial_ring() == R
˓→needs sage.modules
True

#␣

#␣

#␣

#␣

sage.rings.polynomial.multi_polynomial_ring_base.is_MPolynomialRing(x)sage.rings.polynomial.multi_polynomial_ring_base.unpickle_MPolynomialRing_generic(base_ring,n,names,
order)

514

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.multi_polynomial_ring_base.unpickle_MPolynomialRing_generic_v1(base_rinn,names,
order)

3.1.3 Base class for elements of multivariate polynomial rings
class sage.rings.polynomial.multi_polynomial.MPolynomial
Bases: CommutativePolynomialargs()
Returns the names of the arguments of self, in the order they are accepted from call.
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: x.args()(x, y)>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.args()(x, y)

change_ring(R)Return this polynomial with coefficients converted to R.
INPUT:• R – a ring or morphism; if a morphism, the coefficients are mapped to the codomain of R
OUTPUT: a new polynomial with the base ring changed to R.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = x^3 + 3/5*y + 1
sage: f.change_ring(GF(7))
x^3 + 2*y + 1
sage: g = x^2 + 5*ysage: g.change_ring(GF(5))
x^2>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) + Integer(3)/Integer(5)*y + Integer(1)>>> f.change_ring(GF(Integer(7)))
x^3 + 2*y + 1>>> g = x**Integer(2) + Integer(5)*y>>> g.change_ring(GF(Integer(5)))
x^2sage: # needs sage.rings.finite_rings
sage: R.<x,y> = GF(9, a )[](continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

515

Polynomials, Release 10.4

(continued from previous page)

sage: (x+2*y).change_ring(GF(3))
x - y>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(9), a )[ x, y ]; (x, y,) = R._first_ngens(2)>>> (x+Integer(2)*y).change_ring(GF(Integer(3)))
x - ysage: # needs sage.rings.finite_rings
sage: F.<a> = GF(7^2)
sage: R.<x,y> = F[]sage: f = x^2 + a^2*y^2 + a*x + a^3*ysage: g = f.change_ring(F.frobenius_endomorphism()); gx^2 + (-a - 2)*y^2 + (-a + 1)*x + (2*a + 2)*ysage: g.change_ring(F.frobenius_endomorphism()) == f
True>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(7)**Integer(2), names=( a ,)); (a,) = F._first_ngens(1)>>> R = F[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + a**Integer(2)*y**Integer(2) + a*x + a**Integer(3)*y>>> g = f.change_ring(F.frobenius_endomorphism()); gx^2 + (-a - 2)*y^2 + (-a + 1)*x + (2*a + 2)*y>>> g.change_ring(F.frobenius_endomorphism()) == f
True
sage: # needs sage.rings.number_fieldsage: K.<z> = CyclotomicField(3)sage: R.<x,y> = K[]
sage: f = x^2 + z*y
sage: f.change_ring(K.embeddings(CC)[1])x^2 + (-0.500000000000000 - 0.866025403784438*I)*y>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(3), names=( z ,)); (z,) = K._first_ngens(1)>>> R = K[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + z*y>>> f.change_ring(K.embeddings(CC)[Integer(1)])
x^2 + (-0.500000000000000 - 0.866025403784438*I)*y
sage: # needs sage.rings.number_fieldsage: K.<w> = CyclotomicField(5)sage: R.<x,y> = K[]
sage: f = x^2 + w*y
sage: f.change_ring(K.embeddings(QQbar)[1])x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(5), names=( w ,)); (w,) = K._first_ngens(1)>>> R = K[ x, y ]; (x, y,) = R._first_ngens(2)(continues on next page)

516

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = x**Integer(2) + w*y>>> f.change_ring(K.embeddings(QQbar)[Integer(1)])
x^2 + (-0.8090169943749474? + 0.5877852522924731?*I)*y

coefficients()
Return the nonzero coefficients of this polynomial in a list.
The returned list is decreasingly ordered by the term ordering of self.parent(), i.e. thelist of coefficients matches the list of monomials returned by sage.rings.polynomial.
multi_polynomial_libsingular.MPolynomial_libsingular.monomials().
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ, 3, order= degrevlex )sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[23, 6, 1]
sage: R.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[6, 23, 1]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), order= degrevlex , names=( x , y , z
˓→ ,)); (x, y, z,) = R._first_ngens(3)>>> f = Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[23, 6, 1]>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( x , y , z ,));␣
˓→(x, y, z,) = R._first_ngens(3)>>> f = Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[6, 23, 1]

Test the same stuff with base ring Z – different implementation:
sage: R.<x,y,z> = PolynomialRing(ZZ, 3, order= degrevlex )sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[23, 6, 1]
sage: R.<x,y,z> = PolynomialRing(ZZ, 3, order= lex )sage: f = 23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[6, 23, 1]>>> from sage.all import *>>> R = PolynomialRing(ZZ, Integer(3), order= degrevlex , names=( x , y , z
˓→ ,)); (x, y, z,) = R._first_ngens(3)>>> f = Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[23, 6, 1]>>> R = PolynomialRing(ZZ, Integer(3), order= lex , names=( x , y , z ,));␣
˓→(x, y, z,) = R._first_ngens(3)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

517

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[6, 23, 1]

AUTHOR:• Didier Deshommes
content()
Return the content of this polynomial. Here, we define content as the gcd of the coefficients in the base ring.
See also:
content_ideal()
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: f = 4*x+6*y
sage: f.content()2
sage: f.content().parent()
Integer Ring>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(4)*x+Integer(6)*y>>> f.content()2>>> f.content().parent()
Integer Ring

content_ideal()
Return the content ideal of this polynomial, defined as the ideal generated by its coefficients.
See also:
content()
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: f = 2*x*y + 6*x - 4*y + 2
sage: f.content_ideal()
Principal ideal (2) of Integer Ringsage: S.<z,t> = R[]
sage: g = x*z + y*t
sage: g.content_ideal()
Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(2)*x*y + Integer(6)*x - Integer(4)*y + Integer(2)>>> f.content_ideal()
Principal ideal (2) of Integer Ring>>> S = R[ z, t ]; (z, t,) = S._first_ngens(2)>>> g = x*z + y*t(continues on next page)

518

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> g.content_ideal()
Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring

denominator()
Return a denominator of self.
First, the lcm of the denominators of the entries of self is computed and returned. If this computation fails,
the unit of the parent of self is returned.
Note that some subclasses may implement its own denominator function.
Warning: This is not the denominator of the rational function defined by self, which would always be 1
since self is a polynomial.
EXAMPLES:First we compute the denominator of a polynomial with integer coefficients, which is of course 1.
sage: R.<x,y> = ZZ[]
sage: f = x^3 + 17*y + x + y
sage: f.denominator()
1>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) + Integer(17)*y + x + y>>> f.denominator()
1

Next we compute the denominator of a polynomial over a number field.
sage: # needs sage.rings.number_field sage.symbolic
sage: R.<x,y> = NumberField(symbolic_expression(x^2+3), a )[ x,y ]sage: f = (1/17)*x^19 + (1/6)*y - (2/3)*x + 1/3; f
1/17*x^19 - 2/3*x + 1/6*y + 1/3
sage: f.denominator()
102>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> R = NumberField(symbolic_expression(x**Integer(2)+Integer(3)), a )[ x,y ];˓→ (x, y,) = R._first_ngens(2)>>> f = (Integer(1)/Integer(17))*x**Integer(19) + (Integer(1)/Integer(6))*y -␣˓→(Integer(2)/Integer(3))*x + Integer(1)/Integer(3); f
1/17*x^19 - 2/3*x + 1/6*y + 1/3>>> f.denominator()
102

Finally, we try to compute the denominator of a polynomial with coefficients in the real numbers, which is aring whose elements do not have a denominator method.
sage: # needs sage.rings.real_mpfr
sage: R.<a,b,c> = RR[]
sage: f = a + b + RR( 0.3 ); f
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

519

Polynomials, Release 10.4

(continued from previous page)a + b + 0.300000000000000
sage: f.denominator()
1.00000000000000>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> f = a + b + RR( 0.3 ); f
a + b + 0.300000000000000>>> f.denominator()
1.00000000000000

Check that the denominator is an element over the base whenever the base has no denominator function. This
closes Issue #9063:
sage: R.<a,b,c> = GF(5)[]sage: x = R(0)sage: x.denominator()1
sage: type(x.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >sage: type(a.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >sage: from sage.rings.polynomial.multi_polynomial_element import MPolynomial
sage: isinstance(a / b, MPolynomial)
False
sage: isinstance(a.numerator() / a.denominator(), MPolynomial)
True>>> from sage.all import *>>> R = GF(Integer(5))[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> x = R(Integer(0))>>> x.denominator()
1>>> type(x.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >>>> type(a.denominator())<class sage.rings.finite_rings.integer_mod.IntegerMod_int >>>> from sage.rings.polynomial.multi_polynomial_element import MPolynomial>>> isinstance(a / b, MPolynomial)
False>>> isinstance(a.numerator() / a.denominator(), MPolynomial)
Truederivative(*args)
The formal derivative of this polynomial, with respect to variables supplied in args.
Multiple variables and iteration counts may be supplied; see documentation for the global function derivative() for more details.
See also:_derivative()
EXAMPLES:
Polynomials implemented via Singular:

520

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.libs.singularsage: R.<x, y> = PolynomialRing(FiniteField(5))
sage: f = x^3*y^5 + x^7*ysage: type(f)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_
˓→libsingular >sage: f.derivative(x)2*x^6*y - 2*x^2*y^5
sage: f.derivative(y)x^7>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(FiniteField(Integer(5)), names=( x , y ,)); (x, y,) =␣
˓→R._first_ngens(2)>>> f = x**Integer(3)*y**Integer(5) + x**Integer(7)*y>>> type(f)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_
˓→libsingular >>>> f.derivative(x)2*x^6*y - 2*x^2*y^5>>> f.derivative(y)x^7Generic multivariate polynomials:
sage: R.<t> = PowerSeriesRing(QQ)
sage: S.<x, y> = PolynomialRing(R)sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
sage: type(f)<class sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict >sage: f.derivative(x)# with respect to x
(2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2
sage: f.derivative(y)# with respect to y
(3*t^2 + O(t^3))*x^2*y^2
sage: f.derivative(t)# with respect to t (recurses into base ring)(2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3
sage: f.derivative(x, y)# with respect to x and then y(6*t^2 + O(t^3))*x*y^2
sage: f.derivative(y, 3)# with respect to y three times(6*t^2 + O(t^3))*x^2
sage: f.derivative()# can t figure out the variable
Traceback (most recent call last):...
ValueError: must specify which variable to differentiate with respect to>>> from sage.all import *>>> R = PowerSeriesRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x , y ,)); (x, y,) = S._first_ngens(2)>>> f = (t**Integer(2) + O(t**Integer(3)))*x**Integer(2)*y**Integer(3) +␣˓→(Integer(37)*t**Integer(4) + O(t**Integer(5)))*x**Integer(3)>>> type(f)<class sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict >>>> f.derivative(x)# with respect to x
(2*t^2 + O(t^3))*x*y^3 + (111*t^4 + O(t^5))*x^2>>> f.derivative(y)# with respect to y
(3*t^2 + O(t^3))*x^2*y^2(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

521

Polynomials, Release 10.4

(continued from previous page)>>> f.derivative(t)# with respect to t (recurses into base ring)(2*t + O(t^2))*x^2*y^3 + (148*t^3 + O(t^4))*x^3>>> f.derivative(x, y)# with respect to x and then y(6*t^2 + O(t^3))*x*y^2>>> f.derivative(y, Integer(3))# with respect to y three times(6*t^2 + O(t^3))*x^2>>> f.derivative()# can t figure out the variable
Traceback (most recent call last):...
ValueError: must specify which variable to differentiate with respect to

Polynomials over the symbolic ring (just for fun….):
sage: # needs sage.symbolic
sage: x = var("x")
sage: S.<u, v> = PolynomialRing(SR)sage: f = u*v*x
sage: f.derivative(x) == u*v
True
sage: f.derivative(u) == v*x
True>>> from sage.all import *>>> # needs sage.symbolic>>> x = var("x")>>> S = PolynomialRing(SR, names=( u ,>>> f = u*v*x>>> f.derivative(x) == u*v
True>>> f.derivative(u) == v*x
Truev ,)); (u, v,) = S._first_ngens(2)discriminant(variable)
Returns the discriminant of self with respect to the given variable.
INPUT:• variable – The variable with respect to which we compute the discriminant
OUTPUT: An element of the base ring of the polynomial ring.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: f = 4*x*y^2 + 1/4*x*y*z + 3/2*x*z^2 - 1/2*z^2sage: f.discriminant(x)˓→needs sage.libs.singular1
sage: f.discriminant(y)˓→needs sage.libs.singular-383/16*x^2*z^2 + 8*x*z^2
sage: f.discriminant(z)˓→needs sage.libs.singular-383/16*x^2*y^2 + 8*x*y^2

#␣

#␣

#␣

>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)(continues on next page)522

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(4)*x*y**Integer(2) + Integer(1)/Integer(4)*x*y*z + Integer(3)/˓→Integer(2)*x*z**Integer(2) - Integer(1)/Integer(2)*z**Integer(2)>>> f.discriminant(x)#␣˓→needs sage.libs.singular1>>> f.discriminant(y)#␣˓→needs sage.libs.singular-383/16*x^2*z^2 + 8*x*z^2>>> f.discriminant(z)#␣˓→needs sage.libs.singular-383/16*x^2*y^2 + 8*x*y^2

Note that, unlike the univariate case, the result lives in the same ring as the polynomial:
sage: R.<x,y> = QQ[]
sage: f = x^5*y + 3*x^2*y^2 - 2*x + y - 1
sage: f.discriminant(y)#␣˓→needs sage.libs.singularx^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1
sage: f.polynomial(y).discriminant()#␣˓→needs sage.libs.pari sage.modulesx^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1
sage: f.discriminant(y).parent() == f.polynomial(y).discriminant().parent() ␣˓→# needs sage.libs.singular sage.modules
False>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(5)*y + Integer(3)*x**Integer(2)*y**Integer(2) -␣˓→Integer(2)*x + y - Integer(1)>>> f.discriminant(y)#␣˓→needs sage.libs.singularx^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1>>> f.polynomial(y).discriminant()#␣˓→needs sage.libs.pari sage.modulesx^10 + 2*x^5 + 24*x^3 + 12*x^2 + 1>>> f.discriminant(y).parent() == f.polynomial(y).discriminant().parent()␣˓→# needs sage.libs.singular sage.modules
False

AUTHOR: Miguel Marcogcd(other)
Return a greatest common divisor of this polynomial and other.
INPUT:• other – a polynomial with the same parent as this polynomial
EXAMPLES:
sage: Q.<z> = Frac(QQ[ z ])sage: R.<x,y> = Q[]
sage: r = x*y - (2*z-1)/(z^2+z+1) * x + y/z
sage: p = r * (x + z*y - 1/z^2)
sage: q = r * (x*y*z + 1)
sage: gcd(p, q)(z^3 + z^2 + z)*x*y + (-2*z^2 + z)*x + (z^2 + z + 1)*y3.1. Multivariate Polynomials and Polynomial Rings

523

Polynomials, Release 10.4>>> from sage.all import *>>> Q = Frac(QQ[ z ], names=( z ,)); (z,) = Q._first_ngens(1)>>> R = Q[ x, y ]; (x, y,) = R._first_ngens(2)>>> r = x*y - (Integer(2)*z-Integer(1))/(z**Integer(2)+z+Integer(1)) * x + y/z>>> p = r * (x + z*y - Integer(1)/z**Integer(2))>>> q = r * (x*y*z + Integer(1))>>> gcd(p, q)(z^3 + z^2 + z)*x*y + (-2*z^2 + z)*x + (z^2 + z + 1)*y

Polynomials over polynomial rings are converted to a simpler polynomial ring with all variables to compute
the gcd:
sage: A.<z,t> = ZZ[]
sage: B.<x,y> = A[]
sage: r = x*y*z*t + 1
sage: p = r * (x - y + z - t + 1)
sage: q = r * (x*z - y*t)
sage: gcd(p, q)
˓→needs sage.libs.singular
z*t*x*y + 1
sage: _.parent()
Multivariate Polynomial Ring in x, y overMultivariate Polynomial Ring in z, t over Integer Ring>>> from sage.all import *>>> A = ZZ[ z, t ]; (z, t,) = A._first_ngens(2)>>> B = A[ x, y ]; (x, y,) = B._first_ngens(2)>>> r = x*y*z*t + Integer(1)>>> p = r * (x - y + z - t + Integer(1))>>> q = r * (x*z - y*t)>>> gcd(p, q)
˓→needs sage.libs.singular
z*t*x*y + 1>>> _.parent()
Multivariate Polynomial Ring in x, y overMultivariate Polynomial Ring in z, t over Integer Ring#␣#␣

Some multivariate polynomial rings have no gcd implementation:
sage: R.<x,y> = GaussianIntegers()[]#␣˓→needs sage.rings.number_fieldsage: x.gcd(x)Traceback (most recent call last):...
NotImplementedError: GCD is not implemented for multivariate polynomials over
Gaussian Integers generated by I in Number Field in I with defining␣˓→polynomial x^2 + 1 with I = 1*I>>> from sage.all import *>>> R = GaussianIntegers()[ x, y ]; (x, y,) = R._first_ngens(2)# needs sage.
˓→rings.number_field>>> x.gcd(x)Traceback (most recent call last):...
NotImplementedError: GCD is not implemented for multivariate polynomials over
Gaussian Integers generated by I in Number Field in I with defining␣˓→polynomial x^2 + 1 with I = 1*I

524

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

gradient()
Return a list of partial derivatives of this polynomial, ordered by the variables of self.parent().
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(ZZ, 3)
sage: f = x*y + 1
sage: f.gradient()[y, x, 0]>>> from sage.all import *>>> P = PolynomialRing(ZZ, Integer(3), names=( x ,˓→P._first_ngens(3)>>> f = x*y + Integer(1)>>> f.gradient()[y, x, 0]y ,z ,)); (x, y, z,) =␣homogeneous_components()
Return the homogeneous components of this polynomial.
OUTPUT:
A dictionary mapping degrees to homogeneous polynomials.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: (x^3 + 2*x*y^3 + 4*y^3 + y).homogeneous_components(){1: y, 3: x^3 + 4*y^3, 4: 2*x*y^3}
sage: R.zero().homogeneous_components(){}>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> (x**Integer(3) + Integer(2)*x*y**Integer(3) + Integer(4)*y**Integer(3) +␣˓→y).homogeneous_components(){1: y, 3: x^3 + 4*y^3, 4: 2*x*y^3}>>> R.zero().homogeneous_components(){}

In case of weighted term orders, the polynomials are homogeneous with respect to the weights:
sage: S.<a,b,c> = PolynomialRing(ZZ, order=TermOrder( wdegrevlex , (1,2,3)))
sage: (a^6 + b^3 + b*c + a^2*c + c + a + 1).homogeneous_components(){0: 1, 1: a, 3: c, 5: a^2*c + b*c, 6: a^6 + b^3}>>> from sage.all import *>>> S = PolynomialRing(ZZ, order=TermOrder( wdegrevlex , (Integer(1),˓→Integer(2),Integer(3))), names=( a ,b , c ,)); (a, b, c,) = S._first_
˓→ngens(3)>>> (a**Integer(6) + b**Integer(3) + b*c + a**Integer(2)*c + c + a +␣˓→Integer(1)).homogeneous_components(){0: 1, 1: a, 3: c, 5: a^2*c + b*c, 6: a^6 + b^3}

homogenize(var='h')Return the homogenization of this polynomial.
The polynomial itself is returned if it is homogeneous already. Otherwise, the monomials are multiplied withthe smallest powers of var such that they all have the same total degree.
3.1. Multivariate Polynomials and Polynomial Rings

525

Polynomials, Release 10.4

INPUT:• var – a variable in the polynomial ring (as a string, an element of the ring, or a zero-based index in thelist of variables) or a name for a new variable (default: h )OUTPUT:If var specifies a variable in the polynomial ring, then a homogeneous element in that ring is returned.
Otherwise, a homogeneous element is returned in a polynomial ring with an extra last variable var.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = x^2 + y + 1 + 5*x*y^10
sage: f.homogenize()
5*x*y^10 + x^2*h^9 + y*h^10 + h^11>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + y + Integer(1) + Integer(5)*x*y**Integer(10)>>> f.homogenize()
5*x*y^10 + x^2*h^9 + y*h^10 + h^11

The parameter var can be used to specify the name of the variable:
sage: g = f.homogenize( z ); g
5*x*y^10 + x^2*z^9 + y*z^10 + z^11
sage: g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> g = f.homogenize( z ); g
5*x*y^10 + x^2*z^9 + y*z^10 + z^11>>> g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field

However, if the polynomial is homogeneous already, then that parameter is ignored and no extra variable isadded to the polynomial ring:sage: f = x^2 + y^2
sage: g = f.homogenize( z ); gx^2 + y^2
sage: g.parent()
Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> f = x**Integer(2) + y**Integer(2)>>> g = f.homogenize( z ); gx^2 + y^2>>> g.parent()
Multivariate Polynomial Ring in x, y over Rational Field

If you want the ring of the result to be independent of whether the polynomial is homogenized, you can use
var to use an existing variable to homogenize:
sage: R.<x,y,z> = QQ[]
sage: f = x^2 + y^2
sage: g = f.homogenize(z); g(continues on next page)

526

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x^2 + y^2
sage: g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: f = x^2 - ysage: g = f.homogenize(z); gx^2 - y*z
sage: g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> f = x**Integer(2) + y**Integer(2)>>> g = f.homogenize(z); gx^2 + y^2>>> g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field>>> f = x**Integer(2) - y>>> g = f.homogenize(z); gx^2 - y*z>>> g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field

The parameter var can also be given as a zero-based index in the list of variables:sage: g = f.homogenize(2); gx^2 - y*z>>> from sage.all import *>>> g = f.homogenize(Integer(2)); gx^2 - y*z

If the variable specified by var is not present in the polynomial, then setting it to 1 yields the original polynomial:
sage: g(x,y,1)x^2 - y>>> from sage.all import *>>> g(x,y,Integer(1))
x^2 - yIf it is present already, this might not be the case:sage: g = f.homogenize(x); gx^2 - x*y
sage: g(1,y,z)-y + 1>>> from sage.all import *>>> g = f.homogenize(x); gx^2 - x*y>>> g(Integer(1),y,z)-y + 1

In particular, this can be surprising in positive characteristic:

3.1. Multivariate Polynomials and Polynomial Rings

527

Polynomials, Release 10.4

sage: R.<x,y> = GF(2)[]sage: f = x + 1
sage: f.homogenize(x)0>>> from sage.all import *>>> R = GF(Integer(2))[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x + Integer(1)>>> f.homogenize(x)0inverse_mod(I)Returns an inverse of self modulo the polynomial ideal 𝐼, namely a multivariate polynomial 𝑓 such that
self * f - 1 belongs to 𝐼.
INPUT:• I – an ideal of the polynomial ring in which self lives
OUTPUT:a multivariate polynomial representing the inverse of f modulo 𝐼
EXAMPLES:
sage: R.<x1,x2> = QQ[]
sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1)sage: f = x1 + 3*x2^2; g = f.inverse_mod(I); g
˓→# needs sage.libs.singular
1/16*x1 + 3/16
sage: (f*g).reduce(I)˓→# needs sage.libs.singular1>>> from sage.all import *>>> R = QQ[ x1, x2 ]; (x1, x2,) = R._first_ngens(2)>>> I = R.ideal(x2**Integer(2) + x1 - Integer(2), x1**Integer(2) - Integer(1))>>> f = x1 + Integer(3)*x2**Integer(2); g = f.inverse_mod(I); g␣˓→# needs sage.libs.singular
1/16*x1 + 3/16>>> (f*g).reduce(I)#␣˓→needs sage.libs.singular1

Test a non-invertible element:
sage: R.<x1,x2> = QQ[]
sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1)sage: f = x1 + x2
sage: f.inverse_mod(I)˓→# needs sage.libs.singularTraceback (most recent call last):...
ArithmeticError: element is non-invertible>>> from sage.all import *>>> R = QQ[ x1, x2 ]; (x1, x2,) = R._first_ngens(2)(continues on next page)

528

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> I = R.ideal(x2**Integer(2) + x1 - Integer(2), x1**Integer(2) - Integer(1))>>> f = x1 + x2>>> f.inverse_mod(I)#␣˓→needs sage.libs.singularTraceback (most recent call last):...
ArithmeticError: element is non-invertible

is_generator()
Returns True if this polynomial is a generator of its parent.
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: x.is_generator()Truesage: (x + y - y).is_generator()Truesage: (x*y).is_generator()
False
sage: R.<x,y> = QQ[]
sage: x.is_generator()Truesage: (x + y - y).is_generator()Truesage: (x*y).is_generator()
False>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.is_generator()True>>> (x + y - y).is_generator()True>>> (x*y).is_generator()
False>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.is_generator()True>>> (x + y - y).is_generator()True>>> (x*y).is_generator()False

is_homogeneous()
Return True if self is a homogeneous polynomial.
Note: This is a generic implementation which is likely overridden by subclasses.
is_lorentzian(explain=False)
Return whether this is a Lorentzian polynomial.
INPUT:• explain – boolean (default: False); if True return a tuple whose first element is the boolean result

3.1. Multivariate Polynomials and Polynomial Rings

529

Polynomials, Release 10.4of the test, and the second element is a string describing the reason the test failed, or None if the test
succeeded.
Lorentzian polynomials are a class of polynomials connected with the area of discrete convex analysis. A
polynomial 𝑓 with positive real coefficients is Lorentzian if:• 𝑓 is homogeneous;• the support of 𝑓 is 𝑀 -convex• 𝑓 has degree less than 2, or if its degree is at least two, the collection of sequential partial derivatives of𝑓 which are quadratic forms have Gram matrices with at most one positive eigenvalue.
Note in particular that the zero polynomial is Lorentzian. Examples of Lorentzian polynomials include homogeneous stable polynomials, volume polynomials of convex bodies and projective varieties, and Schurpolynomials after renormalizing the coefficient of each monomial 𝑥𝛼 by 1/𝛼!.
EXAMPLES:
Renormalized Schur polynomials are Lorentzian, but not in general if the renormalization is skipped:
sage: P.<x,y> = QQ[]
sage: p = (x^2 / 2) + x*y + (y^2 / 2)sage: p.is_lorentzian()True
sage: p = x^2 + x*y + y^2
sage: p.is_lorentzian()False>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> p = (x**Integer(2) / Integer(2)) + x*y + (y**Integer(2) / Integer(2))>>> p.is_lorentzian()True>>> p = x**Integer(2) + x*y + y**Integer(2)>>> p.is_lorentzian()
False

Homogeneous linear forms and constant polynomials with positive coefficients are Lorentzian, as well as thezero polynomial:
sage: p = x + 2*ysage: p.is_lorentzian()True
sage: p = P(5)sage: p.is_lorentzian()True
sage: P.zero().is_lorentzian()True>>> from sage.all import *>>> p = x + Integer(2)*y>>> p.is_lorentzian()True>>> p = P(Integer(5))>>> p.is_lorentzian()
True>>> P.zero().is_lorentzian()
True

530

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Inhomogeneous polynomials and polynomials with negative coefficients are not Lorentzian:sage: p = x^2 + 2*x + y^2
sage: p.is_lorentzian()False
sage: p = 2*x^2 - y^2sage: p.is_lorentzian()False>>> from sage.all import *>>> p = x**Integer(2) + Integer(2)*x + y**Integer(2)>>> p.is_lorentzian()False>>> p = Integer(2)*x**Integer(2) - y**Integer(2)>>> p.is_lorentzian()
False

It is an error to check if a polynomial is Lorentzian if its base ring is not a subring of the real numbers, as thenotion is not defined in this case:sage: # needs sage.rings.real_mpfr
sage: Q.<z,w> = CC[]
sage: q = z^2 + w^2
sage: q.is_lorentzian()Traceback (most recent call last):...
NotImplementedError: is_lorentzian only implemented for real polynomials>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> Q = CC[ z, w ]; (z, w,) = Q._first_ngens(2)>>> q = z**Integer(2) + w**Integer(2)>>> q.is_lorentzian()Traceback (most recent call last):...
NotImplementedError: is_lorentzian only implemented for real polynomials

The method can give a reason for a polynomial failing to be Lorentzian:sage: p = x^2 + 2*x + y^2
sage: p.is_lorentzian(explain=True)(False, inhomogeneous )>>> from sage.all import *>>> p = x**Integer(2) + Integer(2)*x + y**Integer(2)>>> p.is_lorentzian(explain=True)(False, inhomogeneous )REFERENCES:
For full definitions and related discussion, see [BrHu2019] and [HMMS2019]. The second reference gives
the characterization of Lorentzian polynomials applied in this implementation explicitly.
is_nilpotent()
Return True if self is nilpotent, i.e., some power of self is 0.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

531

Polynomials, Release 10.4

sage: R.<x,y> = QQbar[]
˓→needs sage.rings.number_fieldsage: (x + y).is_nilpotent()
˓→needs sage.rings.number_field
False
sage: R(0).is_nilpotent()
˓→needs sage.rings.number_fieldTrue
sage: _.<x,y> = Zmod(4)[]sage: (2*x).is_nilpotent()
True
sage: (2 + y*x).is_nilpotent()
False
sage: _.<x,y> = Zmod(36)[]
sage: (4 + 6*x).is_nilpotent()
False
sage: (6*x + 12*y + 18*x*y + 24*(x^2+y^2)).is_nilpotent()
True

#␣
#␣

#␣

>>> from sage.all import *>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)# needs sage.rings.number_
˓→field>>> (x + y).is_nilpotent()#␣˓→needs sage.rings.number_field
False>>> R(Integer(0)).is_nilpotent()␣˓→# needs sage.rings.number_field
True>>> _ = Zmod(Integer(4))[ x, y ]; (x, y,) = _._first_ngens(2)>>> (Integer(2)*x).is_nilpotent()
True>>> (Integer(2) + y*x).is_nilpotent()
False>>> _ = Zmod(Integer(36))[ x, y ]; (x, y,) = _._first_ngens(2)>>> (Integer(4) + Integer(6)*x).is_nilpotent()
False>>> (Integer(6)*x + Integer(12)*y + Integer(18)*x*y +␣˓→Integer(24)*(x**Integer(2)+y**Integer(2))).is_nilpotent()
True

is_square(root=False)
Test whether this polynomial is a square.
INPUT:• root – if set to True, return a pair (True, root) where root is a square root or (False,
None) if it is not a square.
EXAMPLES:
sage: R.<a,b> = QQ[]
sage: a.is_square()False
sage: ((1+a*b^2)^2).is_square()True
sage: ((1+a*b^2)^2).is_square(root=True)(True, a*b^2 + 1)

532

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ a, b ]; (a, b,) = R._first_ngens(2)>>> a.is_square()False>>> ((Integer(1)+a*b**Integer(2))**Integer(2)).is_square()True>>> ((Integer(1)+a*b**Integer(2))**Integer(2)).is_square(root=True)(True, a*b^2 + 1)

is_symmetric(group=None)
Return whether this polynomial is symmetric.
INPUT:• group (default: symmetric group) – if set, test whether the polynomial is invariant with respect to thegiven permutation group
EXAMPLES:
sage: # needs sage.groups
sage: R.<x,y,z> = QQ[]
sage: p = (x+y+z)**2 - 3 * (x+y)*(x+z)*(y+z)
sage: p.is_symmetric()True
sage: (x + y - z).is_symmetric()
False
sage: R.one().is_symmetric()True
sage: p = (x-y)*(y-z)*(z-x)
sage: p.is_symmetric()
False
sage: p.is_symmetric(AlternatingGroup(3))
True
sage: R.<x,y> = QQ[]
sage: ((x + y)**2).is_symmetric()
˓→needs sage.groupsTrue
sage: R.one().is_symmetric()
˓→needs sage.groupsTrue
sage: (x + 2*y).is_symmetric()
˓→needs sage.groups
False

#␣

#␣

#␣

>>> from sage.all import *>>> # needs sage.groups>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> p = (x+y+z)**Integer(2) - Integer(3) * (x+y)*(x+z)*(y+z)>>> p.is_symmetric()True>>> (x + y - z).is_symmetric()
False>>> R.one().is_symmetric()
True>>> p = (x-y)*(y-z)*(z-x)>>> p.is_symmetric()
False(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

533

Polynomials, Release 10.4

(continued from previous page)>>> p.is_symmetric(AlternatingGroup(Integer(3)))
True>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> ((x + y)**Integer(2)).is_symmetric()˓→# needs sage.groups
True>>> R.one().is_symmetric()
˓→needs sage.groups
True>>> (x + Integer(2)*y).is_symmetric()˓→# needs sage.groups
False

␣

#␣

␣

An example with a GAP permutation group (here the quaternions):
sage: R = PolynomialRing(QQ, x , 8)
sage: x = R.gens()
sage: p = sum(prod(x[i] for i in e)....:
for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7),....:(3,4,5), (3,4,6), (3,5,6), (4,5,6)])
sage: p.is_symmetric(libgap.TransitiveGroup(8, 5))
˓→needs sage.groupsTrue
sage: p = sum(prod(x[i] for i in e)....:
for e in [(0,1,2), (0,1,7), (0,2,7), (1,2,7),....:(3,4,5), (3,4,6), (3,5,6)])
sage: p.is_symmetric(libgap.TransitiveGroup(8, 5))
˓→needs sage.groups
False

#␣

#␣

>>> from sage.all import *>>> R = PolynomialRing(QQ, x , Integer(8))>>> x = R.gens()>>> p = sum(prod(x[i] for i in e)...
for e in [(Integer(0),Integer(1),Integer(2)), (Integer(0),˓→Integer(1),Integer(7)), (Integer(0),Integer(2),Integer(7)), (Integer(1),˓→Integer(2),Integer(7)),...
(Integer(3),Integer(4),Integer(5)), (Integer(3),˓→Integer(4),Integer(6)), (Integer(3),Integer(5),Integer(6)), (Integer(4),˓→Integer(5),Integer(6))])>>> p.is_symmetric(libgap.TransitiveGroup(Integer(8), Integer(5)))␣˓→# needs sage.groups
True>>> p = sum(prod(x[i] for i in e)...
for e in [(Integer(0),Integer(1),Integer(2)), (Integer(0),Integer(1),˓→Integer(7)), (Integer(0),Integer(2),Integer(7)), (Integer(1),Integer(2),˓→Integer(7)),...
(Integer(3),Integer(4),Integer(5)), (Integer(3),Integer(4),˓→Integer(6)), (Integer(3),Integer(5),Integer(6))])>>> p.is_symmetric(libgap.TransitiveGroup(Integer(8), Integer(5)))␣˓→# needs sage.groups
False

is_unit()
Return True if self is a unit, that is, has a multiplicative inverse.

534

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: (x + y).is_unit()
False
sage: R(0).is_unit()
False
sage: R(-1).is_unit()
True
sage: R(-1 + x).is_unit()
False
sage: R(2).is_unit()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> (x + y).is_unit()
False>>> R(Integer(0)).is_unit()
False>>> R(-Integer(1)).is_unit()
True>>> R(-Integer(1) + x).is_unit()
False>>> R(Integer(2)).is_unit()
True

Check that Issue #22454 is fixed:
sage: _.<x,y> = Zmod(4)[]sage: (1 + 2*x).is_unit()
True
sage: (x*y).is_unit()
False
sage: _.<x,y> = Zmod(36)[]
sage: (7+ 6*x + 12*y - 18*x*y).is_unit()
True>>> from sage.all import *>>> _ = Zmod(Integer(4))[ x, y ]; (x, y,) = _._first_ngens(2)>>> (Integer(1) + Integer(2)*x).is_unit()True>>> (x*y).is_unit()
False>>> _ = Zmod(Integer(36))[ x, y ]; (x, y,) = _._first_ngens(2)>>> (Integer(7)+ Integer(6)*x + Integer(12)*y - Integer(18)*x*y).is_unit()
True

iterator_exp_coeff(as_ETuples=True)
Iterate over self as pairs of ((E)Tuple, coefficient).
INPUT:• as_ETuples – (default: True) if True, iterate over pairs whose first element is an ETuple, otherwise as a tuples
EXAMPLES:
3.1. Multivariate Polynomials and Polynomial Rings

535

Polynomials, Release 10.4

sage: R.<a,b,c> = QQ[]
sage: f = a*c^3 + a^2*b + 2*b^4
sage: list(f.iterator_exp_coeff())[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]
sage: list(f.iterator_exp_coeff(as_ETuples=False))[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]
sage: R.<a,b,c> = PolynomialRing(QQ, 3, order= lex )sage: f = a*c^3 + a^2*b + 2*b^4
sage: list(f.iterator_exp_coeff())[((2, 1, 0), 1), ((1, 0, 3), 1), ((0, 4, 0), 2)]>>> from sage.all import *>>> R = QQ[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> f = a*c**Integer(3) + a**Integer(2)*b + Integer(2)*b**Integer(4)>>> list(f.iterator_exp_coeff())[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]>>> list(f.iterator_exp_coeff(as_ETuples=False))[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( a , b ,˓→(a, b, c,) = R._first_ngens(3)>>> f = a*c**Integer(3) + a**Integer(2)*b + Integer(2)*b**Integer(4)>>> list(f.iterator_exp_coeff())[((2, 1, 0), 1), ((1, 0, 3), 1), ((0, 4, 0), 2)]c ,));␣

jacobian_ideal()
Return the Jacobian ideal of the polynomial self.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: f = x^3 + y^3 + z^3
sage: f.jacobian_ideal()
Ideal (3*x^2, 3*y^2, 3*z^2) ofMultivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> f = x**Integer(3) + y**Integer(3) + z**Integer(3)>>> f.jacobian_ideal()
Ideal (3*x^2, 3*y^2, 3*z^2) ofMultivariate Polynomial Ring in x, y, z over Rational Fieldlift(I)
Given an ideal 𝐼 = (𝑓1 , . . . , 𝑓𝑟 ) that contains self, find 𝑠1 , . . . , 𝑠𝑟 such that self = 𝑠1 𝑓1 + ... + 𝑠𝑟 𝑓𝑟 .
EXAMPLES:
sage: # needs sage.rings.real_mpfr
sage: A.<x,y> = PolynomialRing(CC, 2, order= degrevlex )sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ])sage: f = x*y^13 + y^12
sage: M = f.lift(I); M#␣˓→needs sage.libs.singular[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4](continues on next page)

536

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: sum(map(mul, zip(M, I.gens()))) == f˓→needs sage.libs.singular
True

#␣

>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> A = PolynomialRing(CC, Integer(2), order= degrevlex , names=( x , y ,));␣
˓→(x, y,) = A._first_ngens(2)>>> I = A.ideal([x**Integer(10) + x**Integer(9)*y**Integer(2), y**Integer(8) ˓→ x**Integer(2)*y**Integer(7) ])>>> f = x*y**Integer(13) + y**Integer(12)>>> M = f.lift(I); M#␣˓→needs sage.libs.singular[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]>>> sum(map(mul, zip(M, I.gens()))) == f#␣˓→needs sage.libs.singularTruemacaulay_resultant(*args)
This is an implementation of the Macaulay resultant. It computes the resultant of universal polynomials aswell as polynomials with constant coefficients. This is a project done in sage days 55. It’s based on theimplementation in Maple by Manfred Minimair, which in turn is based on the references [CLO], [Can],[Mac]. It calculates the Macaulay resultant for a list of Polynomials, up to sign!
AUTHORS:• Hao Chen, Solomon Vishkautsan (7-2014)
INPUT:• args – a list of 𝑛 − 1 homogeneous polynomials in 𝑛 variables. works when args[0] is the list ofpolynomials, or args is itself the list of polynomials
OUTPUT:• the Macaulay resultant
EXAMPLES:
The number of polynomials has to match the number of variables:sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: y.macaulay_resultant(x + z)
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: number of polynomials(= 2) must equal number of variables (= 3)#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> y.macaulay_resultant(x + z)#␣˓→needs sage.modules
Traceback (most recent call last):...
TypeError: number of polynomials(= 2) must equal number of variables (= 3)The polynomials need to be all homogeneous:
3.1. Multivariate Polynomials and Polynomial Rings

537

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: y.macaulay_resultant([x + z, z + x^3])
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: resultant for non-homogeneous polynomials is not supported#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> y.macaulay_resultant([x + z, z + x**Integer(3)])␣˓→# needs sage.modules
Traceback (most recent call last):...
TypeError: resultant for non-homogeneous polynomials is not supported

All polynomials must be in the same ring:sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: S.<x,y> = PolynomialRing(QQ, 2)
sage: y.macaulay_resultant(z + x, z)
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: not all inputs are polynomials in the calling ring#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> S = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = S._first_
˓→ngens(2)>>> y.macaulay_resultant(z + x, z)#␣˓→needs sage.modules
Traceback (most recent call last):...
TypeError: not all inputs are polynomials in the calling ring

The following example recreates Proposition 2.10 in Ch.3 of Using Algebraic Geometry:sage: K.<x,y> = PolynomialRing(ZZ, 2)
sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,2])
sage: flist[0].macaulay_resultant(flist[1:])˓→needs sage.modulesu2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 +␣
˓→u1*u2*u3*u5*u7+ u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^
˓→2*u3*u5*u8+ u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9- u1*u2*u3^2*u10 + u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10+ u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11#␣>>> from sage.all import *>>> K = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = K._first_
˓→ngens(2)>>> flist, R = K._macaulay_resultant_universal_polynomials([Integer(1),˓→Integer(1),Integer(2)])(continues on next page)

538

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> flist[Integer(0)].macaulay_resultant(flist[Integer(1):])˓→# needs sage.modulesu2^2*u4^2*u6 - 2*u1*u2*u4*u5*u6 + u1^2*u5^2*u6 - u2^2*u3*u4*u7 +␣
˓→u1*u2*u3*u5*u7+ u0*u2*u4*u5*u7 - u0*u1*u5^2*u7 + u1*u2*u3*u4*u8 - u0*u2*u4^2*u8 - u1^
˓→2*u3*u5*u8+ u0*u1*u4*u5*u8 + u2^2*u3^2*u9 - 2*u0*u2*u3*u5*u9 + u0^2*u5^2*u9- u1*u2*u3^2*u10 + u0*u2*u3*u4*u10 + u0*u1*u3*u5*u10 - u0^2*u4*u5*u10+ u1^2*u3^2*u11 - 2*u0*u1*u3*u4*u11 + u0^2*u4^2*u11␣The following example degenerates into the determinant of a 3 × 3 matrix:
sage: K.<x,y> = PolynomialRing(ZZ, 2)
sage: flist, R = K._macaulay_resultant_universal_polynomials([1,1,1])
sage: flist[0].macaulay_resultant(flist[1:])˓→needs sage.modules-u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8#␣>>> from sage.all import *>>> K = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = K._first_
˓→ngens(2)>>> flist, R = K._macaulay_resultant_universal_polynomials([Integer(1),˓→Integer(1),Integer(1)])>>> flist[Integer(0)].macaulay_resultant(flist[Integer(1):])␣˓→# needs sage.modules-u2*u4*u6 + u1*u5*u6 + u2*u3*u7 - u0*u5*u7 - u1*u3*u8 + u0*u4*u8

The following example is by Patrick Ingram (arXiv 1310.4114):
sage: U = PolynomialRing(ZZ, y ,2); y0,y1 = U.gens()
sage: R = PolynomialRing(U, x ,3); x0,x1,x2 = R.gens()
sage: f0 = y0*x2^2 - x0^2 + 2*x1*x2
sage: f1 = y1*x2^2 - x1^2 + 2*x0*x2
sage: f2 = x0*x1 - x2^2
sage: f0.macaulay_resultant(f1, f2)
˓→needs sage.modulesy0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27>>> from sage.all import *>>> U = PolynomialRing(ZZ, y ,Integer(2)); y0,y1 = U.gens()>>> R = PolynomialRing(U, x ,Integer(3)); x0,x1,x2 = R.gens()>>> f0 = y0*x2**Integer(2) - x0**Integer(2) + Integer(2)*x1*x2>>> f1 = y1*x2**Integer(2) - x1**Integer(2) + Integer(2)*x0*x2>>> f2 = x0*x1 - x2**Integer(2)>>> f0.macaulay_resultant(f1, f2)
˓→needs sage.modulesy0^2*y1^2 - 4*y0^3 - 4*y1^3 + 18*y0*y1 - 27#␣#␣a simple example with constant rational coefficients:
sage: R.<x,y,z,w> = PolynomialRing(QQ, 4)
sage: w.macaulay_resultant([z, y, x])
˓→needs sage.modules1

3.1. Multivariate Polynomials and Polynomial Rings

#␣

539

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(4), names=( x ,˓→ w,) = R._first_ngens(4)>>> w.macaulay_resultant([z, y, x])
˓→needs sage.modules
1

y ,

z ,

w ,)); (x, y, z,#␣an example where the resultant vanishes:sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: (x + y).macaulay_resultant([y^2, x])
˓→needs sage.modules0#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x ,˓→R._first_ngens(3)>>> (x + y).macaulay_resultant([y**Integer(2), x])˓→# needs sage.modules
0y ,z ,)); (x, y, z,) =␣␣an example of bad reduction at a prime p = 5:
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: y.macaulay_resultant([x^3 + 25*y^2*x, 5*z])
˓→needs sage.libs.pari sage.modules125#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> y.macaulay_resultant([x**Integer(3) + Integer(25)*y**Integer(2)*x,␣
˓→Integer(5)*z])# needs sage.libs.pari sage.modules
125

The input can given as an unpacked list of polynomials:
sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: y.macaulay_resultant(x^3 + 25*y^2*x, 5*z)
˓→needs sage.libs.pari sage.modules125#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> y.macaulay_resultant(x**Integer(3) + Integer(25)*y**Integer(2)*x,␣
˓→Integer(5)*z)# needs sage.libs.pari sage.
˓→modules
125

an example when the coefficients live in a finite field:
sage: F = FiniteField(11)sage: R.<x,y,z,w> = PolynomialRing(F, 4)
sage: z.macaulay_resultant([x^3, 5*y, w])
˓→needs sage.modules sage.rings.finite_rings
4

540

#␣

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> F = FiniteField(Integer(11))>>> R = PolynomialRing(F, Integer(4), names=( x , y , z , w ,)); (x, y, z,␣
˓→w,) = R._first_ngens(4)>>> z.macaulay_resultant([x**Integer(3), Integer(5)*y, w])␣˓→# needs sage.modules sage.rings.finite_rings
4

example when the denominator in the algorithm vanishes(in this case the resultant is the constant term of thequotient of char polynomials of numerator/denominator):sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: y.macaulay_resultant([x + z, z^2])
˓→needs sage.libs.pari sage.modules-1>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x ,˓→R._first_ngens(3)>>> y.macaulay_resultant([x + z, z**Integer(2)])˓→# needs sage.libs.pari sage.modules
-1

#␣

y ,

z ,)); (x, y, z,) =␣␣

When there are only 2 polynomials, the Macaulay resultant degenerates to the traditional resultant:sage: R.<x> = PolynomialRing(QQ, 1)
sage: f = x^2 + 1; g = x^5 + 1
sage: fh = f.homogenize()
sage: gh = g.homogenize()
sage: RH = fh.parent()
sage: f.resultant(g) == fh.macaulay_resultant(gh)˓→needs sage.modules
True

#␣

>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(1), names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(2) + Integer(1); g = x**Integer(5) + Integer(1)>>> fh = f.homogenize()>>> gh = g.homogenize()>>> RH = fh.parent()>>> f.resultant(g) == fh.macaulay_resultant(gh)#␣˓→needs sage.modules
True

map_coefficients(f, new_base_ring=None)
Returns the polynomial obtained by applying f to the non-zero coefficients of self.
If f is a sage.categories.map.Map, then the resulting polynomial will be defined over the codomainof f. Otherwise, the resulting polynomial will be over the same ring as self. Set new_base_ring tooverride this behaviour.
INPUT:• f – a callable that will be applied to the coefficients of self.
• new_base_ring (optional) – if given, the resulting polynomial will be defined over this ring.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

541

Polynomials, Release 10.4

sage: k.<a> = GF(9); R.<x,y> = k[]; f = x*a + 2*x^3*y*a + a
˓→needs sage.rings.finite_rings
sage: f.map_coefficients(lambda a: a + 1)
˓→needs sage.rings.finite_rings(-a + 1)*x^3*y + (a + 1)*x + (a + 1)

#␣#␣>>> from sage.all import *>>> k = GF(Integer(9), names=( a ,)); (a,) = k._first_ngens(1); R = k[ x, y ];˓→ (x, y,) = R._first_ngens(2);f = x*a + Integer(2)*x**Integer(3)*y*a + a ␣˓→# needs sage.rings.finite_rings>>> f.map_coefficients(lambda a: a + Integer(1))␣˓→# needs sage.rings.finite_rings(-a + 1)*x^3*y + (a + 1)*x + (a + 1)

Examples with different base ring:sage: # needs sage.rings.finite_rings
sage: R.<r> = GF(9); S.
 = GF(81)sage: h = Hom(R,S)[0]; hRing morphism:
From: Finite Field in r of size 3^2
To:
Finite Field in s of size 3^4
Defn: r |--> 2*s^3 + 2*s^2 + 1
sage: T.<X,Y> = R[]
sage: f = r*X + Y
sage: g = f.map_coefficients(h); g(-s^3 - s^2 + 1)*X + Y
sage: g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field in s of size 3^4sage: h = lambda x: x.trace()sage: g = f.map_coefficients(h); g
X - Ysage: g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field in r of size 3^2
sage: g = f.map_coefficients(h, new_base_ring=GF(3)); gX - Y
sage: g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field of size 3>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(9), names=( r ,)); (r,) = R._first_ngens(1); S =␣
˓→GF(Integer(81), names=( s ,)); (s,) = S._first_ngens(1)>>> h = Hom(R,S)[Integer(0)]; h
Ring morphism:
From: Finite Field in r of size 3^2
To:
Finite Field in s of size 3^4
Defn: r |--> 2*s^3 + 2*s^2 + 1>>> T = R[ X, Y ]; (X, Y,) = T._first_ngens(2)>>> f = r*X + Y>>> g = f.map_coefficients(h); g(-s^3 - s^2 + 1)*X + Y>>> g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field in s of size 3^4>>> h = lambda x: x.trace()>>> g = f.map_coefficients(h); g
X - Y(continues on next page)542

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field in r of size 3^2>>> g = f.map_coefficients(h, new_base_ring=GF(Integer(3))); g
X - Y>>> g.parent()
Multivariate Polynomial Ring in X, Y over Finite Field of size 3

newton_polytope()
Return the Newton polytope of this polynomial.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = 1 + x*y + x^3 + y^3
sage: P = f.newton_polytope(); P#␣˓→needs sage.geometry.polyhedron
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
sage: P.is_simple()#␣˓→needs sage.geometry.polyhedron
True>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(1) + x*y + x**Integer(3) + y**Integer(3)>>> P = f.newton_polytope(); P#␣˓→needs sage.geometry.polyhedron
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices>>> P.is_simple()#␣˓→needs sage.geometry.polyhedron
True

nth_root(n)Return a 𝑛-th root of this element.
If there is no such root, a ValueError is raised.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: a = 32 * (x*y + 1)^5 * (x+y+z)^5
sage: a.nth_root(5)2*x^2*y + 2*x*y^2 + 2*x*y*z + 2*x + 2*y + 2*z
sage: b = x + 2*y + 3*z
sage: b.nth_root(42)Traceback (most recent call last):...
ValueError: not a 42nd power
sage: R.<x,y> = QQ[]
sage: S.<z,t> = R[]
sage: T.<u,v> = S[]
sage: p = (1 + x*u + y + v) * (1 + z*t)
sage: (p**3).nth_root(3)(x*z*t + x)*u + (z*t + 1)*v + (y + 1)*z*t + y + 1
sage: (p**3).nth_root(3).parent() is p.parent()
True
sage: ((1+x+z+t)**2).nth_root(3)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

543

Polynomials, Release 10.4

(continued from previous page)

Traceback (most recent call last):...
ValueError: not a 3rd power>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> a = Integer(32) * (x*y + Integer(1))**Integer(5) * (x+y+z)**Integer(5)>>> a.nth_root(Integer(5))
2*x^2*y + 2*x*y^2 + 2*x*y*z + 2*x + 2*y + 2*z>>> b = x + Integer(2)*y + Integer(3)*z>>> b.nth_root(Integer(42))
Traceback (most recent call last):...
ValueError: not a 42nd power>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> S = R[ z, t ]; (z, t,) = S._first_ngens(2)>>> T = S[ u, v ]; (u, v,) = T._first_ngens(2)>>> p = (Integer(1) + x*u + y + v) * (Integer(1) + z*t)>>> (p**Integer(3)).nth_root(Integer(3))(x*z*t + x)*u + (z*t + 1)*v + (y + 1)*z*t + y + 1>>> (p**Integer(3)).nth_root(Integer(3)).parent() is p.parent()
True>>> ((Integer(1)+x+z+t)**Integer(2)).nth_root(Integer(3))
Traceback (most recent call last):...
ValueError: not a 3rd power

numerator()
Return a numerator of self, computed as self * self.denominator().
Note that some subclasses may implement its own numerator function.
Warning: This is not the numerator of the rational function defined by self, which would always beself since self is a polynomial.
EXAMPLES:First we compute the numerator of a polynomial with integer coefficients, which is of course self.
sage: R.<x, y> = ZZ[]
sage: f = x^3 + 17*x + y + 1
sage: f.numerator()x^3 + 17*x + y + 1
sage: f == f.numerator()
True>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) + Integer(17)*x + y + Integer(1)>>> f.numerator()x^3 + 17*x + y + 1>>> f == f.numerator()
True

544

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Next we compute the numerator of a polynomial over a number field.
sage: # needs sage.rings.number_field sage.symbolic
sage: R.<x,y> = NumberField(symbolic_expression(x^2+3),
sage: f = (1/17)*y^19 - (2/3)*x + 1/3; f
1/17*y^19 - 2/3*x + 1/3
sage: f.numerator()
3*y^19 - 34*x + 17
sage: f == f.numerator()
Falsea )[ x,y ]>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> R = NumberField(symbolic_expression(x**Integer(2)+Integer(3)), a )[ x,y˓→ ]; (x, y,) = R._first_ngens(2)>>> f = (Integer(1)/Integer(17))*y**Integer(19) - (Integer(2)/Integer(3))*x +␣˓→Integer(1)/Integer(3); f
1/17*y^19 - 2/3*x + 1/3>>> f.numerator()
3*y^19 - 34*x + 17>>> f == f.numerator()
False

We try to compute the numerator of a polynomial with coefficients in the finite field of 3 elements.
sage: K.<x,y,z> = GF(3)[ x, y, z ]sage: f = 2*x*z + 2*z^2 + 2*y + 1; f-x*z - z^2 - y + 1
sage: f.numerator()-x*z - z^2 - y + 1>>> from sage.all import *>>> K = GF(Integer(3))[ x, y, z ]; (x, y, z,) = K._first_ngens(3)>>> f = Integer(2)*x*z + Integer(2)*z**Integer(2) + Integer(2)*y + Integer(1);˓→ f-x*z - z^2 - y + 1>>> f.numerator()-x*z - z^2 - y + 1

We check that the computation the numerator and denominator are valid.
sage: # needs sage.rings.number_field sage.symbolic
sage: K = NumberField(symbolic_expression( x^3+2 ),sage: f = K.random_element()
sage: f.numerator() / f.denominator() == f
True
sage: R = RR[ x,y,z ]sage: f = R.random_element()
sage: f.numerator() / f.denominator() == f
True>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> K = NumberField(symbolic_expression( x^3+2 ),>>> f = K.random_element()>>> f.numerator() / f.denominator() == f
Truea )[ x ][ s,t ]a )[ x ][ s,t ](continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

545

Polynomials, Release 10.4

(continued from previous page)>>> R = RR[ x,y,z ]>>> f = R.random_element()>>> f.numerator() / f.denominator() == fTruepolynomial(var)
Let var be one of the variables of the parent of self. This returns self viewed as a univariate polynomial
in var over the polynomial ring generated by all the other variables of the parent.
EXAMPLES:
sage: R.<x,w,z> = QQ[]
sage: f = x^3 + 3*w*x + w^5 + (17*w^3)*x + z^5
sage: f.polynomial(x)x^3 + (17*w^3 + 3*w)*x + w^5 + z^5
sage: parent(f.polynomial(x))
Univariate Polynomial Ring in x
over Multivariate Polynomial Ring in w, z over Rational Field
sage: f.polynomial(w)w^5 + 17*x*w^3 + 3*x*w + z^5 + x^3
sage: f.polynomial(z)z^5 + w^5 + 17*x*w^3 + x^3 + 3*x*w
sage: R.<x,w,z,k> = ZZ[]
sage: f = x^3 + 3*w*x + w^5 + (17*w^3)*x + z^5 +x*w*z*k + 5
sage: f.polynomial(x)x^3 + (17*w^3 + w*z*k + 3*w)*x + w^5 + z^5 + 5
sage: f.polynomial(w)w^5 + 17*x*w^3 + (x*z*k + 3*x)*w + z^5 + x^3 + 5
sage: f.polynomial(z)z^5 + x*w*k*z + w^5 + 17*x*w^3 + x^3 + 3*x*w + 5
sage: f.polynomial(k)x*w*z*k + w^5 + z^5 + 17*x*w^3 + x^3 + 3*x*w + 5
sage: R.<x,y> = GF(5)[]sage: f = x^2 + x + y
sage: f.polynomial(x)x^2 + x + y
sage: f.polynomial(y)y + x^2 + x>>> from sage.all import *>>> R = QQ[ x, w, z ]; (x, w, z,) = R._first_ngens(3)>>> f = x**Integer(3) + Integer(3)*w*x + w**Integer(5) +␣˓→(Integer(17)*w**Integer(3))*x + z**Integer(5)>>> f.polynomial(x)x^3 + (17*w^3 + 3*w)*x + w^5 + z^5>>> parent(f.polynomial(x))
Univariate Polynomial Ring in x
over Multivariate Polynomial Ring in w, z over Rational Field>>> f.polynomial(w)w^5 + 17*x*w^3 + 3*x*w + z^5 + x^3>>> f.polynomial(z)z^5 + w^5 + 17*x*w^3 + x^3 + 3*x*w>>> R = ZZ[ x, w, z, k ]; (x, w, z, k,) = R._first_ngens(4)>>> f = x**Integer(3) + Integer(3)*w*x + w**Integer(5) +␣
(continues on next page)

546

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(Integer(17)*w**Integer(3))*x + z**Integer(5) +x*w*z*k + Integer(5)>>> f.polynomial(x)x^3 + (17*w^3 + w*z*k + 3*w)*x + w^5 + z^5 + 5>>> f.polynomial(w)w^5 + 17*x*w^3 + (x*z*k + 3*x)*w + z^5 + x^3 + 5>>> f.polynomial(z)z^5 + x*w*k*z + w^5 + 17*x*w^3 + x^3 + 3*x*w + 5>>> f.polynomial(k)x*w*z*k + w^5 + z^5 + 17*x*w^3 + x^3 + 3*x*w + 5>>> R = GF(Integer(5))[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + x + y>>> f.polynomial(x)x^2 + x + y>>> f.polynomial(y)y + x^2 + x˓→reduced_form(**kwds)
Return a reduced form of this polynomial.
The algorithm is from Stoll and Cremona’s “On the Reduction Theory of Binary Forms” [CS2003]. Thistakes a two variable homogeneous polynomial and finds a reduced form. This is a 𝑆𝐿(2, Z)-equivalent binary
form whose covariant in the upper half plane is in the fundamental domain. If the polynomial has multiple
roots, they are removed and the algorithm is applied to the portion without multiple roots.
This reduction should also minimize the sum of the squares of the coefficients, but this is not always the case.
By default the coefficient minimizing algorithm in [HS2018] is applied. The coefficients can be minimized
either with respect to the sum of their squares or the maximum of their global heights.
A portion of the algorithm uses Newton’s method to find a solution to a system of equations. If Newton’s
method fails to converge to a point in the upper half plane, the function will use the less precise 𝑧0 covariant
from the 𝑄0 form as defined on page 7 of [CS2003]. Additionally, if this polynomial has a root with multiplicity at least half the total degree of the polynomial, then we must also use the 𝑧0 covariant. See [CS2003]
for details.
Note that, if the covariant is within error_limit of the boundary but outside the fundamental domain,
our function will erroneously move it to within the fundamental domain, hence our conjugation will be off by
1. If you don’t want this to happen, decrease your error_limit and increase your precision.
Implemented by Rebecca Lauren Miller as part of GSOC 2016. Smallest coefficients added by Ben Hutz July
2018.
INPUT:
keywords:• prec – integer, sets the precision (default: 300)
• return_conjugation – boolean. Returns element of 𝑆𝐿(2, Z) (default: True)• error_limit – sets the error tolerance (default: 0.000001)• smallest_coeffs – (default: True), boolean, whether to find the model with smallest coefficients• norm_type – either norm or height . What type of norm to use for smallest coefficients• emb – (optional) embedding of based field into CC
OUTPUT:• a polynomial (reduced binary form)• a matrix (element of 𝑆𝐿(2, Z))
3.1. Multivariate Polynomials and Polynomial Rings

547

Polynomials, Release 10.4

Todo: When Newton’s Method doesn’t converge to a root in the upper half plane. Now we just return 𝑧0 .
It would be better to modify and find the unique root in the upper half plane.
EXAMPLES:
sage: R.<x,h> = PolynomialRing(QQ)
sage: f = 19*x^8 - 262*x^7*h + 1507*x^6*h^2 - 4784*x^5*h^3 + 9202*x^4*h^4\-10962*x^3*h^5 + 7844*x^2*h^6 - 3040*x*h^7 + 475*h^8
sage: f.reduced_form(prec=200, smallest_coeffs=False)#␣˓→needs sage.modules sage.rings.complex_interval_field(-x^8 - 2*x^7*h + 7*x^6*h^2 + 16*x^5*h^3 + 2*x^4*h^4 - 2*x^3*h^5 + 4*x^2*h^6 -␣
˓→5*h^8,[ 1 -2][ 1 -1])>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , h ,)); (x, h,) = R._first_ngens(2)>>> f = Integer(19)*x**Integer(8) - Integer(262)*x**Integer(7)*h +␣˓→Integer(1507)*x**Integer(6)*h**Integer(2) -␣˓→Integer(4784)*x**Integer(5)*h**Integer(3) +␣˓→Integer(9202)*x**Integer(4)*h**Integer(4)\-10962*x^3*h^5 + 7844*x^2*h^6 - 3040*x*h^7 + 475*h^8>>> f.reduced_form(prec=Integer(200), smallest_coeffs=False)␣˓→# needs sage.modules sage.rings.complex_interval_field(-x^8 - 2*x^7*h + 7*x^6*h^2 + 16*x^5*h^3 + 2*x^4*h^4 - 2*x^3*h^5 + 4*x^2*h^6 -␣
˓→5*h^8,<BLANKLINE>[ 1 -2][ 1 -1])

An example where the multiplicity is too high:sage: R.<x,y> = PolynomialRing(QQ)
sage: f = x^3 + 378666*x^2*y - 12444444*x*y^2 + 1234567890*y^3
sage: j = f * (x-545*y)^9
sage: j.reduced_form(prec=200, smallest_coeffs=False)
˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: cannot have a root with multiplicity >= 12/2>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) + Integer(378666)*x**Integer(2)*y -␣˓→Integer(12444444)*x*y**Integer(2) + Integer(1234567890)*y**Integer(3)>>> j = f * (x-Integer(545)*y)**Integer(9)>>> j.reduced_form(prec=Integer(200), smallest_coeffs=False)˓→# needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: cannot have a root with multiplicity >= 12/2

548

#␣

␣

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

An example where Newton’s Method does not find the right root:
sage: R.<x,y> = PolynomialRing(QQ)
sage: F = x^6 + 3*x^5*y - 8*x^4*y^2 - 2*x^3*y^3 - 44*x^2*y^4 - 8*x*y^5
sage: F.reduced_form(smallest_coeffs=False, prec=400)#␣˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ArithmeticError: Newton s method converged to z not in the upper half plane>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = x**Integer(6) + Integer(3)*x**Integer(5)*y -␣˓→Integer(8)*x**Integer(4)*y**Integer(2) -␣˓→Integer(2)*x**Integer(3)*y**Integer(3) -␣˓→Integer(44)*x**Integer(2)*y**Integer(4) - Integer(8)*x*y**Integer(5)>>> F.reduced_form(smallest_coeffs=False, prec=Integer(400))˓→# needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ArithmeticError: Newton s method converged to z not in the upper half plane␣An example with covariant on the boundary, therefore a non-unique form:
sage: R.<x,y> = PolynomialRing(QQ)
sage: F = 5*x^2*y - 5*x*y^2 - 30*y^3
sage: F.reduced_form(smallest_coeffs=False)
˓→needs sage.modules sage.rings.complex_interval_field([1 1]
5*x^2*y + 5*x*y^2 - 30*y^3, [0 1])#␣

>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = Integer(5)*x**Integer(2)*y - Integer(5)*x*y**Integer(2) -␣˓→Integer(30)*y**Integer(3)>>> F.reduced_form(smallest_coeffs=False)#␣˓→needs sage.modules sage.rings.complex_interval_field([1 1]
5*x^2*y + 5*x*y^2 - 30*y^3, [0 1])An example where precision needs to be increased:sage: R.<x,y> = PolynomialRing(QQ)
sage: F = (-16*x^7 - 114*x^6*y - 345*x^5*y^2 - 599*x^4*y^3....:- 666*x^3*y^4 - 481*x^2*y^5 - 207*x*y^6 - 40*y^7)
sage: F.reduced_form(prec=50, smallest_coeffs=False)#␣˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: accuracy of Newton s root not within tolerance(0.000012... > 1e˓→06),
increase precision
sage: F.reduced_form(prec=100, smallest_coeffs=False)#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

549

Polynomials, Release 10.4

(continued from previous page)needs sage.modules sage.rings.complex_interval_field˓→([-1 -1]-x^5*y^2 - 24*x^3*y^4 - 3*x^2*y^5 - 2*x*y^6 + 16*y^7, [ 1 0])>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = (-Integer(16)*x**Integer(7) - Integer(114)*x**Integer(6)*y -␣˓→Integer(345)*x**Integer(5)*y**Integer(2) -␣˓→Integer(599)*x**Integer(4)*y**Integer(3)...
- Integer(666)*x**Integer(3)*y**Integer(4) -␣˓→Integer(481)*x**Integer(2)*y**Integer(5) - Integer(207)*x*y**Integer(6) -␣˓→Integer(40)*y**Integer(7))>>> F.reduced_form(prec=Integer(50), smallest_coeffs=False)␣˓→# needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: accuracy of Newton s root not within tolerance(0.000012... > 1e˓→06),
increase precision>>> F.reduced_form(prec=Integer(100), smallest_coeffs=False)␣˓→# needs sage.modules sage.rings.complex_interval_field([-1 -1]-x^5*y^2 - 24*x^3*y^4 - 3*x^2*y^5 - 2*x*y^6 + 16*y^7, [ 1 0])
sage: R.<x,y> = PolynomialRing(QQ)
sage: F = - 8*x^4 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 -␣
˓→1825511633*y^4
sage: F.reduced_form(return_conjugation=False)
˓→needs sage.modules sage.rings.complex_interval_fieldx^4 + 9*x^3*y - 3*x*y^3 - 8*y^4#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = - Integer(8)*x**Integer(4) - Integer(3933)*x**Integer(3)*y -␣˓→Integer(725085)*x**Integer(2)*y**Integer(2) -␣˓→Integer(59411592)*x*y**Integer(3) - Integer(1825511633)*y**Integer(4)>>> F.reduced_form(return_conjugation=False)#␣˓→needs sage.modules sage.rings.complex_interval_fieldx^4 + 9*x^3*y - 3*x*y^3 - 8*y^4
sage: R.<x,y> = QQ[]
sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3
sage: F.reduced_form()
˓→needs sage.modules sage.rings.complex_interval_field([1 4]-2*x^3 - 22*x^2*y - 77*x*y^2 + 43*y^3, [0 1])#␣

>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)(continues on next page)

550

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> F = -Integer(2)*x**Integer(3) + Integer(2)*x**Integer(2)*y +␣˓→Integer(3)*x*y**Integer(2) + Integer(127)*y**Integer(3)>>> F.reduced_form()
˓→needs sage.modules sage.rings.complex_interval_field([1 4]-2*x^3 - 22*x^2*y - 77*x*y^2 + 43*y^3, [0 1])#␣sage: R.<x,y> = QQ[]
sage: F = -2*x^3 + 2*x^2*y + 3*x*y^2 + 127*y^3
sage: F.reduced_form(norm_type= height )˓→needs sage.modules sage.rings.complex_interval_field([5 4]-58*x^3 - 47*x^2*y + 52*x*y^2 + 43*y^3, [1 1])>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> F = -Integer(2)*x**Integer(3) + Integer(2)*x**Integer(2)*y +␣˓→Integer(3)*x*y**Integer(2) + Integer(127)*y**Integer(3)>>> F.reduced_form(norm_type= height )˓→needs sage.modules sage.rings.complex_interval_field([5 4]-58*x^3 - 47*x^2*y + 52*x*y^2 + 43*y^3, [1 1]
)

#␣

#␣

sage: R.<x,y,z> = PolynomialRing(QQ)
sage: F = x^4 + x^3*y*z + y^2*z
sage: F.reduced_form()
˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: (=x^3*y*z + x^4 + y^2*z) must have two variables#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> F = x**Integer(4) + x**Integer(3)*y*z + y**Integer(2)*z>>> F.reduced_form()#␣˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: (=x^3*y*z + x^4 + y^2*z) must have two variables
sage: R.<x,y> = PolynomialRing(ZZ)
sage: F = - 8*x^6 - 3933*x^3*y - 725085*x^2*y^2 - 59411592*x*y^3 - 99*y^6
sage: F.reduced_form(return_conjugation=False)
˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: (=-8*x^6 - 99*y^6 - 3933*x^3*y - 725085*x^2*y^2 59411592*x*y^3) must be homogeneous

3.1. Multivariate Polynomials and Polynomial Rings

#␣

551

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = - Integer(8)*x**Integer(6) - Integer(3933)*x**Integer(3)*y -␣˓→Integer(725085)*x**Integer(2)*y**Integer(2) -␣˓→Integer(59411592)*x*y**Integer(3) - Integer(99)*y**Integer(6)>>> F.reduced_form(return_conjugation=False)#␣˓→needs sage.modules sage.rings.complex_interval_field
Traceback (most recent call last):...
ValueError: (=-8*x^6 - 99*y^6 - 3933*x^3*y - 725085*x^2*y^2 59411592*x*y^3) must be homogeneous
sage: R.<x,y> = PolynomialRing(RR)
sage: F = (217.992172373276*x^3 + 96023.1505442490*x^2*y....:+ 1.40987971253579e7*x*y^2 + 6.90016027113216e8*y^3)
sage: F.reduced_form(smallest_coeffs=False) # tol 1e-8
˓→needs sage.modules sage.rings.complex_interval_field(-39.5673942565918*x^3 + 111.874026298523*x^2*y+ 231.052762985229*x*y^2 - 138.380829811096*y^3,#␣[-147 -148][
1
1])>>> from sage.all import *>>> R = PolynomialRing(RR, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> F = (RealNumber( 217.992172373276 )*x**Integer(3) + RealNumber( 96023.
˓→1505442490 )*x**Integer(2)*y...
+ RealNumber( 1.40987971253579e7 )*x*y**Integer(2) + RealNumber( 6.
˓→90016027113216e8 )*y**Integer(3))>>> F.reduced_form(smallest_coeffs=False) # tol 1e-8#␣˓→needs sage.modules sage.rings.complex_interval_field(-39.5673942565918*x^3 + 111.874026298523*x^2*y+ 231.052762985229*x*y^2 - 138.380829811096*y^3,<BLANKLINE>[-147 -148][
11])
sage: R.<x,y> = PolynomialRing(CC)#␣˓→needs sage.rings.real_mpfr
sage: F = ((0.759099196558145 + 0.845425869641446*CC.0)*x^3#␣
˓→needs sage.rings.real_mpfr....:+ (84.8317207268542 + 93.8840848648033*CC.0)*x^2*y....:+ (3159.07040755858 + 3475.33037377779*CC.0)*x*y^2....:+ (39202.5965389079 + 42882.5139724962*CC.0)*y^3)
sage: F.reduced_form(smallest_coeffs=False) # tol 1e-11#␣˓→needs sage.modules sage.rings.complex_interval_field sage.rings.real_mpfr((-0.759099196558145 - 0.845425869641446*I)*x^3+ (-0.571709908900118 - 0.0418133346027929*I)*x^2*y+ (0.856525964330103 - 0.0721403997649759*I)*x*y^2+ (-0.965531044130330 + 0.754252314465703*I)*y^3,(continues on next page)

552

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[-1 37][ 0 -1])>>> from sage.all import *>>> R = PolynomialRing(CC, names=( x , y ,)); (x, y,) = R._first_ngens(2)#␣
˓→needs sage.rings.real_mpfr>>> F = ((RealNumber( 0.759099196558145 ) + RealNumber( 0.845425869641446
˓→ )*CC.gen(0))*x**Integer(3)# needs sage.rings.real_mpfr...
+ (RealNumber( 84.8317207268542 ) + RealNumber( 93.8840848648033
˓→ )*CC.gen(0))*x**Integer(2)*y...
+ (RealNumber( 3159.07040755858 ) + RealNumber( 3475.33037377779
˓→ )*CC.gen(0))*x*y**Integer(2)...
+ (RealNumber( 39202.5965389079 ) + RealNumber( 42882.5139724962
˓→ )*CC.gen(0))*y**Integer(3))>>> F.reduced_form(smallest_coeffs=False) # tol 1e-11#␣˓→needs sage.modules sage.rings.complex_interval_field sage.rings.real_mpfr((-0.759099196558145 - 0.845425869641446*I)*x^3+ (-0.571709908900118 - 0.0418133346027929*I)*x^2*y+ (0.856525964330103 - 0.0721403997649759*I)*x*y^2+ (-0.965531044130330 + 0.754252314465703*I)*y^3,<BLANKLINE>[-1 37][ 0 -1])

specialization(D=None, phi=None)
Specialization of this polynomial.
Given a family of polynomials defined over a polynomial ring. A specialization is a particular member of thatfamily. The specialization can be specified either by a dictionary or a SpecializationMorphism.
INPUT:• D – dictionary (optional)• phi – SpecializationMorphism (optional)
OUTPUT: a new polynomial
EXAMPLES:
sage: R.<c> = PolynomialRing(QQ)
sage: S.<x,y> = PolynomialRing(R)sage: F = x^2 + c*y^2
sage: F.specialization({c:2})x^2 + 2*y^2>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( c ,)); (c,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x , y ,)); (x, y,) = S._first_ngens(2)>>> F = x**Integer(2) + c*y**Integer(2)>>> F.specialization({c:Integer(2)})
x^2 + 2*y^2

3.1. Multivariate Polynomials and Polynomial Rings

553

Polynomials, Release 10.4

sage: S.<a,b> = PolynomialRing(QQ)
sage: P.<x,y,z> = PolynomialRing(S)sage: RR.<c,d> = PolynomialRing(P)sage: f = a*x^2 + b*y^3 + c*y^2 - b*a*d + d^2 - a*c*b*z^2
sage: f.specialization({a:2, z:4, d:2})(y^2 - 32*b)*c + b*y^3 + 2*x^2 - 4*b + 4>>> from sage.all import *>>> S = PolynomialRing(QQ, names=( a , b ,)); (a, b,) = S._first_ngens(2)>>> P = PolynomialRing(S, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> RR = PolynomialRing(P, names=( c , d ,)); (c, d,) = RR._first_ngens(2)>>> f = a*x**Integer(2) + b*y**Integer(3) + c*y**Integer(2) - b*a*d +␣
˓→d**Integer(2) - a*c*b*z**Integer(2)>>> f.specialization({a:Integer(2), z:Integer(4), d:Integer(2)})(y^2 - 32*b)*c + b*y^3 + 2*x^2 - 4*b + 4

Check that we preserve multi- versus uni-variate:sage: R.<l> = PolynomialRing(QQ, 1)
sage: S.<k> = PolynomialRing(R)sage: K.<a, b, c> = PolynomialRing(S)sage: F = a*k^2 + b*l + c^2
sage: F.specialization({b:56, c:5}).parent()
Univariate Polynomial Ring in a over Univariate Polynomial Ring in kover Multivariate Polynomial Ring in l over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(1), names=( l ,)); (l,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( k ,)); (k,) = S._first_ngens(1)>>> K = PolynomialRing(S, names=( a , b , c ,)); (a, b, c,) = K._first_
˓→ngens(3)>>> F = a*k**Integer(2) + b*l + c**Integer(2)>>> F.specialization({b:Integer(56), c:Integer(5)}).parent()
Univariate Polynomial Ring in a over Univariate Polynomial Ring in kover Multivariate Polynomial Ring in l over Rational Field

subresultants(other, variable=None)
Return the nonzero subresultant polynomials of self and other.
INPUT:• other – a polynomial
OUTPUT: a list of polynomials in the same ring as self
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1)
sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1)
sage: p.subresultants(q, y)[2*x^6 - 22*x^5 + 102*x^4 - 274*x^3 + 488*x^2 - 552*x + 288,-x^3 - x^2*y + 6*x^2 + 5*x*y - 11*x - 6*y + 6]
sage: p.subresultants(q, x)[2*y^6 - 22*y^5 + 102*y^4 - 274*y^3 + 488*y^2 - 552*y + 288,
x*y^2 + y^3 - 5*x*y - 6*y^2 + 6*x + 11*y - 6]554

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> p = (y**Integer(2) + Integer(6))*(x - Integer(1)) - y*(x**Integer(2) +␣˓→Integer(1))>>> q = (x**Integer(2) + Integer(6))*(y - Integer(1)) - x*(y**Integer(2) +␣˓→Integer(1))>>> p.subresultants(q, y)[2*x^6 - 22*x^5 + 102*x^4 - 274*x^3 + 488*x^2 - 552*x + 288,-x^3 - x^2*y + 6*x^2 + 5*x*y - 11*x - 6*y + 6]>>> p.subresultants(q, x)[2*y^6 - 22*y^5 + 102*y^4 - 274*y^3 + 488*y^2 - 552*y + 288,
x*y^2 + y^3 - 5*x*y - 6*y^2 + 6*x + 11*y - 6]sylvester_matrix(right, variable=None)
Given two nonzero polynomials self and right, return the Sylvester matrix of the polynomials with respect
to a given variable.
Note that the Sylvester matrix is not defined if one of the polynomials is zero.
INPUT:• self, right – multivariate polynomials• variable – optional, compute the Sylvester matrix with respect to this variable. If variable is notprovided, the first variable of the polynomial ring is used.
OUTPUT:• The Sylvester matrix of self and right.
EXAMPLES:
sage: R.<x, y> = PolynomialRing(ZZ)
sage: f = (y + 1)*x + 3*x**2
sage: g = (y + 2)*x + 4*x**2
sage: M = f.sylvester_matrix(g, x)
˓→needs sage.modules
sage: M˓→needs sage.modules[
3 y + 100][
0
3 y + 10][
4 y + 200][
0
4 y + 20]#␣#␣>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = (y + Integer(1))*x + Integer(3)*x**Integer(2)>>> g = (y + Integer(2))*x + Integer(4)*x**Integer(2)>>> M = f.sylvester_matrix(g, x)#␣˓→needs sage.modules>>> M#␣˓→needs sage.modules[
3 y + 100][
0
3 y + 10][
4 y + 200][
0
4 y + 20]

If the polynomials share a non-constant common factor then the determinant of the Sylvester matrix will be
zero:

3.1. Multivariate Polynomials and Polynomial Rings

555

Polynomials, Release 10.4

sage: M.determinant()
˓→needs sage.modules0#␣

sage: f.sylvester_matrix(1 + g, x).determinant()
˓→needs sage.modulesy^2 - y + 7#␣>>> from sage.all import *>>> M.determinant()
˓→needs sage.modules0#␣>>> f.sylvester_matrix(Integer(1) + g, x).determinant()˓→# needs sage.modulesy^2 - y + 7

␣If both polynomials are of positive degree with respect to variable, the determinant of the Sylvester matrix
is the resultant:sage: f = R.random_element(4) or (x^2 * y^2)
sage: g = R.random_element(4) or (x^2 * y^2)
sage: f.sylvester_matrix(g, x).determinant() == f.resultant(g, x)
˓→needs sage.libs.singular sage.modules
True>>> from sage.all import *>>> f = R.random_element(Integer(4)) or (x**Integer(2) * y**Integer(2))>>> g = R.random_element(Integer(4)) or (x**Integer(2) * y**Integer(2))>>> f.sylvester_matrix(g, x).determinant() == f.resultant(g, x)
˓→needs sage.libs.singular sage.modules
True

#␣

#␣

truncate(var, n)
Returns a new multivariate polynomial obtained from self by deleting all terms that involve the given variable to a power at least n.
weighted_degree(*weights)
Return the weighted degree of self, which is the maximum weighted degree of all monomials in self;
the weighted degree of a monomial is the sum of all powers of the variables in the monomial, each power
multiplied with its respective weight in weights.
This method is given for convenience. It is faster to use polynomial rings with weighted term orders and thestandard degree function.
INPUT:• weights – Either individual numbers, an iterable or a dictionary, specifying the weights of each variable. If it is a dictionary, it maps each variable of self to its weight. If it is a sequence of individual numbers or a tuple, the weights are specified in the order of the generators as given by self.
parent().gens():
EXAMPLES:
sage: R.<x,y,z> = GF(7)[]sage: p = x^3 + y + x*z^2
sage: p.weighted_degree({z:0, x:1, y:2})(continues on next page)

556

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)3
sage: p.weighted_degree(1, 2, 0)
3sage: p.weighted_degree((1, 4, 2))5sage: p.weighted_degree((1, 4, 1))4
sage: p.weighted_degree(2**64, 2**50, 2**128)
680564733841876926945195958937245974528
sage: q = R.random_element(100, 20)
sage: q.weighted_degree(1, 1, 1) == q.total_degree()True>>> from sage.all import *>>> R = GF(Integer(7))[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> p = x**Integer(3) + y + x*z**Integer(2)>>> p.weighted_degree({z:Integer(0), x:Integer(1), y:Integer(2)})
3>>> p.weighted_degree(Integer(1), Integer(2), Integer(0))
3>>> p.weighted_degree((Integer(1), Integer(4), Integer(2)))
5>>> p.weighted_degree((Integer(1), Integer(4), Integer(1)))
4>>> p.weighted_degree(Integer(2)**Integer(64), Integer(2)**Integer(50),␣
˓→Integer(2)**Integer(128))
680564733841876926945195958937245974528>>> q = R.random_element(Integer(100), Integer(20))>>> q.weighted_degree(Integer(1), Integer(1), Integer(1)) == q.total_degree()True

You may also work with negative weights
sage: p.weighted_degree(-1, -2, -1)-2>>> from sage.all import *>>> p.weighted_degree(-Integer(1), -Integer(2), -Integer(1))-2Note that only integer weights are allowed
sage: p.weighted_degree(x, 1, 1)
Traceback (most recent call last):...
TypeError: unable to convert non-constant polynomial x to Integer Ringsage: p.weighted_degree(2/1, 1, 1)
6>>> from sage.all import *>>> p.weighted_degree(x, Integer(1), Integer(1))
Traceback (most recent call last):...
TypeError: unable to convert non-constant polynomial x to Integer Ring>>> p.weighted_degree(Integer(2)/Integer(1), Integer(1), Integer(1))
6

3.1. Multivariate Polynomials and Polynomial Rings

557

Polynomials, Release 10.4

The weighted_degree() coincides with the degree() of a weighted polynomial ring, but the latter
is faster.
sage: K = PolynomialRing(QQ, x,y , order=TermOrder( wdegrevlex , (2,3)))
sage: p = K.random_element(10)sage: p.degree() == p.weighted_degree(2,3)
True>>> from sage.all import *>>> K = PolynomialRing(QQ, x,y , order=TermOrder( wdegrevlex , (Integer(2),˓→Integer(3))))>>> p = K.random_element(Integer(10))>>> p.degree() == p.weighted_degree(Integer(2),Integer(3))
Trueclass sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular
Bases: MPolynomial
Abstract base class for MPolynomial_libsingularThis class is defined for the purpose of isinstance() tests. It should not be instantiated.
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingularsage: R1.<x> = QQ[]
sage: isinstance(x, MPolynomial_libsingular)
False
sage: R2.<y,z> = QQ[]
sage: isinstance(y, MPolynomial_libsingular)#␣˓→needs sage.libs.singularTrue>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial import MPolynomial_libsingular>>> R1 = QQ[ x ]; (x,) = R1._first_ngens(1)>>> isinstance(x, MPolynomial_libsingular)
False>>> R2 = QQ[ y, z ]; (y, z,) = R2._first_ngens(2)>>> isinstance(y, MPolynomial_libsingular)#␣˓→needs sage.libs.singularTrue

By design, there is a unique direct subclass:sage: len(sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular.__˓→subclasses__()) <= 1
True>>> from sage.all import *>>> len(sage.rings.polynomial.multi_polynomial.MPolynomial_libsingular.__˓→subclasses__()) <= Integer(1)Truesage.rings.polynomial.multi_polynomial.is_MPolynomial(x)558

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

3.1.4 Multivariate Polynomial Rings over Generic Rings
Sage implements multivariate polynomial rings through several backends. This generic implementation uses the classes
PolyDict and ETuple to construct a dictionary with exponent tuples as keys and coefficients as values.
AUTHORS:• David Joyner and William Stein• Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of Singular features• Martin Albrecht (2006-04-21): reorganize class hierarchy for singular rep• Martin Albrecht (2007-04-20): reorganized class hierarchy to support Pyrex implementations• Robert Bradshaw (2007-08-15): Coercions from rings in a subset of the variables.
EXAMPLES:
We construct the Frobenius morphism on F5 [𝑥, 𝑦, 𝑧] over F5 :sage: R.<x,y,z> = GF(5)[]sage: frob = R.hom([x^5, y^5, z^5])
sage: frob(x^2 + 2*y - z^4)-z^20 + x^10 + 2*y^5
sage: frob((x + 2*y)^3)
˓→needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15
sage: (x^5 + 2*y^5)^3
˓→needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15>>> from sage.all import *>>> R = GF(Integer(5))[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> frob = R.hom([x**Integer(5), y**Integer(5), z**Integer(5)])>>> frob(x**Integer(2) + Integer(2)*y - z**Integer(4))-z^20 + x^10 + 2*y^5>>> frob((x + Integer(2)*y)**Integer(3))˓→# needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15>>> (x**Integer(5) + Integer(2)*y**Integer(5))**Integer(3)˓→# needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15

#␣

#␣

␣

␣

We make a polynomial ring in one variable over a polynomial ring in two variables:sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: S.<t> = PowerSeriesRing(R)sage: t*(x+y)(x + y)*t>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> S = PowerSeriesRing(R, names=( t ,)); (t,) = S._first_ngens(1)>>> t*(x+y)(x + y)*t

class
sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_macaulay2_repr
Bases: object
3.1. Multivariate Polynomials and Polynomial Rings

559

Polynomials, Release 10.4

A mixin class for polynomial rings that support conversion to Macaulay2.
class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict(base_ring,n,names,
order)
Bases: MPolynomialRing_macaulay2_repr, PolynomialRing_singular_repr, MPolynomialRing_base
Multivariable polynomial ring.
EXAMPLES:
sage: R = PolynomialRing(Integers(12), x , 5); R
Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Ring of integers modulo 12
sage: loads(R.dumps()) == R
True>>> from sage.all import *>>> R = PolynomialRing(Integers(Integer(12)), x , Integer(5)); R
Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Ring of integers modulo 12>>> loads(R.dumps()) == R
True

Element_hidden
alias of MPolynomial_polydict
monomial_all_divisors(t)Return a list of all monomials that divide t, coefficients are ignored.
INPUT:• t – a monomial.
OUTPUT: a list of monomials.
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order= degrevlex )sage: P.monomial_all_divisors(x^2*z^3)[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(QQ,Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> P.monomial_all_divisors(x**Integer(2)*z**Integer(3))[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]

ALGORITHM: addwithcarry idea by Toon Segers
monomial_divides(a, b)
Return False if a does not divide b and True otherwise.
INPUT:

560

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• a – monomial• b – monomial
OUTPUT: Boolean
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(ZZ,3, order= degrevlex )sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
Truesage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
False>>> from sage.all import *>>> P = PolynomialRing(ZZ,Integer(3), order= degrevlex , names=( x , y ,˓→)); (x, y, z,) = P._first_ngens(3)>>> P.monomial_divides(x*y*z, x**Integer(3)*y**Integer(2)*z**Integer(4))
True>>> P.monomial_divides(x**Integer(3)*y**Integer(2)*z**Integer(4), x*y*z)
False

z ,

monomial_lcm(f, g)
LCM for monomials. Coefficients are ignored.
INPUT:• f – monomial.
• g – monomial.
OUTPUT: monomial.
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order= degrevlex )sage: P.monomial_lcm(3/2*x*y, x)x*y>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(QQ,Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> P.monomial_lcm(Integer(3)/Integer(2)*x*y, x)x*ymonomial_pairwise_prime(h, g)
Return True if h and g are pairwise prime.
Both are treated as monomials.
INPUT:• h – monomial.
• g – monomial.
OUTPUT: Boolean.
EXAMPLES:
3.1. Multivariate Polynomials and Polynomial Rings

561

Polynomials, Release 10.4

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ,3, order= degrevlex )sage: P.monomial_pairwise_prime(x^2*z^3, y^4)True>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(QQ,Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> P.monomial_pairwise_prime(x**Integer(2)*z**Integer(3), y**Integer(4))
Truesage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
False>>> from sage.all import *>>> P.monomial_pairwise_prime(Integer(1)/˓→Integer(2)*x**Integer(3)*y**Integer(2), Integer(3)/Integer(4)*y**Integer(3))
False

monomial_quotient(f, g, coeff=False)
Return f/g, where both f and g are treated as monomials.
Coefficients are ignored by default.
INPUT:• f – monomial.
• g – monomial.
• coeff – divide coefficients as well (default: False).
OUTPUT: monomial.
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z> = MPolynomialRing_polydict_domain(QQ, 3, order= degrevlex )sage: P.monomial_quotient(3/2*x*y, x)y>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(QQ, Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> P.monomial_quotient(Integer(3)/Integer(2)*x*y, x)ysage: P.monomial_quotient(3/2*x*y, 2*x, coeff=True)
3/4*y

562

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P.monomial_quotient(Integer(3)/Integer(2)*x*y, Integer(2)*x, coeff=True)
3/4*yNote: Assumes that the head term of f is a multiple of the head term of g and return the multiplicant m. If
this rule is violated, funny things may happen.
monomial_reduce(f, G)
Try to find a g in G where g.lm() divides f.
If found, (flt,g) is returned, (0,0) otherwise, where flt is f/g.lm(). It is assumed that G is iterable
and contains ONLY elements in this ring.
INPUT:• f – monomial• G – list/set of mpolynomials
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order= degrevlex )sage: f = x*y^2
sage: G = [3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, P(1/2)]
sage: P.monomial_reduce(f,G)(y, 1/4*x*y + 2/7)>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(QQ,Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> f = x*y**Integer(2)>>> G = [Integer(3)/Integer(2)*x**Integer(3) + y**Integer(2) + Integer(1)/˓→Integer(2), Integer(1)/Integer(4)*x*y + Integer(2)/Integer(7), P(Integer(1)/˓→Integer(2))]>>> P.monomial_reduce(f,G)(y, 1/4*x*y + 2/7)
sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain
sage: P.<x,y,z> = MPolynomialRing_polydict_domain(Zmod(23432),3, order=
˓→ degrevlex )sage: f = x*y^2
sage: G = [3*x^3 + y^2 + 2, 4*x*y + 7, P(2)]sage: P.monomial_reduce(f,G)(y, 4*x*y + 7)>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_
˓→polydict_domain>>> P = MPolynomialRing_polydict_domain(Zmod(Integer(23432)),Integer(3),␣
˓→order= degrevlex , names=( x ,y , z ,)); (x, y, z,) = P._first_ngens(3)>>> f = x*y**Integer(2)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

563

Polynomials, Release 10.4

(continued from previous page)>>> G = [Integer(3)*x**Integer(3) + y**Integer(2) + Integer(2),␣
˓→Integer(4)*x*y + Integer(7), P(Integer(2))]>>> P.monomial_reduce(f,G)(y, 4*x*y + 7)

sum(terms)
Return a sum of elements of this multipolynomial ring.
This is method is much faster than the Python builtin sum().
EXAMPLES:
sage: R = QQ[ x ]sage: S = R[ y, z ]sage: x = R.gen()sage: y, z = S.gens()
sage: S.sum([x*y, 2*x^2*z - 2*x*y, 1 + y + z])(-x + 1)*y + (2*x^2 + 1)*z + 1>>> from sage.all import *>>> R = QQ[ x ]>>> S = R[ y, z ]>>> x = R.gen()>>> y, z = S.gens()>>> S.sum([x*y, Integer(2)*x**Integer(2)*z - Integer(2)*x*y, Integer(1) + y +␣˓→z])(-x + 1)*y + (2*x^2 + 1)*z + 1

Comparison with builtin sum():
sage: sum([x*y, 2*x^2*z - 2*x*y, 1 + y + z])(-x + 1)*y + (2*x^2 + 1)*z + 1>>> from sage.all import *>>> sum([x*y, Integer(2)*x**Integer(2)*z - Integer(2)*x*y, Integer(1) + y +␣˓→z])(-x + 1)*y + (2*x^2 + 1)*z + 1

class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain(base_ring,n,names,
order)
Bases: IntegralDomain, MPolynomialRing_polydict
ideal(*gens, **kwds)
Create an ideal in this polynomial ring.
is_field(proof=True)
is_integral_domain(proof=True)

564

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

3.1.5 Generic Multivariate Polynomials
AUTHORS:• David Joyner: first version• William Stein: use dict’s instead of lists• Martin Albrecht malb@informatik.uni-bremen.de: some functions added• William Stein (2006-02-11): added better __div__ behavior.
• Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some Singular features• William Stein (2006-04-19): added e.g., f[1,3] to get coeff of 𝑥𝑦 3 ; added examples of the new R.x,y =PolynomialRing(QQ,2) notation.
• Martin Albrecht: improved singular coercions (restructured class hierarchy) and added ETuples• Robert Bradshaw (2007-08-14): added support for coercion of polynomials in a subset of variables (including
multi-level univariate rings)• Joel B. Mohler (2008-03): Refactored interactions with ETuples.
EXAMPLES:
We verify Lagrange’s four squares identity:
sage: R.<a0,a1,a2,a3,b0,b1,b2,b3> = QQbar[]
˓→needs sage.rings.number_fieldsage: ((a0^2 + a1^2 + a2^2 + a3^2) * (b0^2 + b1^2 + b2^2 + b3^2) ==˓→needs sage.rings.number_field....: (a0*b0 - a1*b1 - a2*b2 - a3*b3)^2 + (a0*b1 + a1*b0 + a2*b3 - a3*b2)^2....: + (a0*b2 - a1*b3 + a2*b0 + a3*b1)^2 + (a0*b3 + a1*b2 - a2*b1 + a3*b0)^2)
True

#␣
#␣

>>> from sage.all import *>>> R = QQbar[ a0, a1, a2, a3, b0, b1, b2, b3 ]; (a0, a1, a2, a3, b0, b1, b2, b3,) =␣
˓→R._first_ngens(8)# needs sage.rings.number_field>>> ((a0**Integer(2) + a1**Integer(2) + a2**Integer(2) + a3**Integer(2)) *␣˓→(b0**Integer(2) + b1**Integer(2) + b2**Integer(2) + b3**Integer(2)) ==␣˓→# needs sage.rings.number_field... (a0*b0 - a1*b1 - a2*b2 - a3*b3)**Integer(2) + (a0*b1 + a1*b0 + a2*b3 -␣
˓→a3*b2)**Integer(2)... + (a0*b2 - a1*b3 + a2*b0 + a3*b1)**Integer(2) + (a0*b3 + a1*b2 - a2*b1 +␣
˓→a3*b0)**Integer(2))
Trueclass sage.rings.polynomial.multi_polynomial_element.MPolynomial_element(parent,x)Bases: MPolynomial
Generic multivariate polynomial.
This implementation is based on the PolyDict.
Todo: As mentioned in their docstring, PolyDict objects never clear zeros. In all arithmetic operations on
MPolynomial_element there is an additional call to the method remove_zeros to clear them. This is not
ideal because of the presence of inexact zeros, see Issue #35174.

3.1. Multivariate Polynomials and Polynomial Rings

565

Polynomials, Release 10.4

element()
hamming_weight()
Return the number of non-zero coefficients of this polynomial.
This is also called weight, hamming_weight() or sparsity.
EXAMPLES:
sage: # needs sage.rings.real_mpfr
sage: R.<x, y> = CC[]
sage: f = x^3 - ysage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x+y)^100
sage: f.number_of_terms()
101>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = CC[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) - y>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x+y)**Integer(100)>>> f.number_of_terms()
101

The method hamming_weight() is an alias:
sage: f.hamming_weight()
˓→needs sage.rings.real_mpfr
101>>> from sage.all import *>>> f.hamming_weight()
˓→needs sage.rings.real_mpfr
101

#␣

#␣

number_of_terms()
Return the number of non-zero coefficients of this polynomial.
This is also called weight, hamming_weight() or sparsity.
EXAMPLES:
sage: # needs sage.rings.real_mpfr
sage: R.<x, y> = CC[]
sage: f = x^3 - ysage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x+y)^100(continues on next page)

566

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.number_of_terms()
101>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = CC[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) - y>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x+y)**Integer(100)>>> f.number_of_terms()
101

The method hamming_weight() is an alias:
sage: f.hamming_weight()
˓→needs sage.rings.real_mpfr
101>>> from sage.all import *>>> f.hamming_weight()
˓→needs sage.rings.real_mpfr
101

#␣

#␣

class sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict(parent,x)Bases: Polynomial_singular_repr, MPolynomial_element
Multivariate polynomials implemented in pure python using polydicts.
coefficient(degrees)
Return the coefficient of the variables with the degrees specified in the python dictionary degrees. Mathematically, this is the coefficient in the base ring adjoined by the variables of this ring not listed in degrees.
However, the result has the same parent as this polynomial.
This function contrasts with the function monomial_coefficient which returns the coefficient in thebase ring of a monomial.
INPUT:• degrees – Can be any of:– a dictionary of degree restrictions– a list of degree restrictions (with None in the unrestricted variables)– a monomial (very fast, but not as flexible)
OUTPUT: element of the parent of self
See also:
For coefficients of specific monomials, look at monomial_coefficient().
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

567

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: R.<x, y> = QQbar[]
sage: f = 2 * x * ysage: c = f.coefficient({x: 1, y: 1}); c2
sage: c.parent()
Multivariate Polynomial Ring in x, y over Algebraic Field
sage: c in PolynomialRing(QQbar, 2, names=[ x , y ])Truesage: f = y^2 - x^9 - 7*x + 5*x*y
sage: f.coefficient({y: 1})
5*x
sage: f.coefficient({y: 0})-x^9 + (-7)*x
sage: f.coefficient({x: 0, y: 0})0sage: f = (1+y+y^2) * (1+x+x^2)
sage: f.coefficient({x: 0})y^2 + y + 1
sage: f.coefficient([0, None])y^2 + y + 1
sage: f.coefficient(x)y^2 + y + 1
sage: # Be aware that this may not be what you think!
sage: # The physical appearance of the variable x is deceiving --␣
˓→particularly if the exponent would be a variable.
sage: f.coefficient(x^0) # outputs the full polynomialx^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(2) * x * y>>> c = f.coefficient({x: Integer(1), y: Integer(1)}); c2>>> c.parent()
Multivariate Polynomial Ring in x, y over Algebraic Field>>> c in PolynomialRing(QQbar, Integer(2), names=[ x , y ])True>>> f = y**Integer(2) - x**Integer(9) - Integer(7)*x + Integer(5)*x*y>>> f.coefficient({y: Integer(1)})
5*x>>> f.coefficient({y: Integer(0)})-x^9 + (-7)*x>>> f.coefficient({x: Integer(0), y: Integer(0)})
0>>> f = (Integer(1)+y+y**Integer(2)) * (Integer(1)+x+x**Integer(2))>>> f.coefficient({x: Integer(0)})
y^2 + y + 1>>> f.coefficient([Integer(0), None])y^2 + y + 1>>> f.coefficient(x)y^2 + y + 1>>> # Be aware that this may not be what you think!
>>> # The physical appearance of the variable x is deceiving -- particularly␣˓→if the exponent would be a variable.
>>> f.coefficient(x**Integer(0)) # outputs the full polynomial(continues on next page)

568

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1
sage: # needs sage.rings.real_mpfr
sage: R.<x,y> = RR[]
sage: f = x*y + 5
sage: c = f.coefficient({x: 0, y: 0}); c
5.00000000000000
sage: parent(c)Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> R = RR[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x*y + Integer(5)>>> c = f.coefficient({x: Integer(0), y: Integer(0)}); c
5.00000000000000>>> parent(c)Multivariate Polynomial Ring in x, y over Real Field with 53 bits of precision

AUTHORS:• Joel B. Mohler (2007-10-31)
constant_coefficient()
Return the constant coefficient of this multivariate polynomial.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.constant_coefficient()
5
sage: f = 3*x^2
sage: f.constant_coefficient()0>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.constant_coefficient()5>>> f = Integer(3)*x**Integer(2)>>> f.constant_coefficient()0

degree(x=None, std_grading=False)
Return the degree of self in x, where x must be one of the generators for the parent of self.
INPUT:• x – multivariate polynomial (a generator of the parent of self). If x is not specified (or is None),return the total degree, which is the maximum degree of any monomial. Note that a weighted termordering alters the grading of the generators of the ring; see the tests below. To avoid this behavior, set
the optional argument std_grading=True.
3.1. Multivariate Polynomials and Polynomial Rings

569

Polynomials, Release 10.4

OUTPUT: integer
EXAMPLES:
sage: R.<x,y> = RR[]
sage: f = y^2 - x^9 - x
sage: f.degree(x)9sage: f.degree(y)2sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x)3sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)10>>> from sage.all import *>>> R = RR[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = y**Integer(2) - x**Integer(9) - x>>> f.degree(x)9>>> f.degree(y)2>>> (y**Integer(10)*x - Integer(7)*x**Integer(2)*y**Integer(5) +␣˓→Integer(5)*x**Integer(3)).degree(x)3>>> (y**Integer(10)*x - Integer(7)*x**Integer(2)*y**Integer(5) +␣˓→Integer(5)*x**Integer(3)).degree(y)10Note that total degree takes into account if we are working in a polynomial ring with a weighted term order.
sage: R = PolynomialRing(QQ, x,y , order=TermOrder( wdeglex ,(2,3)))
sage: x,y = R.gens()
sage: x.degree()2
sage: y.degree()3
sage: x.degree(y), x.degree(x), y.degree(x), y.degree(y)(0, 1, 0, 1)
sage: f = x^2*y + x*y^2
sage: f.degree(x)2sage: f.degree(y)2sage: f.degree()8
sage: f.degree(std_grading=True)
3>>> from sage.all import *>>> R = PolynomialRing(QQ, x,y , order=TermOrder( wdeglex ,(Integer(2),˓→Integer(3))))>>> x,y = R.gens()>>> x.degree()2>>> y.degree()3>>> x.degree(y), x.degree(x), y.degree(x), y.degree(y)(continues on next page)

570

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(0, 1, 0, 1)>>> f = x**Integer(2)*y + x*y**Integer(2)>>> f.degree(x)2>>> f.degree(y)2>>> f.degree()8>>> f.degree(std_grading=True)
3

Note that if x is not a generator of the parent of self, for example if it is a generator of a polynomial algebra
which maps naturally to this one, then it is converted to an element of this algebra. (This fixes the problem
reported in Issue #17366.)
sage: x, y = ZZ[ x , y ].gens()
sage: GF(3037000453)[ x , y ].gen(0).degree(x)˓→needs sage.rings.finite_rings1
sage: x0, y0 = QQ[ x , y ].gens()
sage: GF(3037000453)[ x , y ].gen(0).degree(x0)˓→needs sage.rings.finite_rings
Traceback (most recent call last):...
TypeError: x must canonically coerce to parent
sage: GF(3037000453)[ x , y ].gen(0).degree(x^2)
˓→needs sage.rings.finite_rings
Traceback (most recent call last):...
TypeError: x must be one of the generators of the parent>>> from sage.all import *>>> x, y = ZZ[ x , y ].gens()>>> GF(Integer(3037000453))[ x , y ].gen(Integer(0)).degree(x)˓→# needs sage.rings.finite_rings
1>>> x0, y0 = QQ[ x , y ].gens()>>> GF(Integer(3037000453))[ x , y ].gen(Integer(0)).degree(x0)˓→# needs sage.rings.finite_rings
Traceback (most recent call last):...
TypeError: x must canonically coerce to parent>>> GF(Integer(3037000453))[ x , y ].gen(Integer(0)).degree(x**Integer(2))˓→# needs sage.rings.finite_rings
Traceback (most recent call last):...
TypeError: x must be one of the generators of the parent

#␣

#␣

#␣

␣

␣

␣

degrees()
Returns a tuple (precisely - an ETuple) with the degree of each variable in this polynomial. The list ofdegrees is, of course, ordered by the order of the generators.
EXAMPLES:
3.1. Multivariate Polynomials and Polynomial Rings

571

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: R.<x,y,z> = PolynomialRing(QQbar)
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.degrees()(2, 2, 0)
sage: f = x^2 + z^2
sage: f.degrees()(2, 0, 2)
sage: f.total_degree() # this simply illustrates that total degree is not␣˓→the sum of the degrees
2
sage: R.<x,y,z,u> = PolynomialRing(QQbar)
sage: f = (1-x) * (1+y+z+x^3)^5
sage: f.degrees()(16, 5, 5, 0)
sage: R(0).degrees()(0, 0, 0, 0)>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQbar, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.degrees()(2, 2, 0)>>> f = x**Integer(2) + z**Integer(2)>>> f.degrees()(2, 0, 2)>>> f.total_degree() # this simply illustrates that total degree is not the␣˓→sum of the degrees
2>>> R = PolynomialRing(QQbar, names=( x , y , z , u ,)); (x, y, z, u,) = R.
˓→_first_ngens(4)>>> f = (Integer(1)-x) * (Integer(1)+y+z+x**Integer(3))**Integer(5)>>> f.degrees()(16, 5, 5, 0)>>> R(Integer(0)).degrees()(0, 0, 0, 0)

dict()
Return underlying dictionary with keys the exponents and values the coefficients of this polynomial.
exponents(as_ETuples=True)
Return the exponents of the monomials appearing in self.
INPUT:• as_ETuples – (default: True): return the list of exponents as a list of ETuples
OUTPUT:
The list of exponents as a list of ETuples or tuples.
EXAMPLES:
sage: R.<a,b,c> = PolynomialRing(QQbar, 3)
˓→needs sage.rings.number_field#␣(continues on next page)

572

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = a^3 + b + 2*b^2˓→needs sage.rings.number_fieldsage: f.exponents()
˓→needs sage.rings.number_field[(3, 0, 0), (0, 2, 0), (0, 1, 0)]>>> from sage.all import *>>> R = PolynomialRing(QQbar, Integer(3), names=( a , b ,˓→= R._first_ngens(3)# needs sage.rings.number_field>>> f = a**Integer(3) + b + Integer(2)*b**Integer(2)˓→# needs sage.rings.number_field>>> f.exponents()
˓→needs sage.rings.number_field[(3, 0, 0), (0, 2, 0), (0, 1, 0)]#␣#␣c ,)); (a, b, c,)␣␣#␣

By default the list of exponents is a list of ETuples:sage: type(f.exponents()[0])˓→needs sage.rings.number_field<class sage.rings.polynomial.polydict.ETuple >sage: type(f.exponents(as_ETuples=False)[0])˓→needs sage.rings.number_field<... tuple >#␣#␣>>> from sage.all import *>>> type(f.exponents()[Integer(0)])˓→# needs sage.rings.number_field<class sage.rings.polynomial.polydict.ETuple >>>> type(f.exponents(as_ETuples=False)[Integer(0)])˓→# needs sage.rings.number_field<... tuple >␣␣factor(proof=None)
Compute the irreducible factorization of this polynomial.
INPUT:• proof – insist on provably correct results (default: True unless explicitly disabled for the "polynomial" subsystem with sage.structure.proof.proof.WithProof.)
global_height(prec=None)
Return the (projective) global height of the polynomial.
This returns the absolute logarithmic height of the coefficients thought of as a projective point.
INPUT:• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQbar, 2)
˓→needs sage.rings.number_fieldsage: f = QQbar(i)*x^2 + 3*x*y
˓→needs sage.rings.number_fieldsage: f.global_height()

#␣
#␣
#␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

573

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field
1.09861228866811
˓→>>> from sage.all import *>>> R = PolynomialRing(QQbar, Integer(2), names=( x ,˓→first_ngens(2)# needs sage.rings.number_field>>> f = QQbar(i)*x**Integer(2) + Integer(3)*x*y˓→# needs sage.rings.number_field>>> f.global_height()
˓→needs sage.rings.number_field
1.09861228866811y ,)); (x, y,) = R._␣#␣Scaling should not change the result:
sage: # needs sage.rings.number_field sage.symbolic
sage: R.<x, y> = PolynomialRing(QQbar, 2)
sage: f = 1/25*x^2 + 25/3*x + 1 + QQbar(sqrt(2))*y^2
sage: f.global_height()
6.43775164973640
sage: g = 100 * fsage: g.global_height()
6.43775164973640>>> from sage.all import *>>> # needs sage.rings.number_field sage.symbolic>>> R = PolynomialRing(QQbar, Integer(2), names=( x , y ,)); (x, y,) = R._
˓→first_ngens(2)>>> f = Integer(1)/Integer(25)*x**Integer(2) + Integer(25)/Integer(3)*x +␣˓→Integer(1) + QQbar(sqrt(Integer(2)))*y**Integer(2)>>> f.global_height()
6.43775164973640>>> g = Integer(100) * f>>> g.global_height()
6.43775164973640
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 + 1)
sage: Q.<q,r> = PolynomialRing(K, implementation= generic )sage: f = 12 * q
sage: f.global_height()
0.000000000000000>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) + Integer(1), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> Q = PolynomialRing(K, implementation= generic , names=( q , r ,)); (q, r,
˓→) = Q._first_ngens(2)>>> f = Integer(12) * q>>> f.global_height()
0.000000000000000

574

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 1/123*x*y + 12
sage: f.global_height(prec=2)
˓→needs sage.symbolic
8.0>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x ,˓→y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(123)*x*y + Integer(12)>>> f.global_height(prec=Integer(2))˓→# needs sage.symbolic
8.0#␣y ,)); (x,␣␣

sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 0*x*y
sage: f.global_height()
˓→needs sage.rings.real_mpfr
0.000000000000000>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x ,˓→y,) = R._first_ngens(2)>>> f = Integer(0)*x*y>>> f.global_height()
˓→needs sage.rings.real_mpfr
0.000000000000000#␣y ,)); (x,␣#␣

integral(var=None)
Integrate self with respect to variable var.
Note: The integral is always chosen so the constant term is 0.
If var is not one of the generators of this ring, integral(var) is called recursively on each coefficientof this polynomial.
EXAMPLES:
On polynomials with rational coefficients:
sage: x, y = PolynomialRing(QQ,
sage: ex = x*y + x - ysage: it = ex.integral(x); it
1/2*x^2*y + 1/2*x^2 - x*y
sage: it.parent() == x.parent()Truex, y ).gens()

sage: R = ZZ[ x ][ y, z ]sage: y, z = R.gens()
sage: R.an_element().integral(y).parent()
Multivariate Polynomial Ring in y, z
over Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> x, y = PolynomialRing(QQ,

x, y ).gens()(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

575

Polynomials, Release 10.4

(continued from previous page)>>> ex = x*y + x - y>>> it = ex.integral(x); it
1/2*x^2*y + 1/2*x^2 - x*y>>> it.parent() == x.parent()
True>>> R = ZZ[ x ][ y, z ]>>> y, z = R.gens()>>> R.an_element().integral(y).parent()
Multivariate Polynomial Ring in y, z
over Univariate Polynomial Ring in x over Rational Field

On polynomials with coefficients in power series:
sage: # needs sage.rings.number_fieldsage: R.<t> = PowerSeriesRing(QQbar)
sage: S.<x, y> = PolynomialRing(R)sage: f = (t^2 + O(t^3))*x^2*y^3 + (37*t^4 + O(t^5))*x^3
sage: f.parent()
Multivariate Polynomial Ring in x, yover Power Series Ring in t over Algebraic Field
sage: f.integral(x)# with respect to x
(1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4
sage: f.integral(x).parent()
Multivariate Polynomial Ring in x, yover Power Series Ring in t over Algebraic Field
sage: f.integral(y)# with respect to y
(1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*ysage: f.integral(t)# with respect to t (recurses into base ring)(1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PowerSeriesRing(QQbar, names=( t ,)); (t,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x , y ,)); (x, y,) = S._first_ngens(2)>>> f = (t**Integer(2) + O(t**Integer(3)))*x**Integer(2)*y**Integer(3) +␣˓→(Integer(37)*t**Integer(4) + O(t**Integer(5)))*x**Integer(3)>>> f.parent()
Multivariate Polynomial Ring in x, yover Power Series Ring in t over Algebraic Field>>> f.integral(x)# with respect to x
(1/3*t^2 + O(t^3))*x^3*y^3 + (37/4*t^4 + O(t^5))*x^4>>> f.integral(x).parent()
Multivariate Polynomial Ring in x, yover Power Series Ring in t over Algebraic Field>>> f.integral(y)# with respect to y
(1/4*t^2 + O(t^3))*x^2*y^4 + (37*t^4 + O(t^5))*x^3*y>>> f.integral(t)# with respect to t (recurses into base ring)(1/3*t^3 + O(t^4))*x^2*y^3 + (37/5*t^5 + O(t^6))*x^3

inverse_of_unit()
Return the inverse of a unit in a ring.
is_constant()
Return True if self is a constant and False otherwise.
EXAMPLES:
576

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.is_constant()
False
sage: g = 10*x^0sage: g.is_constant()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.is_constant()
False>>> g = Integer(10)*x**Integer(0)>>> g.is_constant()
True

is_generator()
Return True if self is a generator of its parent.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: x.is_generator()Truesage: (x + y - y).is_generator()Truesage: (x*y).is_generator()
False>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.is_generator()True>>> (x + y - y).is_generator()True>>> (x*y).is_generator()False

is_homogeneous()
Return True if self is a homogeneous polynomial.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: (x + y).is_homogeneous()
True
sage: (x.parent()(0)).is_homogeneous()
True
sage: (x + y^2).is_homogeneous()
False(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

577

Polynomials, Release 10.4

(continued from previous page)

sage: (x^2 + y^2).is_homogeneous()
True
sage: (x^2 + y^2*x).is_homogeneous()
False
sage: (x^2*y + y^2*x).is_homogeneous()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> (x + y).is_homogeneous()
True>>> (x.parent()(Integer(0))).is_homogeneous()
True>>> (x + y**Integer(2)).is_homogeneous()
False>>> (x**Integer(2) + y**Integer(2)).is_homogeneous()
True>>> (x**Integer(2) + y**Integer(2)*x).is_homogeneous()
False>>> (x**Integer(2)*y + y**Integer(2)*x).is_homogeneous()
True

is_monomial()
Return True if self is a monomial, which we define to be a product of generators with coefficient 1.
Use is_term() to allow the coefficient to not be 1.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: x.is_monomial()
True
sage: (x + 2*y).is_monomial()
False
sage: (2*x).is_monomial()
False
sage: (x*y).is_monomial()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.is_monomial()
True>>> (x + Integer(2)*y).is_monomial()
False>>> (Integer(2)*x).is_monomial()
False>>> (x*y).is_monomial()
True

To allow a non-1 leading coefficient, use is_term():

578

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: (2*x*y).is_term()
˓→needs sage.rings.number_fieldTrue
sage: (2*x*y).is_monomial()
˓→needs sage.rings.number_field
False>>> from sage.all import *>>> (Integer(2)*x*y).is_term()˓→# needs sage.rings.number_field
True>>> (Integer(2)*x*y).is_monomial()˓→# needs sage.rings.number_field
False

#␣

#␣

␣

␣

is_term()
Return True if self is a term, which we define to be a product of generators times some coefficient, which
need not be 1.
Use is_monomial() to require that the coefficient be 1.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: x.is_term()
Truesage: (x + 2*y).is_term()
False
sage: (2*x).is_term()
Truesage: (7*x^5*y).is_term()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.is_term()True>>> (x + Integer(2)*y).is_term()
False>>> (Integer(2)*x).is_term()True>>> (Integer(7)*x**Integer(5)*y).is_term()
True

To require leading coefficient 1, use is_monomial():sage: (2*x*y).is_monomial()
˓→needs sage.rings.number_field
False
sage: (2*x*y).is_term()
˓→needs sage.rings.number_field
True>>> from sage.all import *>>> (Integer(2)*x*y).is_monomial()

#␣

#␣

␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

579

Polynomials, Release 10.4

(continued from previous page)˓→# needs sage.rings.number_field

False>>> (Integer(2)*x*y).is_term()˓→# needs sage.rings.number_fieldTrue␣

is_univariate()
Return True if this multivariate polynomial is univariate and False otherwise.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.is_univariate()
False
sage: g = f.subs({x: 10}); g
700*y^2 + (-2)*y + 305
sage: g.is_univariate()Truesage: f = x^0
sage: f.is_univariate()
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.is_univariate()
False>>> g = f.subs({x: Integer(10)}); g
700*y^2 + (-2)*y + 305>>> g.is_univariate()
True>>> f = x**Integer(0)>>> f.is_univariate()
True

iterator_exp_coeff(as_ETuples=True)
Iterate over self as pairs of ((E)Tuple, coefficient).
INPUT:• as_ETuples – (default: True) if True iterate over pairs whose first element is an ETuple, otherwise
as a tuples
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQbar, order= lex )˓→needs sage.rings.number_fieldsage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3)
˓→needs sage.rings.number_fieldsage: list(f.iterator_exp_coeff())
˓→needs sage.rings.number_field[((4, 1, 3), 1), ((2, 0, 1), 1), ((1, 5, 2), 1)]

#␣
#␣
#␣

(continues on next page)

580

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: R.<x,y,z> = PolynomialRing(QQbar, order= deglex )˓→needs sage.rings.number_fieldsage: f = (x^1*y^5*z^2 + x^2*z + x^4*y^1*z^3)
˓→needs sage.rings.number_fieldsage: list(f.iterator_exp_coeff(as_ETuples=False))
˓→needs sage.rings.number_field[((4, 1, 3), 1), ((1, 5, 2), 1), ((2, 0, 1), 1)]

#␣
#␣
#␣

>>> from sage.all import *>>> R = PolynomialRing(QQbar, order= lex , names=( x , y , z ,)); (x, y, z,
˓→) = R._first_ngens(3)# needs sage.rings.number_field>>> f = (x**Integer(1)*y**Integer(5)*z**Integer(2) + x**Integer(2)*z +␣
˓→x**Integer(4)*y**Integer(1)*z**Integer(3))#␣˓→needs sage.rings.number_field>>> list(f.iterator_exp_coeff())#␣˓→needs sage.rings.number_field[((4, 1, 3), 1), ((2, 0, 1), 1), ((1, 5, 2), 1)]>>> R = PolynomialRing(QQbar, order= deglex , names=( x , y , z ,)); (x, y,␣
˓→z,) = R._first_ngens(3)# needs sage.rings.number_field>>> f = (x**Integer(1)*y**Integer(5)*z**Integer(2) + x**Integer(2)*z +␣
˓→x**Integer(4)*y**Integer(1)*z**Integer(3))#␣˓→needs sage.rings.number_field>>> list(f.iterator_exp_coeff(as_ETuples=False))#␣˓→needs sage.rings.number_field[((4, 1, 3), 1), ((1, 5, 2), 1), ((2, 0, 1), 1)]lc()
Returns the leading coefficient of self, i.e., self.coefficient(self.lm())
EXAMPLES:
sage: R.<x,y,z> = QQbar[]
˓→needs sage.rings.number_fieldsage: f = 3*x^2 - y^2 - x*y
˓→needs sage.rings.number_fieldsage: f.lc()
˓→needs sage.rings.number_field
3

#␣
#␣
#␣

>>> from sage.all import *>>> R = QQbar[ x, y, z ]; (x, y, z,) = R._first_ngens(3)# needs sage.rings.
˓→number_field>>> f = Integer(3)*x**Integer(2) - y**Integer(2) - x*y␣˓→# needs sage.rings.number_field>>> f.lc()#␣˓→needs sage.rings.number_field3

lift(I)
Given an ideal 𝐼 = (𝑓1 , ..., 𝑓𝑟 ) and some 𝑔 (= self) in 𝐼, find 𝑠1 , ..., 𝑠𝑟 such that 𝑔 = 𝑠1 𝑓1 + ... + 𝑠𝑟 𝑓𝑟 .
ALGORITHM: Use Singular.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

581

Polynomials, Release 10.4

sage: # needs sage.rings.real_mpfr
sage: A.<x,y> = PolynomialRing(CC, 2, order= degrevlex )sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7])
sage: f = x*y^13 + y^12
sage: M = f.lift(I); M#␣˓→needs sage.libs.singular[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]
sage: sum(map(mul, zip(M, I.gens()))) == f#␣˓→needs sage.libs.singularTrue>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> A = PolynomialRing(CC, Integer(2), order= degrevlex , names=( x , y ,));␣
˓→(x, y,) = A._first_ngens(2)>>> I = A.ideal([x**Integer(10) + x**Integer(9)*y**Integer(2), y**Integer(8) ˓→ x**Integer(2)*y**Integer(7)])>>> f = x*y**Integer(13) + y**Integer(12)>>> M = f.lift(I); M#␣˓→needs sage.libs.singular[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]>>> sum(map(mul, zip(M, I.gens()))) == f#␣˓→needs sage.libs.singular
True

lm()
Return the lead monomial of self with respect to the term order of self.parent().
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(GF(7), 3, order= lex )sage: (x^1*y^2 + y^3*z^4).lm()x*y^2
sage: (x^3*y^2*z^4 + x^3*y^2*z^1).lm()x^3*y^2*z^4>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(7)), Integer(3), order= lex , names=( x ,˓→ ,z ,)); (x, y, z,) = R._first_ngens(3)>>> (x**Integer(1)*y**Integer(2) + y**Integer(3)*z**Integer(4)).lm()x*y^2>>> (x**Integer(3)*y**Integer(2)*z**Integer(4) +␣˓→x**Integer(3)*y**Integer(2)*z**Integer(1)).lm()x^3*y^2*z^4ysage: # needs sage.rings.real_mpfr
sage: R.<x,y,z> = PolynomialRing(CC, 3, order= deglex )sage: (x^1*y^2*z^3 + x^3*y^2*z^0).lm()x*y^2*z^3
sage: (x^1*y^2*z^4 + x^1*y^1*z^5).lm()x*y^2*z^4>>> from sage.all import *>>> # needs sage.rings.real_mpfr(continues on next page)

582

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> R = PolynomialRing(CC, Integer(3), order= deglex , names=( x ,˓→)); (x, y, z,) = R._first_ngens(3)>>> (x**Integer(1)*y**Integer(2)*z**Integer(3) +␣˓→x**Integer(3)*y**Integer(2)*z**Integer(0)).lm()x*y^2*z^3>>> (x**Integer(1)*y**Integer(2)*z**Integer(4) +␣˓→x**Integer(1)*y**Integer(1)*z**Integer(5)).lm()x*y^2*z^4

y ,

z ,

sage: # needs sage.rings.number_fieldsage: R.<x,y,z> = PolynomialRing(QQbar, 3, order= degrevlex )sage: (x^1*y^5*z^2 + x^4*y^1*z^3).lm()x*y^5*z^2
sage: (x^4*y^7*z^1 + x^4*y^2*z^3).lm()x^4*y^7*z>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQbar, Integer(3), order= degrevlex , names=( x ,˓→ z ,)); (x, y, z,) = R._first_ngens(3)>>> (x**Integer(1)*y**Integer(5)*z**Integer(2) +␣˓→x**Integer(4)*y**Integer(1)*z**Integer(3)).lm()x*y^5*z^2>>> (x**Integer(4)*y**Integer(7)*z**Integer(1) +␣˓→x**Integer(4)*y**Integer(2)*z**Integer(3)).lm()x^4*y^7*z

y ,local_height(v, prec=None)
Return the maximum of the local height of the coefficients of this polynomial.
INPUT:• v – a prime or prime ideal of the base ring.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 1/1331*x^2 + 1/4000*ysage: f.local_height(1331)
˓→needs sage.rings.real_mpfr
7.19368581839511#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x , y ,)); (x,␣˓→y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(1331)*x**Integer(2) + Integer(1)/Integer(4000)*y>>> f.local_height(Integer(1331))␣˓→# needs sage.rings.real_mpfr
7.19368581839511
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

583

Polynomials, Release 10.4

(continued from previous page)

sage: K.<k> = NumberField(x^2 - 5)sage: T.<t,w> = PolynomialRing(K, implementation= generic )sage: I = K.ideal(3)sage: f = 1/3*t*w + 3
sage: f.local_height(I)˓→needs sage.symbolic
1.09861228866811#␣>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = PolynomialRing(K, implementation= generic , names=( t , w ,)); (t, w,
˓→) = T._first_ngens(2)>>> I = K.ideal(Integer(3))>>> f = Integer(1)/Integer(3)*t*w + Integer(3)>>> f.local_height(I)#␣˓→needs sage.symbolic
1.09861228866811
sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 1/2*x*y + 2
sage: f.local_height(2, prec=2)
˓→needs sage.rings.real_mpfr
0.75>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x ,˓→y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(2)*x*y + Integer(2)>>> f.local_height(Integer(2), prec=Integer(2))˓→# needs sage.rings.real_mpfr
0.75

#␣

y ,)); (x,␣␣

local_height_arch(i, prec=None)
Return the maximum of the local height at the i-th infinite place of the coefficients of this polynomial.
INPUT:• i – an integer.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 210*x*y
sage: f.local_height_arch(0)˓→needs sage.rings.real_mpfr
5.34710753071747>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x ,#␣y ,)); (x,␣(continues on next page)

584

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)y,) = R._first_ngens(2)>>> f = Integer(210)*x*y>>> f.local_height_arch(Integer(0))˓→# needs sage.rings.real_mpfr
5.34710753071747
˓→␣

sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 - 5)sage: T.<t,w> = PolynomialRing(K, implementation= generic )sage: f = 1/2*t*w + 3
sage: f.local_height_arch(1, prec=52)
1.09861228866811>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = PolynomialRing(K, implementation= generic , names=( t , w ,)); (t, w,
˓→) = T._first_ngens(2)>>> f = Integer(1)/Integer(2)*t*w + Integer(3)>>> f.local_height_arch(Integer(1), prec=Integer(52))
1.09861228866811
sage: R.<x,y> = PolynomialRing(QQ, implementation= generic )sage: f = 1/2*x*y + 3
sage: f.local_height_arch(0, prec=2)
˓→needs sage.rings.real_mpfr
1.0>>> from sage.all import *>>> R = PolynomialRing(QQ, implementation= generic , names=( x ,˓→y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(2)*x*y + Integer(3)>>> f.local_height_arch(Integer(0), prec=Integer(2))˓→# needs sage.rings.real_mpfr
1.0#␣y ,)); (x,␣␣lt()
Return the leading term of self i.e., self.lc()*self.lm(). The notion of “leading term” depends
on the ordering defined in the parent ring.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y,z> = PolynomialRing(QQbar)
sage: f = 3*x^2 - y^2 - x*y
sage: f.lt()
3*x^2
sage: R.<x,y,z> = PolynomialRing(QQbar, order="invlex")
sage: f = 3*x^2 - y^2 - x*y
sage: f.lt()-y^2

3.1. Multivariate Polynomials and Polynomial Rings

585

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = PolynomialRing(QQbar, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> f = Integer(3)*x**Integer(2) - y**Integer(2) - x*y>>> f.lt()
3*x^2>>> R = PolynomialRing(QQbar, order="invlex", names=( x , y , z ,)); (x, y,␣
˓→z,) = R._first_ngens(3)>>> f = Integer(3)*x**Integer(2) - y**Integer(2) - x*y>>> f.lt()-y^2monomial_coefficient(mon)Return the coefficient in the base ring of the monomial mon in self, where mon must have the same parent
as self.
This function contrasts with the function coefficient which returns the coefficient of a monomial viewing
this polynomial in a polynomial ring over a base ring having fewer variables.
INPUT:• mon – a monomial
OUTPUT: coefficient in base ring
See also:
For coefficients in a base ring of fewer variables, look at coefficient().
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 2 * x * ysage: c = f.monomial_coefficient(x*y); c2
sage: c.parent()
Algebraic Field>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(2) * x * y>>> c = f.monomial_coefficient(x*y); c
2>>> c.parent()
Algebraic Field
sage: # needs sage.rings.number_fieldsage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y
sage: f.monomial_coefficient(y^2)
1sage: f.monomial_coefficient(x*y)
5
sage: f.monomial_coefficient(x^9)-1sage: f.monomial_coefficient(x^10)0586

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.rings.number_field>>> f = y**Integer(2) + y**Integer(2)*x - x**Integer(9) - Integer(7)*x +␣˓→Integer(5)*x*y>>> f.monomial_coefficient(y**Integer(2))
1>>> f.monomial_coefficient(x*y)
5>>> f.monomial_coefficient(x**Integer(9))-1>>> f.monomial_coefficient(x**Integer(10))
0sage: # needs sage.rings.number_fieldsage: a = polygen(ZZ, a )sage: K.<a> = NumberField(a^2 + a + 1)
sage: P.<x,y> = K[]
sage: f = (a*x - 1) * ((a+1)*y - 1); f-x*y + (-a)*x + (-a - 1)*y + 1
sage: f.monomial_coefficient(x)-a>>> from sage.all import *>>> # needs sage.rings.number_field>>> a = polygen(ZZ, a )>>> K = NumberField(a**Integer(2) + a + Integer(1), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> P = K[ x, y ]; (x, y,) = P._first_ngens(2)>>> f = (a*x - Integer(1)) * ((a+Integer(1))*y - Integer(1)); f-x*y + (-a)*x + (-a - 1)*y + 1>>> f.monomial_coefficient(x)-amonomials()
Return the list of monomials in self. The returned list is decreasingly ordered by the term ordering ofself.parent().
OUTPUT: list of MPolynomial instances, representing monomials
EXAMPLES:
sage: R.<x,y> = QQbar[]
˓→needs sage.rings.number_fieldsage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
˓→needs sage.rings.number_fieldsage: f.monomials()
˓→needs sage.rings.number_field[x^2*y^2, x^2, y, 1]

#␣
#␣
#␣

>>> from sage.all import *>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)# needs sage.rings.number_
˓→field>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)␣˓→# needs sage.rings.number_field>>> f.monomials()#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

587

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.number_field[x^2*y^2, x^2, y, 1]˓→sage: # needs sage.rings.number_fieldsage: R.<fx,fy,gx,gy> = QQbar[]
sage: F = (fx*gy - fy*gx)^3; F-fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3sage: F.monomials()[fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3]
sage: F.coefficients()[-1, 3, -3, 1]
sage: sum(map(mul, zip(F.coefficients(), F.monomials()))) == F
True>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ fx, fy, gx, gy ]; (fx, fy, gx, gy,) = R._first_ngens(4)>>> F = (fx*gy - fy*gx)**Integer(3); F-fy^3*gx^3 + 3*fx*fy^2*gx^2*gy + (-3)*fx^2*fy*gx*gy^2 + fx^3*gy^3>>> F.monomials()[fy^3*gx^3, fx*fy^2*gx^2*gy, fx^2*fy*gx*gy^2, fx^3*gy^3]>>> F.coefficients()[-1, 3, -3, 1]>>> sum(map(mul, zip(F.coefficients(), F.monomials()))) == F
Truenvariables()Return the number of variables in this polynomial.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.nvariables()2sage: g = f.subs({x: 10}); g
700*y^2 + (-2)*y + 305
sage: g.nvariables()1>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.nvariables()2>>> g = f.subs({x: Integer(10)}); g
700*y^2 + (-2)*y + 305>>> g.nvariables()1

quo_rem(right)
Returns quotient and remainder of self and right.

588

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x,y> = CC[]˓→needs sage.rings.real_mpfr
sage: f = y*x^2 + x + 1
˓→needs sage.rings.real_mpfr
sage: f.quo_rem(x)˓→needs sage.libs.singular sage.rings.real_mpfr(x*y + 1.00000000000000, 1.00000000000000)

#␣
#␣
#␣

sage: R = QQ[ a , b ][ x , y , z ]sage: p1 = R( a + (1+2*b)*x*y + (3-a^2)*z )sage: p2 = R( x-1 )sage: p1.quo_rem(p2)˓→needs sage.libs.singular((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a)#␣sage: R.<x,y> = Qp(5)[]˓→needs sage.rings.padics
sage: x.quo_rem(y)˓→needs sage.libs.singular sage.rings.padics
Traceback (most recent call last):...
TypeError: no conversion of this ring to a Singular ring defined#␣#␣>>> from sage.all import *>>> R = CC[ x, y ]; (x, y,) = R._first_ngens(2)# needs sage.rings.real_mpfr>>> f = y*x**Integer(2) + x + Integer(1)␣˓→# needs sage.rings.real_mpfr>>> f.quo_rem(x)#␣˓→needs sage.libs.singular sage.rings.real_mpfr(x*y + 1.00000000000000, 1.00000000000000)>>> R = QQ[ a , b ][ x , y , z ]>>> p1 = R( a + (1+2*b)*x*y + (3-a^2)*z )>>> p2 = R( x-1 )>>> p1.quo_rem(p2)˓→needs sage.libs.singular((2*b + 1)*y, (2*b + 1)*y + (-a^2 + 3)*z + a)#␣>>> R = Qp(Integer(5))[ x, y ]; (x, y,) = R._first_ngens(2)# needs sage.rings.
˓→padics>>> x.quo_rem(y)#␣˓→needs sage.libs.singular sage.rings.padics
Traceback (most recent call last):...
TypeError: no conversion of this ring to a Singular ring defined

ALGORITHM: Use Singular.
reduce(I)
Reduce this polynomial by the polynomials in 𝐼.
INPUT:• I – a list of polynomials or an ideal
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

589

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: P.<x,y,z> = QQbar[]
sage: f1 = -2 * x^2 + x^3
sage: f2 = -2 * y + x * ysage: f3 = -x^2 + y^2
sage: F = Ideal([f1, f2, f3])
sage: g = x*y - 3*x*y^2
sage: g.reduce(F)˓→needs sage.libs.singular(-6)*y^2 + 2*ysage: g.reduce(F.gens())
˓→needs sage.libs.singular(-6)*y^2 + 2*y#␣#␣>>> from sage.all import *>>> # needs sage.rings.number_field>>> P = QQbar[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f1 = -Integer(2) * x**Integer(2) + x**Integer(3)>>> f2 = -Integer(2) * y + x * y>>> f3 = -x**Integer(2) + y**Integer(2)>>> F = Ideal([f1, f2, f3])>>> g = x*y - Integer(3)*x*y**Integer(2)>>> g.reduce(F)˓→needs sage.libs.singular(-6)*y^2 + 2*y>>> g.reduce(F.gens())
˓→needs sage.libs.singular(-6)*y^2 + 2*y#␣#␣

sage: f = 3*x
˓→needs sage.rings.number_fieldsage: f.reduce([2*x, y])˓→needs sage.rings.number_field
0

#␣
#␣

>>> from sage.all import *>>> f = Integer(3)*x˓→# needs sage.rings.number_field>>> f.reduce([Integer(2)*x, y])˓→# needs sage.rings.number_field0␣␣

sage: # needs sage.rings.number_fieldsage: k.<w> = CyclotomicField(3)sage: A.<y9,y12,y13,y15> = PolynomialRing(k)sage: J = [y9 + y12]sage: f = y9 - y12; f.reduce(J)-2*y12sage: f = y13*y15; f.reduce(J)y13*y15
sage: f = y13*y15 + y9 - y12; f.reduce(J)y13*y15 - 2*y12>>> from sage.all import *>>> # needs sage.rings.number_field>>> k = CyclotomicField(Integer(3), names=( w ,)); (w,) = k._first_ngens(1)(continues on next page)

590

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> A = PolynomialRing(k, names=( y9 , y12 ,˓→y15,) = A._first_ngens(4)>>> J = [y9 + y12]>>> f = y9 - y12; f.reduce(J)-2*y12>>> f = y13*y15; f.reduce(J)y13*y15>>> f = y13*y15 + y9 - y12; f.reduce(J)y13*y15 - 2*y12y13 ,y15 ,)); (y9, y12, y13,␣

Make sure the remainder returns the correct type, fixing Issue #13903:
sage: R.<y1,y2> = PolynomialRing(Qp(5), 2, order= lex )#␣˓→needs sage.rings.padics
sage: G = [y1^2 + y2^2, y1*y2 + y2^2, y2^3]#␣˓→needs sage.rings.padics
sage: type((y2^3).reduce(G))#␣˓→needs sage.rings.padics<class sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict >>>> from sage.all import *>>> R = PolynomialRing(Qp(Integer(5)), Integer(2), order= lex , names=( y1 ,˓→ y2 ,)); (y1, y2,) = R._first_ngens(2)# needs sage.rings.padics>>> G = [y1**Integer(2) + y2**Integer(2), y1*y2 + y2**Integer(2),␣
˓→y2**Integer(3)]# needs sage.rings.padics>>> type((y2**Integer(3)).reduce(G))␣˓→# needs sage.rings.padics<class sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict >resultant(other, variable=None)
Compute the resultant of self and other with respect to variable.
If a second argument is not provided, the first variable of self.parent() is chosen.
For inexact rings or rings not available in Singular, this computes the determinant of the Sylvester matrix.
INPUT:• other – polynomial in self.parent()• variable – (optional) variable (of type polynomial) in self.parent()
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ, 2)
sage: a = x + y
sage: b = x^3 - y^3sage: a.resultant(b)˓→needs sage.libs.singular-2*y^3sage: a.resultant(b, y)
˓→needs sage.libs.singular
2*x^3>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(2), names=( x ,˓→ngens(2)>>> a = x + y#␣#␣y ,)); (x, y,) = P._first_(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

591

Polynomials, Release 10.4

(continued from previous page)>>> b = x**Integer(3) - y**Integer(3)>>> a.resultant(b)˓→needs sage.libs.singular-2*y^3>>> a.resultant(b, y)
˓→needs sage.libs.singular
2*x^3

#␣

#␣

subresultants(other, variable=None)
Return the nonzero subresultant polynomials of self and other.
INPUT:• other – a polynomial
OUTPUT: a list of polynomials in the same ring as self
EXAMPLES:
sage: # needs sage.libs.singular sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: p = (y^2 + 6)*(x - 1) - y*(x^2 + 1)
sage: q = (x^2 + 6)*(y - 1) - x*(y^2 + 1)
sage: p.subresultants(q, y)[2*x^6 + (-22)*x^5 + 102*x^4 + (-274)*x^3 + 488*x^2 + (-552)*x + 288,-x^3 - x^2*y + 6*x^2 + 5*x*y + (-11)*x + (-6)*y + 6]
sage: p.subresultants(q, x)[2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288,
x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6]>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> p = (y**Integer(2) + Integer(6))*(x - Integer(1)) - y*(x**Integer(2) +␣˓→Integer(1))>>> q = (x**Integer(2) + Integer(6))*(y - Integer(1)) - x*(y**Integer(2) +␣˓→Integer(1))>>> p.subresultants(q, y)[2*x^6 + (-22)*x^5 + 102*x^4 + (-274)*x^3 + 488*x^2 + (-552)*x + 288,-x^3 - x^2*y + 6*x^2 + 5*x*y + (-11)*x + (-6)*y + 6]>>> p.subresultants(q, x)[2*y^6 + (-22)*y^5 + 102*y^4 + (-274)*y^3 + 488*y^2 + (-552)*y + 288,
x*y^2 + y^3 + (-5)*x*y + (-6)*y^2 + 6*x + 11*y - 6]

subs(fixed=None, **kwds)
Fix some given variables in a given multivariate polynomial and return the changed multivariate polynomials.
The polynomial itself is not affected. The variable, value pairs for fixing are to be provided as a dictionary of
the form {variable: value}.
This is a special case of evaluating the polynomial with some of the variables constants and the others theoriginal variables.
INPUT:• fixed – (optional) dictionary of inputs• **kwds – named parameters
OUTPUT: new MPolynomial

592

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = x^2 + y + x^2*y^2 + 5
sage: f((5, y))25*y^2 + y + 30
sage: f.subs({x: 5})25*y^2 + y + 30>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + y + x**Integer(2)*y**Integer(2) + Integer(5)>>> f((Integer(5), y))25*y^2 + y + 30>>> f.subs({x: Integer(5)})
25*y^2 + y + 30

total_degree()Return the total degree of self, which is the maximum degree of any monomial in self.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y,z> = QQbar[]
sage: f = 2*x*y^3*z^2sage: f.total_degree()6
sage: f = 4*x^2*y^2*z^3sage: f.total_degree()7
sage: f = 99*x^6*y^3*z^9sage: f.total_degree()18
sage: f = x*y^3*z^6 + 3*x^2
sage: f.total_degree()10
sage: f = z^3 + 8*x^4*y^5*z
sage: f.total_degree()10
sage: f = z^9 + 10*x^4 + y^8*x^2
sage: f.total_degree()10>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> f = Integer(2)*x*y**Integer(3)*z**Integer(2)>>> f.total_degree()6>>> f = Integer(4)*x**Integer(2)*y**Integer(2)*z**Integer(3)>>> f.total_degree()7>>> f = Integer(99)*x**Integer(6)*y**Integer(3)*z**Integer(9)>>> f.total_degree()18(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

593

Polynomials, Release 10.4

(continued from previous page)>>> f = x*y**Integer(3)*z**Integer(6) + Integer(3)*x**Integer(2)>>> f.total_degree()10>>> f = z**Integer(3) + Integer(8)*x**Integer(4)*y**Integer(5)*z>>> f.total_degree()10>>> f = z**Integer(9) + Integer(10)*x**Integer(4) +␣˓→y**Integer(8)*x**Integer(2)>>> f.total_degree()10

univariate_polynomial(R=None)
Returns a univariate polynomial associated to this multivariate polynomial.
INPUT:• R – (default: None) PolynomialRing
If this polynomial is not in at most one variable, then a ValueError exception is raised. This is checkedusing the method is_univariate(). The new Polynomial is over the same base ring as the given
MPolynomial.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.univariate_polynomial()
Traceback (most recent call last):...
TypeError: polynomial must involve at most one variable
sage: g = f.subs({x: 10}); g
700*y^2 + (-2)*y + 305
sage: g.univariate_polynomial()
700*y^2 - 2*y + 305
sage: g.univariate_polynomial(PolynomialRing(QQ, z ))700*z^2 - 2*z + 305>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.univariate_polynomial()
Traceback (most recent call last):...
TypeError: polynomial must involve at most one variable>>> g = f.subs({x: Integer(10)}); g
700*y^2 + (-2)*y + 305>>> g.univariate_polynomial()
700*y^2 - 2*y + 305>>> g.univariate_polynomial(PolynomialRing(QQ, z ))700*z^2 - 2*z + 305

variable(i)Return the 𝑖-th variable occurring in this polynomial.
EXAMPLES:
594

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.variable(0)xsage: f.variable(1)y>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.variable(Integer(0))
x>>> f.variable(Integer(1))
yvariables()Returns the tuple of variables occurring in this polynomial.
EXAMPLES:
sage: # needs sage.rings.number_fieldsage: R.<x,y> = QQbar[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.variables()(x, y)
sage: g = f.subs({x: 10}); g
700*y^2 + (-2)*y + 305
sage: g.variables()(y,)>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQbar[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.variables()(x, y)>>> g = f.subs({x: Integer(10)}); g
700*y^2 + (-2)*y + 305>>> g.variables()(y,)

sage.rings.polynomial.multi_polynomial_element.degree_lowest_rational_function(r,x)
Return the difference of valuations of r with respect to variable x.
INPUT:• r – a multivariate rational function• x – a multivariate polynomial ring generator
OUTPUT: integer – the difference 𝑣𝑎𝑙𝑥 (𝑝) − 𝑣𝑎𝑙𝑥 (𝑞) where 𝑟 = 𝑝/𝑞

3.1. Multivariate Polynomials and Polynomial Rings

595

Polynomials, Release 10.4

Note: This function should be made a method of the FractionFieldElement class.
EXAMPLES:
sage: R1 = PolynomialRing(FiniteField(5), 3, names=["a", "b", "c"])sage: F = FractionField(R1)sage: a,b,c = R1.gens()
sage: f = 3*a*b^2*c^3 + 4*a*b*c
sage: g = a^2*b*c^2 + 2*a^2*b^4*c^7>>> from sage.all import *>>> R1 = PolynomialRing(FiniteField(Integer(5)), Integer(3), names=["a", "b", "c˓→"])>>> F = FractionField(R1)>>> a,b,c = R1.gens()>>> f = Integer(3)*a*b**Integer(2)*c**Integer(3) + Integer(4)*a*b*c>>> g = a**Integer(2)*b*c**Integer(2) +␣˓→Integer(2)*a**Integer(2)*b**Integer(4)*c**Integer(7)24+3𝑏𝑐Consider the quotient 𝑓 /𝑔 = 𝑎𝑐+2𝑎𝑏
3 𝑐6 (note the cancellation).

sage: # needs sage.rings.finite_rings
sage: r = f/g; r(-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c)
sage: degree_lowest_rational_function(r, a)-1
sage: degree_lowest_rational_function(r, b)
0
sage: degree_lowest_rational_function(r, c)-1>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> r = f/g; r(-2*b*c^2 - 1)/(2*a*b^3*c^6 + a*c)>>> degree_lowest_rational_function(r, a)-1>>> degree_lowest_rational_function(r, b)0>>> degree_lowest_rational_function(r, c)-1

3.1.6 Ideals in multivariate polynomial rings
Sage has a powerful system to compute with multivariate polynomial rings. Most algorithms dealing with these ideals are
centered on the computation of Groebner bases. Sage mainly uses Singular to implement this functionality. Singular is
widely regarded as the best open-source system for Groebner basis calculation in multivariate polynomial rings over fields.
EXAMPLES:
We compute a Groebner basis for some given ideal. The type returned by the groebner_basis method is PolynomialSequence, i.e., it is not a MPolynomialIdeal:

596

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: x,y,z = QQ[ x,y,z ].gens()
sage: I = ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)sage: B = I.groebner_basis()
sage: type(B)<class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic >>>> from sage.all import *>>> x,y,z = QQ[ x,y,z ].gens()>>> I = ideal(x**Integer(5) + y**Integer(4) + z**Integer(3) - Integer(1), ␣
˓→x**Integer(3) + y**Integer(3) + z**Integer(2) - Integer(1))>>> B = I.groebner_basis()>>> type(B)<class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic >Groebner bases can be used to solve the ideal membership problem:
sage: f,g,h = B
sage: (2*x*f + g).reduce(B)0sage: (2*x*f + g) in I
True
sage: (2*x*f + 2*z*h + y^3).reduce(B)y^3
sage: (2*x*f + 2*z*h + y^3) in I
False>>> from sage.all import *>>> f,g,h = B>>> (Integer(2)*x*f + g).reduce(B)0>>> (Integer(2)*x*f + g) in I
True>>> (Integer(2)*x*f + Integer(2)*z*h + y**Integer(3)).reduce(B)y^3>>> (Integer(2)*x*f + Integer(2)*z*h + y**Integer(3)) in I
False

We compute a Groebner basis for Cyclic 6, which is a standard benchmark and test ideal.
sage: R.<x,y,z,t,u,v> = QQ[ x,y,z,t,u,v ]sage: I = sage.rings.ideal.Cyclic(R,6)
sage: B = I.groebner_basis()
sage: len(B)45>>> from sage.all import *>>> R = QQ[ x,y,z,t,u,v ]; (x, y, z, t, u, v,) = R._first_ngens(6)>>> I = sage.rings.ideal.Cyclic(R,Integer(6))>>> B = I.groebner_basis()>>> len(B)45

3.1. Multivariate Polynomials and Polynomial Rings

597

Polynomials, Release 10.4

We compute in a quotient of a polynomial ring over Z/17Z:
sage: R.<x,y> = ZZ[]
sage: S.<a,b> = R.quotient((x^2 + y^2, 17))
sage: S
Quotient of Multivariate Polynomial Ring in x, y over Integer Ringby the ideal (x^2 + y^2, 17)
sage: a^2 + b^2 == 0
True
sage: a^3 - b^2-a*b^2 - b^2>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> S = R.quotient((x**Integer(2) + y**Integer(2), Integer(17)), names=( a ,˓→(a, b,) = S._first_ngens(2)>>> S
Quotient of Multivariate Polynomial Ring in x, y over Integer Ringby the ideal (x^2 + y^2, 17)b ,));␣

>>> a**Integer(2) + b**Integer(2) == Integer(0)True>>> a**Integer(3) - b**Integer(2)-a*b^2 - b^2

Note that the result of a computation is not necessarily reduced:
sage: (a+b)^17
a*b^16 + b^17
sage: S(17) == 0
True>>> from sage.all import *>>> (a+b)**Integer(17)a*b^16 + b^17>>> S(Integer(17)) == Integer(0)True

Or we can work with Z/17Z directly:
sage: R.<x,y> = Zmod(17)[]
sage: S.<a,b> = R.quotient((x^2 + y^2,))sage: S
Quotient of Multivariate Polynomial Ring in x, y over Ring ofintegers modulo 17 by the ideal (x^2 + y^2)
sage: a^2 + b^2 == 0
True
sage: a^3 - b^2 == -a*b^2 - b^2 == 16*a*b^2 + 16*b^2
True
sage: (a+b)^17
a*b^16 + b^17
sage: S(17) == 0
True

598

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = Zmod(Integer(17))[ x, y ]; (x, y,) = R._first_ngens(2)>>> S = R.quotient((x**Integer(2) + y**Integer(2),), names=( a ,˓→first_ngens(2)>>> S
Quotient of Multivariate Polynomial Ring in x, y over Ring ofintegers modulo 17 by the ideal (x^2 + y^2)b ,)); (a, b,) = S._>>> a**Integer(2) + b**Integer(2) == Integer(0)True>>> a**Integer(3) - b**Integer(2) == -a*b**Integer(2) - b**Integer(2) ==␣
˓→Integer(16)*a*b**Integer(2) + Integer(16)*b**Integer(2)True>>> (a+b)**Integer(17)a*b^16 + b^17>>> S(Integer(17)) == Integer(0)TrueWorking with a polynomial ring over Z:
sage: R.<x,y,z,w> = ZZ[]
sage: I = ideal(x^2 + y^2 - z^2 - w^2, x-y)
sage: J = I^2
sage: J.groebner_basis()[4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4,
2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2,x^2 - 2*x*y + y^2]
sage: y^2 - 2*x*y + x^2 in J
True
sage: 0 in J
True>>> from sage.all import *>>> R = ZZ[ x, y, z, w ]; (x, y, z, w,) = R._first_ngens(4)>>> I = ideal(x**Integer(2) + y**Integer(2) - z**Integer(2) - w**Integer(2), x-y)>>> J = I**Integer(2)>>> J.groebner_basis()[4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4,
2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2,x^2 - 2*x*y + y^2]>>> y**Integer(2) - Integer(2)*x*y + x**Integer(2) in J
True>>> Integer(0) in J
True

We do a Groebner basis computation over a number field:
sage: K.<zeta> = CyclotomicField(3)sage: R.<x,y,z> = K[]; RMultivariate Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2
sage: i = ideal(x - zeta*y + 1, x^3 - zeta*y^3); i
Ideal (x + (-zeta)*y + 1, x^3 + (-zeta)*y^3) of Multivariate
Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

599

Polynomials, Release 10.4

(continued from previous page)

sage: i.groebner_basis()[y^3 + (2*zeta + 1)*y^2 + (zeta - 1)*y + (-1/3*zeta - 2/3), x + (-zeta)*y + 1]
sage: S = R.quotient(i); S
Quotient of Multivariate Polynomial Ring in x, y, z over
Cyclotomic Field of order 3 and degree 2 by the ideal (x +(-zeta)*y + 1, x^3 + (-zeta)*y^3)
sage: S.0 - zeta*S.1-1
sage: S.0^3 - zeta*S.1^30>>> from sage.all import *>>> K = CyclotomicField(Integer(3), names=( zeta ,)); (zeta,) = K._first_ngens(1)>>> R = K[ x, y, z ]; (x, y, z,) = R._first_ngens(3); R
Multivariate Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2>>> i = ideal(x - zeta*y + Integer(1), x**Integer(3) - zeta*y**Integer(3)); i
Ideal (x + (-zeta)*y + 1, x^3 + (-zeta)*y^3) of Multivariate
Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2>>> i.groebner_basis()[y^3 + (2*zeta + 1)*y^2 + (zeta - 1)*y + (-1/3*zeta - 2/3), x + (-zeta)*y + 1]>>> S = R.quotient(i); S
Quotient of Multivariate Polynomial Ring in x, y, z over
Cyclotomic Field of order 3 and degree 2 by the ideal (x +(-zeta)*y + 1, x^3 + (-zeta)*y^3)>>> S.gen(0) - zeta*S.gen(1)-1>>> S.gen(0)**Integer(3) - zeta*S.gen(1)**Integer(3)0Two examples from the Mathematica documentation (done in Sage):
We compute a Groebner basis:sage: R.<x,y> = PolynomialRing(QQ, order= lex )sage: ideal(x^2 - 2*y^2, x*y - 3).groebner_basis()[x - 2/3*y^3, y^4 - 9/2]>>> from sage.all import *>>> R = PolynomialRing(QQ, order= lex , names=( x , y ,)); (x, y,) = R._
˓→first_ngens(2)>>> ideal(x**Integer(2) - Integer(2)*y**Integer(2), x*y - Integer(3)).
˓→groebner_basis()[x - 2/3*y^3, y^4 - 9/2]

We show that three polynomials have no common root:
sage: R.<x,y> = QQ[]
sage: ideal(x+y, x^2 - 1, y^2 - 2*x).groebner_basis()
[1]

600

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> ideal(x+y, x**Integer(2) - Integer(1), y**Integer(2) - Integer(2)*x).
˓→groebner_basis()[1]

The next example shows how we can use Groebner bases over Z to find the primes modulo which a system of equations
has a solution, when the system has no solutions over the rationals.
We first form a certain ideal 𝐼 in Z[𝑥, 𝑦, 𝑧], and note that the Groebner basis of 𝐼 over contains 1, so
there are no solutions over or an algebraic closure of it (this is not surprising as there are 4 equations in 3
unknowns).
sage: P.<x,y,z> = PolynomialRing(ZZ,order= lex )sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1,....:
x*z + y*z + z^2, -3*x*y + 2*y*z + 6*z^2)
sage: I.change_ring(P.change_ring(QQ)).groebner_basis()[1]>>> from sage.all import *>>> P = PolynomialRing(ZZ,order= lex , names=( x , y , z ,)); (x, y, z,) =␣
˓→P._first_ngens(3)>>> I = ideal(-y**Integer(2) - Integer(3)*y + z**Integer(2) + Integer(3), ˓→Integer(2)*y*z + z**Integer(2) + Integer(2)*z + Integer(1),...
x*z + y*z + z**Integer(2), -Integer(3)*x*y + Integer(2)*y*z +␣˓→Integer(6)*z**Integer(2))>>> I.change_ring(P.change_ring(QQ)).groebner_basis()[1]

However, when we compute the Groebner basis of 𝐼 (defined over Z), we note that there is a certain integer
in the ideal which is not 1.
sage: I.groebner_basis()[x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ...,
2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]>>> from sage.all import *>>> I.groebner_basis()[x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ...,
2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]

Now for each prime 𝑝 dividing this integer 164878, the Groebner basis of 𝐼 modulo 𝑝 will be non-trivial andwill thus give a solution of the original system modulo 𝑝.
sage: factor(164878)
2 * 7 * 11777
sage: I.change_ring(P.change_ring(GF(2))).groebner_basis()˓→# needs sage.rings.finite_rings[x + y + z, y^2 + y, y*z + y, z^2 + 1]
sage: I.change_ring(P.change_ring(GF(7))).groebner_basis()˓→# needs sage.rings.finite_rings[x - 1, y + 3, z - 2]sage: I.change_ring(P.change_ring(GF(11777))).groebner_basis()˓→# needs sage.rings.finite_rings[x + 5633, y - 3007, z - 2626]

3.1. Multivariate Polynomials and Polynomial Rings

␣

␣

␣

601

Polynomials, Release 10.4>>> from sage.all import *>>> factor(Integer(164878))
2 * 7 * 11777>>> I.change_ring(P.change_ring(GF(Integer(2)))).groebner_basis()˓→# needs sage.rings.finite_rings[x + y + z, y^2 + y, y*z + y, z^2 + 1]>>> I.change_ring(P.change_ring(GF(Integer(7)))).groebner_basis()˓→# needs sage.rings.finite_rings[x - 1, y + 3, z - 2]>>> I.change_ring(P.change_ring(GF(Integer(11777)))).groebner_basis()˓→# needs sage.rings.finite_rings[x + 5633, y - 3007, z - 2626]

␣

␣

␣

The Groebner basis modulo any product of the prime factors is also non-trivial:sage: I.change_ring(P.change_ring(IntegerModRing(2 * 7))).groebner_basis()[x + 9*y + 13*z, y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10]>>> from sage.all import *>>> I.change_ring(P.change_ring(IntegerModRing(Integer(2) * Integer(7)))).
˓→groebner_basis()[x + 9*y + 13*z, y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10]

Modulo any other prime the Groebner basis is trivial so there are no other solutions. For example:
sage: I.change_ring(P.change_ring(GF(3))).groebner_basis()˓→# needs sage.rings.finite_rings[1]>>> from sage.all import *>>> I.change_ring(P.change_ring(GF(Integer(3)))).groebner_basis()˓→# needs sage.rings.finite_rings
[1]

␣

␣

Note: Sage distinguishes between lists or sequences of polynomials and ideals. Thus an ideal is not identified
with a particular set of generators. For sequences of multivariate polynomials see sage.rings.polynomial.
multi_polynomial_sequence.PolynomialSequence_generic.
AUTHORS:• William Stein: initial version• Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some Singular features• Martin Albrecht (2007,2008): refactoring, many Singular related functions, added plot()• Martin Albrecht (2009): added Groebner basis over rings functionality from Singular 3.1• John Perry (2012): bug fixing equality & containment of ideals
class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal(ring, gens,coerce=True)
Bases: MPolynomialIdeal_singular_repr, MPolynomialIdeal_macaulay2_repr, MPolynomialIdeal_magma_repr, Ideal_genericCreate an ideal in a multivariate polynomial ring.
602

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

INPUT:• ring – the ring the ideal is defined in• gens – a list of generators for the ideal• coerce – whether to coerce elements to the ring ring
EXAMPLES:
sage: R.<x,y> = PolynomialRing(IntegerRing(), 2, order= lex )sage: R.ideal([x, y])Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ringsage: R.<x0,x1> = GF(3)[]sage: R.ideal([x0^2, x1^3])
Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of␣˓→size 3>>> from sage.all import *>>> R = PolynomialRing(IntegerRing(), Integer(2), order= lex , names=( x , y ,));
˓→ (x, y,) = R._first_ngens(2)>>> R.ideal([x, y])Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring>>> R = GF(Integer(3))[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> R.ideal([x0**Integer(2), x1**Integer(3)])
Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of␣˓→size 3

property basis
Shortcut to gens().
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ,2)
sage: I = Ideal([x, y + 1])
sage: I.basis[x, y + 1]>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(2), names=( x ,˓→ngens(2)>>> I = Ideal([x, y + Integer(1)])>>> I.basis[x, y + 1]y ,)); (x, y,) = P._first_

change_ring(P)Return the ideal I in P spanned by the generators 𝑔1 , ..., 𝑔𝑛 of self as returned by self.gens().
INPUT:• P – a multivariate polynomial ring
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ,3,order= lex )sage: I = sage.rings.ideal.Cyclic(P)sage: I
Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
Multivariate Polynomial Ring in x, y, z over Rational Field

3.1. Multivariate Polynomials and Polynomial Rings

603

Polynomials, Release 10.4>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3),order= lex , names=( x ,˓→ y, z,) = P._first_ngens(3)>>> I = sage.rings.ideal.Cyclic(P)>>> I
Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
Multivariate Polynomial Ring in x, y, z over Rational Fieldy ,z ,)); (x,sage: I.groebner_basis()[x + y + z, y^2 + y*z + z^2, z^3 - 1]>>> from sage.all import *>>> I.groebner_basis()[x + y + z, y^2 + y*z + z^2, z^3 - 1]sage: Q.<x,y,z> = P.change_ring(order= degrevlex ); Q
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: Q.term_order()Degree reverse lexicographic term order>>> from sage.all import *>>> Q = P.change_ring(order= degrevlex , names=( x , y , z ,)); (x, y, z,)␣˓→= Q._first_ngens(3); Q
Multivariate Polynomial Ring in x, y, z over Rational Field>>> Q.term_order()Degree reverse lexicographic term ordersage: J = I.change_ring(Q); J
Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> J = I.change_ring(Q); J
Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: J.groebner_basis()[z^3 - 1, y^2 + y*z + z^2, x + y + z]>>> from sage.all import *>>> J.groebner_basis()[z^3 - 1, y^2 + y*z + z^2, x + y + z]

degree_of_semi_regularity()
Return the degree of semi-regularity of this ideal under the assumption that it is semi-regular.
Let {𝑓1 , ..., 𝑓𝑚 } ⊂ 𝐾[𝑥1 , ..., 𝑥𝑛 ] be homogeneous polynomials of degrees 𝑑1 , ..., 𝑑𝑚 respectively. Thissequence is semi-regular if:• {𝑓1 , ..., 𝑓𝑚 } ̸= 𝐾[𝑥1 , ..., 𝑥𝑛 ]• for all 1 ≤ 𝑖 ≤ 𝑚 and 𝑔 ∈ 𝐾[𝑥1 , . . . , 𝑥𝑛 ]: 𝑑𝑒𝑔(𝑔 · 𝑝𝑖) < 𝐷 and 𝑔 · 𝑓𝑖 ∈< 𝑓1 , . . . , 𝑓𝑖−1 > implies that𝑔 ∈< 𝑓1 , ..., 𝑓𝑖−1 > where 𝐷 is the degree of regularity.
This notion can be extended to affine polynomials by considering their homogeneous components of highest
degree.
604

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

The degree of regularity of a semi-regular sequence 𝑓1 , ..., 𝑓𝑚 of respective degrees 𝑑1 , ..., 𝑑𝑚 is given by
the index of the first non-positive coefficient of:∏︀∑︀(1−𝑧 𝑑𝑖 )𝑐𝑘 𝑧 𝑘 = (1−𝑧)𝑛EXAMPLES:
We consider a homogeneous example:
sage: n = 8
sage: K = GF(127)sage: P = PolynomialRing(K, n, x )sage: s = [K.random_element() for _ in range(n)]sage: L = []sage: for i in range(2 * n):....:f = P.random_element(degree=2, terms=binomial(n, 2))....:
f -= f(*s)....:
L.append(f.homogenize())
sage: I = Ideal(L)sage: I.degree_of_semi_regularity()4>>> from sage.all import *>>> n = Integer(8)>>> K = GF(Integer(127))>>> P = PolynomialRing(K, n, x )>>> s = [K.random_element() for _ in range(n)]>>> L = []>>> for i in range(Integer(2) * n):...
f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))...
f -= f(*s)...
L.append(f.homogenize())>>> I = Ideal(L)>>> I.degree_of_semi_regularity()
4

From this, we expect a Groebner basis computation to reach at most degree 4. For homogeneous systems thisis equivalent to the largest degree in the Groebner basis:sage: max(f.degree() for f in I.groebner_basis())
4>>> from sage.all import *>>> max(f.degree() for f in I.groebner_basis())
4

We increase the number of polynomials and observe a decrease the degree of regularity:
sage: for i in range(2 * n):....:f = P.random_element(degree=2, terms=binomial(n, 2))....:
f -= f(*s)....:
L.append(f.homogenize())
sage: I = Ideal(L)sage: I.degree_of_semi_regularity()3
sage: max(f.degree() for f in I.groebner_basis())
3

3.1. Multivariate Polynomials and Polynomial Rings

605

Polynomials, Release 10.4>>> from sage.all import *>>> for i in range(Integer(2) * n):...
f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))...
f -= f(*s)...
L.append(f.homogenize())>>> I = Ideal(L)>>> I.degree_of_semi_regularity()3>>> max(f.degree() for f in I.groebner_basis())
3

The degree of regularity approaches 2 for quadratic systems as the number of polynomials approaches 𝑛2 :sage: for i in range((n-4) * n):....:f = P.random_element(degree=2, terms=binomial(n, 2))....:
f -= f(*s)....:
L.append(f.homogenize())
sage: I = Ideal(L)sage: I.degree_of_semi_regularity()2
sage: max(f.degree() for f in I.groebner_basis())
2>>> from sage.all import *>>> for i in range((n-Integer(4)) * n):...
f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))...
f -= f(*s)...
L.append(f.homogenize())>>> I = Ideal(L)>>> I.degree_of_semi_regularity()2>>> max(f.degree() for f in I.groebner_basis())
2

Note: It is unknown whether semi-regular sequences exist. However, it is expected that random systems aresemi-regular sequences. For more details about semi-regular sequences see [BFS2004].
gens()
Return a set of generators / a basis of this ideal. This is usually the set of generators provided during object
creation.
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ,2)
sage: I = Ideal([x, y + 1]); I
Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field
sage: I.gens()[x, y + 1]>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(2), names=( x ,˓→ngens(2)y ,)); (x, y,) = P._first_(continues on next page)

606

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> I = Ideal([x, y + Integer(1)]); I
Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field>>> I.gens()[x, y + 1]

groebner_basis(algorithm='', deg_bound=None, mult_bound=None, prot=False, *args, **kwds)
Return the reduced Groebner basis of this ideal.
A Groebner basis 𝑔1 , ..., 𝑔𝑛 for an ideal 𝐼 is a generating set such that < 𝐿𝑀 (𝑔𝑖 ) >= 𝐿𝑀 (𝐼), i.e., theleading monomial ideal of 𝐼 is spanned by the leading terms of 𝑔1 , ..., 𝑔𝑛 . Groebner bases are the key concept
in computational ideal theory in multivariate polynomial rings which allows a variety of problems to be solved.
Additionally, a reduced Groebner basis 𝐺 is a unique representation for the ideal < 𝐺 > with respect to thechosen monomial ordering.
INPUT:• algorithm – determines the algorithm to use, see below for available algorithms.
• deg_bound – only compute to degree deg_bound, that is, ignore all S-polynomials of higher degree.
(default: None)• mult_bound – the computation is stopped if the ideal is zero-dimensional in a ring with local orderingand its multiplicity is lower than mult_bound. Singular only. (default: None)• prot – if set to True the computation protocol of the underlying implementation is printed. If analgorithm from the singular: or magma: family is used, prot may also be sage in which casethe output is parsed and printed in a common format where the amount of information printed can becontrolled via calls to set_verbose().
• *args – additional parameters passed to the respective implementations• **kwds – additional keyword parameters passed to the respective implementations
ALGORITHMS:
autoselect (default)
singular:groebner
Singular’s groebner command
singular:std
Singular’s std command
singular:stdhilb
Singular’s stdhib command
singular:stdfglm
Singular’s stdfglm command
singular:slimgb
Singular’s slimgb commandlibsingular:groebner
libSingular’s groebner commandlibsingular:std
libSingular’s std commandlibsingular:slimgb
libSingular’s slimgb command

3.1. Multivariate Polynomials and Polynomial Rings

607

Polynomials, Release 10.4

libsingular:stdhilb
libSingular’s stdhib commandlibsingular:stdfglm
libSingular’s stdfglm command
toy:buchberger
Sage’s toy/educational buchberger without Buchberger criteria
toy:buchberger2
Sage’s toy/educational buchberger with Buchberger criteria
toy:d_basis
Sage’s toy/educational algorithm for computation over PIDs
macaulay2:gb
Macaulay2’s gb command (if available)macaulay2:f4
Macaulay2’s GroebnerBasis command with the strategy “F4” (if available)macaulay2:mgb
Macaulay2’s GroebnerBasis command with the strategy “MGB” (if available)
msolveoptional package msolve (degrevlex order)
magma:GroebnerBasis
Magma’s Groebnerbasis command (if available)
ginv:TQ , ginv:TQBlockHigh , ginv:TQBlockLow and ginv:TQDegree
One of GINV’s implementations (if available)
giac:gbasis
Giac’s gbasis command (if available)
If only a system is given - e.g. magma - the default algorithm is chosen for that system.
Note: The Singular and libSingular versions of the respective algorithms are identical, but the former calls an
external Singular process while the latter calls a C function, and thus the calling overhead is smaller. However,the libSingular interface does not support pretty printing of computation protocols.
EXAMPLES:
Consider Katsura-3 over with lexicographical term ordering. We compute the reduced Groebner basis
using every available implementation and check their equality.
sage: P.<a,b,c> = PolynomialRing(QQ,3, order= lex )sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis()[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3), order= lex , names=( a , b , c ,));␣
˓→(a, b, c,) = P._first_ngens(3)>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis()(continues on next page)

608

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( libsingular:groebner )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( libsingular:groebner )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( libsingular:std )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( libsingular:std )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( libsingular:stdhilb )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( libsingular:stdhilb )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( libsingular:stdfglm )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( libsingular:stdfglm )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( libsingular:slimgb )(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

609

Polynomials, Release 10.4

(continued from previous page)[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( libsingular:slimgb )[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]

Although Giac does support lexicographical ordering, we use degree reverse lexicographical ordering here,
in order to test against Issue #21884:
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: J = I.change_ring(P.change_ring(order= degrevlex ))sage: gb = J.groebner_basis( giac ) # random
sage: gb[c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/
˓→5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1]sage: J.groebner_basis.set_cache(gb)sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis() #␣˓→testing issue #21884...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 -␣
˓→10/21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> J = I.change_ring(P.change_ring(order= degrevlex ))>>> gb = J.groebner_basis( giac ) # random>>> gb[c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/
˓→5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1]>>> J.groebner_basis.set_cache(gb)>>> ideal(J.transformed_basis()).change_ring(P).interreduced_basis() #␣˓→testing issue #21884...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 -␣
˓→10/21*c^3 + 1/84*c^2 + 1/84*c]

Giac’s gbasis overcan benefit from a probabilistic lifting and multi threaded operations:sage: A9 = PolynomialRing(QQ, 9, x )sage: I9 = sage.rings.ideal.Katsura(A9)sage: print("possible output from giac", flush=True); I9.groebner_basis("giac
˓→", proba_epsilon=1e-7)# long time (3s)possible output...
Polynomial Sequence with 143 Polynomials in 9 Variables>>> from sage.all import *>>> A9 = PolynomialRing(QQ, Integer(9), x )>>> I9 = sage.rings.ideal.Katsura(A9)>>> print("possible output from giac", flush=True); I9.groebner_basis("giac",␣
˓→proba_epsilon=RealNumber( 1e-7 ))# long time (3s)(continues on next page)

610

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

possible output...
Polynomial Sequence with 143 Polynomials in 9 Variables

The list of available Giac options is provided at sage.libs.giac.groebner_basis().
Note that toy:buchberger does not return the reduced Groebner basis,sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: gb = I.groebner_basis( toy:buchberger )sage: gb.is_groebner()True
sage: gb == gb.reduced()
False>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3))˓→caching>>> gb = I.groebner_basis( toy:buchberger )>>> gb.is_groebner()True>>> gb == gb.reduced()False# regenerate to prevent␣

but that toy:buchberger2 does.
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: gb = I.groebner_basis( toy:buchberger2 ); gb[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]
sage: gb == gb.reduced()True>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> gb = I.groebner_basis( toy:buchberger2 ); gb[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/
˓→21*c^3 + 1/84*c^2 + 1/84*c]>>> gb == gb.reduced()
True

Here we use Macaulay2 with three different strategies over a finite field.
sage: # optional - macaulay2
sage: R.<a,b,c> = PolynomialRing(GF(101), 3)
sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent cachingsage: I.groebner_basis( macaulay2:gb )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent cachingsage: I.groebner_basis( macaulay2:f4 )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent cachingsage: I.groebner_basis( macaulay2:mgb )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]

3.1. Multivariate Polynomials and Polynomial Rings

611

Polynomials, Release 10.4>>> from sage.all import *>>> # optional - macaulay2>>> R = PolynomialRing(GF(Integer(101)), Integer(3), names=( a , b , c ,));␣
˓→(a, b, c,) = R._first_ngens(3)>>> I = sage.rings.ideal.Katsura(R,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( macaulay2:gb )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]>>> I = sage.rings.ideal.Katsura(R,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( macaulay2:f4 )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]>>> I = sage.rings.ideal.Katsura(R,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( macaulay2:mgb )[c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]

Over prime fields of small characteristic, we can also use the optional package msolve:
sage: R.<a,b,c> = PolynomialRing(GF(101), 3)
sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent cachingsage: I.groebner_basis( msolve )# optional - msolve[a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(101)), Integer(3), names=( a , b , c ,));␣
˓→(a, b, c,) = R._first_ngens(3)>>> I = sage.rings.ideal.Katsura(R,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( msolve )# optional - msolve[a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]
sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent cachingsage: I.groebner_basis( magma:GroebnerBasis )# optional - magma[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1,
b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]>>> from sage.all import *>>> I = sage.rings.ideal.Katsura(P,Integer(3)) # regenerate to prevent␣˓→caching>>> I.groebner_basis( magma:GroebnerBasis )# optional - magma[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1,
b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

Singular and libSingular can compute Groebner basis with degree restrictions.
sage: R.<x,y> = QQ[]
sage: I = R*[x^3 + y^2, x^2*y + 1]
sage: I.groebner_basis(algorithm= singular )[x^3 + y^2, x^2*y + 1, y^3 - x]sage: I.groebner_basis(algorithm= singular , deg_bound=2)(continues on next page)

612

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[x^3 + y^2, x^2*y + 1]
sage: I.groebner_basis()[x^3 + y^2, x^2*y + 1, y^3 - x]sage: I.groebner_basis(deg_bound=2)[x^3 + y^2, x^2*y + 1]>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> I = R*[x**Integer(3) + y**Integer(2), x**Integer(2)*y + Integer(1)]>>> I.groebner_basis(algorithm= singular )[x^3 + y^2, x^2*y + 1, y^3 - x]>>> I.groebner_basis(algorithm= singular , deg_bound=Integer(2))[x^3 + y^2, x^2*y + 1]>>> I.groebner_basis()[x^3 + y^2, x^2*y + 1, y^3 - x]>>> I.groebner_basis(deg_bound=Integer(2))[x^3 + y^2, x^2*y + 1]

A protocol is printed, if the verbosity level is at least 2, or if the argument prot is provided. Historically,
the protocol did not appear during doctests, so, we skip the examples with protocol output.
sage: from sage.misc.verbose import set_verbose
sage: set_verbose(2)sage: I = R*[x^3+y^2,x^2*y+1]
sage: I.groebner_basis() # not tested
std in (QQ),(x,y),(dp(2),C)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]sage: I.groebner_basis(prot=False)
std in (QQ),(x,y),(dp(2),C)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]sage: set_verbose(0)sage: I.groebner_basis(prot=True) # not tested
std in (QQ),(x,y),(dp(2),C)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]>>> from sage.all import *>>> from sage.misc.verbose import set_verbose>>> set_verbose(Integer(2))>>> I = R*[x**Integer(3)+y**Integer(2),x**Integer(2)*y+Integer(1)]>>> I.groebner_basis() # not tested
std in (QQ),(x,y),(dp(2),C)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]>>> I.groebner_basis(prot=False)
std in (QQ),(x,y),(dp(2),C)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

613

Polynomials, Release 10.4

(continued from previous page)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]>>> set_verbose(Integer(0))>>> I.groebner_basis(prot=True) # not tested
std in (QQ),(x,y),(dp(2),C)[...:2]3ss4s6(S:2)-product criterion:1 chain criterion:0[x^3 + y^2, x^2*y + 1, y^3 - x]

The list of available options is provided at LibSingularOptions.
Note that Groebner bases over Z can also be computed.
sage: P.<a,b,c> = PolynomialRing(ZZ,3)
sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)sage: I.groebner_basis()[b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2,
42*c^3 + b^2 + 2*b*c - 14*c^2 + b,2*b^2 + 6*b*c + 6*c^2 - b - 2*c,
10*b*c + 12*c^2 - b - 4*c,a + 2*b + 2*c - 1]>>> from sage.all import *>>> P = PolynomialRing(ZZ,Integer(3), names=( a , b , c ,)); (a, b, c,) = P.
˓→_first_ngens(3)>>> I = P * (a + Integer(2)*b + Integer(2)*c - Integer(1), a**Integer(2) - a␣
˓→+ Integer(2)*b**Integer(2) + Integer(2)*c**Integer(2), Integer(2)*a*b +␣
˓→Integer(2)*b*c - b)>>> I.groebner_basis()[b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2,
42*c^3 + b^2 + 2*b*c - 14*c^2 + b,2*b^2 + 6*b*c + 6*c^2 - b - 2*c,
10*b*c + 12*c^2 - b - 4*c,a + 2*b + 2*c - 1]sage: I.groebner_basis( macaulay2 )# optional - macaulay2[b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c,
42*c^3 + b^2 + 2*b*c - 14*c^2 + b,2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c,a + 2*b + 2*c - 1]>>> from sage.all import *>>> I.groebner_basis( macaulay2 )# optional - macaulay2[b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c,
42*c^3 + b^2 + 2*b*c - 14*c^2 + b,2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c,a + 2*b + 2*c - 1]

Groebner bases over Z/𝑛Z are also supported:

614

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<a,b,c> = PolynomialRing(Zmod(1000), 3)
sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)sage: I.groebner_basis()[b*c^2 + 732*b*c + 808*b,2*c^3 + 884*b*c + 666*c^2 + 320*b,b^2 + 438*b*c + 281*b,
5*b*c + 156*c^2 + 112*b + 948*c,
50*c^2 + 600*b + 650*c,
a + 2*b + 2*c + 999,
125*b]>>> from sage.all import *>>> P = PolynomialRing(Zmod(Integer(1000)), Integer(3), names=( a , b , c ,˓→)); (a, b, c,) = P._first_ngens(3)>>> I = P * (a + Integer(2)*b + Integer(2)*c - Integer(1), a**Integer(2) - a␣
˓→+ Integer(2)*b**Integer(2) + Integer(2)*c**Integer(2), Integer(2)*a*b +␣
˓→Integer(2)*b*c - b)>>> I.groebner_basis()[b*c^2 + 732*b*c + 808*b,2*c^3 + 884*b*c + 666*c^2 + 320*b,b^2 + 438*b*c + 281*b,
5*b*c + 156*c^2 + 112*b + 948*c,
50*c^2 + 600*b + 650*c,
a + 2*b + 2*c + 999,
125*b]
sage: R.<x,y,z> = PolynomialRing(Zmod(2233497349584))
sage: I = R.ideal([z*(x-3*y), 3^2*x^2-y*z, z^2+y^2])
sage: I.groebner_basis()[2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 - y*z, y^2 + z^2, x*z +2233497349581*y*z, 248166372176*y*z]>>> from sage.all import *>>> R = PolynomialRing(Zmod(Integer(2233497349584)), names=( x , y , z ,));␣
˓→(x, y, z,) = R._first_ngens(3)>>> I = R.ideal([z*(x-Integer(3)*y), Integer(3)**Integer(2)*x**Integer(2)-y*z,
˓→ z**Integer(2)+y**Integer(2)])>>> I.groebner_basis()[2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 - y*z, y^2 + z^2, x*z +2233497349581*y*z, 248166372176*y*z]

Sage also supports local orderings:
sage: P.<x,y,z> = PolynomialRing(QQ, 3, order= negdegrevlex )sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 )sage: I.groebner_basis()[x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6]>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), order= negdegrevlex , names=( x , y ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)>>> I = P * ( x*y*z + z**Integer(5), Integer(2)*x**Integer(2) +␣˓→y**Integer(3) + z**Integer(7), Integer(3)*z**Integer(5) + y**Integer(5) )>>> I.groebner_basis()[x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6]

We can represent every element in the ideal as a combination of the generators using the lift() method:
3.1. Multivariate Polynomials and Polynomial Rings

615

Polynomials, Release 10.4

sage: P.<x,y,z> = PolynomialRing(QQ, 3)
sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 )sage: J = Ideal(I.groebner_basis())
sage: f = sum(P.random_element(terms=2)*f for f in I.gens())
sage: f# random
1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 +␣
˓→3/2*x^2*y*z + 95*x*y*z^2
sage: f.lift(I.gens())# random[2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0]
sage: l = f.lift(J.gens()); l # random[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/
˓→4*y*z^3 + 2*x + 95*z]
sage: sum(map(mul, zip(l,J.gens()))) == f
True>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→P._first_ngens(3)>>> I = P * ( x*y*z + z**Integer(5), Integer(2)*x**Integer(2) + y**Integer(3)␣
˓→+ z**Integer(7), Integer(3)*z**Integer(5) + y**Integer(5) )>>> J = Ideal(I.groebner_basis())>>> f = sum(P.random_element(terms=Integer(2))*f for f in I.gens())>>> f# random
1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 +␣
˓→3/2*x^2*y*z + 95*x*y*z^2>>> f.lift(I.gens())# random[2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0]>>> l = f.lift(J.gens()); l # random[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/
˓→4*y*z^3 + 2*x + 95*z]>>> sum(map(mul, zip(l,J.gens()))) == f
True

Groebner bases over fraction fields of polynomial rings are also supported:
sage: P.<t> = QQ[]
sage: F = Frac(P)sage: R.<X,Y,Z> = F[]sage: I = Ideal([f + P.random_element() for f in sage.rings.ideal.Katsura(R).
˓→gens()])
sage: I.groebner_basis().ideal() == I
True>>> from sage.all import *>>> P = QQ[ t ]; (t,) = P._first_ngens(1)>>> F = Frac(P)>>> R = F[ X, Y, Z ]; (X, Y, Z,) = R._first_ngens(3)>>> I = Ideal([f + P.random_element() for f in sage.rings.ideal.Katsura(R).
˓→gens()])>>> I.groebner_basis().ideal() == ITrue

In cases where a characteristic cannot be determined, we use a toy implementation of Buchberger’s algorithm(see Issue #6581):
sage: R.<a,b> = QQ[]; I = R.ideal(a^2+b^2-1)
sage: Q = QuotientRing(R,I); K = Frac(Q)616(continues on next page)

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: R2.<x,y> = K[]; J = R2.ideal([(a^2+b^2)*x + y, x+y])
sage: J.groebner_basis()verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling␣˓→back to very slow toy implementation.
[x + y]>>> from sage.all import *>>> R = QQ[ a, b ]; (a, b,) = R._first_ngens(2); I = R.
˓→ideal(a**Integer(2)+b**Integer(2)-Integer(1))>>> Q = QuotientRing(R,I); K = Frac(Q)>>> R2 = K[ x, y ]; (x, y,) = R2._first_ngens(2); J = R2.
˓→ideal([(a**Integer(2)+b**Integer(2))*x + y, x+y])>>> J.groebner_basis()verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling␣˓→back to very slow toy implementation.
[x + y]ALGORITHM:
Uses Singular, one of the other systems listed above (if available), or a toy implementation.
groebner_cover()Compute the Gröbner cover of the ideal, over a field with parameters.
The Groebner cover is a partition of the space of parameters, such that the Groebner basis in each part isgiven by the same expression.
EXAMPLES:
sage: F = PolynomialRing(QQ, a ).fraction_field()sage: F.inject_variables()Defining asage: R.<x,y,z> = F[]sage: I = R.ideal([-x+3*y+z-5,2*x+a*z+4,4*x-3*z-1/a])
sage: I.groebner_cover(){Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:0
and Y is defined by:
2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1),(12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x +␣
˓→11],
Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:...
and Y is defined by:
1: [1],
Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:...
and Y is defined by:
1: [1]}

3.1. Multivariate Polynomials and Polynomial Rings

617

Polynomials, Release 10.4>>> from sage.all import *>>> F = PolynomialRing(QQ, a ).fraction_field()>>> F.inject_variables()Defining a>>> R = F[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> I = R.ideal([-x+Integer(3)*y+z-Integer(5),Integer(2)*x+a*z+Integer(4),˓→Integer(4)*x-Integer(3)*z-Integer(1)/a])>>> I.groebner_cover(){Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:0
and Y is defined by:
2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1),(12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x +␣
˓→11],
Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:...
and Y is defined by:
1: [1],
Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational␣
˓→Field,
where X is defined by:...
and Y is defined by:
1: [1]}

groebner_fan(is_groebner_basis=False, symmetry=None, verbose=False)
Return the Groebner fan of this ideal.
The base ring must be

or a finite field F𝑝 of with 𝑝 ≤ 32749.

EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ)
sage: i = ideal(x^2 - y^2 + 1)
sage: g = i.groebner_fan()sage: g.reduced_groebner_bases()[[x^2 - y^2 + 1], [-x^2 + y^2 - 1]]>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> i = ideal(x**Integer(2) - y**Integer(2) + Integer(1))>>> g = i.groebner_fan()>>> g.reduced_groebner_bases()[[x^2 - y^2 + 1], [-x^2 + y^2 - 1]]

INPUT:• is_groebner_basis – bool (default: False). if True, then I.gens() must be a Groebner basis withrespect to the standard degree lexicographic term order.
• symmetry – default: None; if not None, describes symmetries of the ideal• verbose – default: False; if True, printout useful info during computations

618

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

homogenize(var='h')Return homogeneous ideal spanned by the homogeneous polynomials generated by homogenizing the generators of this ideal.
INPUT:• h – variable name or variable in cover ring (default: ‘h’)
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(2))
sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I
Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate
Polynomial Ring in x, y, z over Finite Field of size 2>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(2)), names=( x , y , z ,)); (x, y, z,) =␣
˓→P._first_ngens(3)>>> I = Ideal([x**Integer(2)*y + z + Integer(1), x + y**Integer(2) +␣˓→Integer(1)]); I
Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate
Polynomial Ring in x, y, z over Finite Field of size 2
sage: I.homogenize()
Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) ofMultivariate Polynomial Ring in x, y, z, h over Finite
Field of size 2>>> from sage.all import *>>> I.homogenize()
Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) ofMultivariate Polynomial Ring in x, y, z, h over Finite
Field of size 2
sage: I.homogenize(y)Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate
Polynomial Ring in x, y, z over Finite Field of size 2>>> from sage.all import *>>> I.homogenize(y)Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate
Polynomial Ring in x, y, z over Finite Field of size 2
sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1])
sage: I.homogenize()
Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) ofMultivariate Polynomial Ring in x, y, z, h over Finite
Field of size 2>>> from sage.all import *>>> I = Ideal([x**Integer(2)*y + z**Integer(3) + y**Integer(2)*x, x +␣˓→y**Integer(2) + Integer(1)])>>> I.homogenize()
Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) ofMultivariate Polynomial Ring in x, y, z, h over Finite
Field of size 2

3.1. Multivariate Polynomials and Polynomial Rings

619

Polynomials, Release 10.4

is_homogeneous()
Return True if this ideal is spanned by homogeneous polynomials, i.e., if it is a homogeneous ideal.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ,3)
sage: I = sage.rings.ideal.Katsura(P)sage: I
Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y +2*y*z - y) of Multivariate Polynomial Ring in x, y, z over
Rational Field>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3), names=( x , y , z ,)); (x, y, z,) = P.
˓→_first_ngens(3)>>> I = sage.rings.ideal.Katsura(P)>>> I
Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y +2*y*z - y) of Multivariate Polynomial Ring in x, y, z over
Rational Field
sage: I.is_homogeneous()
False>>> from sage.all import *>>> I.is_homogeneous()
False
sage: J = I.homogenize()
sage: J
Ideal (x + 2*y + 2*z - h, x^2 + 2*y^2 + 2*z^2 - x*h, 2*x*y+ 2*y*z - y*h) of Multivariate Polynomial Ring in x, y, z,
h over Rational Field>>> from sage.all import *>>> J = I.homogenize()>>> J
Ideal (x + 2*y + 2*z - h, x^2 + 2*y^2 + 2*z^2 - x*h, 2*x*y+ 2*y*z - y*h) of Multivariate Polynomial Ring in x, y, z,
h over Rational Field
sage: J.is_homogeneous()
True>>> from sage.all import *>>> J.is_homogeneous()Trueplot(*args, **kwds)
Plot the real zero locus of this principal ideal.
INPUT:• self – a principal ideal in 2 variables• algorithm – set this to ‘surf’ if you want ‘surf’ to plot the ideal (default: None)

620

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• *args – optional tuples (variable, minimum, maximum) for plotting dimensions• **kwds – optional keyword arguments passed on to implicit_plot
EXAMPLES:
Implicit plotting in 2-d:sage: R.<x,y> = PolynomialRing(QQ, 2)
sage: I = R.ideal([y^3 - x^2])
sage: I.plot()# cusp˓→needs sage.plot
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x ,˓→ngens(2)>>> I = R.ideal([y**Integer(3) - x**Integer(2)])>>> I.plot()# cusp˓→needs sage.plot
Graphics object consisting of 1 graphics primitive#␣y ,)); (x, y,) = R._first_#␣sage: I = R.ideal([y^2 - x^2 - 1])sage: I.plot((x,-3, 3), (y, -2, 2))# hyperbola
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> I = R.ideal([y**Integer(2) - x**Integer(2) - Integer(1)])>>> I.plot((x,-Integer(3), Integer(3)), (y, -Integer(2), Integer(2)))˓→hyperbola# needs sage.plot
Graphics object consisting of 1 graphics primitive
sage: I = R.ideal([y^2 + x^2*(1/4) - 1])sage: I.plot()# ellipse
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive

#␣

#␣

#␣

>>> from sage.all import *>>> I = R.ideal([y**Integer(2) + x**Integer(2)*(Integer(1)/Integer(4)) -␣˓→Integer(1)])>>> I.plot()# ellipse#␣˓→needs sage.plot
Graphics object consisting of 1 graphics primitive
sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
sage: I.plot()# elliptic curve
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive#␣>>> from sage.all import *>>> I = R.ideal([y**Integer(2)-(x**Integer(2)-Integer(1))*(x-Integer(2))])>>> I.plot()# elliptic curve#␣˓→needs sage.plot
Graphics object consisting of 1 graphics primitive

3.1. Multivariate Polynomials and Polynomial Rings

621

Polynomials, Release 10.4

sage: f = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2)
sage: I = R.ideal(f)sage: I.plot()# the Singular logo
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive#␣>>> from sage.all import *>>> f = ((x+Integer(3))**Integer(3) + Integer(2)*(x+Integer(3))**Integer(2) -␣˓→y**Integer(2))*(x**Integer(3) - y**Integer(2))*((x-Integer(3))**Integer(3)˓→Integer(2)*(x-Integer(3))**Integer(2)-y**Integer(2))>>> I = R.ideal(f)>>> I.plot()# the Singular logo#␣˓→needs sage.plot
Graphics object consisting of 1 graphics primitive
sage: R.<x,y> = PolynomialRing(QQ, 2)
sage: I = R.ideal([x - 1])sage: I.plot((y, -2, 2))# vertical line
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x ,˓→ngens(2)>>> I = R.ideal([x - Integer(1)])>>> I.plot((y, -Integer(2), Integer(2)))˓→# needs sage.plot
Graphics object consisting of 1 graphics primitive#␣y ,)); (x, y,) = R._first_# vertical line

sage: I = R.ideal([-x^2*y + 1])
sage: I.plot()# blow up
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive␣#␣>>> from sage.all import *>>> I = R.ideal([-x**Integer(2)*y + Integer(1)])>>> I.plot()# blow up
˓→needs sage.plot
Graphics object consisting of 1 graphics primitive#␣random_element(degree, compute_gb=False, *args, **kwds)∑︀Return a random element in this ideal as 𝑟 = ℎ𝑖 𝑓𝑖 .
INPUT:• compute_gb – if True then a Gröbner basis is computed first and 𝑓𝑖 are the elements in the Gröbner
basis. Otherwise whatever basis is returned by self.gens() is used.
• *args and **kwds are passed to R.random_element() with R = self.ring().
EXAMPLES:
We compute a uniformly random element up to the provided degree.
sage: P.<x,y,z> = GF(127)[]
sage: I = sage.rings.ideal.Katsura(P)sage: f = I.random_element(degree=4, compute_gb=True, terms=infinity)(continues on next page)

622

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.degree() <= 4
Truesage: len(list(f)) <= 35
True>>> from sage.all import *>>> P = GF(Integer(127))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> I = sage.rings.ideal.Katsura(P)>>> f = I.random_element(degree=Integer(4), compute_gb=True, terms=infinity)>>> f.degree() <= Integer(4)True>>> len(list(f)) <= Integer(35)True

Note that sampling uniformly at random from the ideal at some large enough degree is equivalent to computing
a Gröbner basis. We give an example showing how to compute a Gröbner basis if we can sample uniformly
at random from an ideal:
sage: n = 3; d = 4
sage: P = PolynomialRing(GF(127), n,
sage: I = sage.rings.ideal.Cyclic(P)x )>>> from sage.all import *>>> n = Integer(3); d = Integer(4)>>> P = PolynomialRing(GF(Integer(127)), n,>>> I = sage.rings.ideal.Cyclic(P)x )1. We sample 𝑛𝑑 uniformly random elements in the ideal:
sage: F = Sequence(I.random_element(degree=d, compute_gb=True,....:terms=infinity)....:
for _ in range(n^d))>>> from sage.all import *>>> F = Sequence(I.random_element(degree=d, compute_gb=True,...
terms=infinity)...
for _ in range(n**d))2. We linearize and compute the echelon form:
sage: A, v = F.coefficients_monomials()sage: A.echelonize()>>> from sage.all import *>>> A, v = F.coefficients_monomials()>>> A.echelonize()

3. The result is the desired Gröbner basis:sage: G = Sequence((A * v).list())
sage: G.is_groebner()True
sage: Ideal(G) == I
True

3.1. Multivariate Polynomials and Polynomial Rings

623

Polynomials, Release 10.4>>> from sage.all import *>>> G = Sequence((A * v).list())>>> G.is_groebner()
True>>> Ideal(G) == I
True

We return some element in the ideal with no guarantee on the distribution:
sage: # needs sage.rings.finite_rings
sage: P = PolynomialRing(GF(127), 10, x )sage: I = sage.rings.ideal.Katsura(P)sage: f = I.random_element(degree=3)
sage: f # random-25*x0^2*x1 + 14*x1^3 + 57*x0*x1*x2 + ... + 19*x7*x9 + 40*x8*x9 + 49*x1
sage: f.degree()3>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> P = PolynomialRing(GF(Integer(127)), Integer(10), x )>>> I = sage.rings.ideal.Katsura(P)>>> f = I.random_element(degree=Integer(3))>>> f # random-25*x0^2*x1 + 14*x1^3 + 57*x0*x1*x2 + ... + 19*x7*x9 + 40*x8*x9 + 49*x1>>> f.degree()3

We show that the default method does not sample uniformly at random from the ideal:
sage: # needs sage.rings.finite_rings
sage: P.<x,y,z> = GF(127)[]
sage: G = Sequence([x + 7, y - 2, z + 110])
sage: I = Ideal([sum(P.random_element() * g for g in G)....:
for _ in range(4)])
sage: all(I.random_element(degree=1) == 0 for _ in range(100))
True>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> P = GF(Integer(127))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> G = Sequence([x + Integer(7), y - Integer(2), z + Integer(110)])>>> I = Ideal([sum(P.random_element() * g for g in G)...
for _ in range(Integer(4))])>>> all(I.random_element(degree=Integer(1)) == Integer(0) for _ in␣˓→range(Integer(100)))
True

If degree equals the degree of the generators, a random linear combination of the generators is returned:
sage: P.<x,y> = QQ[]
sage: I = P.ideal([x^2,y^2])
sage: set_random_seed(5)sage: I.random_element(degree=2)-2*x^2 + 2*y^2624

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> I = P.ideal([x**Integer(2),y**Integer(2)])>>> set_random_seed(Integer(5))>>> I.random_element(degree=Integer(2))-2*x^2 + 2*y^2reduce(f)Reduce an element modulo the reduced Groebner basis for this ideal. This returns 0 if and only if the element
is in this ideal. In any case, this reduction is unique up to monomial orders.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2)
sage: I = (x^3 + y, y) * R
sage: I.reduce(y)0sage: I.reduce(x^3)
0sage: I.reduce(x - y)xsage: I = (y^2 - (x^3 + x)) * R
sage: I.reduce(x^3)
y^2 - xsage: I.reduce(x^6)
y^4 - 2*x*y^2 + x^2
sage: (y^2 - x)^2y^4 - 2*x*y^2 + x^2>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x ,˓→ngens(2)>>> I = (x**Integer(3) + y, y) * R>>> I.reduce(y)0>>> I.reduce(x**Integer(3))
0>>> I.reduce(x - y)xy ,)); (x, y,) = R._first_>>> I = (y**Integer(2) - (x**Integer(3) + x)) * R>>> I.reduce(x**Integer(3))
y^2 - x>>> I.reduce(x**Integer(6))
y^4 - 2*x*y^2 + x^2>>> (y**Integer(2) - x)**Integer(2)y^4 - 2*x*y^2 + x^2

Note: Requires computation of a Groebner basis, which can be a very expensive operation.
subs(in_dict=None, **kwds)
Substitute variables.
This method substitutes some variables in the polynomials that generate the ideal with given values. Variables
that are not specified in the input remain unchanged.
3.1. Multivariate Polynomials and Polynomial Rings

625

Polynomials, Release 10.4

INPUT:• in_dict – (optional) dictionary of inputs• **kwds – named parameters
OUTPUT:
A new ideal with modified generators. If possible, in the same polynomial ring. Raises a TypeError if nocommon polynomial ring of the substituted generators can be found.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(ZZ, 2, xy )sage: I = R.ideal(x^5 + y^5, x^2 + y + x^2*y^2 + 5); I
Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ringsage: I.subs(x=y)
Ideal (2*y^5, y^4 + y^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ringsage: I.subs({x: y})# same substitution but with dictionary
Ideal (2*y^5, y^4 + y^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ring>>> from sage.all import *>>> R = PolynomialRing(ZZ, Integer(2), xy , names=( x , y ,)); (x, y,) = R._
˓→first_ngens(2)>>> I = R.ideal(x**Integer(5) + y**Integer(5), x**Integer(2) + y +␣˓→x**Integer(2)*y**Integer(2) + Integer(5)); I
Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ring>>> I.subs(x=y)
Ideal (2*y^5, y^4 + y^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ring>>> I.subs({x: y})# same substitution but with dictionary
Ideal (2*y^5, y^4 + y^2 + y + 5)
of Multivariate Polynomial Ring in x, y over Integer Ring

The new ideal can be in a different ring:sage: R.<a,b> = PolynomialRing(QQ, 2)
sage: S.<x,y> = PolynomialRing(QQ, 2)
sage: I = R.ideal(a^2 + b^2 + a - b + 2); I
Ideal (a^2 + b^2 + a - b + 2)
of Multivariate Polynomial Ring in a, b over Rational Field
sage: I.subs(a=x, b=y)
Ideal (x^2 + y^2 + x - y + 2)
of Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( a , b ,)); (a, b,) = R._first_
˓→ngens(2)>>> S = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = S._first_
˓→ngens(2)>>> I = R.ideal(a**Integer(2) + b**Integer(2) + a - b + Integer(2)); I
Ideal (a^2 + b^2 + a - b + 2)
of Multivariate Polynomial Ring in a, b over Rational Field>>> I.subs(a=x, b=y)(continues on next page)

626

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Ideal (x^2 + y^2 + x - y + 2)
of Multivariate Polynomial Ring in x, y over Rational Field

The resulting ring need not be a multivariate polynomial ring:sage: T.<t> = PolynomialRing(QQ)
sage: I.subs(a=t, b=t)
Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational␣
˓→Field
sage: var("z")#␣˓→needs sage.symbolicz
sage: I.subs(a=z, b=z)#␣˓→needs sage.symbolic
Principal ideal (2*z^2 + 2) of Symbolic Ring>>> from sage.all import *>>> T = PolynomialRing(QQ, names=( t ,)); (t,) = T._first_ngens(1)>>> I.subs(a=t, b=t)
Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational␣
˓→Field>>> var("z")#␣˓→needs sage.symbolicz>>> I.subs(a=z, b=z)#␣˓→needs sage.symbolic
Principal ideal (2*z^2 + 2) of Symbolic Ring

Variables that are not substituted remain unchanged:
sage: R.<x,y> = PolynomialRing(QQ, 2)
sage: I = R.ideal(x^2 + y^2 + x - y + 2); I
Ideal (x^2 + y^2 + x - y + 2)
of Multivariate Polynomial Ring in x, y over Rational Field
sage: I.subs(x=1)
Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational␣
˓→Field>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = R.ideal(x**Integer(2) + y**Integer(2) + x - y + Integer(2)); I
Ideal (x^2 + y^2 + x - y + 2)
of Multivariate Polynomial Ring in x, y over Rational Field>>> I.subs(x=Integer(1))
Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational␣
˓→Field

weil_restriction()
Compute the Weil restriction of this ideal over some extension field. If the field is a finite field, then thiscomputes the Weil restriction to the prime subfield.
A Weil restriction of scalars - denoted 𝑅𝑒𝑠𝐿/𝑘 - is a functor which, for any finite extension of fields 𝐿/𝑘 andany algebraic variety 𝑋 over 𝐿, produces another corresponding variety 𝑅𝑒𝑠𝐿/𝑘 (𝑋), defined over 𝑘. It isuseful for reducing questions about varieties over large fields to questions about more complicated varieties
over smaller fields.
3.1. Multivariate Polynomials and Polynomial Rings

627

Polynomials, Release 10.4

This function does not compute this Weil restriction directly but computes on generating sets of polynomial
ideals:Let 𝑑 be the degree of the field extension 𝐿/𝑘, let 𝑎 a generator of 𝐿/𝑘 and 𝑝 the minimal polynomial of
𝐿/𝑘. Denote this ideal by 𝐼.
∑︀𝑑−1 𝑖
Specifically, this function first maps each variable 𝑥 to its representation over 𝑘:
𝑖=0 𝑎 𝑥𝑖 . Then eachgenerator of 𝐼 is evaluated over these representations and reduced modulo the minimal polynomial 𝑝. The
result is interpreted as a univariate polynomial in 𝑎 and its coefficients are the new generators of the returned
ideal.
If the input and the output ideals are radical, this is equivalent to the statement about algebraic varieties above.
OUTPUT: MPolynomialIdeal
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(2^2)
sage: P.<x,y> = PolynomialRing(k, 2)
sage: I = Ideal([x*y + 1, a*x + 1])
sage: I.variety()[{y: a, x: a + 1}]
sage: J = I.weil_restriction()sage: J
Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1) of
Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal
sage: J.variety()[{y1: 1, y0: 0, x1: 1, x0: 1}]sage: J.weil_restriction() # returns J
Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1,
x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate
Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(3^5)
sage: P.<x,y,z> = PolynomialRing(k)sage: I = sage.rings.ideal.Katsura(P)sage: I.dimension()0
sage: I.variety()[{z: 0, y: 0, x: 1}]sage: J = I.weil_restriction(); J
Ideal (x0 - y0 - z0 - 1,
x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4,
x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 -␣˓→x0,-x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3+ y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 -␣˓→x1,
x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2- y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 -␣˓→x2,-x1*x2 - x0*x3 - x3*x4 - x4^2
+ y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 -␣˓→x3,
x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2
+ y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 -␣
(continues on next page)

628

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

x4,

˓→

-x0*y0 + x4*y1 + x3*y2 + x2*y3+ x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 -␣
y0,˓→-x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3- x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2+ y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 -␣
y1,

˓→-x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4- y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 -␣
y2,

˓→-x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4- y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 -␣
y3,˓→-x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4- y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 -␣y4)of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4,
z0, z1, z2, z3, z4 over Finite Field of size 3
sage: J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal
sage: from sage.doctest.fixtures import reproducible_repr
sage: print(reproducible_repr(J.variety()))[{x0: 1, x1: 0, x2: 0, x3: 0, x4: 0,
y0: 0, y1: 0, y2: 0, y3: 0, y4: 0,
z0: 0, z1: 0, z2: 0, z3: 0, z4: 0}]˓→>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> k = GF(Integer(2)**Integer(2), names=( a ,)); (a,) = k._first_ngens(1)>>> P = PolynomialRing(k, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> I = Ideal([x*y + Integer(1), a*x + Integer(1)])>>> I.variety()[{y: a, x: a + 1}]>>> J = I.weil_restriction()>>> J
Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1) of
Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2>>> J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal>>> J.variety()[{y1: 1, y0: 0, x1: 1, x0: 1}]>>> J.weil_restriction() # returns J
Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1,
x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate
Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2>>> # needs sage.rings.finite_rings>>> k = GF(Integer(3)**Integer(5), names=( a ,)); (a,) = k._first_ngens(1)>>> P = PolynomialRing(k, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> I = sage.rings.ideal.Katsura(P)>>> I.dimension()0>>> I.variety()[{z: 0, y: 0, x: 1}]>>> J = I.weil_restriction(); J(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

629

Polynomials, Release 10.4

(continued from previous page)

Ideal (x0 - y0 - z0 - 1,
x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4,
x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 -␣˓→x0,-x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3+ y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 -␣˓→x1,
x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2- y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 -␣˓→x2,-x1*x2 - x0*x3 - x3*x4 - x4^2
+ y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 -␣˓→x3,
x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2
+ y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 -␣
˓→x4,-x0*y0 + x4*y1 + x3*y2 + x2*y3+ x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 -␣˓→y0,-x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3- x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2+ y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 -␣
˓→y1,-x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4- y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 -␣˓→y2,-x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4- y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 -␣˓→y3,-x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4- y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 -␣˓→y4)of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4,
z0, z1, z2, z3, z4 over Finite Field of size 3>>> J += sage.rings.ideal.FieldIdeal(J.ring()) # ensure radical ideal>>> from sage.doctest.fixtures import reproducible_repr>>> print(reproducible_repr(J.variety()))[{x0: 1, x1: 0, x2: 0, x3: 0, x4: 0,
y0: 0, y1: 0, y2: 0, y3: 0, y4: 0,
z0: 0, z1: 0, z2: 0, z3: 0, z4: 0}]

Weil restrictions are often used to study elliptic curves over extension fields so we give a simple example
involving those:
sage: K.<a> = QuadraticField(1/3)˓→needs sage.rings.number_fieldsage: E = EllipticCurve(K, [1,2,3,4,5])
˓→needs sage.rings.number_field#␣#␣>>> from sage.all import *>>> K = QuadraticField(Integer(1)/Integer(3), names=( a ,)); (a,) = K._first_
˓→ngens(1)# needs sage.rings.number_field>>> E = EllipticCurve(K, [Integer(1),Integer(2),Integer(3),Integer(4),˓→Integer(5)])# needs sage.rings.number_
˓→field

We pick a point on E:
630

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: p = E.lift_x(1); p
˓→needs sage.rings.number_field(1 : -6 : 1)#␣sage: I = E.defining_ideal(); I˓→needs sage.rings.number_field
Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3)of Multivariate Polynomial Ring in x, y, z
over Number Field in a with defining polynomial x^2 - 1/3
with a = 0.5773502691896258?

#␣>>> from sage.all import *>>> p = E.lift_x(Integer(1)); p˓→# needs sage.rings.number_field(1 : -6 : 1)

␣>>> I = E.defining_ideal(); I˓→needs sage.rings.number_field
Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3)of Multivariate Polynomial Ring in x, y, z
over Number Field in a with defining polynomial x^2 - 1/3
with a = 0.5773502691896258?

#␣

Of course, the point p is a root of all generators of I:
sage: I.subs(x=1, y=2, z=1)
˓→needs sage.rings.number_field
Ideal (0) of Multivariate Polynomial Ring in x, y, z
over Number Field in a with defining polynomial x^2 - 1/3
with a = 0.5773502691896258?

#␣>>> from sage.all import *>>> I.subs(x=Integer(1), y=Integer(2), z=Integer(1))˓→# needs sage.rings.number_field
Ideal (0) of Multivariate Polynomial Ring in x, y, z
over Number Field in a with defining polynomial x^2 - 1/3
with a = 0.5773502691896258?

␣I is also radical:
sage: I.radical() == I˓→needs sage.rings.number_field
True

#␣

>>> from sage.all import *>>> I.radical() == I˓→needs sage.rings.number_field
True

#␣

So we compute its Weil restriction:
sage: J = I.weil_restriction(); J˓→needs sage.rings.number_field
Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0+ 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3- 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

631

Polynomials, Release 10.4

(continued from previous page)- 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2,-3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0+ 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1 - 2/3*x1^2*z1+ x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1+ 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3)of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field>>> from sage.all import *>>> J = I.weil_restriction(); J#␣˓→needs sage.rings.number_field
Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0+ 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3- 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1- 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2,-3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0+ 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1 - 2/3*x1^2*z1+ x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1+ 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3)of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field

We can check that the point p is still a root of all generators of J:
sage: J.subs(x0=1, y0=2, z0=1, x1=0, y1=0, z1=0)
˓→needs sage.rings.number_field
Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1
over Rational Field#␣>>> from sage.all import *>>> J.subs(x0=Integer(1), y0=Integer(2), z0=Integer(1), x1=Integer(0),␣
˓→y1=Integer(0), z1=Integer(0))# needs sage.rings.
˓→number_field
Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1
over Rational Field

Example for relative number fields:
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<w> = NumberField(x^5 - 2)sage: R.<x> = K[]
sage: L.<v> = K.extension(x^2 + 1)
sage: S.<x,y> = L[]sage: I = S.ideal([y^2 - x^3 - 1])sage: I.weil_restriction()
Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of
Multivariate Polynomial Ring in x0, x1, y0, y1
over Number Field in w with defining polynomial x^5 - 2>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(5) - Integer(2), names=( w ,)); (w,) = K._
˓→first_ngens(1)>>> R = K[ x ]; (x,) = R._first_ngens(1)>>> L = K.extension(x**Integer(2) + Integer(1), names=( v ,)); (v,) = L._(continues on next page)

632

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

first_ngens(1)>>> S = L[ x, y ]; (x, y,) = S._first_ngens(2)>>> I = S.ideal([y**Integer(2) - x**Integer(3) - Integer(1)])>>> I.weil_restriction()
Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of
Multivariate Polynomial Ring in x0, x1, y0, y1
over Number Field in w with defining polynomial x^5 - 2
˓→Note: Based on a Singular implementation by Michael Brickenstein
class
sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_macaulay2_repr
Bases: object
An ideal in a multivariate polynomial ring, which has an underlying Macaulay2 ring associated to it.
EXAMPLES:
sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
sage: I = ideal(x*y-z^2, y^2-w^2)
sage: I
Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over␣
˓→Integer Ring>>> from sage.all import *>>> R = PolynomialRing(ZZ, Integer(4), names=( x , y , z , w ,)); (x, y, z, w,
˓→) = R._first_ngens(4)>>> I = ideal(x*y-z**Integer(2), y**Integer(2)-w**Integer(2))>>> I
Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over␣
˓→Integer Ringclass sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_magma_repr
Bases: object
class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_quotient(ring,gens,
coerce=True)
Bases: MPolynomialIdeal
An ideal in a quotient of a multivariate polynomial ring.
EXAMPLES:
sage: Q.<x,y,z,w> = QQ[ x,y,z,w ].quotient([ x*y-z^2 , y^2-w^2 ])sage: I = ideal(x + y^2 + z - 1)sage: I
Ideal (w^2 + x + z - 1) of Quotientof Multivariate Polynomial Ring in x, y, z, w over Rational Fieldby the ideal (x*y - z^2, y^2 - w^2)>>> from sage.all import *>>> Q = QQ[ x,y,z,w ].quotient([ x*y-z^2 ,y^2-w^2 ], names=( x ,

y ,

z ,

w ,

(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

633

Polynomials, Release 10.4

(continued from previous page))); (x, y, z, w,) = Q._first_ngens(4)>>> I = ideal(x + y**Integer(2) + z - Integer(1))>>> I
Ideal (w^2 + x + z - 1) of Quotientof Multivariate Polynomial Ring in x, y, z, w over Rational Fieldby the ideal (x*y - z^2, y^2 - w^2)˓→reduce(f)Reduce an element modulo a Gröbner basis for this ideal. This returns 0 if and only if the element is in thisideal. In any case, this reduction is unique up to monomial orders.
EXAMPLES:
sage: R.<T,U,V,W,X,Y,Z> = PolynomialRing(QQ, order= lex )sage: I = R.ideal([T^2 + U^2 - 1, V^2 + W^2 - 1, X^2 + Y^2 + Z^2 - 1])sage: Q.<t,u,v,w,x,y,z> = R.quotient(I)sage: J = Q.ideal([u*v - x, u*w - y, t - z])sage: J.reduce(t^2 - z^2)0
sage: J.reduce(u^2)-z^2 + 1
sage: t^2 - z^2 in J
True
sage: u^2 in J
False>>> from sage.all import *>>> R = PolynomialRing(QQ, order= lex , names=( T , U , V , W , X , Y ,˓→ Z ,)); (T, U, V, W, X, Y, Z,) = R._first_ngens(7)>>> I = R.ideal([T**Integer(2) + U**Integer(2) - Integer(1), V**Integer(2) +␣˓→W**Integer(2) - Integer(1), X**Integer(2) + Y**Integer(2) + Z**Integer(2) -␣˓→Integer(1)])>>> Q = R.quotient(I, names=( t , u , v , w , x , y , z ,)); (t, u, v,␣
˓→w, x, y, z,) = Q._first_ngens(7)>>> J = Q.ideal([u*v - x, u*w - y, t - z])>>> J.reduce(t**Integer(2) - z**Integer(2))
0>>> J.reduce(u**Integer(2))-z^2 + 1>>> t**Integer(2) - z**Integer(2) in J
True>>> u**Integer(2) in J
False

class sage.rings.polynomial.multi_polynomial_ideal.
MPolynomialIdeal_singular_base_repr
Bases: object
syzygy_module()
Computes the first syzygy (i.e., the module of relations of the given generators) of the ideal.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 2*x^2 + ysage: g = y(continues on next page)

634

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: h = 2*f + g
sage: I = Ideal([f,g,h])sage: M = I.syzygy_module(); M
[
-2
-1
1]
[
-y 2*x^2 + y
0]
sage: G = vector(I.gens())
sage: M*G(0, 0)>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,>>> f = Integer(2)*x**Integer(2) + y>>> g = y>>> h = Integer(2)*f + g>>> I = Ideal([f,g,h])>>> M = I.syzygy_module(); M
[
-2
-1
1]
[
-y 2*x^2 + y
0]>>> G = vector(I.gens())>>> M*G(0, 0)y ,)); (x, y,) = R._first_ngens(2)ALGORITHM: Uses Singular’s syz commandclass
sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
Bases: MPolynomialIdeal_singular_base_repr
An ideal in a multivariate polynomial ring, which has an underlying Singular ring associated to it.
associated_primes(algorithm='sy')
Return a list of the associated primes of primary ideals of which the intersection is 𝐼 = self.
An ideal 𝑄 is called primary if it is a proper ideal of the ring 𝑅 and if whenever 𝑎𝑏 ∈ 𝑄 and 𝑎 ̸∈ 𝑄 then𝑏𝑛 ∈ 𝑄 for some 𝑛 ∈ Z.
If 𝑄 is a primary ideal of the ring 𝑅, then the radical ideal 𝑃 of 𝑄, i.e. 𝑃 = {𝑎 ∈ 𝑅, 𝑎𝑛 ∈ 𝑄} for some𝑛 ∈ Z, is called the associated prime of 𝑄.
If 𝐼 is a proper ideal of the ring 𝑅 then there exists a decomposition in primary ideals 𝑄𝑖 such that• their intersection is 𝐼
• none of the 𝑄𝑖 contains the intersection of the rest, and• the associated prime ideals of 𝑄𝑖 are pairwise different.
This method returns the associated primes of the 𝑄𝑖 .
INPUT:• algorithm – string:–sy – (default) use the Shimoyama-Yokoyama algorithm–

gtz – use the Gianni-Trager-Zacharias algorithm

OUTPUT: a list of associated primes
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

635

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: p = z^2 + 1; q = z^3 + 2
sage: I = (p*q^2, y - z^2) * R
sage: pd = I.associated_primes(); sorted(pd, key=str)[Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over␣˓→Rational Field,
Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over␣˓→Rational Field]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( x , y , z ,));␣
˓→(x, y, z,) = R._first_ngens(3)>>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)>>> I = (p*q**Integer(2), y - z**Integer(2)) * R>>> pd = I.associated_primes(); sorted(pd, key=str)[Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over␣˓→Rational Field,
Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over␣˓→Rational Field]

ALGORITHM:
Uses Singular.
REFERENCES:• Thomas Becker and Volker Weispfenning. Groebner Bases - A Computational Approach To Commutative Algebra. Springer, New York 1993.
basis_is_groebner(singular=None)
Return True if the generators of this ideal (self.gens()) form a Groebner basis.
Let 𝐼 be the set of generators of this ideal. The check is performed by trying to lift 𝑆𝑦𝑧(𝐿𝑀 (𝐼)) to 𝑆𝑦𝑧(𝐼)as 𝐼 forms a Groebner basis if and only if for every element 𝑆 in 𝑆𝑦𝑧(𝐿𝑀 (𝐼)):
𝑆*𝐺=

𝑚
∑︁

ℎ𝑖 𝑔𝑖 − − − − >𝐺 0.

𝑖=0

ALGORITHM:
Uses Singular.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127), 10)
sage: I = sage.rings.ideal.Cyclic(R, 4)
sage: I.basis_is_groebner()
False
sage: I2 = Ideal(I.groebner_basis())
sage: I2.basis_is_groebner()True>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(127)), Integer(10), names=( a , b , c ,˓→ ,e , f , g , h , i , j ,)); (a, b, c, d, e, f, g, h, i, j,) = R._
˓→first_ngens(10)d(continues on next page)

636

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> I = sage.rings.ideal.Cyclic(R, Integer(4))>>> I.basis_is_groebner()
False>>> I2 = Ideal(I.groebner_basis())>>> I2.basis_is_groebner()True

A more complicated example:
sage: R.<U6,U5,U4,U3,U2, u6,u5,u4,u3,u2, h> = PolynomialRing(GF(7583))#␣˓→needs sage.rings.finite_rings
sage: l = [u6 + u5 + u4 + u3 + u2 - 3791*h,#␣˓→needs sage.rings.finite_rings....:
U6 + U5 + U4 + U3 + U2 - 3791*h,....:U2*u2 - h^2, U3*u3 - h^2, U4*u4 - h^2,....:
U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - 3791*U5*h....:- 3791*U4*h - 3791*U3*h - 3791*U2*h - 2842*h^2,....:U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - 3791*u5*h....:- 3791*u4*h - 3791*u3*h - 3791*u2*h - 2842*h^2,....:U5*u5 - h^2, U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3^2*u2 -␣
˓→3791*U5*U3*h....:- 3791*U4*U3*h - 3791*U3^2*h - 3791*U5*U2*h- 3791*U4*U2*h +␣
˓→U3*U2*h....:- 3791*U2^2*h - 3791*U4*u3*h - 3791*U4*u2*h - 3791*U3*u2*h....:- 2843*U5*h^2 + 1897*U4*h^2 - 946*U3*h^2 - 947*U2*h^2 + 2370*h^3,....:U3*u5*u4 + U2*u5*u4 + U3*u4^2 + U2*u4^2 + U2*u4*u3 - 3791*u5*u4*h....:- 3791*u4^2*h - 3791*u4*u3*h - 3791*u4*u2*h + u5*h^2 - 2842*u4*h^
˓→2,
....:
U2*u5*u4*u3 + U2*u4^2*u3 + U2*u4*u3^2 - 3791*u5*u4*u3*h....:- 3791*u4^2*u3*h - 3791*u4*u3^2*h - 3791*u4*u3*u2*h + u5*u4*h^2....:+ u4^2*h^2 + u5*u3*h^2 - 2842*u4*u3*h^2,....:U5^2*U4*u3 + U5*U4^2*u3 + U5^2*U4*u2 + U5*U4^2*u2 + U5^2*U3*u2....:+ 2*U5*U4*U3*u2 + U5*U3^2*u2 - 3791*U5^2*U4*h - 3791*U5*U4^2*h....:- 3791*U5^2*U3*h + U5*U4*U3*h - 3791*U5*U3^2*h - 3791*U5^2*U2*h....:+ U5*U4*U2*h+ U5*U3*U2*h - 3791*U5*U2^2*h - 3791*U5*U3*u2*h....:- 2842*U5^2*h^2 + 1897*U5*U4*h^2 - U4^2*h^2 - 947*U5*U3*h^2....:- U4*U3*h^2 - 948*U5*U2*h^2 - U4*U2*h^2 - 1422*U5*h^3 +␣
˓→3791*U4*h^3,....:
u5*u4*u3*u2*h + u4^2*u3*u2*h + u4*u3^2*u2*h + u4*u3*u2^2*h....:+ 2*u5*u4*u3*h^2 + 2*u4^2*u3*h^2 + 2*u4*u3^2*h^2 + 2*u5*u4*u2*h^2....:+ 2*u4^2*u2*h^2 + 2*u5*u3*u2*h^2 + 1899*u4*u3*u2*h^2,....:U5^2*U4*U3*u2 + U5*U4^2*U3*u2 + U5*U4*U3^2*u2 - 3791*U5^2*U4*U3*h....:- 3791*U5*U4^2*U3*h - 3791*U5*U4*U3^2*h - 3791*U5*U4*U3*U2*h....:+ 3791*U5*U4*U3*u2*h + U5^2*U4*h^2 + U5*U4^2*h^2 + U5^2*U3*h^2....:- U4^2*U3*h^2 - U5*U3^2*h^2 - U4*U3^2*h^2 - U5*U4*U2*h^2 -␣
˓→U5*U3*U2*h^2....:- U4*U3*U2*h^2 + 3791*U5*U4*h^3 + 3791*U5*U3*h^3 + 3791*U4*U3*h^
˓→3,
....:
u4^2*u3*u2*h^2 + 1515*u5*u3^2*u2*h^2 + u4*u3^2*u2*h^2....:+ 1515*u5*u4*u2^2*h^2 + 1515*u5*u3*u2^2*h^2 + u4*u3*u2^2*h^2....:+ 1521*u5*u4*u3*h^3 - 3028*u4^2*u3*h^3 - 3028*u4*u3^2*h^3....:+ 1521*u5*u4*u2*h^3 - 3028*u4^2*u2*h^3 + 1521*u5*u3*u2*h^3....:+ 3420*u4*u3*u2*h^3,....:U5^2*U4*U3*U2*h + U5*U4^2*U3*U2*h + U5*U4*U3^2*U2*h + U5*U4*U3*U2^
˓→2*h
....:
+ 2*U5^2*U4*U3*h^2 + 2*U5*U4^2*U3*h^2 + 2*U5*U4*U3^2*h^2....:+ 2*U5^2*U4*U2*h^2 + 2*U5*U4^2*U2*h^2 + 2*U5^2*U3*U2*h^2(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

637

Polynomials, Release 10.4

(continued from previous page)

....:
....:
....:

- 2*U4^2*U3*U2*h^2 - 2*U5*U3^2*U2*h^2 - 2*U4*U3^2*U2*h^2- 2*U5*U4*U2^2*h^2 - 2*U5*U3*U2^2*h^2 - 2*U4*U3*U2^2*h^2- U5*U4*U3*h^3 - U5*U4*U2*h^3 - U5*U3*U2*h^3 - U4*U3*U2*h^3]

sage: Ideal(l).basis_is_groebner()
˓→needs sage.rings.finite_rings
False
sage: gb = Ideal(l).groebner_basis()
˓→needs sage.rings.finite_rings
sage: Ideal(gb).basis_is_groebner()
˓→needs sage.rings.finite_rings
True

#␣

#␣
#␣

>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(7583)), names=( U6 , U5 , U4 , U3 , U2 ,
˓→
u6 , u5 , u4 , u3 , u2 , h ,)); (U6, U5, U4, U3, U2, u6, u5, u4, u3,␣˓→u2, h,) = R._first_ngens(11)# needs sage.rings.finite_rings>>> l = [u6 + u5 + u4 + u3 + u2 - Integer(3791)*h,␣˓→# needs sage.rings.finite_rings...
U6 + U5 + U4 + U3 + U2 - Integer(3791)*h,...
U2*u2 - h**Integer(2), U3*u3 - h**Integer(2), U4*u4 - h**Integer(2),...
U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - Integer(3791)*U5*h...
- Integer(3791)*U4*h - Integer(3791)*U3*h - Integer(3791)*U2*h -␣˓→Integer(2842)*h**Integer(2),...
U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - Integer(3791)*u5*h...
- Integer(3791)*u4*h - Integer(3791)*u3*h - Integer(3791)*u2*h -␣˓→Integer(2842)*h**Integer(2),...
U5*u5 - h**Integer(2), U4*U2*u3 + U5*U3*u2 + U4*U3*u2 +␣˓→U3**Integer(2)*u2 - Integer(3791)*U5*U3*h...
- Integer(3791)*U4*U3*h - Integer(3791)*U3**Integer(2)*h -␣˓→Integer(3791)*U5*U2*h- Integer(3791)*U4*U2*h + U3*U2*h...
- Integer(3791)*U2**Integer(2)*h - Integer(3791)*U4*u3*h -␣˓→Integer(3791)*U4*u2*h - Integer(3791)*U3*u2*h...
- Integer(2843)*U5*h**Integer(2) + Integer(1897)*U4*h**Integer(2) ˓→ Integer(946)*U3*h**Integer(2) - Integer(947)*U2*h**Integer(2) +␣˓→Integer(2370)*h**Integer(3),...
U3*u5*u4 + U2*u5*u4 + U3*u4**Integer(2) + U2*u4**Integer(2) +␣˓→U2*u4*u3 - Integer(3791)*u5*u4*h...
- Integer(3791)*u4**Integer(2)*h - Integer(3791)*u4*u3*h -␣˓→Integer(3791)*u4*u2*h + u5*h**Integer(2) - Integer(2842)*u4*h**Integer(2),...
U2*u5*u4*u3 + U2*u4**Integer(2)*u3 + U2*u4*u3**Integer(2) -␣˓→Integer(3791)*u5*u4*u3*h...
- Integer(3791)*u4**Integer(2)*u3*h -␣˓→Integer(3791)*u4*u3**Integer(2)*h - Integer(3791)*u4*u3*u2*h +␣
˓→u5*u4*h**Integer(2)...
+ u4**Integer(2)*h**Integer(2) + u5*u3*h**Integer(2) -␣˓→Integer(2842)*u4*u3*h**Integer(2),...
U5**Integer(2)*U4*u3 + U5*U4**Integer(2)*u3 + U5**Integer(2)*U4*u2 +␣
˓→U5*U4**Integer(2)*u2 + U5**Integer(2)*U3*u2...
+ Integer(2)*U5*U4*U3*u2 + U5*U3**Integer(2)*u2 -␣˓→Integer(3791)*U5**Integer(2)*U4*h - Integer(3791)*U5*U4**Integer(2)*h...
- Integer(3791)*U5**Integer(2)*U3*h + U5*U4*U3*h -␣˓→Integer(3791)*U5*U3**Integer(2)*h - Integer(3791)*U5**Integer(2)*U2*h...
+ U5*U4*U2*h+ U5*U3*U2*h - Integer(3791)*U5*U2**Integer(2)*h -␣˓→Integer(3791)*U5*U3*u2*h...
- Integer(2842)*U5**Integer(2)*h**Integer(2) +␣
(continues on next page)

638

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(1897)*U5*U4*h**Integer(2) - U4**Integer(2)*h**Integer(2) -␣˓→Integer(947)*U5*U3*h**Integer(2)...
- U4*U3*h**Integer(2) - Integer(948)*U5*U2*h**Integer(2) -␣˓→U4*U2*h**Integer(2) - Integer(1422)*U5*h**Integer(3) +␣˓→Integer(3791)*U4*h**Integer(3),...
u5*u4*u3*u2*h + u4**Integer(2)*u3*u2*h + u4*u3**Integer(2)*u2*h +␣
˓→u4*u3*u2**Integer(2)*h...
+ Integer(2)*u5*u4*u3*h**Integer(2) +␣˓→Integer(2)*u4**Integer(2)*u3*h**Integer(2) +␣˓→Integer(2)*u4*u3**Integer(2)*h**Integer(2) +␣˓→Integer(2)*u5*u4*u2*h**Integer(2)...
+ Integer(2)*u4**Integer(2)*u2*h**Integer(2) +␣˓→Integer(2)*u5*u3*u2*h**Integer(2) + Integer(1899)*u4*u3*u2*h**Integer(2),...
U5**Integer(2)*U4*U3*u2 + U5*U4**Integer(2)*U3*u2 +␣
˓→U5*U4*U3**Integer(2)*u2 - Integer(3791)*U5**Integer(2)*U4*U3*h...
- Integer(3791)*U5*U4**Integer(2)*U3*h -␣˓→Integer(3791)*U5*U4*U3**Integer(2)*h - Integer(3791)*U5*U4*U3*U2*h...
+ Integer(3791)*U5*U4*U3*u2*h + U5**Integer(2)*U4*h**Integer(2) +␣˓→U5*U4**Integer(2)*h**Integer(2) + U5**Integer(2)*U3*h**Integer(2)...
- U4**Integer(2)*U3*h**Integer(2) -␣˓→U5*U3**Integer(2)*h**Integer(2) - U4*U3**Integer(2)*h**Integer(2) -␣˓→U5*U4*U2*h**Integer(2) - U5*U3*U2*h**Integer(2)...
- U4*U3*U2*h**Integer(2) + Integer(3791)*U5*U4*h**Integer(3) +␣˓→Integer(3791)*U5*U3*h**Integer(3) + Integer(3791)*U4*U3*h**Integer(3),...
u4**Integer(2)*u3*u2*h**Integer(2) +␣˓→Integer(1515)*u5*u3**Integer(2)*u2*h**Integer(2) +␣˓→u4*u3**Integer(2)*u2*h**Integer(2)...
+ Integer(1515)*u5*u4*u2**Integer(2)*h**Integer(2) +␣˓→Integer(1515)*u5*u3*u2**Integer(2)*h**Integer(2) +␣˓→u4*u3*u2**Integer(2)*h**Integer(2)...
+ Integer(1521)*u5*u4*u3*h**Integer(3) -␣˓→Integer(3028)*u4**Integer(2)*u3*h**Integer(3) -␣˓→Integer(3028)*u4*u3**Integer(2)*h**Integer(3)...
+ Integer(1521)*u5*u4*u2*h**Integer(3) -␣˓→Integer(3028)*u4**Integer(2)*u2*h**Integer(3) +␣˓→Integer(1521)*u5*u3*u2*h**Integer(3)...
+ Integer(3420)*u4*u3*u2*h**Integer(3),...
U5**Integer(2)*U4*U3*U2*h + U5*U4**Integer(2)*U3*U2*h +␣
˓→U5*U4*U3**Integer(2)*U2*h + U5*U4*U3*U2**Integer(2)*h...
+ Integer(2)*U5**Integer(2)*U4*U3*h**Integer(2) +␣˓→Integer(2)*U5*U4**Integer(2)*U3*h**Integer(2) +␣˓→Integer(2)*U5*U4*U3**Integer(2)*h**Integer(2)...
+ Integer(2)*U5**Integer(2)*U4*U2*h**Integer(2) +␣˓→Integer(2)*U5*U4**Integer(2)*U2*h**Integer(2) +␣˓→Integer(2)*U5**Integer(2)*U3*U2*h**Integer(2)...
- Integer(2)*U4**Integer(2)*U3*U2*h**Integer(2) -␣˓→Integer(2)*U5*U3**Integer(2)*U2*h**Integer(2) -␣˓→Integer(2)*U4*U3**Integer(2)*U2*h**Integer(2)...
- Integer(2)*U5*U4*U2**Integer(2)*h**Integer(2) -␣˓→Integer(2)*U5*U3*U2**Integer(2)*h**Integer(2) -␣˓→Integer(2)*U4*U3*U2**Integer(2)*h**Integer(2)...
- U5*U4*U3*h**Integer(3) - U5*U4*U2*h**Integer(3) -␣˓→U5*U3*U2*h**Integer(3) - U4*U3*U2*h**Integer(3)]˓→>>> Ideal(l).basis_is_groebner()
˓→needs sage.rings.finite_rings
False

#␣

(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

639

Polynomials, Release 10.4

(continued from previous page)>>> gb = Ideal(l).groebner_basis()
˓→needs sage.rings.finite_rings>>> Ideal(gb).basis_is_groebner()
˓→needs sage.rings.finite_rings
True

#␣
#␣

Note: From the Singular Manual for the reduce function we use in this method: ‘The result may have no
meaning if the second argument (self) is not a standard basis’. I (malb) believe this refers to the mathematical fact that the results may have no meaning if self is no standard basis, i.e., Singular doesn’t ‘add’ any
additional ‘nonsense’ to the result. So we may actually use reduce to determine if self is a Groebner basis.
complete_primary_decomposition()A decorator that creates a cached version of an instance method of a class.
Note: For proper behavior, the method must be a pure function (no side effects). Arguments to themethod must be hashable or transformed into something hashable using key or they must define sage.
structure.sage_object.SageObject._cache_key().
EXAMPLES:
sage: class Foo():....:@cached_method....:
def f(self, t, x=2):....:
print( computing )....:return t**x
sage: a = Foo()>>> from sage.all import *>>> class Foo():...
@cached_method...
def f(self, t, x=Integer(2)):...
print( computing )...
return t**x>>> a = Foo()

The example shows that the actual computation takes place only once, and that the result is identical forequivalent input:
sage: res = a.f(3, 2); rescomputing9sage: a.f(t = 3, x = 2) is res
True
sage: a.f(3) is res
True>>> from sage.all import *>>> res = a.f(Integer(3), Integer(2)); rescomputing9>>> a.f(t = Integer(3), x = Integer(2)) is res
True(continues on next page)

640

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> a.f(Integer(3)) is res
True

Note, however, that the CachedMethod is replaced by a CachedMethodCaller or CachedMethodCallerNoArgs as soon as it is bound to an instance or class:sage: P.<a,b,c,d> = QQ[]
sage: I = P*[a,b]sage: type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >>>> from sage.all import *>>> P = QQ[ a, b, c, d ]; (a, b, c, d,) = P._first_ngens(4)>>> I = P*[a,b]>>> type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >So, you would hardly ever see an instance of this class alive.
The parameter key can be used to pass a function which creates a custom cache key for inputs. In thefollowing example, this parameter is used to ignore the algorithm keyword for caching:sage: class A():....:def _f_normalize(self, x, algorithm): return x....:@cached_method(key=_f_normalize)....:
def f(self, x, algorithm= default ): return xsage: a = A()
sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm")True>>> from sage.all import *>>> class A():...
def _f_normalize(self, x, algorithm): return x...
@cached_method(key=_f_normalize)...
def f(self, x, algorithm= default ): return x>>> a = A()>>> a.f(Integer(1), algorithm="default") is a.f(Integer(1)) is a.f(Integer(1),˓→ algorithm="algorithm")
True

The parameter do_pickle can be used to enable pickling of the cache. Usually the cache is not stored
when pickling:sage: class A():....:@cached_method....:
def f(self, x): return Nonesage: import __main__sage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))
sage: len(b.f.cache)03.1. Multivariate Polynomials and Polynomial Rings

641

Polynomials, Release 10.4>>> from sage.all import *>>> class A():...
@cached_method...
def f(self, x): return None>>> import __main__>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))>>> len(b.f.cache)0

When do_pickle is set, the pickle contains the contents of the cache:sage: class A():....:@cached_method(do_pickle=True)....:def f(self, x): return Nonesage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))
sage: len(b.f.cache)1>>> from sage.all import *>>> class A():...
@cached_method(do_pickle=True)...
def f(self, x): return None>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))>>> len(b.f.cache)
1

Cached methods cannot be copied like usual methods, see Issue #12603. Copying them can lead to very
surprising results:
sage: class A:....:@cached_method....:
def f(self):....:
return 1
sage: class B:
....:
g=A.f
....:
def f(self):....:
return 2
sage: b=B()
sage: b.f()2
sage: b.g()(continues on next page)

642

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)1
sage: b.f()
1>>> from sage.all import *>>> class A:...
@cached_method...
def f(self):...
return Integer(1)>>> class B:
...
g=A.f
...
def f(self):...
return Integer(2)>>> b=B()>>> b.f()2>>> b.g()
1>>> b.f()1

dimension(singular=None)
The dimension of the ring modulo this ideal.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(32003), order= degrevlex )˓→needs sage.rings.finite_rings
sage: I = ideal(x^2 - y, x^3)
˓→needs sage.rings.finite_rings
sage: I.dimension()
˓→needs sage.rings.finite_rings
1

#␣
#␣
#␣

>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(32003)), order= degrevlex , names=( x , y ,˓→z ,)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.finite_rings>>> I = ideal(x**Integer(2) - y, x**Integer(3))␣˓→# needs sage.rings.finite_rings>>> I.dimension()#␣˓→needs sage.rings.finite_rings
1

If the ideal is the total ring, the dimension is −1 by convention.
For polynomials over a finite field of order too large for Singular, this falls back on a toy implementation of
Buchberger to compute the Groebner basis, then uses the algorithm described in Chapter 9, Section 1 of Cox,
Little, and O’Shea’s “Ideals, Varieties, and Algorithms”.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: R.<x,y> = PolynomialRing(GF(2147483659^2), order= lex )sage: I = R.ideal([x*y, x*y + 1])
sage: I.dimension()(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

643

Polynomials, Release 10.4

(continued from previous page)

verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
-1sage: I=ideal([x*(x*y+1), y*(x*y+1)])
sage: I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
1sage: I = R.ideal([x^3*y, x*y^2])
sage: I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
1sage: R.<x,y> = PolynomialRing(GF(2147483659^2), order= lex )sage: I = R.ideal(0)sage: I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
2>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(2147483659)**Integer(2)), order= lex ,␣
˓→names=( x ,y ,)); (x, y,) = R._first_ngens(2)>>> I = R.ideal([x*y, x*y + Integer(1)])>>> I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
-1>>> I=ideal([x*(x*y+Integer(1)), y*(x*y+Integer(1))])>>> I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
1>>> I = R.ideal([x**Integer(3)*y, x*y**Integer(2)])>>> I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
1>>> R = PolynomialRing(GF(Integer(2147483659)**Integer(2)), order= lex ,␣
˓→names=( x ,y ,)); (x, y,) = R._first_ngens(2)>>> I = R.ideal(Integer(0))>>> I.dimension()verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
2

ALGORITHM:
Uses Singular, unless the characteristic is too large.
Note: Requires computation of a Groebner basis, which can be a very expensive operation.
elimination_ideal(variables, algorithm=None, *args, **kwds)
Return the elimination ideal of this ideal with respect to the variables given in variables.

644

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

INPUT:• variables – a list or tuple of variables in self.ring()• algorithm – determines the algorithm to use, see below for available algorithms.
ALGORITHMS:•

libsingular:eliminate – libSingular’s eliminate command (default)•

giac:eliminate – Giac’s eliminate command (if available)

If only a system is given - e.g. ‘giac’ - the default algorithm is chosen for that system.
EXAMPLES:
sage: R.<x,y,t,s,z> = PolynomialRing(QQ,5)
sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3]
sage: J = I.elimination_ideal([t, s]); J
Ideal (y^2 - x*z, x*y - z, x^2 - y)of Multivariate Polynomial Ring in x, y, t, s, z over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ,Integer(5), names=( x , y , t , s , z ,)); (x,␣˓→y, t, s, z,) = R._first_ngens(5)>>> I = R * [x - t, y - t**Integer(2), z - t**Integer(3), s - x +␣˓→y**Integer(3)]>>> J = I.elimination_ideal([t, s]); J
Ideal (y^2 - x*z, x*y - z, x^2 - y)of Multivariate Polynomial Ring in x, y, t, s, z over Rational Field

You can use Giac to compute the elimination ideal:
sage: print("possible output from giac", flush=True); I.elimination_ideal([t,␣˓→s], algorithm="giac") == J
possible output...
True>>> from sage.all import *>>> print("possible output from giac", flush=True); I.elimination_ideal([t,␣˓→s], algorithm="giac") == J
possible output...
True

The list of available Giac options is provided at sage.libs.giac.groebner_basis().
ALGORITHM:
Uses Singular, or Giac (if available).
Note: Requires computation of a Groebner basis, which can be a very expensive operation.
free_resolution(*args, **kwds)
Return a free resolution of self.
For input options, see FreeResolution.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

645

Polynomials, Release 10.4

sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 2*x^2 + ysage: g = ysage: h = 2*f + g
sage: I = R.ideal([f,g,h])sage: res = I.free_resolution()sage: resS^1 <-- S^2 <-- S^1 <-- 0
sage: ascii_art(res.chain_complex())[-x^2][ y x^2][y]
0 <-- C_0 <---------- C_1 <------- C_2 <-- 0
sage: q = ZZ[ q ].fraction_field().gen()sage: R.<x,y,z> = q.parent()[]sage: I = R.ideal([x^2+y^2+z^2, x*y*z^4])
sage: I.free_resolution()
Traceback (most recent call last):...
NotImplementedError: the ring must be a polynomial ring using Singular>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = Integer(2)*x**Integer(2) + y>>> g = y>>> h = Integer(2)*f + g>>> I = R.ideal([f,g,h])>>> res = I.free_resolution()>>> resS^1 <-- S^2 <-- S^1 <-- 0>>> ascii_art(res.chain_complex())[-x^2][ y x^2][y]
0 <-- C_0 <---------- C_1 <------- C_2 <-- 0>>> q = ZZ[ q ].fraction_field().gen()>>> R = q.parent()[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> I = R.ideal([x**Integer(2)+y**Integer(2)+z**Integer(2),␣
˓→x*y*z**Integer(4)])>>> I.free_resolution()
Traceback (most recent call last):...
NotImplementedError: the ring must be a polynomial ring using Singulargenus()
A decorator that creates a cached version of an instance method of a class.
Note: For proper behavior, the method must be a pure function (no side effects). Arguments to themethod must be hashable or transformed into something hashable using key or they must define sage.
structure.sage_object.SageObject._cache_key().
EXAMPLES:
sage: class Foo():....:@cached_method(continues on next page)

646

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)....:def f(self, t, x=2):....:
print( computing )....:return t**x
sage: a = Foo()>>> from sage.all import *>>> class Foo():...
@cached_method...
def f(self, t, x=Integer(2)):...
print( computing )...
return t**x>>> a = Foo()

The example shows that the actual computation takes place only once, and that the result is identical forequivalent input:
sage: res = a.f(3, 2); rescomputing9sage: a.f(t = 3, x = 2) is res
True
sage: a.f(3) is res
True>>> from sage.all import *>>> res = a.f(Integer(3), Integer(2)); rescomputing9>>> a.f(t = Integer(3), x = Integer(2)) is res
True>>> a.f(Integer(3)) is res
True

Note, however, that the CachedMethod is replaced by a CachedMethodCaller or CachedMethodCallerNoArgs as soon as it is bound to an instance or class:sage: P.<a,b,c,d> = QQ[]
sage: I = P*[a,b]sage: type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >>>> from sage.all import *>>> P = QQ[ a, b, c, d ]; (a, b, c, d,) = P._first_ngens(4)>>> I = P*[a,b]>>> type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >So, you would hardly ever see an instance of this class alive.
The parameter key can be used to pass a function which creates a custom cache key for inputs. In thefollowing example, this parameter is used to ignore the algorithm keyword for caching:sage: class A():....:def _f_normalize(self, x, algorithm): return x....:@cached_method(key=_f_normalize)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

647

Polynomials, Release 10.4

(continued from previous page)....:def f(self, x, algorithm= default ): return xsage: a = A()
sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm")True>>> from sage.all import *>>> class A():...
def _f_normalize(self, x, algorithm): return x...
@cached_method(key=_f_normalize)...
def f(self, x, algorithm= default ): return x>>> a = A()>>> a.f(Integer(1), algorithm="default") is a.f(Integer(1)) is a.f(Integer(1),˓→ algorithm="algorithm")
True

The parameter do_pickle can be used to enable pickling of the cache. Usually the cache is not stored
when pickling:sage: class A():....:@cached_method....:
def f(self, x): return Nonesage: import __main__sage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))
sage: len(b.f.cache)0>>> from sage.all import *>>> class A():...
@cached_method...
def f(self, x): return None>>> import __main__>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))>>> len(b.f.cache)0

When do_pickle is set, the pickle contains the contents of the cache:sage: class A():....:@cached_method(do_pickle=True)....:def f(self, x): return Nonesage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))(continues on next page)

648

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: len(b.f.cache)1>>> from sage.all import *>>> class A():...
@cached_method(do_pickle=True)...
def f(self, x): return None>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))>>> len(b.f.cache)
1

Cached methods cannot be copied like usual methods, see Issue #12603. Copying them can lead to very
surprising results:
sage: class A:....:@cached_method....:
def f(self):....:
return 1
sage: class B:
....:
g=A.f
....:
def f(self):....:
return 2
sage: b=B()
sage: b.f()2
sage: b.g()
1
sage: b.f()
1>>> from sage.all import *>>> class A:...
@cached_method...
def f(self):...
return Integer(1)>>> class B:
...
g=A.f
...
def f(self):...
return Integer(2)>>> b=B()>>> b.f()2>>> b.g()
1>>> b.f()
1

graded_free_resolution(*args, **kwds)
Return a graded free resolution of self.
3.1. Multivariate Polynomials and Polynomial Rings

649

Polynomials, Release 10.4

For input options, see GradedFreeResolution.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 2*x^2 + y^2
sage: g = y^2
sage: h = 2*f + g
sage: I = R.ideal([f,g,h])sage: I.graded_free_resolution(shifts=[1])S(-1) <-- S(-3)⊕S(-3) <-- S(-5) <-- 0
sage: f = 2*x^2 + ysage: g = ysage: h = 2*f + g
sage: I = R.ideal([f,g,h])sage: I.graded_free_resolution(degrees=[1,2])
S(0) <-- S(-2)⊕S(-2) <-- S(-4) <-- 0
sage: q = ZZ[ q ].fraction_field().gen()sage: R.<x,y,z> = q.parent()[]sage: I = R.ideal([x^2+y^2+z^2, x*y*z^4])
sage: I.graded_free_resolution()
Traceback (most recent call last):...
NotImplementedError: the ring must be a polynomial ring using Singular>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = Integer(2)*x**Integer(2) + y**Integer(2)>>> g = y**Integer(2)>>> h = Integer(2)*f + g>>> I = R.ideal([f,g,h])>>> I.graded_free_resolution(shifts=[Integer(1)])S(-1) <-- S(-3)⊕S(-3) <-- S(-5) <-- 0>>> f = Integer(2)*x**Integer(2) + y>>> g = y>>> h = Integer(2)*f + g>>> I = R.ideal([f,g,h])>>> I.graded_free_resolution(degrees=[Integer(1),Integer(2)])S(0) <-- S(-2)⊕S(-2) <-- S(-4) <-- 0>>> q = ZZ[ q ].fraction_field().gen()>>> R = q.parent()[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> I = R.ideal([x**Integer(2)+y**Integer(2)+z**Integer(2),␣
˓→x*y*z**Integer(4)])>>> I.graded_free_resolution()
Traceback (most recent call last):...
NotImplementedError: the ring must be a polynomial ring using Singularhilbert_numerator(grading=None, algorithm='sage')
Return the Hilbert numerator of this ideal.
INPUT:• grading – (optional) a list or tuple of integers• algorithm – (default: sage ) must be either sage or singular
650

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

⨁︀Let 𝐼 (which is self) be a homogeneous ideal and 𝑅 = 𝑑 𝑅𝑑 (which is self.ring()) be a graded
commutative algebra over a field 𝐾. Then the Hilbert function∑︀∞is defined as 𝐻(𝑑) = dim𝐾 𝑅𝑑 and the Hilbert
series of 𝐼 is defined as the formal power series 𝐻𝑆(𝑡) = 𝑑=0 𝐻(𝑑)𝑡𝑑 .
This power series can be expressed as 𝐻𝑆(𝑡) = 𝑄(𝑡)/(1 − 𝑡)𝑛 where 𝑄(𝑡) is a polynomial over Z and 𝑛
the number of variables in 𝑅. This method returns 𝑄(𝑡), the numerator; hence the name, hilbert_numerator. An optional grading can be given, in which case the graded (or weighted) Hilbert numerator
is given.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
sage: I.hilbert_numerator()˓→needs sage.libs.flint-t^5 + 1
sage: R.<a,b> = PolynomialRing(QQ)
sage: J = R.ideal([a^2*b, a*b^2])
sage: J.hilbert_numerator()˓→needs sage.libs.flintt^4 - 2*t^3 + 1
sage: J.hilbert_numerator(grading=(10,3))
˓→needs sage.libs.flintt^26 - t^23 - t^16 + 1

#␣

#␣

#␣

>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> I = Ideal([x**Integer(3)*y**Integer(2) +␣˓→Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) +␣˓→z**Integer(5)])>>> I.hilbert_numerator()#␣˓→needs sage.libs.flint-t^5 + 1>>> R = PolynomialRing(QQ, names=( a , b ,)); (a, b,) = R._first_ngens(2)>>> J = R.ideal([a**Integer(2)*b, a*b**Integer(2)])>>> J.hilbert_numerator()#␣˓→needs sage.libs.flintt^4 - 2*t^3 + 1>>> J.hilbert_numerator(grading=(Integer(10),Integer(3)))␣˓→# needs sage.libs.flintt^26 - t^23 - t^16 + 1

hilbert_polynomial(algorithm='sage')
Return the Hilbert polynomial of this ideal.
INPUT:• algorithm – (default: sage ) must be either sage or singular⨁︀
Let 𝐼 (which is self) be a homogeneous ideal and 𝑅 = 𝑑 𝑅𝑑 (which is self.ring()) be a graded
commutative algebra over a field 𝐾. The Hilbert polynomial is the unique polynomial 𝐻𝑃 (𝑡) with rationalcoefficients such that 𝐻𝑃 (𝑑) = dim𝐾 𝑅𝑑 for all but finitely many positive integers 𝑑.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
sage: I.hilbert_polynomial()#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

651

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.flint
5*t - 5˓→>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> I = Ideal([x**Integer(3)*y**Integer(2) +␣˓→Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) +␣˓→z**Integer(5)])>>> I.hilbert_polynomial()#␣˓→needs sage.libs.flint
5*t - 5

Of course, the Hilbert polynomial of a zero-dimensional ideal is zero:sage: J0 = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5,....:y^3 - 2*x*z^2 + x*y, x^4 + x*y - y*z^2])
sage: J = P*[m.lm() for m in J0.groebner_basis()]sage: J.dimension()0
sage: J.hilbert_polynomial()
˓→needs sage.libs.flint0#␣>>> from sage.all import *>>> J0 = Ideal([x**Integer(3)*y**Integer(2) +␣˓→Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) +␣˓→z**Integer(5),...
y**Integer(3) - Integer(2)*x*z**Integer(2) + x*y,␣
˓→x**Integer(4) + x*y - y*z**Integer(2)])>>> J = P*[m.lm() for m in J0.groebner_basis()]>>> J.dimension()0>>> J.hilbert_polynomial()#␣˓→needs sage.libs.flint0

It is possible to request a computation using the Singular library:sage: I.hilbert_polynomial(algorithm= singular ) == I.hilbert_polynomial()
˓→needs sage.libs.flint
True
sage: J.hilbert_polynomial(algorithm= singular ) == J.hilbert_polynomial()
˓→needs sage.libs.flint
True>>> from sage.all import *>>> I.hilbert_polynomial(algorithm= singular ) == I.hilbert_polynomial()
˓→needs sage.libs.flint
True>>> J.hilbert_polynomial(algorithm= singular ) == J.hilbert_polynomial()
˓→needs sage.libs.flint
True

#␣

#␣

#␣

#␣

Here is a bigger examples:

652

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: n = 4; m = 11; P = PolynomialRing(QQ, n * m, "x"); x = P.gens()
sage: M = Matrix(n, x)
sage: Minors = P.ideal(M.minors(2))
sage: hp = Minors.hilbert_polynomial(); hp
˓→needs sage.libs.flint
1/21772800*t^13 + 61/21772800*t^12 + 1661/21772800*t^11+ 26681/21772800*t^10 + 93841/7257600*t^9 + 685421/7257600*t^8+ 1524809/3110400*t^7 + 39780323/21772800*t^6 + 6638071/1360800*t^5+ 12509761/1360800*t^4 + 2689031/226800*t^3 + 1494509/151200*t^2+ 12001/2520*t + 1#␣>>> from sage.all import *>>> n = Integer(4); m = Integer(11); P = PolynomialRing(QQ, n * m, "x"); x =␣˓→P.gens()>>> M = Matrix(n, x)>>> Minors = P.ideal(M.minors(Integer(2)))>>> hp = Minors.hilbert_polynomial(); hp#␣˓→needs sage.libs.flint
1/21772800*t^13 + 61/21772800*t^12 + 1661/21772800*t^11+ 26681/21772800*t^10 + 93841/7257600*t^9 + 685421/7257600*t^8+ 1524809/3110400*t^7 + 39780323/21772800*t^6 + 6638071/1360800*t^5+ 12509761/1360800*t^4 + 2689031/226800*t^3 + 1494509/151200*t^2+ 12001/2520*t + 1

Because Singular uses 32-bit integers, the above example would fail with Singular. We don’t test it here, as it
has a side-effect on other tests that is not understood yet (see Issue #26300):
sage: Minors.hilbert_polynomial(algorithm= singular )Traceback (most recent call last):...
RuntimeError: error in Singular function call hilbPoly :int overflow in hilb 1
error occurred in or before poly.lib::hilbPoly line 58:
˓→2);expected intvec-expression. type help intvec;# not tested

intvec v=hilb(I,>>> from sage.all import *>>> Minors.hilbert_polynomial(algorithm= singular )# not tested
Traceback (most recent call last):...
RuntimeError: error in Singular function call hilbPoly :int overflow in hilb 1
error occurred in or before poly.lib::hilbPoly line 58:
intvec v=hilb(I,˓→2);
expected intvec-expression. type help intvec;

Note that in this example, the Hilbert polynomial gives the coefficients of the Hilbert-Poincaré series in all
degrees:sage: P = PowerSeriesRing(QQ, t , default_prec=50)
sage: hs = Minors.hilbert_series()#␣˓→needs sage.libs.flint
sage: list(P(hs.numerator()) / P(hs.denominator())) == [hp(t=k)#␣˓→needs sage.libs.flint....:
for k in range(50)]True

3.1. Multivariate Polynomials and Polynomial Rings

653

Polynomials, Release 10.4>>> from sage.all import *>>> P = PowerSeriesRing(QQ, t , default_prec=Integer(50))>>> hs = Minors.hilbert_series()
˓→needs sage.libs.flint>>> list(P(hs.numerator()) / P(hs.denominator())) == [hp(t=k)˓→needs sage.libs.flint...
for k in␣
˓→range(Integer(50))]
True

#␣
#␣

hilbert_series(grading=None, algorithm='sage')
Return the Hilbert series of this ideal.
INPUT:• grading – (optional) a list or tuple of integers• algorithm – (default: sage ) must be either sage or singular⨁︀
Let 𝐼 (which is self) be a homogeneous ideal and 𝑅 = 𝑑 𝑅𝑑 (which is self.ring()) be a graded
commutative algebra over a field 𝐾. Then the Hilbert function∑︀∞is defined as 𝐻(𝑑) = dim𝐾 𝑅𝑑 and the Hilbert
series of 𝐼 is defined as the formal power series 𝐻𝑆(𝑡) = 𝑑=0 𝐻(𝑑)𝑡𝑑 .
This power series can be expressed as 𝐻𝑆(𝑡) = 𝑄(𝑡)/(1 − 𝑡)𝑛 where 𝑄(𝑡) is a polynomial over Z and 𝑛 thenumber of variables in 𝑅. This method returns 𝑄(𝑡)/(1 − 𝑡)𝑛 , normalised so that the leading monomial of
the numerator is positive.
An optional grading can be given, in which case the graded (or weighted) Hilbert series is given.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
sage: I.hilbert_series()
˓→needs sage.libs.flint(t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1)
sage: R.<a,b> = PolynomialRing(QQ)
sage: J = R.ideal([a^2*b, a*b^2])
sage: J.hilbert_series()
˓→needs sage.libs.flint(t^3 - t^2 - t - 1)/(t - 1)sage: J.hilbert_series(grading=(10,3))
˓→needs sage.libs.flint(t^25 + t^24 + t^23 - t^15 - t^14 - t^13 - t^12 - t^11
- t^10 - t^9 - t^8 - t^7 - t^6 - t^5 - t^4 - t^3 - t^2- t - 1)/(t^12 + t^11 + t^10 - t^2 - t - 1)

#␣

#␣

#␣

sage: K = R.ideal([a^2*b^3, a*b^4 + a^3*b^2])
sage: K.hilbert_series(grading=[1,2])
˓→needs sage.libs.flint(t^11 + t^8 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^2 - 1)sage: K.hilbert_series(grading=[2,1])
˓→needs sage.libs.flint(2*t^7 - t^6 - t^4 - t^2 - 1)/(t - 1)

#␣#␣>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> I = Ideal([x**Integer(3)*y**Integer(2) +␣
(continues on next page)

654

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) +␣˓→z**Integer(5)])>>> I.hilbert_series()#␣˓→needs sage.libs.flint(t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1)>>> R = PolynomialRing(QQ, names=( a , b ,)); (a, b,) = R._first_ngens(2)>>> J = R.ideal([a**Integer(2)*b, a*b**Integer(2)])>>> J.hilbert_series()#␣˓→needs sage.libs.flint(t^3 - t^2 - t - 1)/(t - 1)>>> J.hilbert_series(grading=(Integer(10),Integer(3)))␣˓→# needs sage.libs.flint(t^25 + t^24 + t^23 - t^15 - t^14 - t^13 - t^12 - t^11
- t^10 - t^9 - t^8 - t^7 - t^6 - t^5 - t^4 - t^3 - t^2- t - 1)/(t^12 + t^11 + t^10 - t^2 - t - 1)
˓→>>> K = R.ideal([a**Integer(2)*b**Integer(3), a*b**Integer(4) +␣˓→a**Integer(3)*b**Integer(2)])>>> K.hilbert_series(grading=[Integer(1),Integer(2)])˓→# needs sage.libs.flint(t^11 + t^8 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^2 - 1)>>> K.hilbert_series(grading=[Integer(2),Integer(1)])˓→# needs sage.libs.flint(2*t^7 - t^6 - t^4 - t^2 - 1)/(t - 1)␣␣integral_closure(p=0, r=True, singular=None)
Let 𝐼 = self.
Return the integral closure of 𝐼, ..., 𝐼 𝑝 , where 𝑠𝐼 is an ideal in the polynomial ring 𝑅 = 𝑘[𝑥(1), ...𝑥(𝑛)]. If
𝑝 is not given, or 𝑝 = 0, compute the closure of all powers up to the maximum degree in 𝑡 occurring in theclosure of 𝑅[𝐼𝑡] (so this is the last power whose closure is not just the sum/product of the smaller). If 𝑟 isgiven and r is True, I.integral_closure() starts with a check whether 𝐼 is already a radical
ideal.
INPUT:• p – powers of 𝐼 (default: 0)• r – check whether self is a radical ideal first (default: True)
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: I = ideal([x^2, x*y^4, y^5])
sage: I.integral_closure()[x^2, x*y^4, y^5, x*y^3]>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> I = ideal([x**Integer(2), x*y**Integer(4), y**Integer(5)])>>> I.integral_closure()[x^2, x*y^4, y^5, x*y^3]

ALGORITHM:
Uses libSINGULAR.
interreduced_basis()If this ideal is spanned by (𝑓1 , ..., 𝑓𝑛 ), return (𝑔1 , ..., 𝑔𝑠 ) such that:
3.1. Multivariate Polynomials and Polynomial Rings

655

Polynomials, Release 10.4

• (𝑓1 , ..., 𝑓𝑛 ) = (𝑔1 , ..., 𝑔𝑠 )• 𝐿𝑇 (𝑔𝑖 ) ̸= 𝐿𝑇 (𝑔𝑗 ) for all 𝑖 ̸= 𝑗
• 𝐿𝑇 (𝑔𝑖 ) does not divide 𝑚 for all monomials 𝑚 of {𝑔1 , ..., 𝑔𝑖−1 , 𝑔𝑖+1 , ..., 𝑔𝑠 }• 𝐿𝐶(𝑔𝑖 ) = 1 for all 𝑖 if the coefficient ring is a field.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: I = Ideal([z*x + y^3, z + y^3, z + x*y])
sage: I.interreduced_basis()[y^3 + z, x*y + z, x*z - z]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> I = Ideal([z*x + y**Integer(3), z + y**Integer(3), z + x*y])>>> I.interreduced_basis()[y^3 + z, x*y + z, x*z - z]Note that tail reduction for local orderings is not well-defined:
sage: R.<x,y,z> = PolynomialRing(QQ,order= negdegrevlex )sage: I = Ideal([z*x + y^3, z + y^3, z + x*y])
sage: I.interreduced_basis()[z + x*y, x*y - y^3, x^2*y - y^3]>>> from sage.all import *>>> R = PolynomialRing(QQ,order= negdegrevlex , names=( x , y ,˓→y, z,) = R._first_ngens(3)>>> I = Ideal([z*x + y**Integer(3), z + y**Integer(3), z + x*y])>>> I.interreduced_basis()[z + x*y, x*y - y^3, x^2*y - y^3]z ,)); (x,␣A fixed error with nonstandard base fields:
sage: R.<t> = QQ[ t ]sage: K.<x,y> = R.fraction_field()[ x,y ]sage: I = t*x * K
sage: I.interreduced_basis()[x]>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()[ x,y ]; (x, y,) = K._first_ngens(2)>>> I = t*x * K>>> I.interreduced_basis()[x]

The interreduced basis of 0 is 0:
sage: P.<x,y,z> = GF(2)[]sage: Ideal(P(0)).interreduced_basis()
[0]

656

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> Ideal(P(Integer(0))).interreduced_basis()[0]

ALGORITHM:
Uses Singular’s interred command or sage.rings.polynomial.toy_buchberger.
inter_reduction() if conversion to Singular fails.
intersection(*others)
Return the intersection of the arguments with this ideal.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, 2, order= lex )sage: I = x*R
sage: J = y*R
sage: I.intersection(J)
Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), order= lex , names=( x , y ,)); (x, y,˓→) = R._first_ngens(2)>>> I = x*R>>> J = y*R>>> I.intersection(J)
Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field

The following simple example illustrates that the product need not equal the intersection.
sage: I = (x^2, y) * R
sage: J = (y^2, x) * R
sage: K = I.intersection(J); K
Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational␣
˓→Field
sage: IJ = I*J; IJ
Ideal (x^2*y^2, x^3, y^3, x*y)of Multivariate Polynomial Ring in x, y over Rational Field
sage: IJ == K
False>>> from sage.all import *>>> I = (x**Integer(2), y) * R>>> J = (y**Integer(2), x) * R>>> K = I.intersection(J); K
Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational␣
˓→Field>>> IJ = I*J; IJ
Ideal (x^2*y^2, x^3, y^3, x*y)of Multivariate Polynomial Ring in x, y over Rational Field>>> IJ == K
False

Intersection of several ideals:

3.1. Multivariate Polynomials and Polynomial Rings

657

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: I1 = x * R
sage: I2 = y * R
sage: I3 = (x, y) * R
sage: I4 = (x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z) * R
sage: I1.intersection(I2, I3, I4).groebner_basis()[x^2*y + x*y*z^4, x*y^2 - x*y*z^3, x*y*z^20 - x*y*z^3]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( x , y ,˓→(x, y, z,) = R._first_ngens(3)>>> I1 = x * R>>> I2 = y * R>>> I3 = (x, y) * R>>> I4 = (x**Integer(2) + x*y*z, y**Integer(2) - z**Integer(3)*y,␣
˓→z**Integer(3) + y**Integer(5)*x*z) * R>>> I1.intersection(I2, I3, I4).groebner_basis()[x^2*y + x*y*z^4, x*y^2 - x*y*z^3, x*y*z^20 - x*y*z^3]z ,));␣

The ideals must share the same ring:sage: R2.<x,y> = PolynomialRing(QQ, 2, order= lex )sage: R3.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: I2 = x*R2
sage: I3 = x*R3
sage: I2.intersection(I3)Traceback (most recent call last):...
TypeError: Intersection is only available for ideals of the same ring.
>>> from sage.all import *>>> R2 = PolynomialRing(QQ, Integer(2), order= lex , names=( x , y ,)); (x,␣˓→y,) = R2._first_ngens(2)>>> R3 = PolynomialRing(QQ, Integer(3), order= lex , names=( x , y , z ,));␣
˓→(x, y, z,) = R3._first_ngens(3)>>> I2 = x*R2>>> I3 = x*R3>>> I2.intersection(I3)Traceback (most recent call last):...
TypeError: Intersection is only available for ideals of the same ring.

is_prime(**kwds)
Return True if this ideal is prime.
INPUT:• keyword arguments are passed on to complete_primary_decomposition(); in this way you
can specify the algorithm to use.
EXAMPLES:
sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: I = (x^2 - y^2 - 1) * R
sage: I.is_prime()True
sage: (I^2).is_prime()(continues on next page)

658

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

False
sage: J = (x^2 - y^2) * R
sage: J.is_prime()
False
sage: (J^3).is_prime()
False
sage: (I * J).is_prime()
False>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = (x**Integer(2) - y**Integer(2) - Integer(1)) * R>>> I.is_prime()
True>>> (I**Integer(2)).is_prime()
False>>> J = (x**Integer(2) - y**Integer(2)) * R>>> J.is_prime()
False>>> (J**Integer(3)).is_prime()
False>>> (I * J).is_prime()
False

The following is Issue #5982. Note that the quotient ring is not recognized as being a field at this time, so thefraction field is not the quotient ring itself:
sage: Q = R.quotient(I); Q
Quotient of Multivariate Polynomial Ring in x, y over Rational Fieldby the ideal (x^2 - y^2 - 1)sage: Q.fraction_field()
Fraction Field of
Quotient of Multivariate Polynomial Ring in x, y over Rational Fieldby the ideal (x^2 - y^2 - 1)>>> from sage.all import *>>> Q = R.quotient(I); Q
Quotient of Multivariate Polynomial Ring in x, y over Rational Fieldby the ideal (x^2 - y^2 - 1)>>> Q.fraction_field()
Fraction Field of
Quotient of Multivariate Polynomial Ring in x, y over Rational Fieldby the ideal (x^2 - y^2 - 1)

minimal_associated_primes()
OUTPUT:• list – a list of prime ideals
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

659

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ, 3, xyz )sage: p = z^2 + 1; q = z^3 + 2
sage: I = (p*q^2, y - z^2) * R
sage: sorted(I.minimal_associated_primes(), key=str)[Ideal (z^2 + 1, -z^2 + y)of Multivariate Polynomial Ring in x, y, z over Rational Field,
Ideal (z^3 + 2, -z^2 + y)of Multivariate Polynomial Ring in x, y, z over Rational Field]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), xyz , names=( x , y , z ,)); (x, y,␣
˓→z,) = R._first_ngens(3)>>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)>>> I = (p*q**Integer(2), y - z**Integer(2)) * R>>> sorted(I.minimal_associated_primes(), key=str)[Ideal (z^2 + 1, -z^2 + y)of Multivariate Polynomial Ring in x, y, z over Rational Field,
Ideal (z^3 + 2, -z^2 + y)of Multivariate Polynomial Ring in x, y, z over Rational Field]

ALGORITHM:
Uses Singular.
normal_basis(degree=None, algorithm='libsingular', singular=None)
Return a vector space basis of the quotient ring of this ideal.
INPUT:• degree – integer (default: None)• algorithm – string (default: "libsingular"); if not the default, this will use the kbase() orweightKB() command from Singular• singular – the singular interpreter to use when algorithm is not "libsingular" (default: thedefault instance)
OUTPUT:
Monomials in the basis. If degree is given, only the monomials of the given degree are returned.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: I = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5, x*z - 1)sage: I.normal_basis()[y*z^2, z^2, y*z, z, x*y, y, x, 1]
sage: I.normal_basis(algorithm= singular )[y*z^2, z^2, y*z, z, x*y, y, x, 1]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> I = R.ideal(x**Integer(2) + y**Integer(2) + z**Integer(2) - Integer(4),␣
˓→x**Integer(2) + Integer(2)*y**Integer(2) - Integer(5), x*z - Integer(1))>>> I.normal_basis()[y*z^2, z^2, y*z, z, x*y, y, x, 1]>>> I.normal_basis(algorithm= singular )[y*z^2, z^2, y*z, z, x*y, y, x, 1]

660

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

The result can be restricted to monomials of a chosen degree, which is particularly useful when the quotientring is not finite-dimensional as a vector space.
sage: J = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5)sage: J.dimension()1
sage: [J.normal_basis(d) for d in (0..3)][[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]
sage: [J.normal_basis(d, algorithm= singular ) for d in (0..3)][[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]>>> from sage.all import *>>> J = R.ideal(x**Integer(2) + y**Integer(2) + z**Integer(2) - Integer(4),␣
˓→x**Integer(2) + Integer(2)*y**Integer(2) - Integer(5))>>> J.dimension()1>>> [J.normal_basis(d) for d in (ellipsis_iter(Integer(0),Ellipsis,
˓→Integer(3)))][[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]>>> [J.normal_basis(d, algorithm= singular ) for d in (ellipsis_
˓→iter(Integer(0),Ellipsis,Integer(3)))][[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]

In case of a polynomial ring with a weighted term order, the degree of the monomials is taken with respect
to the weights.
sage: T = TermOrder( wdegrevlex , (1, 2, 3))
sage: R.<x,y,z> = PolynomialRing(QQ, order=T)
sage: B = R.ideal(x*y^2 + x^5, z*y + x^3*y).normal_basis(9); B[x^2*y^2*z, x^3*z^2, x*y*z^2, z^3]
sage: all(f.degree() == 9 for f in B)
True>>> from sage.all import *>>> T = TermOrder( wdegrevlex , (Integer(1), Integer(2), Integer(3)))>>> R = PolynomialRing(QQ, order=T, names=( x , y , z ,)); (x, y, z,) = R._
˓→first_ngens(3)>>> B = R.ideal(x*y**Integer(2) + x**Integer(5), z*y + x**Integer(3)*y).
˓→normal_basis(Integer(9)); B[x^2*y^2*z, x^3*z^2, x*y*z^2, z^3]>>> all(f.degree() == Integer(9) for f in B)
Trueplot(singular=None)
If you somehow manage to install surf, perhaps you can use this function to implicitly plot the real zero locusof this ideal (if principal).
INPUT:• self – must be a principal ideal in 2 or 3 vars over.

EXAMPLES:
Implicit plotting in 2-d:sage: R.<x,y> = PolynomialRing(QQ,2)
sage: I = R.ideal([y^3 - x^2])
sage: I.plot()# cusp(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

661

Polynomials, Release 10.4

(continued from previous page)

Graphics object consisting of 1 graphics primitive
sage: I = R.ideal([y^2 - x^2 - 1])sage: I.plot()# hyperbola
Graphics object consisting of 1 graphics primitive
sage: I = R.ideal([y^2 + x^2*(1/4) - 1])sage: I.plot()# ellipse
Graphics object consisting of 1 graphics primitive
sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
sage: I.plot()# elliptic curve
Graphics object consisting of 1 graphics primitive>>> from sage.all import *>>> R = PolynomialRing(QQ,Integer(2), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = R.ideal([y**Integer(3) - x**Integer(2)])>>> I.plot()# cuspGraphics object consisting of 1 graphics primitive>>> I = R.ideal([y**Integer(2) - x**Integer(2) - Integer(1)])>>> I.plot()# hyperbola
Graphics object consisting of 1 graphics primitive>>> I = R.ideal([y**Integer(2) + x**Integer(2)*(Integer(1)/Integer(4)) -␣˓→Integer(1)])>>> I.plot()# ellipse
Graphics object consisting of 1 graphics primitive>>> I = R.ideal([y**Integer(2)-(x**Integer(2)-Integer(1))*(x-Integer(2))])>>> I.plot()# elliptic curve
Graphics object consisting of 1 graphics primitive

Implicit plotting in 3-d:sage: R.<x,y,z> = PolynomialRing(QQ,3)
sage: I = R.ideal([y^2 + x^2*(1/4) - z])sage: I.plot()# a cone; optional - surf
sage: I = R.ideal([y^2 + z^2*(1/4) - x])sage: I.plot()# same code, from a different angle; optional - surf
sage: I = R.ideal([x^2*y^2+x^2*z^2+y^2*z^2-16*x*y*z])
sage: I.plot()# Steiner surface; optional - surf>>> from sage.all import *>>> R = PolynomialRing(QQ,Integer(3), names=( x , y , z ,)); (x, y, z,) = R.
˓→_first_ngens(3)>>> I = R.ideal([y**Integer(2) + x**Integer(2)*(Integer(1)/Integer(4)) - z])>>> I.plot()# a cone; optional - surf>>> I = R.ideal([y**Integer(2) + z**Integer(2)*(Integer(1)/Integer(4)) - x])>>> I.plot()# same code, from a different angle; optional - surf>>> I = R.
˓→ideal([x**Integer(2)*y**Integer(2)+x**Integer(2)*z**Integer(2)+y**Integer(2)*z**Integer(2)˓→Integer(16)*x*y*z])>>> I.plot()# Steiner surface; optional - surf

AUTHORS:• David Joyner (2006-02-12)
primary_decomposition(algorithm='sy')
Return a list of primary ideals such that their intersection is self.

662

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

An ideal 𝑄 is called primary if it is a proper ideal of the ring 𝑅, and if whenever 𝑎𝑏 ∈ 𝑄 and 𝑎 ̸∈ 𝑄, then𝑏𝑛 ∈ 𝑄 for some 𝑛 ∈ Z.
If 𝑄 is a primary ideal of the ring 𝑅, then the radical ideal 𝑃 of 𝑄 (i.e., the ideal consisting of all 𝑎 ∈ 𝑅 with𝑎𝑛 ∈ 𝑄 for some 𝑛 ∈ Z), is called the associated prime of 𝑄.
If 𝐼 is a proper ideal of a Noetherian ring 𝑅, then there exists a finite collection of primary ideals 𝑄𝑖 suchthat the following hold:• the intersection of the 𝑄𝑖 is 𝐼;• none of the 𝑄𝑖 contains the intersection of the others;• the associated prime ideals of the 𝑄𝑖 are pairwise distinct.
INPUT:• algorithm – string:–sy – (default) use the Shimoyama-Yokoyama algorithm–

gtz – use the Gianni-Trager-Zacharias algorithm

OUTPUT:• a list of primary ideals 𝑄𝑖 forming a primary decomposition of self.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ, 3, order= lex )sage: p = z^2 + 1; q = z^3 + 2
sage: I = (p*q^2, y - z^2) * R
sage: pd = I.primary_decomposition(); sorted(pd, key=str)[Ideal (z^2 + 1, y + 1)
of Multivariate Polynomial Ring in x, y, z over Rational Field,
Ideal (z^6 + 4*z^3 + 4, y - z^2)of Multivariate Polynomial Ring in x, y, z over Rational Field]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( x , y ,˓→(x, y, z,) = R._first_ngens(3)>>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)>>> I = (p*q**Integer(2), y - z**Integer(2)) * R>>> pd = I.primary_decomposition(); sorted(pd, key=str)[Ideal (z^2 + 1, y + 1)
of Multivariate Polynomial Ring in x, y, z over Rational Field,
Ideal (z^6 + 4*z^3 + 4, y - z^2)of Multivariate Polynomial Ring in x, y, z over Rational Field]z ,));␣

sage: from functools import reduce
sage: reduce(lambda Qi, Qj: Qi.intersection(Qj), pd) == I
True>>> from sage.all import *>>> from functools import reduce>>> reduce(lambda Qi, Qj: Qi.intersection(Qj), pd) == I
True

ALGORITHM:
Uses Singular.

3.1. Multivariate Polynomials and Polynomial Rings

663

Polynomials, Release 10.4

REFERENCES:• Thomas Becker and Volker Weispfenning. Groebner Bases - A Computational Approach To Commutative Algebra. Springer, New York 1993.
primary_decomposition_complete()
A decorator that creates a cached version of an instance method of a class.
Note: For proper behavior, the method must be a pure function (no side effects). Arguments to themethod must be hashable or transformed into something hashable using key or they must define sage.
structure.sage_object.SageObject._cache_key().
EXAMPLES:
sage: class Foo():....:@cached_method....:
def f(self, t, x=2):....:
print( computing )....:return t**x
sage: a = Foo()>>> from sage.all import *>>> class Foo():...
@cached_method...
def f(self, t, x=Integer(2)):...
print( computing )...
return t**x>>> a = Foo()

The example shows that the actual computation takes place only once, and that the result is identical forequivalent input:
sage: res = a.f(3, 2); rescomputing9sage: a.f(t = 3, x = 2) is res
True
sage: a.f(3) is res
True>>> from sage.all import *>>> res = a.f(Integer(3), Integer(2)); rescomputing9>>> a.f(t = Integer(3), x = Integer(2)) is res
True>>> a.f(Integer(3)) is res
True

Note, however, that the CachedMethod is replaced by a CachedMethodCaller or CachedMethodCallerNoArgs as soon as it is bound to an instance or class:sage: P.<a,b,c,d> = QQ[]
sage: I = P*[a,b]sage: type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >664

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P = QQ[ a, b, c, d ]; (a, b, c, d,) = P._first_ngens(4)>>> I = P*[a,b]>>> type(I.__class__.gens)<class sage.misc.cachefunc.CachedMethodCallerNoArgs >So, you would hardly ever see an instance of this class alive.
The parameter key can be used to pass a function which creates a custom cache key for inputs. In thefollowing example, this parameter is used to ignore the algorithm keyword for caching:sage: class A():....:def _f_normalize(self, x, algorithm): return x....:@cached_method(key=_f_normalize)....:
def f(self, x, algorithm= default ): return xsage: a = A()
sage: a.f(1, algorithm="default") is a.f(1) is a.f(1, algorithm="algorithm")True>>> from sage.all import *>>> class A():...
def _f_normalize(self, x, algorithm): return x...
@cached_method(key=_f_normalize)...
def f(self, x, algorithm= default ): return x>>> a = A()>>> a.f(Integer(1), algorithm="default") is a.f(Integer(1)) is a.f(Integer(1),˓→ algorithm="algorithm")
True

The parameter do_pickle can be used to enable pickling of the cache. Usually the cache is not stored
when pickling:sage: class A():....:@cached_method....:
def f(self, x): return Nonesage: import __main__sage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))
sage: len(b.f.cache)0>>> from sage.all import *>>> class A():...
@cached_method...
def f(self, x): return None>>> import __main__>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

665

Polynomials, Release 10.4

(continued from previous page)>>> len(b.f.cache)0

When do_pickle is set, the pickle contains the contents of the cache:sage: class A():....:@cached_method(do_pickle=True)....:def f(self, x): return Nonesage: __main__.A = A
sage: a = A()
sage: a.f(1)sage: len(a.f.cache)1
sage: b = loads(dumps(a))
sage: len(b.f.cache)1>>> from sage.all import *>>> class A():...
@cached_method(do_pickle=True)...
def f(self, x): return None>>> __main__.A = A>>> a = A()>>> a.f(Integer(1))>>> len(a.f.cache)1>>> b = loads(dumps(a))>>> len(b.f.cache)
1

Cached methods cannot be copied like usual methods, see Issue #12603. Copying them can lead to very
surprising results:
sage: class A:....:@cached_method....:
def f(self):....:
return 1
sage: class B:
....:
g=A.f
....:
def f(self):....:
return 2
sage: b=B()
sage: b.f()2
sage: b.g()
1
sage: b.f()
1>>> from sage.all import *>>> class A:...
@cached_method...
def f(self):...
return Integer(1)>>> class B:(continues on next page)

666

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

...
...
...

g=A.f
def f(self):
return Integer(2)>>> b=B()>>> b.f()2>>> b.g()
1>>> b.f()1

quotient(J)Given ideals 𝐼 = self and 𝐽 in the same polynomial ring 𝑃 , return the ideal quotient of 𝐼 by 𝐽 consistingof the polynomials 𝑎 of 𝑃 such that {𝑎𝐽 ⊂ 𝐼}.
This is also referred to as the colon ideal (𝐼:𝐽).
INPUT:• J – multivariate polynomial ideal
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: R.<x,y,z> = PolynomialRing(GF(181), 3)
sage: I = Ideal([x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z])
sage: J = Ideal([x])
sage: Q = I.quotient(J)sage: y*z + x in I
False
sage: x in J
True
sage: x * (y*z + x) in I
True>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(181)), Integer(3), names=( x , y , z ,));␣
˓→(x, y, z,) = R._first_ngens(3)>>> I = Ideal([x**Integer(2) + x*y*z, y**Integer(2) - z**Integer(3)*y,␣
˓→z**Integer(3) + y**Integer(5)*x*z])>>> J = Ideal([x])>>> Q = I.quotient(J)>>> y*z + x in I
False>>> x in J
True>>> x * (y*z + x) in I
True

radical()The radical of this ideal.
EXAMPLES:This is an obviously not radical ideal:

3.1. Multivariate Polynomials and Polynomial Rings

667

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ, 3)
sage: I = (x^2, y^3, (x*z)^4 + y^3 + 10*x^2) * R
sage: I.radical()
Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> I = (x**Integer(2), y**Integer(3), (x*z)**Integer(4) + y**Integer(3) +␣˓→Integer(10)*x**Integer(2)) * R>>> I.radical()
Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field

That the radical is correct is clear from the Groebner basis.
sage: I.groebner_basis()[y^3, x^2]>>> from sage.all import *>>> I.groebner_basis()[y^3, x^2]This is the example from the Singular manual:
sage: p = z^2 + 1; q = z^3 + 2
sage: I = (p*q^2, y - z^2) * R
sage: I.radical()
Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
of Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)>>> I = (p*q**Integer(2), y - z**Integer(2)) * R>>> I.radical()
Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
of Multivariate Polynomial Ring in x, y, z over Rational Field

Note: From the Singular manual: A combination of the algorithms of Krick/Logar and Kemper is used.
Works also in positive characteristic (Kempers algorithm).
sage: # needs sage.rings.finite_rings
sage: R.<x,y,z> = PolynomialRing(GF(37), 3)
sage: p = z^2 + 1; q = z^3 + 2
sage: I = (p*q^2, y - z^2) * R
sage: I.radical()
Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(37)), Integer(3), names=( x , y ,˓→(x, y, z,) = R._first_ngens(3)>>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)z ,));␣

(continues on next page)

668

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> I = (p*q**Integer(2), y - z**Integer(2)) * R>>> I.radical()
Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37

saturation(other)
Return the saturation (and saturation exponent) of the ideal self with respect to the ideal other
INPUT:• other – another ideal in the same ring
OUTPUT: a pair (ideal, integer)
EXAMPLES:
sage: R.<x, y, z> = QQ[]
sage: I = R.ideal(x^5*z^3, x*y*z, y*z^4)
sage: J = R.ideal(z)sage: I.saturation(J)(Ideal (y, x^5) of Multivariate Polynomial Ring in x, y, z over Rational␣
˓→Field, 4)>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> I = R.ideal(x**Integer(5)*z**Integer(3), x*y*z, y*z**Integer(4))>>> J = R.ideal(z)>>> I.saturation(J)(Ideal (y, x^5) of Multivariate Polynomial Ring in x, y, z over Rational␣
˓→Field, 4)

syzygy_module()
Computes the first syzygy (i.e., the module of relations of the given generators) of the ideal.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 2*x^2 + ysage: g = ysage: h = 2*f + g
sage: I = Ideal([f,g,h])sage: M = I.syzygy_module(); M
[
-2
-1
1]
[
-y 2*x^2 + y
0]
sage: G = vector(I.gens())
sage: M*G(0, 0)>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,>>> f = Integer(2)*x**Integer(2) + y>>> g = y>>> h = Integer(2)*f + g>>> I = Ideal([f,g,h])>>> M = I.syzygy_module(); M
[
-2
-1
1]
[
-y 2*x^2 + y0]y ,)); (x, y,) = R._first_ngens(2)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

669

Polynomials, Release 10.4

(continued from previous page)>>> G = vector(I.gens())>>> M*G(0, 0)ALGORITHM:
Uses Singular’s syz command.
transformed_basis(algorithm='gwalk', other_ring=None, singular=None)
Return a lex or other_ring Groebner Basis for this ideal.
INPUT:• algorithm – see below for options.
• other_ring – only valid for algorithm= fglm ; if provided, conversion will be performed tothis ring. Otherwise a lex Groebner basis will be returned.
ALGORITHMS:• "fglm" – FGLM algorithm. The input ideal must be given with a reduced Groebner Basis of azero-dimensional ideal• "gwalk" – Groebner Walk algorithm (default)• "awalk1" – ‘first alternative’ algorithm• "awalk2" – ‘second alternative’ algorithm• "twalk" – Tran algorithm• "fwalk" – Fractal Walk algorithm
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ,3)
sage: I = Ideal([y^3+x^2,x^2*y+x^2, x^3-x^2, z^4-x^2-y])sage: I = Ideal(I.groebner_basis())
sage: S.<z,x,y> = PolynomialRing(QQ,3,order= lex )sage: J = Ideal(I.transformed_basis( fglm ,S))
sage: J
Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3)of Multivariate Polynomial Ring in z, x, y over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ,Integer(3), names=( x , y , z ,)); (x, y, z,) = R.
˓→_first_ngens(3)>>> I = Ideal([y**Integer(3)+x**Integer(2),x**Integer(2)*y+x**Integer(2),␣
˓→x**Integer(3)-x**Integer(2), z**Integer(4)-x**Integer(2)-y])>>> I = Ideal(I.groebner_basis())>>> S = PolynomialRing(QQ,Integer(3),order= lex , names=( z , x , y ,)); (z,˓→ x, y,) = S._first_ngens(3)>>> J = Ideal(I.transformed_basis( fglm ,S))>>> J
Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3)of Multivariate Polynomial Ring in z, x, y over Rational Field
sage: R.<z,y,x> = PolynomialRing(GF(32003), 3, order= lex )˓→needs sage.rings.finite_rings
sage: I = Ideal([y^3 + x*y*z + y^2*z + x*z^3, 3 + x*y + x^2*y + y^2*z])#␣#␣(continues on next page)

670

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.finite_rings
sage: I.transformed_basis( gwalk )#␣˓→needs sage.rings.finite_rings[z*y^2 + y*x^2 + y*x + 3,
z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3- 8297*y^6*x^2 - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2+ 3556*y^5*x + 3556*y^4*x^3 + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x- 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - 1185*y^2*x^6 - 8297*y^2*x^5- 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 + x^5 + 2*x^4 + x^
˓→3,y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7- 3*y^3*x^6 - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3- 27*y*x^3 - 27*y*x^2 - 27*x]
˓→>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(32003)), Integer(3), order= lex , names=( z˓→ ,y , x ,)); (z, y, x,) = R._first_ngens(3)# needs sage.rings.finite_
˓→rings>>> I = Ideal([y**Integer(3) + x*y*z + y**Integer(2)*z + x*z**Integer(3),␣
˓→Integer(3) + x*y + x**Integer(2)*y + y**Integer(2)*z])# needs sage.
˓→rings.finite_rings>>> I.transformed_basis( gwalk )#␣˓→needs sage.rings.finite_rings[z*y^2 + y*x^2 + y*x + 3,
z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3- 8297*y^6*x^2 - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2+ 3556*y^5*x + 3556*y^4*x^3 + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x- 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - 1185*y^2*x^6 - 8297*y^2*x^5- 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 + x^5 + 2*x^4 + x^
˓→3,y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7- 3*y^3*x^6 - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3- 27*y*x^3 - 27*y*x^2 - 27*x]

ALGORITHM:
Uses Singular.
triangular_decomposition(algorithm=None, singular=None)
Decompose zero-dimensional ideal self into triangular sets.
This requires that the given basis is reduced w.r.t. to the lexicographical monomial ordering. If the basis ofself does not have this property, the required Groebner basis is computed implicitly.
INPUT:• algorithm – string or None (default: None)
ALGORITHMS:• "singular:triangL" – decomposition of self into triangular systems (Lazard).
• "singular:triangLfak" – decomposition of self into triangular systems plus factorization.
• "singular:triangM" – decomposition of self into triangular systems (Moeller).
OUTPUT: a list 𝑇 of lists 𝑡 such that the variety of self is the union of the varieties of 𝑡 in 𝐿 and each 𝑡 isin triangular form.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

671

Polynomials, Release 10.4

sage: P.<e,d,c,b,a> = PolynomialRing(QQ, 5, order= lex )sage: I = sage.rings.ideal.Cyclic(P)sage: GB = Ideal(I.groebner_basis( libsingular:stdfglm ))sage: GB.triangular_decomposition( singular:triangLfak )[Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3,
e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b,␣
˓→a over Rational Field,
Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1,
-11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a -␣
˓→24,
11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2,
-11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - 1, c + a^3 + a^2 + a + 1, -d + a^3, -e + a^2) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1,
c + b^2*a^3 + b^2*a^2 + b^2*a + b^2,
-d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2,
-e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1,
-11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a␣
˓→- 24,11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1,
-11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field]
sage: R.<x1,x2> = PolynomialRing(QQ, 2, order= lex )sage: f1 = 1/2*((x1^2 + 2*x1 - 4)*x2^2 + 2*(x1^2 + x1)*x2 + x1^2)
sage: f2 = 1/2*((x1^2 + 2*x1 + 1)*x2^2 + 2*(x1^2 + x1)*x2 - 4*x1^2)
sage: I = Ideal(f1,f2)
sage: I.triangular_decomposition()[Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,
Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,(continues on next page)

672

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,
Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5)of Multivariate Polynomial Ring in x1, x2 over Rational Field]>>> from sage.all import *>>> P = PolynomialRing(QQ, Integer(5), order= lex , names=( e , d , c , b ,˓→a ,)); (e, d, c, b, a,) = P._first_ngens(5)>>> I = sage.rings.ideal.Cyclic(P)>>> GB = Ideal(I.groebner_basis( libsingular:stdfglm ))>>> GB.triangular_decomposition( singular:triangLfak )[Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3,
e + b^3 + b^2 + b + 1) of Multivariate Polynomial Ring in e, d, c, b,␣
˓→a over Rational Field,
Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1,
-11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a -␣
˓→24,
11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2,
-11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - 1, c + a^3 + a^2 + a + 1, -d + a^3, -e + a^2) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - a, c - a, d^2 + 3*d*a + a^2, e + d + 3*a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,
b - a, c^2 + 3*c*a + a^2, d + c + 3*a, e - a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,b^2 + 3*b*a + a^2, c + b + 3*a, d - a, e - a) of Multivariate␣˓→Polynomial Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + a^2 + a + 1,b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1,
c + b^2*a^3 + b^2*a^2 + b^2*a + b^2,
-d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2,
-e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field,
Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1,
-11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a␣
˓→- 24,11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1,
-11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2) of Multivariate Polynomial␣
˓→Ring in e, d, c, b, a over Rational Field]>>> R = PolynomialRing(QQ, Integer(2), order= lex , names=( x1 ,x2 ,)); (x1,(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

673

Polynomials, Release 10.4

(continued from previous page)x2,) = R._first_ngens(2)>>> f1 = Integer(1)/Integer(2)*((x1**Integer(2) + Integer(2)*x1 -␣
˓→Integer(4))*x2**Integer(2) + Integer(2)*(x1**Integer(2) + x1)*x2 +␣
˓→x1**Integer(2))>>> f2 = Integer(1)/Integer(2)*((x1**Integer(2) + Integer(2)*x1 +␣˓→Integer(1))*x2**Integer(2) + Integer(2)*(x1**Integer(2) + x1)*x2 -␣
˓→Integer(4)*x1**Integer(2))>>> I = Ideal(f1,f2)>>> I.triangular_decomposition()[Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,
Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,
Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational␣
˓→Field,
Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5)of Multivariate Polynomial Ring in x1, x2 over Rational Field]
˓→variety(ring=None)
Return the variety of this ideal.
Given a zero-dimensional ideal 𝐼 (= self) of a polynomial ring 𝑃 whose order is lexicographic, return thevariety of 𝐼 as a list of dictionaries with (variable, value) pairs. By default, the variety of the ideal
over its coefficient field 𝐾 is returned; ring can be specified to find the variety over a different ring.
These dictionaries have cardinality equal to the number of variables in 𝑃 and represent assignments of values
to these variables such that all polynomials in 𝐼 vanish.
If ring is specified, then a triangular decomposition of self is found over the original coefficient field 𝐾;
then the triangular systems are solved using root-finding over ring. This is particularly useful when 𝐾 is QQ(to allow fast symbolic computation of the triangular decomposition) and ring is RR, AA, CC, or QQbar(to compute the whole real or complex variety of the ideal).
Note that with ring=RR or CC, computation is done numerically and potentially inaccurately; in particular,
the number of points in the real variety may be miscomputed. With ring=AA or QQbar, computation isdone exactly (which may be much slower, of course).
INPUT:• ring – return roots in the ring instead of the base ring of this ideal (default: None)• algorithm – algorithm or implementation to use; see below for supported values• proof – return a provably correct result (default: True)
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: K.<w> = GF(27) # this example is from the MAGMA handbook
sage: P.<x, y> = PolynomialRing(K, 2, order= lex )sage: I = Ideal([x^8 + y + 2, y^6 + x*y^5 + x^2])
sage: I = Ideal(I.groebner_basis()); I
Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - y^37 - y^36
+ y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + y^28 + y^27 + y^26
+ y^25 - y^23 + y^22 + y^21 - y^19 - y^18 - y^16 + y^15 + y^13
+ y^12 - y^10 + y^9 + y^8 + y^7 - y^6 + y^4 + y^3 + y^2 + y - 1,y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28
- y^25 + y^24 + y^2 + y + 1)
of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3(continues on next page)

674

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: V = I.variety();sage: sorted(V, key=str)[{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}]
sage: [f.subs(v)# check that all polynomials vanish....: for f in I.gens() for v in V][0, 0, 0, 0, 0, 0]
sage: [I.subs(v).is_zero() for v in V] # same test, but nicer syntax[True, True, True]>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> K = GF(Integer(27), names=( w ,)); (w,) = K._first_ngens(1)# this example␣
˓→is from the MAGMA handbook>>> P = PolynomialRing(K, Integer(2), order= lex , names=( x , y ,)); (x, y,˓→) = P._first_ngens(2)>>> I = Ideal([x**Integer(8) + y + Integer(2), y**Integer(6) +␣˓→x*y**Integer(5) + x**Integer(2)])>>> I = Ideal(I.groebner_basis()); I
Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - y^37 - y^36
+ y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + y^28 + y^27 + y^26
+ y^25 - y^23 + y^22 + y^21 - y^19 - y^18 - y^16 + y^15 + y^13
+ y^12 - y^10 + y^9 + y^8 + y^7 - y^6 + y^4 + y^3 + y^2 + y - 1,y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28
- y^25 + y^24 + y^2 + y + 1)
of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3>>> V = I.variety();>>> sorted(V, key=str)[{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}]>>> [f.subs(v)# check that all polynomials vanish... for f in I.gens() for v in V][0, 0, 0, 0, 0, 0]>>> [I.subs(v).is_zero() for v in V] # same test, but nicer syntax[True, True, True]

However, we only account for solutions in the ground field and not in the algebraic closure:sage: I.vector_space_dimension()
˓→needs sage.rings.finite_rings48>>> from sage.all import *>>> I.vector_space_dimension()
˓→needs sage.rings.finite_rings
48

#␣

#␣

Here we compute the points of intersection of a hyperbola and a circle, in several fields:
sage: K.<x, y> = PolynomialRing(QQ, 2, order= lex )sage: I = Ideal([x*y - 1, (x-2)^2 + (y-1)^2 - 1])sage: I = Ideal(I.groebner_basis()); I
Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1)
of Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> K = PolynomialRing(QQ, Integer(2), order= lex , names=( x ,y ,)); (x, y,(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

675

Polynomials, Release 10.4

(continued from previous page)) = K._first_ngens(2)>>> I = Ideal([x*y - Integer(1), (x-Integer(2))**Integer(2) + (y˓→Integer(1))**Integer(2) - Integer(1)])>>> I = Ideal(I.groebner_basis()); I
Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1)
of Multivariate Polynomial Ring in x, y over Rational Field
˓→

These two curves have one rational intersection:
sage: I.variety()[{y: 1, x: 1}]>>> from sage.all import *>>> I.variety()[{y: 1, x: 1}]

There are two real intersections:sage: sorted(I.variety(ring=RR), key=str)[{y: 0.361103080528647, x: 2.76929235423863},{y: 1.00000000000000, x: 1.00000000000000}]
sage: I.variety(ring=AA)
˓→needs sage.rings.number_field[{y: 1, x: 1},{y: 0.3611030805286474?, x: 2.769292354238632?}]>>> from sage.all import *>>> sorted(I.variety(ring=RR), key=str)[{y: 0.361103080528647, x: 2.76929235423863},{y: 1.00000000000000, x: 1.00000000000000}]>>> I.variety(ring=AA)
˓→needs sage.rings.number_field[{y: 1, x: 1},{y: 0.3611030805286474?, x: 2.769292354238632?}]#␣#␣and a total of four intersections:sage: sorted(I.variety(ring=CC), key=str)[{y: 0.31944845973567... + 1.6331702409152...*I,
x: 0.11535382288068... - 0.58974280502220...*I},{y: 0.31944845973567... - 1.6331702409152...*I,
x: 0.11535382288068... + 0.58974280502220...*I},{y: 0.36110308052864..., x: 2.7692923542386...},{y: 1.00000000000000, x: 1.00000000000000}]
sage: sorted(I.variety(ring=QQbar), key=str)
˓→needs sage.rings.number_field[{y: 0.3194484597356763? + 1.633170240915238?*I,
x: 0.11535382288068429? - 0.5897428050222055?*I},{y: 0.3194484597356763? - 1.633170240915238?*I,
x: 0.11535382288068429? + 0.5897428050222055?*I},{y: 0.3611030805286474?, x: 2.769292354238632?},{y: 1, x: 1}]#␣>>> from sage.all import *>>> sorted(I.variety(ring=CC), key=str)(continues on next page)

676

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)[{y: 0.31944845973567... + 1.6331702409152...*I,
x: 0.11535382288068... - 0.58974280502220...*I},{y: 0.31944845973567... - 1.6331702409152...*I,
x: 0.11535382288068... + 0.58974280502220...*I},{y: 0.36110308052864..., x: 2.7692923542386...},{y: 1.00000000000000, x: 1.00000000000000}]>>> sorted(I.variety(ring=QQbar), key=str)
˓→needs sage.rings.number_field[{y: 0.3194484597356763? + 1.633170240915238?*I,
x: 0.11535382288068429? - 0.5897428050222055?*I},{y: 0.3194484597356763? - 1.633170240915238?*I,
x: 0.11535382288068429? + 0.5897428050222055?*I},{y: 0.3611030805286474?, x: 2.769292354238632?},{y: 1, x: 1}]#␣

We can also use the optional package msolve to compute the variety. See msolve for more information.
sage: I.variety(RBF, algorithm= msolve , proof=False)# optional - msolve[{x: [2.76929235423863 +/- 2.08e-15], y: [0.361103080528647 +/- 4.53e-16]},{x: 1.000000000000000, y: 1.000000000000000}]>>> from sage.all import *>>> I.variety(RBF, algorithm= msolve , proof=False)# optional - msolve[{x: [2.76929235423863 +/- 2.08e-15], y: [0.361103080528647 +/- 4.53e-16]},{x: 1.000000000000000, y: 1.000000000000000}]

Computation over floating point numbers may compute only a partial solution, or even none at all. Noticethat x values are missing from the following variety:sage: R.<x,y> = CC[]
sage: I = ideal([x^2+y^2-1,x*y-1])
sage: sorted(I.variety(), key=str)verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: computations in␣˓→the complex field are inexact; variety may be computed partially or␣˓→incorrectly.
verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to␣˓→very slow toy implementation.
[{y: -0.86602540378443... + 0.500000000000000*I},{y: -0.86602540378443... - 0.500000000000000*I},{y: 0.86602540378443... + 0.500000000000000*I},{y: 0.86602540378443... - 0.500000000000000*I}]>>> from sage.all import *>>> R = CC[ x, y ]; (x, y,) = R._first_ngens(2)>>> I = ideal([x**Integer(2)+y**Integer(2)-Integer(1),x*y-Integer(1)])>>> sorted(I.variety(), key=str)verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: computations in␣˓→the complex field are inexact; variety may be computed partially or␣˓→incorrectly.
verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to␣˓→very slow toy implementation.
[{y: -0.86602540378443... + 0.500000000000000*I},{y: -0.86602540378443... - 0.500000000000000*I},{y: 0.86602540378443... + 0.500000000000000*I},{y: 0.86602540378443... - 0.500000000000000*I}]

This is due to precision error, which causes the computation of an intermediate Groebner basis to fail.
3.1. Multivariate Polynomials and Polynomial Rings

677

Polynomials, Release 10.4

If the ground field’s characteristic is too large for Singular, we resort to a toy implementation:
sage: # needs sage.rings.finite_rings
sage: R.<x,y> = PolynomialRing(GF(2147483659^3), order= lex )sage: I = ideal([x^3 - 2*y^2, 3*x + y^4])
sage: I.variety()verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling␣˓→back to very slow toy implementation.
verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to␣˓→very slow toy implementation.
[{y: 0, x: 0}]>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = PolynomialRing(GF(Integer(2147483659)**Integer(3)), order= lex ,␣
˓→names=( x ,y ,)); (x, y,) = R._first_ngens(2)>>> I = ideal([x**Integer(3) - Integer(2)*y**Integer(2), Integer(3)*x +␣
˓→y**Integer(4)])>>> I.variety()verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling␣˓→back to very slow toy implementation.
verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back␣˓→to very slow toy implementation.
verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to␣˓→very slow toy implementation.
[{y: 0, x: 0}]

The dictionary expressing the variety will be indexed by generators of the polynomial ring after changing to
the target field. But the mapping will also accept generators of the original ring, or even generator names as
strings, when provided as keys:
sage: # needs sage.rings.number_fieldsage: K.<x,y> = QQ[]
sage: I = ideal([x^2 + 2*y - 5, x + y + 3])
sage: v = I.variety(AA)[0]; v[x], v[y](4.464101615137755?, -7.464101615137755?)
sage: list(v)[0].parent()
Multivariate Polynomial Ring in x, y over Algebraic Real Field
sage: v[x]4.464101615137755?
sage: v["y"]-7.464101615137755?
>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = QQ[ x, y ]; (x, y,) = K._first_ngens(2)>>> I = ideal([x**Integer(2) + Integer(2)*y - Integer(5), x + y + Integer(3)])>>> v = I.variety(AA)[Integer(0)]; v[x], v[y](4.464101615137755?, -7.464101615137755?)>>> list(v)[Integer(0)].parent()
Multivariate Polynomial Ring in x, y over Algebraic Real Field>>> v[x]4.464101615137755?
>>> v["y"]-7.464101615137755?

678

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

msolve also works over finite fields:
sage: R.<x, y> = PolynomialRing(GF(536870909), 2, order= lex )˓→needs sage.rings.finite_rings
sage: I = Ideal([x^2 - 1, y^2 - 1])
˓→needs sage.rings.finite_rings
sage: sorted(I.variety(algorithm= msolve ,# optional - msolve,␣˓→needs sage.rings.finite_rings....:
proof=False),....:
key=str)[{x: 1, y: 1},{x: 1, y: 536870908},{x: 536870908, y: 1},{x: 536870908, y: 536870908}]#␣#␣>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(536870909)), Integer(2), order= lex ,␣
˓→names=( x ,y ,)); (x, y,) = R._first_ngens(2)# needs sage.rings.finite_
˓→rings>>> I = Ideal([x**Integer(2) - Integer(1), y**Integer(2) - Integer(1)])␣˓→# needs sage.rings.finite_rings>>> sorted(I.variety(algorithm= msolve ,# optional - msolve, needs␣
˓→sage.rings.finite_rings...
proof=False),...
key=str)[{x: 1, y: 1},{x: 1, y: 536870908},{x: 536870908, y: 1},{x: 536870908, y: 536870908}]

but may fail in small characteristic, especially with ideals of high degree with respect to the characteristic:
sage: R.<x, y> = PolynomialRing(GF(3), 2, order= lex )sage: I = Ideal([x^2 - 1, y^2 - 1])sage: I.variety(algorithm= msolve , proof=False)# optional - msolve
Traceback (most recent call last):...
NotImplementedError: characteristic 3 too small>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(3)), Integer(2), order= lex , names=( x ,˓→ ,)); (x, y,) = R._first_ngens(2)>>> I = Ideal([x**Integer(2) - Integer(1), y**Integer(2) - Integer(1)])>>> I.variety(algorithm= msolve , proof=False)# optional - msolve
Traceback (most recent call last):...
NotImplementedError: characteristic 3 too smally

ALGORITHM:• With algorithm = "triangular_decomposition" (default), uses triangular decomposition,
via Singular if possible, falling back on a toy implementation otherwise.
• With algorithm = "msolve", uses the optional package msolve. Note that msolve uses heuristics
and therefore requires setting the proof flag to False. See msolve for more information.
vector_space_dimension()
Return the vector space dimension of the ring modulo this ideal. If the ideal is not zero-dimensional, a
TypeError is raised.
3.1. Multivariate Polynomials and Polynomial Rings

679

Polynomials, Release 10.4

ALGORITHM:
Uses Singular.
EXAMPLES:
sage: R.<u,v> = PolynomialRing(QQ)
sage: g = u^4 + v^4 + u^3 + v^3
sage: I = ideal(g) + ideal(g.gradient())
sage: I.dimension()0
sage: I.vector_space_dimension()4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( u , v ,)); (u, v,) = R._first_ngens(2)>>> g = u**Integer(4) + v**Integer(4) + u**Integer(3) + v**Integer(3)>>> I = ideal(g) + ideal(g.gradient())>>> I.dimension()0>>> I.vector_space_dimension()
4

When the ideal is not zero-dimensional, we return infinity:
sage: R.<x,y> = PolynomialRing(QQ)
sage: I = R.ideal(x)sage: I.dimension()1
sage: I.vector_space_dimension()+Infinity>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,>>> I = R.ideal(x)>>> I.dimension()1>>> I.vector_space_dimension()+Infinityy ,)); (x, y,) = R._first_ngens(2)Due to integer overflow, the result is correct only modulo 2^32, see Issue #8586:
sage: P.<x,y,z> = PolynomialRing(GF(32003), 3)
˓→needs sage.rings.finite_rings
sage: sage.rings.ideal.FieldIdeal(P).vector_space_dimension()
˓→bug, needs sage.rings.finite_rings
32777216864027#␣# known␣

>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(32003)), Integer(3), names=( x , y , z ,˓→)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.finite_rings>>> sage.rings.ideal.FieldIdeal(P).vector_space_dimension()# known bug,˓→ needs sage.rings.finite_rings
32777216864027

class sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal(ring, gens,coerce=True,
side='left')
680

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Bases: MPolynomialIdeal_singular_repr, Ideal_nc
Creates a non-commutative polynomial ideal.
INPUT:• ring - the g-algebra to which this ideal belongs• gens - the generators of this ideal• coerce (optional - default: True) - generators are coerced into the ring before creating the ideal• side – optional string, either "left" (default) or "twosided"; defines whether this ideal is left oftwo-sided.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2 - H.one()],# indirect doctest....:
coerce=False)
sage: I # random
Left Ideal (y^2, x^2, z^2 - 1) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(I.gens(), key=str)[x^2, y^2, z^2 - 1]sage: H.ideal([y^2, x^2, z^2 - H.one()], side="twosided") # random
Twosided Ideal (y^2, x^2, z^2 - 1) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(H.ideal([y^2, x^2, z^2 - H.one()], side="twosided").gens(),....:
key=str)[x^2, y^2, z^2 - 1]sage: H.ideal([y^2, x^2, z^2 - H.one()], side="right")
Traceback (most recent call last):...
ValueError: Only left and two-sided ideals are allowed.
>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],˓→# indirect doctest...
coerce=False)>>> I # random
Left Ideal (y^2, x^2, z^2 - 1) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(I.gens(), key=str)[x^2, y^2, z^2 - 1]>>> H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side=␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

681

Polynomials, Release 10.4

(continued from previous page)"twosided") # random
Twosided Ideal (y^2, x^2, z^2 - 1) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side=˓→"twosided").gens(),...
key=str)[x^2, y^2, z^2 - 1]>>> H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side="right")
Traceback (most recent call last):...
ValueError: Only left and two-sided ideals are allowed.
˓→elimination_ideal(variables)
Return the elimination ideal of this ideal with respect to the variables given in variables.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
sage: I.elimination_ideal([x, z])
Left Ideal (y^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}
sage: J = I.twostd(); J
Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}
sage: J.elimination_ideal([x, z])Twosided Ideal (y^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→)>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],␣
˓→coerce=False)>>> I.elimination_ideal([x, z])
Left Ideal (y^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}>>> J = I.twostd(); J
Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}>>> J.elimination_ideal([x, z])(continues on next page)682

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Twosided Ideal (y^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {...}ALGORITHM: Uses Singular’s eliminate command
reduce(p)Reduce an element modulo a Groebner basis for this ideal.
It returns 0 if and only if the element is in this ideal. In any case, this reduction is unique up to monomial
orders.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H.<x,y,z> = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: I = H.ideal([y^2, x^2, z^2 - H.one()],....:coerce=False, side= twosided )sage: Q = H.quotient(I); Q #random
Quotient of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
by the ideal (y^2, x^2, z^2 - 1)sage: Q.2^2 == Q.one()# indirect doctest
True>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→, names=( x ,y , z ,)); (x, y, z,) = H._first_ngens(3)>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],...
coerce=False, side= twosided )>>> Q = H.quotient(I); Q #random
Quotient of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
by the ideal (y^2, x^2, z^2 - 1)>>> Q.gen(2)**Integer(2) == Q.one()# indirect doctest
True

Here, we see that the relation that we just found in the quotient is actually a consequence of the given relations:sage: H.2^2 - H.one() in I.std().gens()
˓→needs sage.combinat sage.modules
True>>> from sage.all import *>>> H.gen(2)**Integer(2) - H.one() in I.std().gens()˓→# needs sage.combinat sage.modules
True

#␣

␣

Here is the corresponding direct test:

3.1. Multivariate Polynomials and Polynomial Rings

683

Polynomials, Release 10.4

sage: I.reduce(z^2)˓→needs sage.combinat sage.modules1#␣>>> from sage.all import *>>> I.reduce(z**Integer(2))˓→# needs sage.combinat sage.modules1␣res(length)
Compute the resolution up to a given length of the ideal.
NOTE:
Only left syzygies can be computed. So, even if the ideal is two-sided, then the resolution is only one-sided.
In that case, a warning is printed.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False)
sage: I.res(3)<Resolution>>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→)>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2)-H.one()],␣
˓→coerce=False)>>> I.res(Integer(3))<Resolution>

std()
Compute a GB of the ideal. It is two-sided if and only if the ideal is two-sided.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
sage: I.std() #random
Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(I.std().gens(), key=str)[2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

684

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→)>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],␣
˓→coerce=False)>>> I.std() #random
Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(I.std().gens(), key=str)[2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

If the ideal is a left ideal, then std() returns a left Groebner basis. But if it is a two-sided ideal, then the
output of std() and twostd() coincide:sage: # needs sage.combinat sage.modules
sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])
sage: JL #random
Left Ideal (x^3, y^3, z^3 - 4*z) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(JL.gens(), key=str)[x^3, y^3, z^3 - 4*z]
sage: JL.std() # random
Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z,
x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(JL.std().gens(), key=str)[2*x*y*z - z^2 - 2*z, x*z^2 + 2*x*z, x^3, y*z^2 - 2*y*z, y^3, z^3 - 4*z]
sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side= twosided )sage: JT #random
Twosided Ideal (x^3, y^3, z^3 - 4*z) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(JT.gens(), key=str)[x^3, y^3, z^3 - 4*z]
sage: JT.std() #random
Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z,
y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2,y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}sage: sorted(JT.std().gens(), key=str)[2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x,x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z]
sage: JT.std() == JL.twostd()
True>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> JL = H.ideal([x**Integer(3), y**Integer(3), z**Integer(3) - Integer(4)*z])(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

685

Polynomials, Release 10.4

(continued from previous page)>>> JL #random
Left Ideal (x^3, y^3, z^3 - 4*z) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(JL.gens(), key=str)[x^3, y^3, z^3 - 4*z]>>> JL.std() # random
Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z,
x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(JL.std().gens(), key=str)[2*x*y*z - z^2 - 2*z, x*z^2 + 2*x*z, x^3, y*z^2 - 2*y*z, y^3, z^3 - 4*z]>>> JT = H.ideal([x**Integer(3), y**Integer(3), z**Integer(3) - Integer(4)*z],
˓→ side= twosided )>>> JT #random
Twosided Ideal (x^3, y^3, z^3 - 4*z) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(JT.gens(), key=str)[x^3, y^3, z^3 - 4*z]>>> JT.std() #random
Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z,
y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2,y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}>>> sorted(JT.std().gens(), key=str)[2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x,x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z]>>> JT.std() == JL.twostd()
True

ALGORITHM: Uses Singular’s std command
syzygy_module()
Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal.
NOTE:
Only left syzygies can be computed. So, even if the ideal is two-sided, then the syzygies are only one-sided.
In that case, a warning is printed.
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False)
sage: G = vector(I.gens()); Gd...: UserWarning: You are constructing a free module
over a noncommutative ring. Sage does not have a conceptof left/right and both sided modules, so be careful.
It s also not guaranteed that all multiplications aredone from the right side.
d...: UserWarning: You are constructing a free module(continues on next page)

686

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

over a noncommutative ring. Sage does not have a conceptof left/right and both sided modules, so be careful.
It s also not guaranteed that all multiplications aredone from the right side.
(y^2, x^2, z^2 - 1)sage: M = I.syzygy_module(); M[-z^˓→2 - 8*z - 15
␣
˓→
0
␣
˓→
y^2]
[
␣
˓→
0
␣
˓→
-z^2 + 8*z - 15
␣
˓→
x^2]
[
x^2*z^2 + 8*x^
˓→2*z + 15*x^2
˓→y^2*z^2 + 8*y^2*z - 15*y^2
␣˓→-4*x*y*z + 2*z^2 + 2*z][x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 -␣
˓→282*x*z - 360*x␣
˓→ -y^3*z^2 + 7*y^3*z - 12*y^3␣˓→
6*y*z^2][x^3*z^2 + 7*x^
˓→3*z + 12*x^3-x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 +␣
˓→52*y*z^2 - 224*y*z + 320*y␣˓→-6*x*z^2][ x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 +␣
˓→312*z + 288␣˓→-y^4*z + 4*y^4
␣
˓→
0]
[
2*x^3*y*z + 8*x^3*y + 9*x^
˓→2*z + 27*x^2-2*x*y^3*z + 8*x*y^3 - 12*y^
˓→2*z^2 + 99*y^2*z - 195*y^2
␣˓→-36*x*y*z + 24*z^2 + 18*z][x^
˓→4*z + 4*x^4-x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 -␣
˓→64*x*y + 66*z^2 - 240*z + 288
␣˓→0][x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 -␣
˓→1656*x*z - 2052*x-x*y^4*z + 4*x*y^4 -␣
˓→8*y^3*z^2 + 62*y^3*z - 114*y^3␣˓→
48*y*z^2 - 36*y*z]
sage: M*G
˓→needs sage.combinat sage.modules(0, 0, 0, 0, 0, 0, 0, 0, 0)#␣>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→)>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2)-H.one()],␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

687

Polynomials, Release 10.4

(continued from previous page)

coerce=False)>>> G = vector(I.gens()); Gd...: UserWarning: You are constructing a free module
over a noncommutative ring. Sage does not have a conceptof left/right and both sided modules, so be careful.
It s also not guaranteed that all multiplications aredone from the right side.
d...: UserWarning: You are constructing a free module
over a noncommutative ring. Sage does not have a conceptof left/right and both sided modules, so be careful.
It s also not guaranteed that all multiplications aredone from the right side.
(y^2, x^2, z^2 - 1)>>> M = I.syzygy_module(); M[-z^˓→2 - 8*z - 15
␣
˓→
0
␣
˓→
y^2]
[
␣
˓→
0
␣
˓→
-z^2 + 8*z - 15
␣
˓→
x^2]
[
x^2*z^2 + 8*x^
˓→2*z + 15*x^2
˓→y^2*z^2 + 8*y^2*z - 15*y^2
␣˓→-4*x*y*z + 2*z^2 + 2*z][x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 -␣
˓→282*x*z - 360*x␣
˓→ -y^3*z^2 + 7*y^3*z - 12*y^3␣˓→
6*y*z^2][x^3*z^2 + 7*x^
˓→3*z + 12*x^3-x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 +␣
˓→52*y*z^2 - 224*y*z + 320*y␣˓→-6*x*z^2][ x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 +␣
˓→312*z + 288␣˓→-y^4*z + 4*y^4
␣
˓→
0]
[
2*x^3*y*z + 8*x^3*y + 9*x^
˓→2*z + 27*x^2-2*x*y^3*z + 8*x*y^3 - 12*y^
˓→2*z^2 + 99*y^2*z - 195*y^2
␣˓→-36*x*y*z + 24*z^2 + 18*z][x^
˓→4*z + 4*x^4-x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 -␣
˓→64*x*y + 66*z^2 - 240*z + 288
␣˓→0][x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 -␣
˓→1656*x*z - 2052*x-x*y^4*z + 4*x*y^4 -␣
˓→8*y^3*z^2 + 62*y^3*z - 114*y^3␣˓→
48*y*z^2 - 36*y*z]˓→>>> M*G˓→needs sage.combinat sage.modules(0, 0, 0, 0, 0, 0, 0, 0, 0)#␣

ALGORITHM: Uses Singular’s syz command
twostd()688

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Compute a two-sided GB of the ideal (even if it is a left ideal).
EXAMPLES:
sage: # needs sage.combinat sage.modules
sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})sage: H.inject_variables()Defining x, y, z
sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
sage: I.twostd() #random
Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
sage: sorted(I.twostd().gens(), key=str)[2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]>>> from sage.all import *>>> # needs sage.combinat sage.modules>>> A = FreeAlgebra(QQ, Integer(3), names=( x , y , z ,)); (x, y, z,) = A._˓→first_ngens(3)>>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}˓→)>>> H.inject_variables()Defining x, y, z>>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],␣
˓→coerce=False)>>> I.twostd() #random
Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
>>> sorted(I.twostd().gens(), key=str)[2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

ALGORITHM: Uses Singular’s twostd commandclass sage.rings.polynomial.multi_polynomial_ideal.RequireField(f)Bases: MethodDecorator
Decorator which throws an exception if a computation over a coefficient ring which is not a field is attempted.
Note: This decorator is used automatically internally so the user does not need to use it manually.
sage.rings.polynomial.multi_polynomial_ideal.is_MPolynomialIdeal(x)Return True if the provided argument x is an ideal in a multivariate polynomial ring.
INPUT:• x – an arbitrary object
EXAMPLES:
sage: from sage.rings.polynomial.multi_polynomial_ideal import is_MPolynomialIdeal
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y]>>> from sage.all import *>>> from sage.rings.polynomial.multi_polynomial_ideal import is_MPolynomialIdeal(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

689

Polynomials, Release 10.4

(continued from previous page)>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_ngens(3)>>> I = [x + Integer(2)*y + Integer(2)*z - Integer(1), x**Integer(2) +␣˓→Integer(2)*y**Integer(2) + Integer(2)*z**Integer(2) - x, Integer(2)*x*y +␣˓→Integer(2)*y*z - y]Sage distinguishes between a list of generators for an ideal and the ideal itself. This distinction is inconsistent with
Singular but matches Magma’s behavior.
sage: is_MPolynomialIdeal(I)False>>> from sage.all import *>>> is_MPolynomialIdeal(I)False
sage: I = Ideal(I)sage: is_MPolynomialIdeal(I)True>>> from sage.all import *>>> I = Ideal(I)>>> is_MPolynomialIdeal(I)Truesage.rings.polynomial.multi_polynomial_ideal.require_fieldalias of RequireField

3.1.7 Polynomial Sequences
We call a finite list of polynomials a Polynomial Sequence.
Polynomial sequences in Sage can optionally be viewed as consisting of various parts or sub-sequences. These kind ofpolynomial sequences which naturally split into parts arise naturally for example in algebraic cryptanalysis of symmetric cryptographic primitives. The most prominent examples of these systems are: the small scale variants of the AES[CMR2005] (cf. sage.crypto.mq.sr.SR()) and Flurry/Curry [BPW2006]. By default, a polynomial sequence
has exactly one part.
AUTHORS:• Martin Albrecht (2007ff): initial version• Martin Albrecht (2009): refactoring, clean-up, new functions• Martin Albrecht (2011): refactoring, moved to sage.rings.polynomial• Alex Raichev (2011-06): added algebraic_dependence()• Charles Bouillaguet (2013-1): added solve()
EXAMPLES:
As an example consider a small scale variant of the AES:
sage: sr = mq.SR(2, 1, 2, 4, gf2=True, polybori=True)
˓→needs sage.rings.polynomial.pbori
sage: sr#␣#␣(continues on next page)

690

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.polynomial.pbori
SR(2,1,2,4)
˓→>>> from sage.all import *>>> sr = mq.SR(Integer(2), Integer(1), Integer(2), Integer(4), gf2=True,␣
˓→polybori=True)# needs sage.rings.polynomial.pbori>>> sr#␣
˓→needs sage.rings.polynomial.pbori
SR(2,1,2,4)

We can construct a polynomial sequence for a random plaintext-ciphertext pair and study it:
sage: set_random_seed(1)sage: while True: # workaround (see :issue: 31891 )˓→# needs sage.rings.polynomial.pbori
....:
try:
....:
F, s = sr.polynomial_system()
....:
break
....:
except ZeroDivisionError:
....:
pass
sage: F˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 112 Polynomials in 64 Variables#␣sage: r2 = F.part(2); r2#␣˓→needs sage.rings.polynomial.pbori(w200 + k100 + x100 + x102 + x103,
w201 + k101 + x100 + x101 + x103 + 1,
w202 + k102 + x100 + x101 + x102 + 1,
w203 + k103 + x101 + x102 + x103,
w210 + k110 + x110 + x112 + x113,
w211 + k111 + x110 + x111 + x113 + 1,
w212 + k112 + x110 + x111 + x112 + 1,
w213 + k113 + x111 + x112 + x113,
x100*w100 + x100*w103 + x101*w102 + x102*w101 + x103*w100,
x100*w100 + x100*w101 + x101*w100 + x101*w103 + x102*w102 + x103*w101,
x100*w101 + x100*w102 + x101*w100 + x101*w101 + x102*w100 + x102*w103 + x103*w102,x100*w100 + x100*w102 + x100*w103 + x101*w100 + x101*w101 + x102*w102 + x103*w100 +␣
˓→x100,x100*w101 + x100*w103 + x101*w101 + x101*w102 + x102*w100 + x102*w103 + x103*w101 +␣
˓→x101,x100*w100 + x100*w102 + x101*w100 + x101*w102 + x101*w103 + x102*w100 + x102*w101 +␣
˓→x103*w102 + x102,
x100*w101 + x100*w102 + x101*w100 + x101*w103 + x102*w101 + x103*w103 + x103,
x100*w100 + x100*w101 + x100*w103 + x101*w101 + x102*w100 + x102*w102 + x103*w100 +␣
˓→w100,x100*w102 + x101*w100 + x101*w101 + x101*w103 + x102*w101 + x103*w100 + x103*w102 +␣
˓→w101,x100*w100 + x100*w101 + x100*w102 + x101*w102 + x102*w100 + x102*w101 + x102*w103 +␣
˓→x103*w101 + w102,x100*w101 + x101*w100 + x101*w102 + x102*w100 + x103*w101 + x103*w103 + w103,
x100*w102 + x101*w101 + x102*w100 + x103*w103 + 1,
x110*w110 + x110*w113 + x111*w112 + x112*w111 + x113*w110,x110*w110 + x110*w111 + x111*w110 + x111*w113 + x112*w112 + x113*w111,x110*w111 + x110*w112 + x111*w110 + x111*w111 + x112*w110 + x112*w113 + x113*w112,
x110*w110 + x110*w112 + x110*w113 + x111*w110 + x111*w111 + x112*w112 + x113*w110 +␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

691

Polynomials, Release 10.4

(continued from previous page)x110,
x110*w111 + x110*w113 + x111*w111 + x111*w112 + x112*w110 + x112*w113 + x113*w111 +␣˓→x111,x110*w110 + x110*w112 + x111*w110 + x111*w112 + x111*w113 + x112*w110 + x112*w111 +␣˓→x113*w112 + x112,
x110*w111 + x110*w112 + x111*w110 + x111*w113 + x112*w111 + x113*w113 + x113,
x110*w110 + x110*w111 + x110*w113 + x111*w111 + x112*w110 + x112*w112 + x113*w110 +␣
˓→w110,x110*w112 + x111*w110 + x111*w111 + x111*w113 + x112*w111 + x113*w110 + x113*w112 +␣
˓→w111,x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 +␣˓→x113*w111 + w112,
x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113,
x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1)
˓→>>> from sage.all import *>>> set_random_seed(Integer(1))>>> while True: # workaround (see :issue: 31891 )˓→needs sage.rings.polynomial.pbori
...
try:
...
F, s = sr.polynomial_system()
...
break
...
except ZeroDivisionError:
...
pass
>>> F
˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 112 Polynomials in 64 Variables#␣#␣>>> r2 = F.part(Integer(2)); r2␣˓→# needs sage.rings.polynomial.pbori(w200 + k100 + x100 + x102 + x103,
w201 + k101 + x100 + x101 + x103 + 1,
w202 + k102 + x100 + x101 + x102 + 1,
w203 + k103 + x101 + x102 + x103,
w210 + k110 + x110 + x112 + x113,
w211 + k111 + x110 + x111 + x113 + 1,
w212 + k112 + x110 + x111 + x112 + 1,
w213 + k113 + x111 + x112 + x113,
x100*w100 + x100*w103 + x101*w102 + x102*w101 + x103*w100,
x100*w100 + x100*w101 + x101*w100 + x101*w103 + x102*w102 + x103*w101,
x100*w101 + x100*w102 + x101*w100 + x101*w101 + x102*w100 + x102*w103 + x103*w102,x100*w100 + x100*w102 + x100*w103 + x101*w100 + x101*w101 + x102*w102 + x103*w100 +␣
˓→x100,x100*w101 + x100*w103 + x101*w101 + x101*w102 + x102*w100 + x102*w103 + x103*w101 +␣
˓→x101,x100*w100 + x100*w102 + x101*w100 + x101*w102 + x101*w103 + x102*w100 + x102*w101 +␣
˓→x103*w102 + x102,
x100*w101 + x100*w102 + x101*w100 + x101*w103 + x102*w101 + x103*w103 + x103,
x100*w100 + x100*w101 + x100*w103 + x101*w101 + x102*w100 + x102*w102 + x103*w100 +␣
˓→w100,x100*w102 + x101*w100 + x101*w101 + x101*w103 + x102*w101 + x103*w100 + x103*w102 +␣
˓→w101,x100*w100 + x100*w101 + x100*w102 + x101*w102 + x102*w100 + x102*w101 + x102*w103 +␣
˓→x103*w101 + w102,x100*w101 + x101*w100 + x101*w102 + x102*w100 + x103*w101 + x103*w103 + w103,
x100*w102 + x101*w101 + x102*w100 + x103*w103 + 1,
(continues on next page)

692

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x110*w110 + x110*w113 + x111*w112 + x112*w111 + x113*w110,x110*w110 + x110*w111 + x111*w110 + x111*w113 + x112*w112 + x113*w111,x110*w111 + x110*w112 + x111*w110 + x111*w111 + x112*w110 + x112*w113 + x113*w112,
x110*w110 + x110*w112 + x110*w113 + x111*w110 + x111*w111 + x112*w112 + x113*w110 +␣˓→x110,x110*w111 + x110*w113 + x111*w111 + x111*w112 + x112*w110 + x112*w113 + x113*w111 +␣˓→x111,x110*w110 + x110*w112 + x111*w110 + x111*w112 + x111*w113 + x112*w110 + x112*w111 +␣˓→x113*w112 + x112,
x110*w111 + x110*w112 + x111*w110 + x111*w113 + x112*w111 + x113*w113 + x113,
x110*w110 + x110*w111 + x110*w113 + x111*w111 + x112*w110 + x112*w112 + x113*w110 +␣
˓→w110,x110*w112 + x111*w110 + x111*w111 + x111*w113 + x112*w111 + x113*w110 + x113*w112 +␣
˓→w111,x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 +␣˓→x113*w111 + w112,
x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113,
x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1)

We separate the system in independent subsystems:
sage: C = Sequence(r2).connected_components(); C#␣˓→needs sage.rings.polynomial.pbori[[w200 + k100 + x100 + x102 + x103,
w201 + k101 + x100 + x101 + x103 + 1,
w202 + k102 + x100 + x101 + x102 + 1,
w203 + k103 + x101 + x102 + x103,
x100*w100 + x100*w103 + x101*w102 + x102*w101 + x103*w100,
x100*w100 + x100*w101 + x101*w100 + x101*w103 + x102*w102 + x103*w101,
x100*w101 + x100*w102 + x101*w100 + x101*w101 + x102*w100 + x102*w103 + x103*w102,x100*w100 + x100*w102 + x100*w103 + x101*w100 + x101*w101 + x102*w102 + x103*w100 +␣
˓→x100,x100*w101 + x100*w103 + x101*w101 + x101*w102 + x102*w100 + x102*w103 + x103*w101 +␣
˓→x101,x100*w100 + x100*w102 + x101*w100 + x101*w102 + x101*w103 + x102*w100 + x102*w101 +␣
˓→x103*w102 + x102,
x100*w101 + x100*w102 + x101*w100 + x101*w103 + x102*w101 + x103*w103 + x103,
x100*w100 + x100*w101 + x100*w103 + x101*w101 + x102*w100 + x102*w102 + x103*w100 +␣
˓→w100,x100*w102 + x101*w100 + x101*w101 + x101*w103 + x102*w101 + x103*w100 + x103*w102 +␣
˓→w101,x100*w100 + x100*w101 + x100*w102 + x101*w102 + x102*w100 + x102*w101 + x102*w103 +␣
˓→x103*w101 + w102,x100*w101 + x101*w100 + x101*w102 + x102*w100 + x103*w101 + x103*w103 + w103,
x100*w102 + x101*w101 + x102*w100 + x103*w103 + 1],[w210 + k110 + x110 + x112 + x113,
w211 + k111 + x110 + x111 + x113 + 1,
w212 + k112 + x110 + x111 + x112 + 1,
w213 + k113 + x111 + x112 + x113,
x110*w110 + x110*w113 + x111*w112 + x112*w111 + x113*w110,x110*w110 + x110*w111 + x111*w110 + x111*w113 + x112*w112 + x113*w111,x110*w111 + x110*w112 + x111*w110 + x111*w111 + x112*w110 + x112*w113 + x113*w112,
x110*w110 + x110*w112 + x110*w113 + x111*w110 + x111*w111 + x112*w112 + x113*w110 +␣˓→x110,x110*w111 + x110*w113 + x111*w111 + x111*w112 + x112*w110 + x112*w113 + x113*w111 +␣˓→x111,x110*w110 + x110*w112 + x111*w110 + x111*w112 + x111*w113 + x112*w110 + x112*w111 +␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

693

Polynomials, Release 10.4

(continued from previous page)x113*w112 + x112,
x110*w111 + x110*w112 + x111*w110 + x111*w113 + x112*w111 + x113*w113 + x113,
x110*w110 + x110*w111 + x110*w113 + x111*w111 + x112*w110 + x112*w112 + x113*w110 +␣
˓→w110,x110*w112 + x111*w110 + x111*w111 + x111*w113 + x112*w111 + x113*w110 + x113*w112 +␣
˓→w111,x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 +␣˓→x113*w111 + w112,
x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113,
x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1]]
sage: C[0].groebner_basis()#␣˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 30 Polynomials in 16 Variables˓→>>> from sage.all import *>>> C = Sequence(r2).connected_components(); C#␣˓→needs sage.rings.polynomial.pbori[[w200 + k100 + x100 + x102 + x103,
w201 + k101 + x100 + x101 + x103 + 1,
w202 + k102 + x100 + x101 + x102 + 1,
w203 + k103 + x101 + x102 + x103,
x100*w100 + x100*w103 + x101*w102 + x102*w101 + x103*w100,
x100*w100 + x100*w101 + x101*w100 + x101*w103 + x102*w102 + x103*w101,
x100*w101 + x100*w102 + x101*w100 + x101*w101 + x102*w100 + x102*w103 + x103*w102,x100*w100 + x100*w102 + x100*w103 + x101*w100 + x101*w101 + x102*w102 + x103*w100 +␣
˓→x100,x100*w101 + x100*w103 + x101*w101 + x101*w102 + x102*w100 + x102*w103 + x103*w101 +␣
˓→x101,x100*w100 + x100*w102 + x101*w100 + x101*w102 + x101*w103 + x102*w100 + x102*w101 +␣
˓→x103*w102 + x102,
x100*w101 + x100*w102 + x101*w100 + x101*w103 + x102*w101 + x103*w103 + x103,
x100*w100 + x100*w101 + x100*w103 + x101*w101 + x102*w100 + x102*w102 + x103*w100 +␣
˓→w100,x100*w102 + x101*w100 + x101*w101 + x101*w103 + x102*w101 + x103*w100 + x103*w102 +␣
˓→w101,x100*w100 + x100*w101 + x100*w102 + x101*w102 + x102*w100 + x102*w101 + x102*w103 +␣
˓→x103*w101 + w102,x100*w101 + x101*w100 + x101*w102 + x102*w100 + x103*w101 + x103*w103 + w103,
x100*w102 + x101*w101 + x102*w100 + x103*w103 + 1],[w210 + k110 + x110 + x112 + x113,
w211 + k111 + x110 + x111 + x113 + 1,
w212 + k112 + x110 + x111 + x112 + 1,
w213 + k113 + x111 + x112 + x113,
x110*w110 + x110*w113 + x111*w112 + x112*w111 + x113*w110,x110*w110 + x110*w111 + x111*w110 + x111*w113 + x112*w112 + x113*w111,x110*w111 + x110*w112 + x111*w110 + x111*w111 + x112*w110 + x112*w113 + x113*w112,
x110*w110 + x110*w112 + x110*w113 + x111*w110 + x111*w111 + x112*w112 + x113*w110 +␣˓→x110,x110*w111 + x110*w113 + x111*w111 + x111*w112 + x112*w110 + x112*w113 + x113*w111 +␣˓→x111,x110*w110 + x110*w112 + x111*w110 + x111*w112 + x111*w113 + x112*w110 + x112*w111 +␣˓→x113*w112 + x112,
x110*w111 + x110*w112 + x111*w110 + x111*w113 + x112*w111 + x113*w113 + x113,
x110*w110 + x110*w111 + x110*w113 + x111*w111 + x112*w110 + x112*w112 + x113*w110 +␣
˓→w110,x110*w112 + x111*w110 + x111*w111 + x111*w113 + x112*w111 + x113*w110 + x113*w112 +␣
(continues on next page)

694

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)w111,
x110*w110 + x110*w111 + x110*w112 + x111*w112 + x112*w110 + x112*w111 + x112*w113 +␣˓→x113*w111 + w112,
x110*w111 + x111*w110 + x111*w112 + x112*w110 + x113*w111 + x113*w113 + w113,
x110*w112 + x111*w111 + x112*w110 + x113*w113 + 1]]>>> C[Integer(0)].groebner_basis()␣˓→# needs sage.rings.polynomial.pbori
Polynomial Sequence with 30 Polynomials in 16 Variables
˓→and compute the coefficient matrix:
sage: A,v = Sequence(r2).coefficients_monomials()
˓→needs sage.rings.polynomial.pbori
sage: A.rank()
˓→needs sage.rings.polynomial.pbori
32

#␣
#␣

>>> from sage.all import *>>> A,v = Sequence(r2).coefficients_monomials()
˓→needs sage.rings.polynomial.pbori>>> A.rank()
˓→needs sage.rings.polynomial.pbori
32

#␣
#␣

Using these building blocks we can implement a simple XL algorithm easily:
sage: sr = mq.SR(1,1,1,4, gf2=True, polybori=True, order= lex )˓→needs sage.rings.polynomial.pbori
sage: while True: # workaround (see :issue: 31891 )˓→# needs sage.rings.polynomial.pbori
....:
try:
....:
F, s = sr.polynomial_system()
....:
break
....:
except ZeroDivisionError:
....:
pass

#␣

sage: # needs sage.rings.polynomial.pbori
sage: monomials = [a*b for a in F.variables() for b in F.variables() if a < b]sage: len(monomials)
190
sage: F2 = Sequence(map(mul, cartesian_product_iterator((monomials, F))))sage: A, v = F2.coefficients_monomials(sparse=False)
sage: A.echelonize()
sage: A
6840 x 4474 dense matrix over Finite Field of size 2...
sage: A.rank()
4056
sage: A[4055] * v
k001*k003>>> from sage.all import *>>> sr = mq.SR(Integer(1),Integer(1),Integer(1),Integer(4), gf2=True, polybori=True,␣
˓→order= lex )# needs sage.rings.polynomial.pbori>>> while True: # workaround (see :issue: 31891 )#␣˓→needs sage.rings.polynomial.pbori...
try:(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

695

Polynomials, Release 10.4

(continued from previous page)

...
...
...
...

F, s = sr.polynomial_system()
break
except ZeroDivisionError:
pass>>> # needs sage.rings.polynomial.pbori>>> monomials = [a*b for a in F.variables() for b in F.variables() if a < b]>>> len(monomials)
190>>> F2 = Sequence(map(mul, cartesian_product_iterator((monomials, F))))>>> A, v = F2.coefficients_monomials(sparse=False)>>> A.echelonize()>>> A
6840 x 4474 dense matrix over Finite Field of size 2...
>>> A.rank()
4056>>> A[Integer(4055)] * v
k001*k003

Note: In many other computer algebra systems (cf. Singular) this class would be called Ideal but an ideal is a very
distinct object from its generators and thus this is not an ideal in Sage.

Classessage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence(arg1,
arg2=None, immutable=False,
cr=False,
cr_str=None)
Construct a new polynomial sequence object.
INPUT:• arg1 – a multivariate polynomial ring, an ideal or a matrix• arg2 – an iterable object of parts or polynomials (default:None)– immutable – if True the sequence is immutable (default: False)– cr – print a line break after each element (default: False)– cr_str – print a line break after each element if ‘str’ is called (default: None)
EXAMPLES:
sage: P.<a,b,c,d> = PolynomialRing(GF(127), 4)
sage: I = sage.rings.ideal.Katsura(P)˓→needs sage.libs.singular#␣>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(4), names=( a ,˓→ (a, b, c, d,) = P._first_ngens(4)>>> I = sage.rings.ideal.Katsura(P)˓→needs sage.libs.singular

696

b ,

c ,

d ,));#␣

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

If a list of tuples is provided, those form the parts:
sage: F = Sequence([I.gens(),I.gens()], I.ring()); F˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c,
a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]sage: F.nparts()
˓→needs sage.libs.singular2>>> from sage.all import *>>> F = Sequence([I.gens(),I.gens()], I.ring()); F˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c,
a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]>>> F.nparts()
˓→needs sage.libs.singular2# indirect doctest#␣#␣# indirect doctest#␣#␣

If an ideal is provided, the generators are used:
sage: Sequence(I)˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]>>> from sage.all import *>>> Sequence(I)˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]#␣#␣

If a list of polynomials is provided, the system has only one part:sage: F = Sequence(I.gens(), I.ring()); F˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]sage: F.nparts()#␣#␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

697

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.singular˓→1>>> from sage.all import *>>> F = Sequence(I.gens(), I.ring()); F˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]>>> F.nparts()
˓→needs sage.libs.singular
1

#␣

#␣

We test that the ring is inferred correctly:
sage: P.<x,y,z> = GF(2)[]sage: from sage.rings.polynomial.multi_polynomial_sequence import␣
˓→PolynomialSequence
sage: PolynomialSequence([1,x,y]).ring()
Multivariate Polynomial Ring in x, y, z over Finite Field of size 2
sage: PolynomialSequence([[1,x,y], [0]]).ring()
Multivariate Polynomial Ring in x, y, z over Finite Field of size 2>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence>>> PolynomialSequence([Integer(1),x,y]).ring()
Multivariate Polynomial Ring in x, y, z over Finite Field of size 2>>> PolynomialSequence([[Integer(1),x,y], [Integer(0)]]).ring()
Multivariate Polynomial Ring in x, y, z over Finite Field of size 2class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic(parts,
ring,
immutable=False
cr=False,
cr_str=None)
Bases: Sequence_generic
Construct a new system of multivariate polynomials.
INPUT:• part – a list of lists with polynomials• ring – a multivariate polynomial ring
• immutable – if True the sequence is immutable (default: False)• cr – print a line break after each element (default: False)• cr_str – print a line break after each element if ‘str’ is called (default: None)
EXAMPLES:

698

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<a,b,c,d> = PolynomialRing(GF(127), 4)
sage: I = sage.rings.ideal.Katsura(P)˓→needs sage.libs.singular#␣

sage: Sequence([I.gens()], I.ring()) # indirect doctest
˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), Integer(4), names=( a ,˓→ (a, b, c, d,) = P._first_ngens(4)>>> I = sage.rings.ideal.Katsura(P)˓→sage.libs.singular>>> Sequence([I.gens()], I.ring()) # indirect doctest
˓→sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]

#␣

b ,

c ,

d ,));# needs␣

# needs␣

If an ideal is provided, the generators are used.:sage: Sequence(I)˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]>>> from sage.all import *>>> Sequence(I)˓→sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]#␣# needs␣

If a list of polynomials is provided, the system has only one part.:sage: Sequence(I.gens(), I.ring())
˓→needs sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]>>> from sage.all import *>>> Sequence(I.gens(), I.ring())
˓→sage.libs.singular[a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c]#␣# needs␣

algebraic_dependence()
Returns the ideal of annihilating polynomials for the polynomials in self, if those polynomials are algebraically dependent. Otherwise, returns the zero ideal.
OUTPUT:
If the polynomials 𝑓1 , . . . , 𝑓𝑟 in self are algebraically dependent, then the output is the ideal {𝐹 ∈𝐾[𝑇1 , . . . , 𝑇𝑟 ] : 𝐹 (𝑓1 , . . . , 𝑓𝑟 ) = 0} of annihilating polynomials of 𝑓1 , . . . , 𝑓𝑟 . Here 𝐾 is the coefficientring of polynomial ring of 𝑓1 , . . . , 𝑓𝑟 and 𝑇1 , . . . , 𝑇𝑟 are new indeterminates. If 𝑓1 , . . . , 𝑓𝑟 are algebraicallyindependent, then the output is the zero ideal in 𝐾[𝑇1 , . . . , 𝑇𝑟 ].

3.1. Multivariate Polynomials and Polynomial Rings

699

Polynomials, Release 10.4

EXAMPLES:
sage: # needs sage.libs.singularsage: R.<x,y> = PolynomialRing(QQ)
sage: S = Sequence([x, x*y])
sage: I = S.algebraic_dependence(); I
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> S = Sequence([x, x*y])>>> I = S.algebraic_dependence(); I
Ideal (0) of Multivariate Polynomial Ring in T0, T1 over Rational Field
sage: # needs sage.libs.singularsage: R.<x,y> = PolynomialRing(QQ)
sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2])sage: I = S.algebraic_dependence(); I
Ideal (16 + 32*T2 - 8*T0^2 + 24*T2^2 - 8*T0^2*T2 + 8*T2^3 + 9*T0^4 - 2*T0^
˓→2*T2^2+ T2^4 - T0^4*T1 + 8*T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8)of Multivariate Polynomial Ring in T0, T1, T2 over Rational Field
sage: [F(S) for F in I.gens()][0]>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> S = Sequence([x, (x**Integer(2) + y**Integer(2) - Integer(1))**Integer(2),˓→ x*y - Integer(2)])>>> I = S.algebraic_dependence(); I
Ideal (16 + 32*T2 - 8*T0^2 + 24*T2^2 - 8*T0^2*T2 + 8*T2^3 + 9*T0^4 - 2*T0^
˓→2*T2^2+ T2^4 - T0^4*T1 + 8*T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8)of Multivariate Polynomial Ring in T0, T1, T2 over Rational Field>>> [F(S) for F in I.gens()][0]
sage: # needs sage.libs.singularsage: R.<x,y> = PolynomialRing(GF(7))
sage: S = Sequence([x, (x^2 + y^2 - 1)^2, x*y - 2])sage: I = S.algebraic_dependence(); I
Ideal (2 - 3*T2 - T0^2 + 3*T2^2 - T0^2*T2 + T2^3 + 2*T0^4 - 2*T0^2*T2^2+ T2^4 - T0^4*T1 + T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8)of Multivariate Polynomial Ring in T0, T1, T2 over Finite Field of size 7
sage: [F(S) for F in I.gens()][0]>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(GF(Integer(7)), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> S = Sequence([x, (x**Integer(2) + y**Integer(2) - Integer(1))**Integer(2),˓→ x*y - Integer(2)])>>> I = S.algebraic_dependence(); I(continues on next page)

700

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Ideal (2 - 3*T2 - T0^2 + 3*T2^2 - T0^2*T2 + T2^3 + 2*T0^4 - 2*T0^2*T2^2+ T2^4 - T0^4*T1 + T0^4*T2 - 2*T0^6 + 2*T0^4*T2^2 + T0^8)of Multivariate Polynomial Ring in T0, T1, T2 over Finite Field of size 7>>> [F(S) for F in I.gens()][0]Note: This function’s code also works for sequences of polynomials from a univariate polynomial ring, but
i don’t know where in the Sage codebase to put it to use it to that effect.
AUTHORS:• Alex Raichev (2011-06-22)
coefficient_matrix(sparse=True)
Return tuple (A,v) where A is the coefficient matrix of this system and v the matching monomial vector.
Thus value of A[i,j] corresponds the coefficient of the monomial v[j] in the i-th polynomial in thissystem.
Monomials are order w.r.t. the term ordering of self.ring() in reverse order, i.e. such that the smallest
entry comes last.
INPUT:• sparse – construct a sparse matrix (default: True)
EXAMPLES:
sage: # needs sage.libs.singularsage: P.<a,b,c,d> = PolynomialRing(GF(127), 4)
sage: I = sage.rings.ideal.Katsura(P)sage: I.gens()[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]sage: F = Sequence(I)sage: A,v = F.coefficient_matrix()
doctest:warning...
DeprecationWarning: the function coefficient_matrix is deprecated; use␣˓→coefficients_monomials instead
See https://github.com/sagemath/sage/issues/37035 for details.
sage: A
[ 0
0
0
0
0
0
0
0
0
1
2
2
2 126]
[ 1
0
2
0
0
2
0
0
2 126
0
0
0
0]
[ 0
2
0
0
2
0
0
2
0
0 126
0
0
0]
[ 0
0
1
2
0
0
2
0
0
0
0 126
0
0]
sage: v
[a^2]
[a*b]
[b^2]
[a*c]
[b*c]
[c^2]
[b*d]
[c*d]
[d^2]
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

701

Polynomials, Release 10.4

(continued from previous page)

[ a]
[ b]
[ c]
[ d]
[ 1]
sage: A*v[
a + 2*b + 2*c + 2*d - 1][a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a][
2*a*b + 2*b*c + 2*c*d - b][b^2 + 2*a*c + 2*b*d - c]>>> from sage.all import *>>> # needs sage.libs.singular>>> P = PolynomialRing(GF(Integer(127)), Integer(4), names=( a , b , c ,˓→ ,)); (a, b, c, d,) = P._first_ngens(4)>>> I = sage.rings.ideal.Katsura(P)>>> I.gens()[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]>>> F = Sequence(I)>>> A,v = F.coefficient_matrix()
doctest:warning...
DeprecationWarning: the function coefficient_matrix is deprecated; use␣˓→coefficients_monomials instead
See https://github.com/sagemath/sage/issues/37035 for details.
>>> A
[ 0
0
0
0
0
0
0
0
0
1
2
2
2 126]
[ 1
0
2
0
0
2
0
0
2 126
0
0
0
0]
[ 0
2
0
0
2
0
0
2
0
0 126
0
0
0]
[ 0
0
1
2
0
0
2
0
0
0
0 126
0
0]
>>> v
[a^2]
[a*b]
[b^2]
[a*c]
[b*c]
[c^2]
[b*d]
[c*d]
[d^2]
[ a]
[ b]
[ c]
[ d]
[ 1]
>>> A*v[
a + 2*b + 2*c + 2*d - 1][a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a][
2*a*b + 2*b*c + 2*c*d - b][b^2 + 2*a*c + 2*b*d - c]dcoefficients_monomials(order=None, sparse=True)
Return the matrix of coefficients A and the matching vector of monomials v, such that A*v == vector(self).

702

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Thus value of A[i,j] corresponds the coefficient of the monomial v[j] in the i-th polynomial in thissystem.
Monomials are ordered w.r.t. the term ordering of order if given; otherwise, they are ordered w.r.t. self.
ring() in reverse order, i.e., such that the smallest entry comes last.
INPUT:• sparse – construct a sparse matrix (default: True)• order – a list or tuple specifying the order of monomials (default: None)
EXAMPLES:
sage: # needs sage.libs.singularsage: P.<a,b,c,d> = PolynomialRing(GF(127), 4)
sage: I = sage.rings.ideal.Katsura(P)sage: I.gens()[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]sage: F = Sequence(I)sage: A,v = F.coefficients_monomials()sage: A
[ 0
0
0
0
0
0
0
0
0
1
2
2
2 126]
[ 1
0
2
0
0
2
0
0
2 126
0
0
0
0]
[ 0
2
0
0
2
0
0
2
0
0 126
0
0
0]
[ 0
0
1
2
0
0
2
0
0
0
0 126
0
0]
sage: v(a^2, a*b, b^2, a*c, b*c, c^2, b*d, c*d, d^2, a, b, c, d, 1)
sage: A*v
(a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c)>>> from sage.all import *>>> # needs sage.libs.singular>>> P = PolynomialRing(GF(Integer(127)), Integer(4), names=( a ,˓→ ,)); (a, b, c, d,) = P._first_ngens(4)>>> I = sage.rings.ideal.Katsura(P)>>> I.gens()[a + 2*b + 2*c + 2*d - 1,a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b,b^2 + 2*a*c + 2*b*d - c]>>> F = Sequence(I)>>> A,v = F.coefficients_monomials()
>>> A
[ 0
0
0
0
0
0
0
0
0
1
2
2
2 126]
[ 1
0
2
0
0
2
0
0
2 126
0
0
0
0]
[ 0
2
0
0
2
0
0
2
0
0 126
0
0
0]
[ 0
0
1
2
0
0
2
0
0
0
0 126
0
0]
>>> v
(a^2, a*b, b^2, a*c, b*c, c^2, b*d, c*d, d^2, a, b, c, d, 1)>>> A*v(a + 2*b + 2*c + 2*d - 1, a^2 + 2*b^2 + 2*c^2 + 2*d^2 - a,
2*a*b + 2*b*c + 2*c*d - b, b^2 + 2*a*c + 2*b*d - c)

b ,

c ,

d

connected_components()
Split the polynomial system in systems which do not share any variables.
3.1. Multivariate Polynomials and Polynomial Rings

703

Polynomials, Release 10.4

EXAMPLES:
As an example consider one part of AES, which naturally splits into four subsystems which are independent:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(2, 4, 4, 8, gf2=True, polybori=True)
sage: while True: # workaround (see :issue: 31891 )
....:
try:
....:
F, s = sr.polynomial_system()
....:
break
....:
except ZeroDivisionError:
....:
pass
sage: Fz = Sequence(F.part(2))
sage: Fz.connected_components()[Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables]>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(Integer(2), Integer(4), Integer(4), Integer(8), gf2=True,␣
˓→polybori=True)>>> while True: # workaround (see :issue: 31891 )
...
try:
...
F, s = sr.polynomial_system()
...
break
...
except ZeroDivisionError:...
pass>>> Fz = Sequence(F.part(Integer(2)))>>> Fz.connected_components()[Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables,
Polynomial Sequence with 128 Polynomials in 128 Variables]

connection_graph()
Return the graph which has the variables of this system as vertices and edges between two variables if they
appear in the same polynomial.
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: B.<x,y,z> = BooleanPolynomialRing()sage: F = Sequence([x*y + y + 1, z + 1])
sage: G = F.connection_graph(); GGraph on 3 vertices
sage: G.is_connected()False
sage: F = Sequence([x])
sage: F.connection_graph()
Graph on 1 vertex>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> B = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = B._first_
˓→ngens(3)>>> F = Sequence([x*y + y + Integer(1), z + Integer(1)])(continues on next page)704

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> G = F.connection_graph(); GGraph on 3 vertices>>> G.is_connected()
False>>> F = Sequence([x])>>> F.connection_graph()
Graph on 1 vertex

groebner_basis(*args, **kwargs)
Compute and return a Groebner basis for the ideal spanned by the polynomials in this system.
INPUT:• args – list of arguments passed to MPolynomialIdeal.groebner_basis call
• kwargs – dictionary of arguments passed to MPolynomialIdeal.groebner_basis call
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(allow_zero_inversions=True)
sage: F, s = sr.polynomial_system()sage: gb = F.groebner_basis()
sage: Ideal(gb).basis_is_groebner()True>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(allow_zero_inversions=True)>>> F, s = sr.polynomial_system()>>> gb = F.groebner_basis()>>> Ideal(gb).basis_is_groebner()
True

ideal()
Return ideal spanned by the elements of this system.
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(allow_zero_inversions=True)
sage: F, s = sr.polynomial_system()sage: P = F.ring()sage: I = F.ideal()
sage: J = I.elimination_ideal(P.gens()[4:-4])
sage: J <= I
True
sage: set(J.gens().variables()).issubset(P.gens()[:4] + P.gens()[-4:])
True>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(allow_zero_inversions=True)>>> F, s = sr.polynomial_system()>>> P = F.ring()>>> I = F.ideal()>>> J = I.elimination_ideal(P.gens()[Integer(4):-Integer(4)])(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

705

Polynomials, Release 10.4

(continued from previous page)>>> J <= I
True>>> set(J.gens().variables()).issubset(P.gens()[:Integer(4)] + P.gens()[˓→Integer(4):])
True

is_groebner(singular=Singular)
Returns True if the generators of this ideal (self.gens()) form a Groebner basis.
Let 𝐼 be the set of generators of this ideal. The check is performed by trying to lift 𝑆𝑦𝑧(𝐿𝑀 (𝐼)) to 𝑆𝑦𝑧(𝐼)as 𝐼 forms a Groebner basis if and only if for every element 𝑆 in 𝑆𝑦𝑧(𝐿𝑀 (𝐼)):∑︀𝑚
𝑆 * 𝐺 = 𝑖=0 ℎ𝑖 𝑔𝑖 − − − − >𝐺 0.
EXAMPLES:
sage: # needs sage.libs.singularsage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127), 10)
sage: I = sage.rings.ideal.Cyclic(R, 4)
sage: I.basis.is_groebner()
False
sage: I2 = Ideal(I.groebner_basis())
sage: I2.basis.is_groebner()True>>> from sage.all import *>>> # needs sage.libs.singular>>> R = PolynomialRing(GF(Integer(127)), Integer(10), names=( a , b , c ,˓→ ,e , f , g , h , i , j ,)); (a, b, c, d, e, f, g, h, i, j,) = R._
˓→first_ngens(10)>>> I = sage.rings.ideal.Cyclic(R, Integer(4))>>> I.basis.is_groebner()
False>>> I2 = Ideal(I.groebner_basis())>>> I2.basis.is_groebner()Truedmaximal_degree()Return the maximal degree of any polynomial in this sequence.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(7))
sage: F = Sequence([x*y + x, x])sage: F.maximal_degree()2
sage: P.<x,y,z> = PolynomialRing(GF(7))
sage: F = Sequence([], universe=P)
sage: F.maximal_degree()-1>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(7)), names=( x ,˓→P._first_ngens(3)>>> F = Sequence([x*y + x, x])>>> F.maximal_degree()y ,z ,)); (x, y, z,) =␣

(continues on next page)

706

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)2>>> P = PolynomialRing(GF(Integer(7)), names=( x ,˓→P._first_ngens(3)>>> F = Sequence([], universe=P)>>> F.maximal_degree()-1y ,z ,)); (x, y, z,) =␣

monomials()
Return an unordered tuple of monomials in this polynomial system.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori
sage: len(F.monomials())
˓→needs sage.rings.polynomial.pbori
49>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori>>> len(F.monomials())
˓→needs sage.rings.polynomial.pbori
49

#␣
#␣
#␣

#␣
#␣
#␣

nmonomials()
Return the number of monomials present in this system.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori
sage: F.nmonomials()
˓→needs sage.rings.polynomial.pbori
49>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori>>> F.nmonomials()
˓→needs sage.rings.polynomial.pbori
49

#␣
#␣
#␣

#␣
#␣
#␣

nparts()Return number of parts of this system.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

707

Polynomials, Release 10.4

sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F, s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori
sage: F.nparts()
˓→needs sage.rings.polynomial.pbori
4

#␣
#␣
#␣

>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F, s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori>>> F.nparts()
˓→needs sage.rings.polynomial.pbori
4

#␣
#␣
#␣

nvariables()Return number of variables present in this system.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori
sage: F.nvariables()˓→needs sage.rings.polynomial.pbori
20

#␣
#␣
#␣

>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori>>> F.nvariables()˓→needs sage.rings.polynomial.pbori
20

#␣
#␣
#␣

part(i)Return i-th part of this system.
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(allow_zero_inversions=True)
sage: F, s = sr.polynomial_system()sage: R0 = F.part(1)sage: R0(k000^2 + k001, k001^2 + k002, k002^2 + k003, k003^2 + k000)>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(allow_zero_inversions=True)>>> F, s = sr.polynomial_system()>>> R0 = F.part(Integer(1))(continues on next page)

708

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> R0(k000^2 + k001, k001^2 + k002, k002^2 + k003, k003^2 + k000)

parts()
Return a tuple of parts of this system.
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(allow_zero_inversions=True)
sage: F, s = sr.polynomial_system()sage: l = F.parts()
sage: len(l)4>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(allow_zero_inversions=True)>>> F, s = sr.polynomial_system()>>> l = F.parts()>>> len(l)4reduced()If this sequence is (𝑓1 , ..., 𝑓𝑛 ) then this method returns (𝑔1 , ..., 𝑔𝑠 ) such that:• (𝑓1 , ..., 𝑓𝑛 ) = (𝑔1 , ..., 𝑔𝑠 )• 𝐿𝑇 (𝑔𝑖 ) ̸= 𝐿𝑇 (𝑔𝑗 ) for all 𝑖 ̸= 𝑗
• 𝐿𝑇 (𝑔𝑖 ) does not divide 𝑚 for all monomials 𝑚 of {𝑔1 , ..., 𝑔𝑖−1 , 𝑔𝑖+1 , ..., 𝑔𝑠 }• 𝐿𝐶(𝑔𝑖 ) = 1 for all 𝑖 if the coefficient ring is a field.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: F = Sequence([z*x+y^3,z+y^3,z+x*y])
sage: F.reduced()[y^3 + z, x*y + z, x*z - z]>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> F = Sequence([z*x+y**Integer(3),z+y**Integer(3),z+x*y])>>> F.reduced()[y^3 + z, x*y + z, x*z - z]Note that tail reduction for local orderings is not well-defined:
sage: R.<x,y,z> = PolynomialRing(QQ,order= negdegrevlex )sage: F = Sequence([z*x+y^3,z+y^3,z+x*y])
sage: F.reduced()[z + x*y, x*y - y^3, x^2*y - y^3]>>> from sage.all import *>>> R = PolynomialRing(QQ,order= negdegrevlex , names=( x ,y ,z ,)); (x,␣(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

709

Polynomials, Release 10.4

(continued from previous page)y, z,) = R._first_ngens(3)>>> F = Sequence([z*x+y**Integer(3),z+y**Integer(3),z+x*y])>>> F.reduced()[z + x*y, x*y - y^3, x^2*y - y^3]˓→A fixed error with nonstandard base fields:
sage: R.<t>=QQ[ t ]sage: K.<x,y>=R.fraction_field()[ x,y ]sage: I=t*x*K
sage: I.basis.reduced()[x]>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()[ x,y ]; (x, y,) = K._first_ngens(2)>>> I=t*x*K>>> I.basis.reduced()[x]

The interreduced basis of 0 is 0:
sage: P.<x,y,z> = GF(2)[]sage: Sequence([P(0)]).reduced()[0]>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> Sequence([P(Integer(0))]).reduced()[0]

Leading coefficients are reduced to 1:
sage: P.<x,y> = QQ[]
sage: Sequence([2*x,y]).reduced()[x, y]
sage: P.<x,y> = CC[]˓→needs sage.rings.real_mpfr
sage: Sequence([2*x,y]).reduced()[x, y]#␣>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> Sequence([Integer(2)*x,y]).reduced()[x, y]>>> P = CC[ x, y ]; (x, y,) = P._first_ngens(2)# needs sage.rings.real_mpfr>>> Sequence([Integer(2)*x,y]).reduced()[x, y]ALGORITHM:
Uses Singular’s interred command or sage.rings.polynomial.toy_buchberger.
inter_reduction() if conversion to Singular fails.

710

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

ring()
Return the polynomial ring all elements live in.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True, gf2=True, order= block )#␣˓→needs sage.rings.polynomial.pbori
sage: F, s = sr.polynomial_system()#␣˓→needs sage.rings.polynomial.pbori
sage: print(F.ring().repr_long())#␣˓→needs sage.rings.polynomial.pbori
Polynomial Ring
Base Ring : Finite Field of size 2
Size : 20 Variables
Block 0 : Ordering : deglex
Names: k100, k101, k102, k103, x100, x101, x102, x103, w100,␣˓→w101, w102, w103, s000, s001, s002, s003
Block 1 : Ordering : deglex
Names: k000, k001, k002, k003>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True, gf2=True, order= block )#␣˓→needs sage.rings.polynomial.pbori>>> F, s = sr.polynomial_system()#␣˓→needs sage.rings.polynomial.pbori>>> print(F.ring().repr_long())#␣˓→needs sage.rings.polynomial.pbori
Polynomial Ring
Base Ring : Finite Field of size 2
Size : 20 Variables
Block 0 : Ordering : deglex
Names: k100, k101, k102, k103, x100, x101, x102, x103, w100,␣˓→w101, w102, w103, s000, s001, s002, s003
Block 1 : Ordering : deglex
Names: k000, k001, k002, k003

subs(*args, **kwargs)
Substitute variables for every polynomial in this system and return a new system. See MPolynomial.
subs() for calling convention.
INPUT:• args – arguments to be passed to MPolynomial.subs()• kwargs – keyword arguments to be passed to MPolynomial.subs()
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F, s = sr.polynomial_system(); F˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 40 Polynomials in 20 Variables
sage: F = F.subs(s); F˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 40 Polynomials in 16 Variables

3.1. Multivariate Polynomials and Polynomial Rings

#␣
#␣

#␣

711

Polynomials, Release 10.4>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F, s = sr.polynomial_system(); F˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 40 Polynomials in 20 Variables>>> F = F.subs(s); F˓→needs sage.rings.polynomial.pbori
Polynomial Sequence with 40 Polynomials in 16 Variables

#␣
#␣

#␣

universe()
Return the polynomial ring all elements live in.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True, gf2=True, order= block )#␣˓→needs sage.rings.polynomial.pbori
sage: F, s = sr.polynomial_system()#␣˓→needs sage.rings.polynomial.pbori
sage: print(F.ring().repr_long())#␣˓→needs sage.rings.polynomial.pbori
Polynomial Ring
Base Ring : Finite Field of size 2
Size : 20 Variables
Block 0 : Ordering : deglex
Names: k100, k101, k102, k103, x100, x101, x102, x103, w100,␣˓→w101, w102, w103, s000, s001, s002, s003
Block 1 : Ordering : deglex
Names: k000, k001, k002, k003>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True, gf2=True, order= block )#␣˓→needs sage.rings.polynomial.pbori>>> F, s = sr.polynomial_system()#␣˓→needs sage.rings.polynomial.pbori>>> print(F.ring().repr_long())#␣˓→needs sage.rings.polynomial.pbori
Polynomial Ring
Base Ring : Finite Field of size 2
Size : 20 Variables
Block 0 : Ordering : deglex
Names: k100, k101, k102, k103, x100, x101, x102, x103, w100,␣˓→w101, w102, w103, s000, s001, s002, s003
Block 1 : Ordering : deglex
Names: k000, k001, k002, k003

variables()Return all variables present in this system. This tuple may or may not be equal to the generators of the ringof this system.
EXAMPLES:
sage: sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori
sage: F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori
sage: F.variables()[:10]

#␣
#␣
#␣
(continues on next page)712

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.polynomial.pbori(k003, k002, k001, k000, s003, s002, s001, s000, w103, w102)
˓→>>> from sage.all import *>>> sr = mq.SR(allow_zero_inversions=True)
˓→needs sage.rings.polynomial.pbori>>> F,s = sr.polynomial_system()
˓→needs sage.rings.polynomial.pbori>>> F.variables()[:Integer(10)]˓→# needs sage.rings.polynomial.pbori(k003, k002, k001, k000, s003, s002, s001, s000, w103, w102)

#␣
#␣
␣

class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2(parts,
ring,
immutable=False,
cr=False,
cr_str=None)
Bases: PolynomialSequence_generic
Polynomial Sequences over F2 .
coefficients_monomials(order=None, sparse=True)
Return the matrix of coefficients A and the matching vector of monomials v, such that A*v == vector(self).
Thus value of A[i,j] corresponds the coefficient of the monomial v[j] in the i-th polynomial in thissystem.
Monomials are ordered w.r.t. the term ordering of order if given; otherwise, they are ordered w.r.t. self.
ring() in reverse order, i.e., such that the smallest entry comes last.
INPUT:• sparse – construct a sparse matrix (default: True)• order – a list or tuple specifying the order of monomials (default: None)
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: B.<x,y,z> = BooleanPolynomialRing()sage: F = Sequence([x*y + y + 1, z + 1])
sage: A, v = F.coefficients_monomials()sage: A
[1 1 0 1][0 0 1 1]
sage: v
(x*y, y, z, 1)
sage: A*v
(x*y + y + 1, z + 1)>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> B = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = B._first_
˓→ngens(3)>>> F = Sequence([x*y + y + Integer(1), z + Integer(1)])(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

713

Polynomials, Release 10.4

(continued from previous page)>>> A, v = F.coefficients_monomials()>>> A[1 1 0 1][0 0 1 1]>>> v(x*y, y, z, 1)>>> A*v(x*y + y + 1, z + 1)

eliminate_linear_variables(maxlength=+Infinity, skip=None, return_reductors=False,
use_polybori=False)
Return a new system where linear leading variables are eliminated if the tail of the polynomial has length at
most maxlength.
INPUT:• maxlength – an optional upper bound on the number of monomials by which a variable is replaced.
If maxlength==+Infinity then no condition is checked. (default: +Infinity).
• skip – an optional callable to skip eliminations. It must accept two parameters and return either Trueor False. The two parameters are the leading term and the tail of a polynomial (default: None).
• return_reductors – if True the list of polynomials with linear leading terms which were used for
reduction is also returned (default: False).
• use_polybori – if True then polybori.ll.eliminate is called. While this is typically fasterthan what is implemented here, it is less flexible (skip is not supported) and may increase the degree(default: False)
OUTPUT:
With return_reductors=True, a pair of sequences of boolean polynomials are returned, along withthe promises that:
1. The union of the two sequences spans the same boolean ideal as the argument of the method
2. The second sequence only contains linear polynomials, and it forms a reduced groebner basis (they all
have pairwise distinct leading variables, and the leading variable of a polynomial does not occur anywherein other polynomials).
3. The leading variables of the second sequence do not occur anywhere in the first sequence (these variables
have been eliminated).
With return_reductors=False, only the first sequence is returned.
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: B.<a,b,c,d> = BooleanPolynomialRing()sage: F = Sequence([c + d + b + 1, a + c + d, a*b + c, b*c*d + c])sage: F.eliminate_linear_variables() # everything vanishes[]
sage: F.eliminate_linear_variables(maxlength=2)[b + c + d + 1, b*c + b*d + c, b*c*d + c]sage: F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)== a )[a + c + d, a*c + a*d + a + c, c*d + c]>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori(continues on next page)714

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> B = BooleanPolynomialRing(names=( a , b , c , d ,)); (a, b, c, d,) = B.
˓→_first_ngens(4)>>> F = Sequence([c + d + b + Integer(1), a + c + d, a*b + c, b*c*d + c])>>> F.eliminate_linear_variables() # everything vanishes[]>>> F.eliminate_linear_variables(maxlength=Integer(2))[b + c + d + 1, b*c + b*d + c, b*c*d + c]>>> F.eliminate_linear_variables(skip=lambda lm,tail: str(lm)== a )[a + c + d, a*c + a*d + a + c, c*d + c]

The list of reductors can be requested by setting return_reductors to True:
sage: # needs sage.rings.polynomial.pbori
sage: B.<a,b,c,d> = BooleanPolynomialRing()sage: F = Sequence([a + b + d, a + b + c])sage: F, R = F.eliminate_linear_variables(return_reductors=True)
sage: F[]sage: R[a + b + d, c + d]>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> B = BooleanPolynomialRing(names=( a , b , c , d ,)); (a, b, c, d,) = B.
˓→_first_ngens(4)>>> F = Sequence([a + b + d, a + b + c])>>> F, R = F.eliminate_linear_variables(return_reductors=True)
>>> F
[]
>>> R
[a + b + d, c + d]

If the input system is detected to be inconsistent then [1] is returned, and the list of reductors is empty:
sage: # needs sage.rings.polynomial.pbori
sage: R.<x,y,z> = BooleanPolynomialRing()sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z])
sage: S.eliminate_linear_variables()[1]
sage: R.<x,y,z> = BooleanPolynomialRing()sage: S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + 1, x + y + z])
sage: S.eliminate_linear_variables(return_reductors=True)([1], [])>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> R = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + Integer(1), x + y + z])>>> S.eliminate_linear_variables()[1]>>> R = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> S = Sequence([x*y*z + x*y + z*y + x*z, x + y + z + Integer(1), x + y + z])>>> S.eliminate_linear_variables(return_reductors=True)([1], [])

3.1. Multivariate Polynomials and Polynomial Rings

715

Polynomials, Release 10.4

Note: This is called “massaging” in [BCJ2007].
reduced()If this sequence is 𝑓1 , ..., 𝑓𝑛 , return 𝑔1 , ..., 𝑔𝑠 such that:• (𝑓1 , ..., 𝑓𝑛 ) = (𝑔1 , ..., 𝑔𝑠 )• 𝐿𝑇 (𝑔𝑖 ) ̸= 𝐿𝑇 (𝑔𝑗 ) for all 𝑖 ̸= 𝑗
• 𝐿𝑇 (𝑔𝑖 ) does not divide 𝑚 for all monomials 𝑚 of 𝑔1 , ..., 𝑔𝑖−1 , 𝑔𝑖+1 , ..., 𝑔𝑠
EXAMPLES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(1, 1, 1, 4, gf2=True, polybori=True)
sage: while True: # workaround (see :issue: 31891 )
....:
try:
....:
F, s = sr.polynomial_system()
....:
break
....:
except ZeroDivisionError:
....:
pass
sage: g = F.reduced()sage: len(g) == len(set(gi.lt() for gi in g))True
sage: for i in range(len(g)):....:
for j in range(len(g)):....:
if i == j:....:continue....:
for t in list(g[j]):....:assert g[i].lt() not in t.divisors()>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(Integer(1), Integer(1), Integer(1), Integer(4), gf2=True,␣
˓→polybori=True)>>> while True: # workaround (see :issue: 31891 )
...
try:
...
F, s = sr.polynomial_system()
...
break
...
except ZeroDivisionError:...
pass>>> g = F.reduced()>>> len(g) == len(set(gi.lt() for gi in g))
True>>> for i in range(len(g)):...
for j in range(len(g)):...
if i == j:...
continue...
for t in list(g[j]):...
assert g[i].lt() not in t.divisors()solve(algorithm='polybori', n=1, eliminate_linear_variables=True, verbose=False, **kwds)
Find solutions of this boolean polynomial system.
This function provide a unified interface to several algorithms dedicated to solving systems of boolean equations. Depending on the particular nature of the system, some might be much faster than some others.
INPUT:
716

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• self – a sequence of boolean polynomials• algorithm – the method to use. Possible values are polybori, sat and exhaustive_search.
(default: polybori, since it is always available)• n – number of solutions to return. If n == +Infinity then all solutions are returned. If 𝑛 < ∞then 𝑛 solutions are returned if the equations have at least 𝑛 solutions. Otherwise, all the solutions are
returned. (default: 1)• eliminate_linear_variables – whether to eliminate variables that appear linearly. This reduces the number of variables (makes solving faster a priori), but is likely to make the equations denser(may make solving slower depending on the method).
• verbose – whether to display progress and (potentially) useful information while the computation runs.
(default: False)
EXAMPLES:
Without argument, a single arbitrary solution is returned:
sage: # needs sage.rings.polynomial.pbori
sage: from sage.doctest.fixtures import reproducible_repr
sage: R.<x,y,z> = BooleanPolynomialRing()sage: S = Sequence([x*y + z, y*z + x, x + y + z + 1])
sage: sol = S.solve()
sage: print(reproducible_repr(sol))[{x: 0, y: 1, z: 0}]>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> from sage.doctest.fixtures import reproducible_repr>>> R = BooleanPolynomialRing(names=( x , y , z ,)); (x, y, z,) = R._first_
˓→ngens(3)>>> S = Sequence([x*y + z, y*z + x, x + y + z + Integer(1)])>>> sol = S.solve()>>> print(reproducible_repr(sol))[{x: 0, y: 1, z: 0}]

We check that it is actually a solution:
sage: S.subs(sol[0])˓→needs sage.rings.polynomial.pbori[0, 0, 0]>>> from sage.all import *>>> S.subs(sol[Integer(0)])˓→# needs sage.rings.polynomial.pbori[0, 0, 0]#␣␣

We obtain all solutions:sage: sols = S.solve(n=Infinity)
˓→needs sage.rings.polynomial.pbori
sage: print(reproducible_repr(sols))
˓→needs sage.rings.polynomial.pbori[{x: 0, y: 1, z: 0}, {x: 1, y: 1, z: 1}]sage: [S.subs(x) for x in sols]
˓→needs sage.rings.polynomial.pbori[[0, 0, 0], [0, 0, 0]]3.1. Multivariate Polynomials and Polynomial Rings

#␣
#␣

#␣

717

Polynomials, Release 10.4>>> from sage.all import *>>> sols = S.solve(n=Infinity)
˓→needs sage.rings.polynomial.pbori>>> print(reproducible_repr(sols))
˓→needs sage.rings.polynomial.pbori[{x: 0, y: 1, z: 0}, {x: 1, y: 1, z: 1}]>>> [S.subs(x) for x in sols]
˓→needs sage.rings.polynomial.pbori[[0, 0, 0], [0, 0, 0]]

#␣
#␣

#␣

We can force the use of exhaustive search if the optional package FES is present:
sage: sol = S.solve(algorithm= exhaustive_search )˓→needs sage.rings.polynomial.pbori
sage: print(reproducible_repr(sol))
˓→needs sage.rings.polynomial.pbori[{x: 1, y: 1, z: 1}]sage: S.subs(sol[0])˓→needs sage.rings.polynomial.pbori[0, 0, 0]>>> from sage.all import *>>> sol = S.solve(algorithm= exhaustive_search )˓→needs sage.rings.polynomial.pbori>>> print(reproducible_repr(sol))
˓→needs sage.rings.polynomial.pbori[{x: 1, y: 1, z: 1}]>>> S.subs(sol[Integer(0)])˓→# needs sage.rings.polynomial.pbori[0, 0, 0]# optional - fes#␣# optional - fes#␣# optional - fes#␣# optional - fes#␣# optional - fes#␣# optional - fes

␣And we may use SAT-solvers if they are available:
sage: sol = S.solve(algorithm= sat )˓→needs sage.rings.polynomial.pbori
sage: print(reproducible_repr(sol))
˓→needs sage.rings.polynomial.pbori[{x: 0, y: 1, z: 0}]sage: S.subs(sol[0])˓→needs sage.rings.polynomial.pbori[0, 0, 0]# optional - pycryptosat#␣# optional - pycryptosat#␣#␣>>> from sage.all import *>>> sol = S.solve(algorithm= sat )# optional - pycryptosat
˓→needs sage.rings.polynomial.pbori>>> print(reproducible_repr(sol))# optional - pycryptosat
˓→needs sage.rings.polynomial.pbori[{x: 0, y: 1, z: 0}]>>> S.subs(sol[Integer(0)])˓→# needs sage.rings.polynomial.pbori[0, 0, 0]

#␣
#␣

␣

class sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2e(parts,
ring,
immutable=False,
cr=False,
cr_str=None)
718

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Bases: PolynomialSequence_generic
PolynomialSequence over F2𝑒 , i.e extensions over F( 2).
weil_restriction()
Project this polynomial system to F2 .
That is, compute the Weil restriction of scalars for the variety corresponding to this polynomial system andexpress it as a polynomial system over F2 .
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(2^2)
sage: P.<x,y> = PolynomialRing(k, 2)
sage: a = P.base_ring().gen()sage: F = Sequence([x*y + 1, a*x + 1], P)
sage: F2 = F.weil_restriction()sage: F2[x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + x0,
x1^2 + x1, y0^2 + y0, y1^2 + y1]>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> k = GF(Integer(2)**Integer(2), names=( a ,)); (a,) = k._first_ngens(1)>>> P = PolynomialRing(k, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)>>> a = P.base_ring().gen()>>> F = Sequence([x*y + Integer(1), a*x + Integer(1)], P)>>> F2 = F.weil_restriction()>>> F2[x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1, x0^2 + x0,
x1^2 + x1, y0^2 + y0, y1^2 + y1]

Another bigger example for a small scale AES:
sage: # needs sage.rings.polynomial.pbori
sage: sr = mq.SR(1, 1, 1, 4, gf2=False)
sage: while True: # workaround (see :issue: 31891 )
....:
try:
....:
F, s = sr.polynomial_system()
....:
break
....:
except ZeroDivisionError:
....:
pass
sage: F
Polynomial Sequence with 40 Polynomials in 20 Variables
sage: F2 = F.weil_restriction(); F2
Polynomial Sequence with 240 Polynomials in 80 Variables>>> from sage.all import *>>> # needs sage.rings.polynomial.pbori>>> sr = mq.SR(Integer(1), Integer(1), Integer(1), Integer(4), gf2=False)>>> while True: # workaround (see :issue: 31891 )
...
try:
...
F, s = sr.polynomial_system()
...
break
...
except ZeroDivisionError:(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

719

Polynomials, Release 10.4

(continued from previous page)

...
pass
>>> F
Polynomial Sequence with 40 Polynomials in 20 Variables>>> F2 = F.weil_restriction(); F2
Polynomial Sequence with 240 Polynomials in 80 Variables

sage.rings.polynomial.multi_polynomial_sequence.is_PolynomialSequence(F)Return True if F is a PolynomialSequence.
INPUT:• F – anything
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ)
sage: I = [[x^2 + y^2], [x^2 - y^2]]
sage: F = Sequence(I, P); F[x^2 + y^2, x^2 - y^2]
sage: from sage.rings.polynomial.multi_polynomial_sequence import is_
˓→PolynomialSequence
sage: is_PolynomialSequence(F)True>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> I = [[x**Integer(2) + y**Integer(2)], [x**Integer(2) - y**Integer(2)]]>>> F = Sequence(I, P); F[x^2 + y^2, x^2 - y^2]>>> from sage.rings.polynomial.multi_polynomial_sequence import is_
˓→PolynomialSequence>>> is_PolynomialSequence(F)True

3.1.8 Multivariate Polynomials via libSINGULAR
This module implements specialized and optimized implementations for multivariate polynomials over many coefficientrings, via a shared library interface to SINGULAR. In particular, the following coefficient rings are supported by this
implementation:• the rational numbers,• the ring of integers Z,• Z/𝑛Z for any integer 𝑛,• finite fields F𝑝𝑛 for 𝑝 prime and 𝑛 > 0,
• and absolute number fields(𝑎).

EXAMPLES:
We show how to construct various multivariate polynomial rings:

720

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y,z> = QQ[]
sage: P
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: f = 27/113 * x^2 + y*z + 1/2; f
27/113*x^2 + y*z + 1/2
sage: P.term_order()Degree reverse lexicographic term ordersage: P = PolynomialRing(GF(127), 3, names= abc , order= lex ); P
Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
sage: a,b,c = P.gens()
sage: f = 57 * a^2*b + 43 * c + 1; f
57*a^2*b + 43*c + 1
sage: P.term_order()
Lexicographic term ordersage: z = QQ[ z ].0
sage: K.
 = NumberField(z^2 - 2)
˓→needs sage.rings.number_fieldsage: P.<x,y> = PolynomialRing(K, 2)
˓→needs sage.rings.number_fieldsage: 1/2*s*x^2 + 3/4*s
˓→needs sage.rings.number_field(1/2*s)*x^2 + (3/4*s)

#␣
#␣
#␣

sage: P.<x,y,z> = ZZ[]; P
Multivariate Polynomial Ring in x, y, z over Integer Ringsage: P.<x,y,z> = Zmod(2^10)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024
sage: P.<x,y,z> = Zmod(3^10)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049
sage: P.<x,y,z> = Zmod(2^100)[]; P
Multivariate Polynomial Ring in x, y, z over
Ring of integers modulo 1267650600228229401496703205376
sage: P.<x,y,z> = Zmod(2521352)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352
sage: type(P)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular
˓→ >sage: P.<x,y,z> = Zmod(25213521351515232)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232
sage: type(P)<class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_with_
˓→category >>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> PMultivariate Polynomial Ring in x, y, z over Rational Field(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

721

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(27)/Integer(113) * x**Integer(2) + y*z + Integer(1)/Integer(2); f
27/113*x^2 + y*z + 1/2>>> P.term_order()Degree reverse lexicographic term order>>> P = PolynomialRing(GF(Integer(127)), Integer(3), names= abc , order= lex ); P
Multivariate Polynomial Ring in a, b, c over Finite Field of size 127>>> a,b,c = P.gens()>>> f = Integer(57) * a**Integer(2)*b + Integer(43) * c + Integer(1); f
57*a^2*b + 43*c + 1>>> P.term_order()
Lexicographic term order>>> z = QQ[ z ].gen(0)>>> K = NumberField(z**Integer(2) - Integer(2), names=( s ,)); (s,) = K._first_
˓→ngens(1)# needs sage.rings.number_field>>> P = PolynomialRing(K, Integer(2), names=( x , y ,)); (x, y,) = P._first_ngens(2)˓→# needs sage.rings.number_field>>> Integer(1)/Integer(2)*s*x**Integer(2) + Integer(3)/Integer(4)*s␣˓→# needs sage.rings.number_field(1/2*s)*x^2 + (3/4*s)>>> P = ZZ[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Integer Ring>>> P = Zmod(Integer(2)**Integer(10))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024>>> P = Zmod(Integer(3)**Integer(10))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049>>> P = Zmod(Integer(2)**Integer(100))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over
Ring of integers modulo 1267650600228229401496703205376>>> P = Zmod(Integer(2521352))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352>>> type(P)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular
˓→ >>>> P = Zmod(Integer(25213521351515232))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 25213521351515232>>> type(P)<class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_with_
˓→category >We construct the Frobenius morphism on F5 [𝑥, 𝑦, 𝑧] over F5 :sage: R.<x,y,z> = PolynomialRing(GF(5), 3)
sage: frob = R.hom([x^5, y^5, z^5])
sage: frob(x^2 + 2*y - z^4)-z^20 + x^10 + 2*y^5
sage: frob((x + 2*y)^3)
˓→needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15#␣(continues on next page)722

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: (x^5 + 2*y^5)^3
˓→needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15#␣>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(5)), Integer(3), names=( x , y , z ,)); (x, y, z,
˓→) = R._first_ngens(3)>>> frob = R.hom([x**Integer(5), y**Integer(5), z**Integer(5)])>>> frob(x**Integer(2) + Integer(2)*y - z**Integer(4))-z^20 + x^10 + 2*y^5>>> frob((x + Integer(2)*y)**Integer(3))␣˓→# needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15>>> (x**Integer(5) + Integer(2)*y**Integer(5))**Integer(3)␣˓→# needs sage.rings.finite_ringsx^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15

We make a polynomial ring in one variable over a polynomial ring in two variables:sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: S.<t> = PowerSeriesRing(R)sage: t*(x+y)(x + y)*t>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> S = PowerSeriesRing(R, names=( t ,)); (t,) = S._first_ngens(1)>>> t*(x+y)(x + y)*t

Todo: Implement Real, Complex coefficient rings via libSINGULAR
AUTHORS:• Martin Albrecht (2007-01): initial implementation• Joel Mohler (2008-01): misc improvements, polishing• Martin Albrecht (2008-08): added(𝑎) and Z support• Simon King (2009-04): improved coercion• Martin Albrecht (2009-05): added Z/𝑛Z support, refactoring• Martin Albrecht (2009-06): refactored the code to allow better re-use• Simon King (2011-03): use a faster way of conversion from the base ring.
• Volker Braun (2011-06): major cleanup, refcount singular rings, bugfixes.
classsage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular
Bases: MPolynomialRing_base
Construct a multivariate polynomial ring subject to the following conditions:
INPUT:

3.1. Multivariate Polynomials and Polynomial Rings

723

Polynomials, Release 10.4

• base_ring – base ring (must be either GF(q), ZZ, ZZ/nZZ,
QQ or absolute number field)• n – number of variables (must be at least 1)• names – names of ring variables, may be string of list/tuple• order – term order (default: degrevlex)
EXAMPLES:
sage: P.<x,y,z> = QQ[]; P
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: f = 27/113 * x^2 + y*z + 1/2; f
27/113*x^2 + y*z + 1/2
sage: P.term_order()Degree reverse lexicographic term ordersage: P = PolynomialRing(GF(127), 3, names= abc , order= lex ); P
Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
sage: a,b,c = P.gens()
sage: f = 57 * a^2*b + 43 * c + 1; f
57*a^2*b + 43*c + 1
sage: P.term_order()
Lexicographic term ordersage: z = QQ[ z ].0
sage: K.
 = NumberField(z^2 - 2)
˓→needs sage.rings.number_fieldsage: P.<x,y> = PolynomialRing(K, 2)
˓→needs sage.rings.number_fieldsage: 1/2*s*x^2 + 3/4*s
˓→needs sage.rings.number_field(1/2*s)*x^2 + (3/4*s)

#␣
#␣
#␣

sage: P.<x,y,z> = ZZ[]; P
Multivariate Polynomial Ring in x, y, z over Integer Ringsage: P.<x,y,z> = Zmod(2^10)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024
sage: P.<x,y,z> = Zmod(3^10)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049
sage: P.<x,y,z> = Zmod(2^100)[]; P
Multivariate Polynomial Ring in x, y, z over
Ring of integers modulo 1267650600228229401496703205376
sage: P.<x,y,z> = Zmod(2521352)[]; P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352
sage: type(P)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_
˓→libsingular >sage: P.<x,y,z> = Zmod(25213521351515232)[]; P
Multivariate Polynomial Ring in x, y, z over
Ring of integers modulo 25213521351515232
sage: type(P)<class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_with_(continues on next page)724

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)category >˓→sage: P.<x,y,z> = PolynomialRing(Integers(2^32), order= lex )sage: P(2^32-1)
4294967295>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Rational Field>>> f = Integer(27)/Integer(113) * x**Integer(2) + y*z + Integer(1)/Integer(2); f
27/113*x^2 + y*z + 1/2>>> P.term_order()Degree reverse lexicographic term order>>> P = PolynomialRing(GF(Integer(127)), Integer(3), names= abc , order= lex ); P
Multivariate Polynomial Ring in a, b, c over Finite Field of size 127>>> a,b,c = P.gens()>>> f = Integer(57) * a**Integer(2)*b + Integer(43) * c + Integer(1); f
57*a^2*b + 43*c + 1>>> P.term_order()
Lexicographic term order>>> z = QQ[ z ].gen(0)>>> K = NumberField(z**Integer(2) - Integer(2), names=( s ,)); (s,) = K._first_
˓→ngens(1)# needs sage.rings.number_field>>> P = PolynomialRing(K, Integer(2), names=( x , y ,)); (x, y,) = P._first_
˓→ngens(2)# needs sage.rings.number_field>>> Integer(1)/Integer(2)*s*x**Integer(2) + Integer(3)/Integer(4)*s˓→# needs sage.rings.number_field(1/2*s)*x^2 + (3/4*s)␣>>> P = ZZ[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Integer Ring>>> P = Zmod(Integer(2)**Integer(10))[ x, y, z ]; (x, y, z,) = P._first_ngens(3);␣
˓→PMultivariate Polynomial Ring in x, y, z over Ring of integers modulo 1024>>> P = Zmod(Integer(3)**Integer(10))[ x, y, z ]; (x, y, z,) = P._first_ngens(3);␣
˓→PMultivariate Polynomial Ring in x, y, z over Ring of integers modulo 59049>>> P = Zmod(Integer(2)**Integer(100))[ x, y, z ]; (x, y, z,) = P._first_ngens(3);˓→ PMultivariate Polynomial Ring in x, y, z over
Ring of integers modulo 1267650600228229401496703205376>>> P = Zmod(Integer(2521352))[ x, y, z ]; (x, y, z,) = P._first_ngens(3); P
Multivariate Polynomial Ring in x, y, z over Ring of integers modulo 2521352>>> type(P)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_
˓→libsingular >>>> P = Zmod(Integer(25213521351515232))[ x, y, z ]; (x, y, z,) = P._first_
˓→ngens(3); P
Multivariate Polynomial Ring in x, y, z over(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

725

Polynomials, Release 10.4

(continued from previous page)

Ring of integers modulo 25213521351515232>>> type(P)<class sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_with_
˓→category >>>> P = PolynomialRing(Integers(Integer(2)**Integer(32)), order= lex , names=( x ,˓→y , z ,)); (x, y, z,) = P._first_ngens(3)>>> P(Integer(2)**Integer(32)-Integer(1))
4294967295

Element
alias of MPolynomial_libsingulargen(n=0)
Returns the n-th generator of this multivariate polynomial ring.
INPUT:• n – an integer >= 0
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.gen(), P.gen(1)(x, y)
sage: P = PolynomialRing(GF(127), 1000,
sage: P.gen(500)
x500

x )

sage: P.<SAGE,SINGULAR> = QQ[] # weird names
sage: P.gen(1)SINGULAR>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.gen(), P.gen(Integer(1))(x, y)>>> P = PolynomialRing(GF(Integer(127)), Integer(1000),>>> P.gen(Integer(500))
x500

x )

>>> P = QQ[ SAGE, SINGULAR ]; (SAGE, SINGULAR,) = P._first_ngens(2)# weird␣˓→names>>> P.gen(Integer(1))
SINGULAR

ideal(*gens, **kwds)
Create an ideal in this polynomial ring.
INPUT:• *gens – list or tuple of generators (or several input arguments)• coerce – bool (default: True); this must be a keyword argument. Only set it to False if you arecertain that each generator is already in the ring.
EXAMPLES:
726

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y,z> = QQ[]
sage: sage.rings.ideal.Katsura(P)˓→needs sage.rings.function_field
Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y)of Multivariate Polynomial Ring in x, y, z over Rational Field#␣

sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x])
Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 + 2*y^2 + 2*z^2 - x)of Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> sage.rings.ideal.Katsura(P)˓→needs sage.rings.function_field
Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y)of Multivariate Polynomial Ring in x, y, z over Rational Field#␣>>> P.ideal([x + Integer(2)*y + Integer(2)*z-Integer(1), Integer(2)*x*y +␣˓→Integer(2)*y*z-y, x**Integer(2) + Integer(2)*y**Integer(2) +␣˓→Integer(2)*z**Integer(2)-x])
Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 + 2*y^2 + 2*z^2 - x)of Multivariate Polynomial Ring in x, y, z over Rational Field

monomial_all_divisors(t)Return a list of all monomials that divide t.
Coefficients are ignored.
INPUT:• t – a monomial
OUTPUT:a list of monomials
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.monomial_all_divisors(x^2*z^3)[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.monomial_all_divisors(x**Integer(2)*z**Integer(3))[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]

ALGORITHM: addwithcarry idea by Toon Segers
monomial_divides(a, b)
Return False if a does not divide b and True otherwise.
Coefficients are ignored.
INPUT:• a – monomial• b – monomial

3.1. Multivariate Polynomials and Polynomial Rings

727

Polynomials, Release 10.4

EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
Truesage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
False>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.monomial_divides(x*y*z, x**Integer(3)*y**Integer(2)*z**Integer(4))
True>>> P.monomial_divides(x**Integer(3)*y**Integer(2)*z**Integer(4), x*y*z)
False

monomial_lcm(f, g)
LCM for monomials. Coefficients are ignored.
INPUT:• f – monomial• g – monomial
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.monomial_lcm(3/2*x*y,x)x*y>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.monomial_lcm(Integer(3)/Integer(2)*x*y,x)x*ymonomial_pairwise_prime(g, h)Return True if h and g are pairwise prime. Both are treated as monomials.
Coefficients are ignored.
INPUT:• h – monomial• g – monomial
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.monomial_pairwise_prime(x^2*z^3, y^4)
Truesage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
False>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.monomial_pairwise_prime(x**Integer(2)*z**Integer(3), y**Integer(4))
True(continues on next page)

728

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> P.monomial_pairwise_prime(Integer(1)/˓→Integer(2)*x**Integer(3)*y**Integer(2), Integer(3)/Integer(4)*y**Integer(3))
False

monomial_quotient(f, g, coeff=False)
Return f/g, where both f and`` g are treated as monomials.
Coefficients are ignored by default.
INPUT:• f – monomial• g – monomial• coeff – divide coefficients as well (default: False)
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: P.monomial_quotient(3/2*x*y,x)ysage: P.monomial_quotient(3/2*x*y,x,coeff=True)
3/2*y>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> P.monomial_quotient(Integer(3)/Integer(2)*x*y,x)y>>> P.monomial_quotient(Integer(3)/Integer(2)*x*y,x,coeff=True)
3/2*yNote, that Z behaves different if coeff=True:
sage: P.monomial_quotient(2*x,3*x)
1
sage: P.<x,y> = PolynomialRing(ZZ)
sage: P.monomial_quotient(2*x,3*x,coeff=True)
Traceback (most recent call last):...
ArithmeticError: Cannot divide these coefficients.
>>> from sage.all import *>>> P.monomial_quotient(Integer(2)*x,Integer(3)*x)
1>>> P = PolynomialRing(ZZ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> P.monomial_quotient(Integer(2)*x,Integer(3)*x,coeff=True)
Traceback (most recent call last):...
ArithmeticError: Cannot divide these coefficients.

3.1. Multivariate Polynomials and Polynomial Rings

729

Polynomials, Release 10.4

Warning: Assumes that the head term of f is a multiple of the head term of g and return the multiplicant
m. If this rule is violated, funny things may happen.
monomial_reduce(f, G)
Try to find a g in G where g.lm() divides f. If found (flt,g) is returned, (0,0) otherwise, where
flt is f/g.lm().
It is assumed that G is iterable and contains only elements in this polynomial ring.
Coefficients are ignored.
INPUT:• f – monomial• G – list/set of mpolynomials
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: f = x*y^2
sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2
sage: P.monomial_reduce(f,G)(y, 1/4*x*y + 2/7)]>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = x*y**Integer(2)>>> G = [ Integer(3)/Integer(2)*x**Integer(3) + y**Integer(2) + Integer(1)/˓→Integer(2), Integer(1)/Integer(4)*x*y + Integer(2)/Integer(7), Integer(1)/˓→Integer(2)]>>> P.monomial_reduce(f,G)(y, 1/4*x*y + 2/7)

ngens()
Returns the number of variables in this multivariate polynomial ring.
EXAMPLES:
sage: P.<x,y> = QQ[]
sage: P.ngens()2
sage: k.<a> = GF(2^16)
˓→needs sage.rings.finite_rings
sage: P = PolynomialRing(k, 1000,
˓→needs sage.rings.finite_rings
sage: P.ngens()
˓→needs sage.rings.finite_rings
1000

#␣
x )

#␣
#␣

>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> P.ngens()2>>> k = GF(Integer(2)**Integer(16), names=( a ,)); (a,) = k._first_ngens(1)#␣
(continues on next page)730

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.finite_rings>>> P = PolynomialRing(k, Integer(1000),˓→# needs sage.rings.finite_rings>>> P.ngens()
˓→needs sage.rings.finite_rings
1000
˓→

x )

␣
#␣

class
sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular
Bases: MPolynomial_libsingular
A multivariate polynomial implemented using libSINGULAR.
add_m_mul_q(m, q)
Return self + m*q, where m must be a monomial and q a polynomial.
INPUT:• m – a monomial• q – a polynomial
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ,3)
sage: x.add_m_mul_q(y,z)
y*z + x>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3), names=( x ,˓→_first_ngens(3)>>> x.add_m_mul_q(y,z)
y*z + xy ,z ,)); (x, y, z,) = P.

coefficient(degrees)
Return the coefficient of the variables with the degrees specified in the python dictionary degrees. Mathematically, this is the coefficient in the base ring adjoined by the variables of this ring not listed in degrees.
However, the result has the same parent as this polynomial.
This function contrasts with the function monomial_coefficient which returns the coefficient in thebase ring of a monomial.
INPUT:• degrees – Can be any of: - a dictionary of degree restrictions - a list of degree restrictions (with Nonein the unrestricted variables) - a monomial (very fast, but not as flexible)
OUTPUT: element of the parent of this element.
Note: For coefficients of specific monomials, look at monomial_coefficient().
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f=x*y+y+5
sage: f.coefficient({x:0,y:1})
1(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

731

Polynomials, Release 10.4

(continued from previous page)

sage: f.coefficient({x:0})
y + 5
sage: f=(1+y+y^2)*(1+x+x^2)
sage: f.coefficient({x:0})y^2 + y + 1
sage: f.coefficient([0,None])y^2 + y + 1
sage: f.coefficient(x)y^2 + y + 1>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f=x*y+y+Integer(5)>>> f.coefficient({x:Integer(0),y:Integer(1)})
1>>> f.coefficient({x:Integer(0)})
y + 5>>> f=(Integer(1)+y+y**Integer(2))*(Integer(1)+x+x**Integer(2))>>> f.coefficient({x:Integer(0)})
y^2 + y + 1>>> f.coefficient([Integer(0),None])y^2 + y + 1>>> f.coefficient(x)y^2 + y + 1

Note that exponents have all variables specified:sage: x.coefficient(x.exponents()[0])1sage: f.coefficient([1,0])
1
sage: f.coefficient({x:1,y:0})
1>>> from sage.all import *>>> x.coefficient(x.exponents()[Integer(0)])
1>>> f.coefficient([Integer(1),Integer(0)])
1>>> f.coefficient({x:Integer(1),y:Integer(0)})
1

Be aware that this may not be what you think! The physical appearance of the variable x is deceiving –particularly if the exponent would be a variable.
sage: f.coefficient(x^0) # outputs the full polynomialx^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1
sage: R.<x,y> = GF(389)[]
sage: f = x*y + 5
sage: c = f.coefficient({x:0, y:0}); c
5
sage: parent(c)Multivariate Polynomial Ring in x, y over Finite Field of size 389>>> from sage.all import *(continues on next page)732

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f.coefficient(x**Integer(0)) # outputs the full polynomialx^2*y^2 + x^2*y + x*y^2 + x^2 + x*y + y^2 + x + y + 1>>> R = GF(Integer(389))[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x*y + Integer(5)>>> c = f.coefficient({x:Integer(0), y:Integer(0)}); c5>>> parent(c)Multivariate Polynomial Ring in x, y over Finite Field of size 389

AUTHOR:• Joel B. Mohler (2007.10.31)
coefficients()
Return the nonzero coefficients of this polynomial in a list. The returned list is decreasingly ordered by theterm ordering of the parent.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(QQ, order= degrevlex )sage: f=23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[23, 6, 1]
sage: R.<x,y,z> = PolynomialRing(QQ, order= lex )sage: f=23*x^6*y^7 + x^3*y+6*x^7*z
sage: f.coefficients()[6, 23, 1]>>> from sage.all import *>>> R = PolynomialRing(QQ, order= degrevlex , names=( x ,˓→z,) = R._first_ngens(3)>>> f=Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[23, 6, 1]>>> R = PolynomialRing(QQ, order= lex , names=( x ,˓→R._first_ngens(3)>>> f=Integer(23)*x**Integer(6)*y**Integer(7) +␣˓→x**Integer(3)*y+Integer(6)*x**Integer(7)*z>>> f.coefficients()[6, 23, 1]

y ,

y ,

z ,)); (x, y,␣

z ,)); (x, y, z,) =␣

AUTHOR:• Didier Deshommes
constant_coefficient()
Return the constant coefficient of this multivariate polynomial.
EXAMPLES:
sage: P.<x, y> = QQ[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.constant_coefficient()
5
sage: f = 3*x^2(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

733

Polynomials, Release 10.4

(continued from previous page)

sage: f.constant_coefficient()0>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.constant_coefficient()5>>> f = Integer(3)*x**Integer(2)>>> f.constant_coefficient()0

degree(x=None, std_grading=False)
Return the degree of this polynomial.
INPUT:• x – (default: None) a generator of the parent ring
OUTPUT:
If x is None, return the total degree of self. Note that this result is affected by the weighting given to thegenerators of the parent ring. Otherwise, if x is (or is coercible to) a generator of the parent ring, the output
is the maximum degree of x in self. This is not affected by the weighting of the generators.
EXAMPLES:
sage: R.<x, y> = QQ[]
sage: f = y^2 - x^9 - x
sage: f.degree(x)9sage: f.degree(y)2sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x)3sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y)10>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = y**Integer(2) - x**Integer(9) - x>>> f.degree(x)9>>> f.degree(y)2>>> (y**Integer(10)*x - Integer(7)*x**Integer(2)*y**Integer(5) +␣˓→Integer(5)*x**Integer(3)).degree(x)3>>> (y**Integer(10)*x - Integer(7)*x**Integer(2)*y**Integer(5) +␣˓→Integer(5)*x**Integer(3)).degree(y)10When the generators have a grading (weighting) then the total degree respects this, but the degree for a given
generator is unaffected:

734

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: T = TermOrder("wdegrevlex", (2, 3))
sage: R.<x, y> = PolynomialRing(QQ, order=T)
sage: f = x^2 * y + y^4
sage: f.degree()12
sage: f.degree(x)2sage: f.degree(y)4>>> from sage.all import *>>> T = TermOrder("wdegrevlex", (Integer(2), Integer(3)))>>> R = PolynomialRing(QQ, order=T, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> f = x**Integer(2) * y + y**Integer(4)>>> f.degree()12>>> f.degree(x)2>>> f.degree(y)4The term ordering of the parent ring determines the grading of the generators.
sage: T = TermOrder( wdegrevlex , (1,2,3,4))
sage: R = PolynomialRing(QQ, x , 12, order=T+T+T)
sage: [x.degree() for x in R.gens()][1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]>>> from sage.all import *>>> T = TermOrder( wdegrevlex , (Integer(1),Integer(2),Integer(3),Integer(4)))>>> R = PolynomialRing(QQ, x , Integer(12), order=T+T+T)>>> [x.degree() for x in R.gens()][1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]

A matrix term ordering determines the grading of the generators by the first row of the matrix.
sage: m = matrix(3, [3,2,1,1,1,0,1,0,0])
sage: m[3 2 1][1 1 0][1 0 0]sage: R.<x,y,z> = PolynomialRing(QQ, order=TermOrder(m))
sage: x.degree(), y.degree(), z.degree()(3, 2, 1)
sage: f = x^3*y + x*z^4
sage: f.degree()11>>> from sage.all import *>>> m = matrix(Integer(3), [Integer(3),Integer(2),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(1),Integer(0),Integer(0)])>>> m[3 2 1][1 1 0][1 0 0](continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

735

Polynomials, Release 10.4

(continued from previous page)>>> R = PolynomialRing(QQ, order=TermOrder(m), names=( x ,˓→ z,) = R._first_ngens(3)>>> x.degree(), y.degree(), z.degree()(3, 2, 1)>>> f = x**Integer(3)*y + x*z**Integer(4)>>> f.degree()11y ,z ,)); (x, y,

If the first row contains zero, the grading becomes the standard one.
sage: m = matrix(3, [3,0,1,1,1,0,1,0,0])
sage: m[3 0 1][1 1 0][1 0 0]sage: R.<x,y,z> = PolynomialRing(QQ, order=TermOrder(m))
sage: x.degree(), y.degree(), z.degree()(1, 1, 1)
sage: f = x^3*y + x*z^4
sage: f.degree()5>>> from sage.all import *>>> m = matrix(Integer(3), [Integer(3),Integer(0),Integer(1),Integer(1),˓→Integer(1),Integer(0),Integer(1),Integer(0),Integer(0)])>>> m[3 0 1][1 1 0][1 0 0]>>> R = PolynomialRing(QQ, order=TermOrder(m), names=( x , y , z ,)); (x, y,
˓→ z,) = R._first_ngens(3)>>> x.degree(), y.degree(), z.degree()(1, 1, 1)>>> f = x**Integer(3)*y + x*z**Integer(4)>>> f.degree()5

To get the degree with the standard grading regardless of the term ordering of the parent ring, use
std_grading=True.
sage: f.degree(std_grading=True)
5>>> from sage.all import *>>> f.degree(std_grading=True)5

degrees()
Returns a tuple with the maximal degree of each variable in this polynomial. The list of degrees is orderedby the order of the generators.
EXAMPLES:
sage: R.<y0,y1,y2> = PolynomialRing(QQ,3)
sage: q = 3*y0*y1*y1*y2; q
3*y0*y1^2*y2(continues on next page)

736

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: q.degrees()(1, 2, 1)
sage: (q + y0^5).degrees()(5, 2, 1)>>> from sage.all import *>>> R = PolynomialRing(QQ,Integer(3), names=( y0 ,˓→) = R._first_ngens(3)>>> q = Integer(3)*y0*y1*y1*y2; q
3*y0*y1^2*y2>>> q.degrees()(1, 2, 1)>>> (q + y0**Integer(5)).degrees()(5, 2, 1)y1 ,y2 ,)); (y0, y1, y2,dict()
Return a dictionary representing self. This dictionary is in the same format as the generic MPolynomial: The
dictionary consists of ETuple:coefficient pairs.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: f=2*x*y^3*z^2 + 1/7*x^2 + 2/3
sage: f.dict(){(0, 0, 0): 2/3, (1, 3, 2): 2, (2, 0, 0): 1/7}>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> f=Integer(2)*x*y**Integer(3)*z**Integer(2) + Integer(1)/˓→Integer(7)*x**Integer(2) + Integer(2)/Integer(3)>>> f.dict(){(0, 0, 0): 2/3, (1, 3, 2): 2, (2, 0, 0): 1/7}

divides(other)
Return True if this polynomial divides other.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: p = 3*x*y + 2*y*z + x*z
sage: q = x + y + z + 1
sage: r = p * q
sage: p.divides(r)Truesage: q.divides(p)False
sage: r.divides(0)Truesage: R.zero().divides(r)False
sage: R.zero().divides(0)True>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

737

Polynomials, Release 10.4

(continued from previous page)>>> p = Integer(3)*x*y + Integer(2)*y*z + x*z>>> q = x + y + z + Integer(1)>>> r = p * q>>> p.divides(r)True>>> q.divides(p)False>>> r.divides(Integer(0))
True>>> R.zero().divides(r)False>>> R.zero().divides(Integer(0))
Trueexponents(as_ETuples=True)
Return the exponents of the monomials appearing in this polynomial.
INPUT:• as_ETuples – (default: True) if True returns the result as a list of ETuples, otherwise returns a listof tuples
EXAMPLES:
sage: R.<a,b,c> = QQ[]
sage: f = a^3 + b + 2*b^2
sage: f.exponents()[(3, 0, 0), (0, 2, 0), (0, 1, 0)]
sage: f.exponents(as_ETuples=False)[(3, 0, 0), (0, 2, 0), (0, 1, 0)]>>> from sage.all import *>>> R = QQ[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> f = a**Integer(3) + b + Integer(2)*b**Integer(2)>>> f.exponents()[(3, 0, 0), (0, 2, 0), (0, 1, 0)]>>> f.exponents(as_ETuples=False)[(3, 0, 0), (0, 2, 0), (0, 1, 0)]factor(proof=None)
Return the factorization of this polynomial.
INPUT:• proof – ignored.
EXAMPLES:
sage: R.<x, y> = QQ[]
sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); fx^5 + 2*x^3*y^2 + x^4 + 2*x^2*y^2 + x^3 + 2*x*y^2
sage: F = f.factor(); F
x * (x^2 + x + 1) * (x^2 + 2*y^2)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = (x**Integer(3) + Integer(2)*y**Integer(2)*x) * (x**Integer(2) + x +␣(continues on next page)

738

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(1)); fx^5 + 2*x^3*y^2 + x^4 + 2*x^2*y^2 + x^3 + 2*x*y^2>>> F = f.factor(); F
x * (x^2 + x + 1) * (x^2 + 2*y^2)˓→Next we factor the same polynomial, but over the finite field of order 3.:
sage: R.<x, y> = GF(3)[]sage: f = (x^3 + 2*y^2*x) * (x^2 + x + 1); fx^5 - x^3*y^2 + x^4 - x^2*y^2 + x^3 - x*y^2
sage: F = f.factor()sage: F # order is somewhat random(-1) * x * (-x + y) * (x + y) * (x - 1)^2>>> from sage.all import *>>> R = GF(Integer(3))[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = (x**Integer(3) + Integer(2)*y**Integer(2)*x) * (x**Integer(2) + x +␣˓→Integer(1)); fx^5 - x^3*y^2 + x^4 - x^2*y^2 + x^3 - x*y^2>>> F = f.factor()>>> F # order is somewhat random(-1) * x * (-x + y) * (x + y) * (x - 1)^2

Next we factor a polynomial, but over a finite field of order 9.:
sage: # needs sage.rings.finite_rings
sage: K.<a> = GF(3^2)
sage: R.<x, y> = K[]
sage: f = (x^3 + 2*a*y^2*x) * (x^2 + x + 1); fx^5 + (-a)*x^3*y^2 + x^4 + (-a)*x^2*y^2 + x^3 + (-a)*x*y^2
sage: F = f.factor(); F((-a)) * x * (x - 1)^2 * ((-a + 1)*x^2 + y^2)
sage: f - F
0>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> K = GF(Integer(3)**Integer(2), names=( a ,)); (a,) = K._first_ngens(1)>>> R = K[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = (x**Integer(3) + Integer(2)*a*y**Integer(2)*x) * (x**Integer(2) + x +␣˓→Integer(1)); fx^5 + (-a)*x^3*y^2 + x^4 + (-a)*x^2*y^2 + x^3 + (-a)*x*y^2>>> F = f.factor(); F((-a)) * x * (x - 1)^2 * ((-a + 1)*x^2 + y^2)>>> f - F
0

Next we factor a polynomial over a number field.:sage: # needs sage.rings.number_fieldsage: p = polygen(ZZ, p )sage: K.
 = NumberField(p^3 - 2)sage: KXY.<x,y> = K[]
sage: factor(x^3 - 2*y^3)(x + (-s)*y) * (x^2 + s*x*y + (s^2)*y^2)
sage: k = (x^3-2*y^3)^5*(x+s*y)^2*(2/3 + s^2)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

739

Polynomials, Release 10.4

(continued from previous page)

sage: k.factor()((s^2 + 2/3)) * (x + s*y)^2 * (x + (-s)*y)^5 * (x^2 + s*x*y + (s^2)*y^2)^5>>> from sage.all import *>>> # needs sage.rings.number_field>>> p = polygen(ZZ, p )>>> K = NumberField(p**Integer(3) - Integer(2), names=( s ,)); (s,) = K._
˓→first_ngens(1)>>> KXY = K[ x, y ]; (x, y,) = KXY._first_ngens(2)>>> factor(x**Integer(3) - Integer(2)*y**Integer(3))(x + (-s)*y) * (x^2 + s*x*y + (s^2)*y^2)>>> k = (x**Integer(3)˓→Integer(2)*y**Integer(3))**Integer(5)*(x+s*y)**Integer(2)*(Integer(2)/˓→Integer(3) + s**Integer(2))>>> k.factor()((s^2 + 2/3)) * (x + s*y)^2 * (x + (-s)*y)^5 * (x^2 + s*x*y + (s^2)*y^2)^5This shows that issue Issue #2780 is fixed, i.e. that the unit part of the factorization is set correctly:
sage: # needs sage.rings.number_fieldsage: x = polygen(ZZ, x )sage: K.<a> = NumberField(x^2 + 1)
sage: R.<y, z> = PolynomialRing(K)sage: f = 2*y^2 + 2*z^2sage: F = f.factor(); F.unit()
2>>> from sage.all import *>>> # needs sage.rings.number_field>>> x = polygen(ZZ, x )>>> K = NumberField(x**Integer(2) + Integer(1), names=( a ,)); (a,) = K._
˓→first_ngens(1)>>> R = PolynomialRing(K, names=( y , z ,)); (y, z,) = R._first_ngens(2)>>> f = Integer(2)*y**Integer(2) + Integer(2)*z**Integer(2)>>> F = f.factor(); F.unit()
2

Another example:
sage: R.<x,y,z> = GF(32003)[]
˓→needs sage.rings.finite_rings
sage: f = 9*(x-1)^2*(y+z)˓→needs sage.rings.finite_rings
sage: f.factor()˓→needs sage.rings.finite_rings(9) * (y + z) * (x - 1)^2

#␣
#␣
#␣

sage: R.<x,w,v,u> = QQ[ x , w , v , u ]sage: p = (4*v^4*u^2 - 16*v^2*u^4 + 16*u^6 - 4*v^4*u + 8*v^2*u^3 + v^4)
sage: p.factor()(-2*v^2*u + 4*u^3 + v^2)^2
sage: R.<a,b,c,d> = QQ[]
sage: f = (-2) * (a - d) * (-a + b) * (b - d) * (a - c) * (b - c) * (c - d)sage: F = f.factor(); F(-2) * (c - d) * (-b + c) * (b - d) * (-a + c) * (-a + b) * (a - d)sage: F[0][0](continues on next page)

740

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)c - d
sage: F.unit()-2>>> from sage.all import *>>> R = GF(Integer(32003))[ x, y, z ]; (x, y, z,) = R._first_ngens(3)# needs␣
˓→sage.rings.finite_rings>>> f = Integer(9)*(x-Integer(1))**Integer(2)*(y+z)␣˓→# needs sage.rings.finite_rings>>> f.factor()#␣˓→needs sage.rings.finite_rings(9) * (y + z) * (x - 1)^2>>> R = QQ[ x , w , v , u ]; (x, w, v, u,) = R._first_ngens(4)>>> p = (Integer(4)*v**Integer(4)*u**Integer(2) -␣˓→Integer(16)*v**Integer(2)*u**Integer(4) + Integer(16)*u**Integer(6) -␣˓→Integer(4)*v**Integer(4)*u + Integer(8)*v**Integer(2)*u**Integer(3) +␣˓→v**Integer(4))>>> p.factor()(-2*v^2*u + 4*u^3 + v^2)^2>>> R = QQ[ a, b, c, d ]; (a, b, c, d,) = R._first_ngens(4)>>> f = (-Integer(2)) * (a - d) * (-a + b) * (b - d) * (a - c) * (b - c) *␣˓→(c - d)>>> F = f.factor(); F(-2) * (c - d) * (-b + c) * (b - d) * (-a + c) * (-a + b) * (a - d)>>> F[Integer(0)][Integer(0)]c - d>>> F.unit()-2

Constant elements are factorized in the base rings.
sage: P.<x,y> = ZZ[]
sage: P(2^3*7).factor()
2^3 * 7sage: P.<x,y> = GF(2)[]sage: P(1).factor()
1>>> from sage.all import *>>> P = ZZ[ x, y ]; (x, y,) = P._first_ngens(2)>>> P(Integer(2)**Integer(3)*Integer(7)).factor()
2^3 * 7>>> P = GF(Integer(2))[ x, y ]; (x, y,) = P._first_ngens(2)>>> P(Integer(1)).factor()
1

Factorization for finite prime fields with characteristic > 229 is not supported
sage: q = 1073741789
sage: T.<aa, bb> = PolynomialRing(GF(q))˓→needs sage.rings.finite_rings
sage: f = aa^2 + 12124343*bb*aa + 32434598*bb^2
˓→needs sage.rings.finite_rings
sage: f.factor()˓→needs sage.rings.finite_rings

#␣
#␣
#␣
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

741

Polynomials, Release 10.4

(continued from previous page)

Traceback (most recent call last):...
NotImplementedError: Factorization of multivariate polynomials
over prime fields with characteristic > 2^29 is not implemented.
>>> from sage.all import *>>> q = Integer(1073741789)>>> T = PolynomialRing(GF(q), names=( aa , bb ,)); (aa, bb,) = T._first_
˓→ngens(2)# needs sage.rings.finite_rings>>> f = aa**Integer(2) + Integer(12124343)*bb*aa +␣˓→Integer(32434598)*bb**Integer(2)# needs sage.
˓→rings.finite_rings>>> f.factor()#␣˓→needs sage.rings.finite_rings
Traceback (most recent call last):...
NotImplementedError: Factorization of multivariate polynomials
over prime fields with characteristic > 2^29 is not implemented.

Factorization over the integers is now supported, see Issue #17840:
sage: P.<x,y> = PolynomialRing(ZZ)
sage: f = 12 * (3*x*y + 4) * (5*x - 2) * (2*y + 7)^2
sage: f.factor()
2^2 * 3 * (2*y + 7)^2 * (5*x - 2) * (3*x*y + 4)
sage: g = -12 * (x^2 - y^2)
sage: g.factor()(-1) * 2^2 * 3 * (x - y) * (x + y)sage: factor(-4*x*y - 2*x + 2*y + 1)(-1) * (2*y + 1) * (2*x - 1)>>> from sage.all import *>>> P = PolynomialRing(ZZ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> f = Integer(12) * (Integer(3)*x*y + Integer(4)) * (Integer(5)*x -␣
˓→Integer(2)) * (Integer(2)*y + Integer(7))**Integer(2)>>> f.factor()
2^2 * 3 * (2*y + 7)^2 * (5*x - 2) * (3*x*y + 4)>>> g = -Integer(12) * (x**Integer(2) - y**Integer(2))>>> g.factor()(-1) * 2^2 * 3 * (x - y) * (x + y)>>> factor(-Integer(4)*x*y - Integer(2)*x + Integer(2)*y + Integer(1))(-1) * (2*y + 1) * (2*x - 1)

Factorization over non-integral domains is not supported
sage: R.<x,y> = PolynomialRing(Zmod(4))
sage: f = (2*x + 1) * (x^2 + x + 1)
sage: f.factor()
Traceback (most recent call last):...
NotImplementedError: Factorization of multivariate polynomials
over Ring of integers modulo 4 is not implemented.
>>> from sage.all import *>>> R = PolynomialRing(Zmod(Integer(4)), names=( x ,y ,)); (x, y,) = R._(continues on next page)742

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

first_ngens(2)>>> f = (Integer(2)*x + Integer(1)) * (x**Integer(2) + x + Integer(1))>>> f.factor()
Traceback (most recent call last):...
NotImplementedError: Factorization of multivariate polynomials
over Ring of integers modulo 4 is not implemented.
˓→

gcd(right, algorithm=None, **kwds)
Return the greatest common divisor of self and right.
INPUT:• right – polynomial• algorithm - ezgcd – EZGCD algorithm - modular – multi-modular algorithm (default)• **kwds – ignored
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: f = (x*y*z)^6 - 1
sage: g = (x*y*z)^4 - 1
sage: f.gcd(g)x^2*y^2*z^2 - 1
sage: GCD([x^3 - 3*x + 2, x^4 - 1, x^6 -1])x - 1
sage: R.<x,y> = QQ[]
sage: f = (x^3 + 2*y^2*x)^2
sage: g = x^2*y^2
sage: f.gcd(g)x^2>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = (x*y*z)**Integer(6) - Integer(1)>>> g = (x*y*z)**Integer(4) - Integer(1)>>> f.gcd(g)x^2*y^2*z^2 - 1>>> GCD([x**Integer(3) - Integer(3)*x + Integer(2), x**Integer(4) -␣˓→Integer(1), x**Integer(6) -Integer(1)])
x - 1>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = (x**Integer(3) + Integer(2)*y**Integer(2)*x)**Integer(2)>>> g = x**Integer(2)*y**Integer(2)>>> f.gcd(g)x^2

We compute a gcd over a finite field:
sage: # needs sage.rings.finite_rings
sage: F.<u> = GF(31^2)
sage: R.<x,y,z> = F[]sage: p = x^3 + (1+u)*y^3 + z^3
sage: q = p^3 * (x - y + z*u)
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

743

Polynomials, Release 10.4

(continued from previous page)

sage: gcd(p,q)
x^3 + (u + 1)*y^3 + z^3
sage: gcd(p,q) # yes, twice -- tests that singular ring is properly set.
x^3 + (u + 1)*y^3 + z^3>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> F = GF(Integer(31)**Integer(2), names=( u ,)); (u,) = F._first_ngens(1)>>> R = F[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> p = x**Integer(3) + (Integer(1)+u)*y**Integer(3) + z**Integer(3)>>> q = p**Integer(3) * (x - y + z*u)>>> gcd(p,q)
x^3 + (u + 1)*y^3 + z^3>>> gcd(p,q) # yes, twice -- tests that singular ring is properly set.
x^3 + (u + 1)*y^3 + z^3

We compute a gcd over a number field:
sage: # needs sage.rings.number_fieldsage: x = polygen(QQ)
sage: F.<u> = NumberField(x^3 - 2)sage: R.<x,y,z> = F[]sage: p = x^3 + (1+u)*y^3 + z^3
sage: q = p^3 * (x - y + z*u)
sage: gcd(p,q)
x^3 + (u + 1)*y^3 + z^3>>> from sage.all import *>>> # needs sage.rings.number_field>>> x = polygen(QQ)>>> F = NumberField(x**Integer(3) - Integer(2), names=( u ,)); (u,) = F._˓→first_ngens(1)>>> R = F[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> p = x**Integer(3) + (Integer(1)+u)*y**Integer(3) + z**Integer(3)>>> q = p**Integer(3) * (x - y + z*u)>>> gcd(p,q)
x^3 + (u + 1)*y^3 + z^3

global_height(prec=None)
Return the (projective) global height of the polynomial.
This returns the absolute logarithmic height of the coefficients thought of as a projective point.
INPUT:• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 3*x^3 + 2*x*y^2
sage: exp(f.global_height())
˓→needs sage.symbolic
3.00000000000000

744

#␣

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(3) + Integer(2)*x*y**Integer(2)>>> exp(f.global_height())#␣˓→needs sage.symbolic
3.00000000000000
sage: # needs sage.rings.number_fieldsage: K.<k> = CyclotomicField(3)sage: R.<x,y> = PolynomialRing(K, sparse=True)
sage: f = k*x*y + 1
sage: exp(f.global_height())
1.00000000000000>>> from sage.all import *>>> # needs sage.rings.number_field>>> K = CyclotomicField(Integer(3), names=( k ,)); (k,) = K._first_ngens(1)>>> R = PolynomialRing(K, sparse=True, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> f = k*x*y + Integer(1)>>> exp(f.global_height())
1.00000000000000

Scaling should not change the result:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 1/25*x^2 + 25/3*x*y + y^2
sage: f.global_height()
˓→needs sage.symbolic
6.43775164973640
sage: g = 100 * fsage: g.global_height()
˓→needs sage.symbolic
6.43775164973640#␣#␣>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(25)*x**Integer(2) + Integer(25)/Integer(3)*x*y +␣
˓→y**Integer(2)>>> f.global_height()#␣˓→needs sage.symbolic
6.43775164973640>>> g = Integer(100) * f>>> g.global_height()#␣˓→needs sage.symbolic
6.43775164973640
sage: R.<x> = PolynomialRing(QQ)
sage: K.<k> = NumberField(x^2 + 5)
sage: T.<t,w> = PolynomialRing(K)sage: f = 1/1331 * t^2 + 5 * w + 7
sage: f.global_height()
˓→needs sage.symbolic
9.13959596745043

3.1. Multivariate Polynomials and Polynomial Rings

#␣

745

Polynomials, Release 10.4>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) + Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = PolynomialRing(K, names=( t , w ,)); (t, w,) = T._first_ngens(2)>>> f = Integer(1)/Integer(1331) * t**Integer(2) + Integer(5) * w + Integer(7)>>> f.global_height()#␣˓→needs sage.symbolic
9.13959596745043
sage: R.<x,y> = QQ[]
sage: f = 1/123*x*y + 12
sage: f.global_height(prec=2)
˓→needs sage.symbolic
8.0#␣

>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(123)*x*y + Integer(12)>>> f.global_height(prec=Integer(2))˓→# needs sage.symbolic
8.0␣

sage: R.<x,y> = QQ[]
sage: f = 0*x*y
sage: f.global_height()
0.000000000000000>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(0)*x*y>>> f.global_height()
0.000000000000000

gradient()
Return a list of partial derivatives of this polynomial, ordered by the variables of the parent.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ,3)
sage: f= x*y + 1
sage: f.gradient()[y, x, 0]>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3), names=( x ,˓→_first_ngens(3)>>> f= x*y + Integer(1)>>> f.gradient()[y, x, 0]y ,z ,)); (x, y, z,) = P.

hamming_weight()
Return the number of non-zero coefficients of this polynomial.
This is also called weight, hamming_weight() or sparsity.
EXAMPLES:
746

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: R.<x, y> = ZZ[]
sage: f = x^3 - ysage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x+y)^100
sage: f.number_of_terms()
101>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) - y>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x+y)**Integer(100)>>> f.number_of_terms()
101

The method hamming_weight() is an alias:
sage: f.hamming_weight()
101>>> from sage.all import *>>> f.hamming_weight()
101

in_subalgebra(J, algorithm='algebra_containment')
Return whether this polynomial is contained in the subalgebra generated by J
INPUT:• J – list of elements of the parent polynomial ring• algorithm – can be "algebra_containment" (the default), "inSubring", or "groebner".
– "algebra_containment": use Singular’s algebra_containment function, https://www.singular.uni-kl.de/Manual/4-2-1/sing_1247.htm#SEC1328. The Singular documentationsuggests that this is frequently faster than the next option.
– "inSubring": use Singular’s inSubring function, https://www.singular.uni-kl.de/Manual/
4-2-0/sing_1240.htm#SEC1321.
– "groebner": use the algorithm described in Singular’s documentation, but within Sage: if thesubalgebra generators are 𝑦1 , …, 𝑦𝑚 , then create a new polynomial algebra with the old generators
along with new ones: 𝑧1 , …, 𝑧𝑚 . Create the ideal (𝑧1 −𝑦1 , ..., 𝑧𝑚 −𝑦𝑚 ), and reduce the polynomial
modulo this ideal. The polynomial is contained in the subalgebra if and only if the remainder involves
only the new variables 𝑧𝑖 .
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: J = [x^2 + y^2, x^2 + z^2]
sage: (y^2).in_subalgebra(J)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

747

Polynomials, Release 10.4

(continued from previous page)

False
sage: a = (x^2 + y^2) * (x^2 + z^2)
sage: a.in_subalgebra(J, algorithm= inSubring )Truesage: (a^2).in_subalgebra(J, algorithm= groebner )Truesage: (a + a^2).in_subalgebra(J)True>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> J = [x**Integer(2) + y**Integer(2), x**Integer(2) + z**Integer(2)]>>> (y**Integer(2)).in_subalgebra(J)False>>> a = (x**Integer(2) + y**Integer(2)) * (x**Integer(2) + z**Integer(2))>>> a.in_subalgebra(J, algorithm= inSubring )True>>> (a**Integer(2)).in_subalgebra(J, algorithm= groebner )True>>> (a + a**Integer(2)).in_subalgebra(J)True

integral(var)Integrate this polynomial with respect to the provided variable.
One requires thatis contained in the ring.

INPUT:• variable – the integral is taken with respect to variable
EXAMPLES:
sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: f = 3*x^3*y^2 + 5*y^2 + 3*x + 2
sage: f.integral(x)3/4*x^4*y^2 + 5*x*y^2 + 3/2*x^2 + 2*x
sage: f.integral(y)x^3*y^3 + 5/3*y^3 + 3*x*y + 2*y>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> f = Integer(3)*x**Integer(3)*y**Integer(2) + Integer(5)*y**Integer(2) +␣˓→Integer(3)*x + Integer(2)>>> f.integral(x)3/4*x^4*y^2 + 5*x*y^2 + 3/2*x^2 + 2*x>>> f.integral(y)x^3*y^3 + 5/3*y^3 + 3*x*y + 2*yCheck that Issue #15896 is solved:
sage: s = x+y
sage: s.integral(x)+x
1/2*x^2 + x*y + x
sage: s.integral(x)*s
1/2*x^3 + 3/2*x^2*y + x*y^2748

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> s = x+y>>> s.integral(x)+x
1/2*x^2 + x*y + x>>> s.integral(x)*s
1/2*x^3 + 3/2*x^2*y + x*y^2

inverse_of_unit()
Return the inverse of this polynomial if it is a unit.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: x.inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: Element is not a unit.
sage: R(1/2).inverse_of_unit()
2>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> x.inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: Element is not a unit.
>>> R(Integer(1)/Integer(2)).inverse_of_unit()2

is_constant()
Return True if this polynomial is constant.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(127))
sage: x.is_constant()
False
sage: P(1).is_constant()
True>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), names=( x ,˓→= P._first_ngens(3)>>> x.is_constant()
False>>> P(Integer(1)).is_constant()
True

y ,

z ,)); (x, y, z,)␣is_homogeneous()
Return True if this polynomial is homogeneous.
EXAMPLES:
sage: P.<x,y> = PolynomialRing(RationalField(), 2)
sage: (x+y).is_homogeneous()(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

749

Polynomials, Release 10.4

(continued from previous page)True
sage: (x.parent()(0)).is_homogeneous()
True
sage: (x+y^2).is_homogeneous()
False
sage: (x^2 + y^2).is_homogeneous()
True
sage: (x^2 + y^2*x).is_homogeneous()
False
sage: (x^2*y + y^2*x).is_homogeneous()
True>>> from sage.all import *>>> P = PolynomialRing(RationalField(), Integer(2), names=( x ,˓→) = P._first_ngens(2)>>> (x+y).is_homogeneous()
True>>> (x.parent()(Integer(0))).is_homogeneous()
True>>> (x+y**Integer(2)).is_homogeneous()
False>>> (x**Integer(2) + y**Integer(2)).is_homogeneous()
True>>> (x**Integer(2) + y**Integer(2)*x).is_homogeneous()
False>>> (x**Integer(2)*y + y**Integer(2)*x).is_homogeneous()Truey ,)); (x, y,

is_monomial()
Return True if this polynomial is a monomial. A monomial is defined to be a product of generators withcoefficient 1.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: x.is_monomial()
True
sage: (2*x).is_monomial()
False
sage: (x*y).is_monomial()
True
sage: (x*y + x).is_monomial()
False
sage: P(2).is_monomial()
False
sage: P.zero().is_monomial()
False>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x ,˓→ngens(3)>>> x.is_monomial()
True>>> (Integer(2)*x).is_monomial()
False>>> (x*y).is_monomial()y ,z ,)); (x, y, z,) = P._first_(continues on next page)

750

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True>>> (x*y + x).is_monomial()
False>>> P(Integer(2)).is_monomial()
False>>> P.zero().is_monomial()
False

is_squarefree()Return True if this polynomial is square free.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: f= x^2 + 2*x*y + 1/2*z
sage: f.is_squarefree()True
sage: h = f^2
sage: h.is_squarefree()False>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_
˓→ngens(3)>>> f= x**Integer(2) + Integer(2)*x*y + Integer(1)/Integer(2)*z>>> f.is_squarefree()True>>> h = f**Integer(2)>>> h.is_squarefree()False

is_term()
Return True if self is a term, which we define to be a product of generators times some coefficient, which
need not be 1.
Use is_monomial() to require that the coefficient be 1.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: x.is_term()
Truesage: (2*x).is_term()
Truesage: (x*y).is_term()
Truesage: (x*y + x).is_term()
False
sage: P(2).is_term()
Truesage: P.zero().is_term()
False>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x ,˓→ngens(3)y ,z ,)); (x, y, z,) = P._first_(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

751

Polynomials, Release 10.4

(continued from previous page)>>> x.is_term()True>>> (Integer(2)*x).is_term()True>>> (x*y).is_term()True>>> (x*y + x).is_term()
False>>> P(Integer(2)).is_term()
True>>> P.zero().is_term()
False

is_univariate()
Return True if self is a univariate polynomial, that is if self contains only one variable.
EXAMPLES:
sage: P.<x,y,z> = GF(2)[]sage: f = x^2 + 1
sage: f.is_univariate()Truesage: f = y*x^2 + 1
sage: f.is_univariate()
False
sage: f = P(0)sage: f.is_univariate()
True>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = x**Integer(2) + Integer(1)>>> f.is_univariate()
True>>> f = y*x**Integer(2) + Integer(1)>>> f.is_univariate()
False>>> f = P(Integer(0))>>> f.is_univariate()
True

is_zero()Return True if this polynomial is zero.
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ)
sage: x.is_zero()False
sage: (x - x).is_zero()True>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x ,>>> x.is_zero()Falsey ,)); (x, y,) = P._first_ngens(2)(continues on next page)752

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> (x - x).is_zero()
Trueiterator_exp_coeff(as_ETuples=True)
Iterate over self as pairs of ((E)Tuple, coefficient).
INPUT:• as_ETuples – (default: True) if True iterate over pairs whose first element is an ETuple, otherwise
as a tuples
EXAMPLES:
sage: R.<a,b,c> = QQ[]
sage: f = a*c^3 + a^2*b + 2*b^4
sage: list(f.iterator_exp_coeff())[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]
sage: list(f.iterator_exp_coeff(as_ETuples=False))[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]
sage: R.<a,b,c> = PolynomialRing(QQ, 3, order= lex )sage: f = a*c^3 + a^2*b + 2*b^4
sage: list(f.iterator_exp_coeff())[((2, 1, 0), 1), ((1, 0, 3), 1), ((0, 4, 0), 2)]>>> from sage.all import *>>> R = QQ[ a, b, c ]; (a, b, c,) = R._first_ngens(3)>>> f = a*c**Integer(3) + a**Integer(2)*b + Integer(2)*b**Integer(4)>>> list(f.iterator_exp_coeff())[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]>>> list(f.iterator_exp_coeff(as_ETuples=False))[((0, 4, 0), 2), ((1, 0, 3), 1), ((2, 1, 0), 1)]>>> R = PolynomialRing(QQ, Integer(3), order= lex , names=( a , b ,˓→(a, b, c,) = R._first_ngens(3)>>> f = a*c**Integer(3) + a**Integer(2)*b + Integer(2)*b**Integer(4)>>> list(f.iterator_exp_coeff())[((2, 1, 0), 1), ((1, 0, 3), 1), ((0, 4, 0), 2)]c ,));␣

lc()
Leading coefficient of this polynomial with respect to the term order of self.parent().
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(GF(7), 3, order= lex )sage: f = 3*x^1*y^2 + 2*y^3*z^4sage: f.lc()
3
sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
sage: f.lc()
5>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(7)), Integer(3), order= lex , names=( x ,˓→ ,z ,)); (x, y, z,) = R._first_ngens(3)y(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

753

Polynomials, Release 10.4

(continued from previous page)>>> f = Integer(3)*x**Integer(1)*y**Integer(2) +␣˓→Integer(2)*y**Integer(3)*z**Integer(4)>>> f.lc()
3>>> f = Integer(5)*x**Integer(3)*y**Integer(2)*z**Integer(4) +␣˓→Integer(4)*x**Integer(3)*y**Integer(2)*z**Integer(1)>>> f.lc()
5lcm(g)
Return the least common multiple of self and 𝑔.
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: p = (x+y)*(y+z)
sage: q = (z^4+2)*(y+z)
sage: lcm(p,q)
x*y*z^4 + y^2*z^4 + x*z^5 + y*z^5 + 2*x*y + 2*y^2 + 2*x*z + 2*y*z
sage: P.<x,y,z> = ZZ[]
sage: p = 2*(x+y)*(y+z)
sage: q = 3*(z^4+2)*(y+z)
sage: lcm(p,q)
6*x*y*z^4 + 6*y^2*z^4 + 6*x*z^5 + 6*y*z^5 + 12*x*y + 12*y^2 + 12*x*z + 12*y*z
sage: # needs sage.rings.finite_rings
sage: r.<x,y> = PolynomialRing(GF(2**8, a ), 2)
sage: a = r.base_ring().0
sage: f = (a^2+a)*x^2*y + (a^4+a^3+a)*y + a^5
sage: f.lcm(x^4)(a^2 + a)*x^6*y + (a^4 + a^3 + a)*x^4*y + (a^5)*x^4
sage: # needs sage.rings.number_fieldsage: w = polygen(ZZ, w )sage: r.<x,y> = PolynomialRing(NumberField(w^4 + 1,
sage: a = r.base_ring().0
sage: f = (a^2+a)*x^2*y + (a^4+a^3+a)*y + a^5
sage: f.lcm(x^4)(a^2 + a)*x^6*y + (a^3 + a - 1)*x^4*y + (-a)*x^4a ), 2)>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> p = (x+y)*(y+z)>>> q = (z**Integer(4)+Integer(2))*(y+z)>>> lcm(p,q)
x*y*z^4 + y^2*z^4 + x*z^5 + y*z^5 + 2*x*y + 2*y^2 + 2*x*z + 2*y*z>>> P = ZZ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> p = Integer(2)*(x+y)*(y+z)>>> q = Integer(3)*(z**Integer(4)+Integer(2))*(y+z)>>> lcm(p,q)
6*x*y*z^4 + 6*y^2*z^4 + 6*x*z^5 + 6*y*z^5 + 12*x*y + 12*y^2 + 12*x*z + 12*y*z>>> # needs sage.rings.finite_rings(continues on next page)754

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> r = PolynomialRing(GF(Integer(2)**Integer(8), a ), Integer(2), names=( x˓→ ,y ,)); (x, y,) = r._first_ngens(2)>>> a = r.base_ring().gen(0)>>> f = (a**Integer(2)+a)*x**Integer(2)*y + (a**Integer(4)+a**Integer(3)+a)*y␣
˓→+ a**Integer(5)>>> f.lcm(x**Integer(4))(a^2 + a)*x^6*y + (a^4 + a^3 + a)*x^4*y + (a^5)*x^4>>> # needs sage.rings.number_field>>> w = polygen(ZZ, w )>>> r = PolynomialRing(NumberField(w**Integer(4) + Integer(1), a ),␣
˓→Integer(2), names=( x ,y ,)); (x, y,) = r._first_ngens(2)>>> a = r.base_ring().gen(0)>>> f = (a**Integer(2)+a)*x**Integer(2)*y + (a**Integer(4)+a**Integer(3)+a)*y␣
˓→+ a**Integer(5)>>> f.lcm(x**Integer(4))(a^2 + a)*x^6*y + (a^3 + a - 1)*x^4*y + (-a)*x^4lift(I)
given an ideal I = (f_1,...,f_r) and some g (== self) in I, find s_1,...,s_r such that g= s_1 f_1 + ... + s_r f_r.
A ValueError exception is raised if g (== self) does not belong to I.
EXAMPLES:
sage: A.<x,y> = PolynomialRing(QQ,2,order= degrevlex )sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ])sage: f = x*y^13 + y^12
sage: M = f.lift(I)sage: M[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]
sage: sum( map( mul , zip( M, I.gens() ) ) ) == f
True>>> from sage.all import *>>> A = PolynomialRing(QQ,Integer(2),order= degrevlex , names=( x , y ,));␣
˓→(x, y,) = A._first_ngens(2)>>> I = A.ideal([x**Integer(10) + x**Integer(9)*y**Integer(2), y**Integer(8) ˓→ x**Integer(2)*y**Integer(7) ])>>> f = x*y**Integer(13) + y**Integer(12)>>> M = f.lift(I)>>> M[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]>>> sum( map( mul , zip( M, I.gens() ) ) ) == fTrue

Check that Issue #13671 is fixed:
sage: R.<x1,x2> = QQ[]
sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1)sage: f = I.gen(0) + x2*I.gen(1)sage: f.lift(I)[1, x2]sage: (f+1).lift(I)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

755

Polynomials, Release 10.4

(continued from previous page)

Traceback (most recent call last):...
ValueError: polynomial is not in the ideal>>> from sage.all import *>>> R = QQ[ x1, x2 ]; (x1, x2,) = R._first_ngens(2)>>> I = R.ideal(x2**Integer(2) + x1 - Integer(2), x1**Integer(2) - Integer(1))>>> f = I.gen(Integer(0)) + x2*I.gen(Integer(1))>>> f.lift(I)[1, x2]>>> (f+Integer(1)).lift(I)Traceback (most recent call last):...
ValueError: polynomial is not in the ideal

Check that we can work over the integers:
sage: R.<x1,x2> = ZZ[]
sage: I = R.ideal(x2**2 + x1 - 2, x1**2 - 1)sage: f = I.gen(0) + x2*I.gen(1)sage: f.lift(I)[1, x2]sage: (f+1).lift(I)Traceback (most recent call last):...
ValueError: polynomial is not in the ideal
sage: A.<x,y> = PolynomialRing(ZZ,2,order= degrevlex )sage: I = A.ideal([x^10 + x^9*y^2, y^8 - x^2*y^7 ])sage: f = x*y^13 + y^12
sage: M = f.lift(I)sage: M[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]>>> from sage.all import *>>> R = ZZ[ x1, x2 ]; (x1, x2,) = R._first_ngens(2)>>> I = R.ideal(x2**Integer(2) + x1 - Integer(2), x1**Integer(2) - Integer(1))>>> f = I.gen(Integer(0)) + x2*I.gen(Integer(1))>>> f.lift(I)[1, x2]>>> (f+Integer(1)).lift(I)Traceback (most recent call last):...
ValueError: polynomial is not in the ideal>>> A = PolynomialRing(ZZ,Integer(2),order= degrevlex , names=( x , y ,));␣
˓→(x, y,) = A._first_ngens(2)>>> I = A.ideal([x**Integer(10) + x**Integer(9)*y**Integer(2), y**Integer(8) ˓→ x**Integer(2)*y**Integer(7) ])>>> f = x*y**Integer(13) + y**Integer(12)>>> M = f.lift(I)>>> M[y^7, x^7*y^2 + x^8 + x^5*y^3 + x^6*y + x^3*y^4 + x^4*y^2 + x*y^5 + x^2*y^3 +␣˓→y^4]

lm()
Returns the lead monomial of self with respect to the term order of self.parent(). In Sage a mono756

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

mial is a product of variables in some power without a coefficient.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(GF(7), 3, order= lex )sage: f = x^1*y^2 + y^3*z^4sage: f.lm()x*y^2
sage: f = x^3*y^2*z^4 + x^3*y^2*z^1
sage: f.lm()x^3*y^2*z^4
sage: R.<x,y,z>=PolynomialRing(QQ, 3, order= deglex )sage: f = x^1*y^2*z^3 + x^3*y^2*z^0sage: f.lm()x*y^2*z^3
sage: f = x^1*y^2*z^4 + x^1*y^1*z^5
sage: f.lm()x*y^2*z^4
sage: R.<x,y,z>=PolynomialRing(GF(127), 3, order= degrevlex )sage: f = x^1*y^5*z^2 + x^4*y^1*z^3
sage: f.lm()x*y^5*z^2
sage: f = x^4*y^7*z^1 + x^4*y^2*z^3sage: f.lm()x^4*y^7*z>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(7)), Integer(3), order= lex , names=( x ,˓→ ,z ,)); (x, y, z,) = R._first_ngens(3)>>> f = x**Integer(1)*y**Integer(2) + y**Integer(3)*z**Integer(4)>>> f.lm()x*y^2>>> f = x**Integer(3)*y**Integer(2)*z**Integer(4) +␣˓→x**Integer(3)*y**Integer(2)*z**Integer(1)>>> f.lm()x^3*y^2*z^4>>> R = PolynomialRing(QQ, Integer(3), order= deglex , names=( x ,˓→)); (x, y, z,) = R._first_ngens(3)>>> f = x**Integer(1)*y**Integer(2)*z**Integer(3) +␣˓→x**Integer(3)*y**Integer(2)*z**Integer(0)>>> f.lm()x*y^2*z^3>>> f = x**Integer(1)*y**Integer(2)*z**Integer(4) +␣˓→x**Integer(1)*y**Integer(1)*z**Integer(5)>>> f.lm()x*y^2*z^4

y ,

y

z ,

>>> R = PolynomialRing(GF(Integer(127)), Integer(3), order= degrevlex ,␣
˓→names=( x ,y , z ,)); (x, y, z,) = R._first_ngens(3)>>> f = x**Integer(1)*y**Integer(5)*z**Integer(2) +␣˓→x**Integer(4)*y**Integer(1)*z**Integer(3)>>> f.lm()x*y^5*z^2>>> f = x**Integer(4)*y**Integer(7)*z**Integer(1) +␣˓→x**Integer(4)*y**Integer(2)*z**Integer(3)(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

757

Polynomials, Release 10.4

(continued from previous page)>>> f.lm()x^4*y^7*z

local_height(v, prec=None)
Return the maximum of the local height of the coefficients of this polynomial.
INPUT:• v – a prime or prime ideal of the base ring.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 1/1331*x^2 + 1/4000*y^2
sage: f.local_height(1331)
7.19368581839511>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(1331)*x**Integer(2) + Integer(1)/˓→Integer(4000)*y**Integer(2)>>> f.local_height(Integer(1331))
7.19368581839511
sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 - 5)sage: T.<t,w> = K[]
sage: I = K.ideal(3)sage: f = 1/3*t*w + 3
sage: f.local_height(I)1.09861228866811>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = K[ t, w ]; (t, w,) = T._first_ngens(2)>>> I = K.ideal(Integer(3))>>> f = Integer(1)/Integer(3)*t*w + Integer(3)>>> f.local_height(I)1.09861228866811
sage: R.<x,y> = QQ[]
sage: f = 1/2*x*y + 2
sage: f.local_height(2, prec=2)
0.75>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(2)*x*y + Integer(2)(continues on next page)

758

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> f.local_height(Integer(2), prec=Integer(2))
0.75

local_height_arch(i, prec=None)
Return the maximum of the local height at the i-th infinite place of the coefficients of this polynomial.
INPUT:• i – an integer.
• prec – desired floating point precision (default: default RealField precision).
OUTPUT: a real number.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = 210*x*y
sage: f.local_height_arch(0)5.34710753071747>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x ,>>> f = Integer(210)*x*y>>> f.local_height_arch(Integer(0))
5.34710753071747y ,)); (x, y,) = R._first_ngens(2)sage: # needs sage.rings.number_fieldsage: R.<x> = QQ[]
sage: K.<k> = NumberField(x^2 - 5)sage: T.<t,w> = K[]
sage: f = 1/2*t*w + 3
sage: f.local_height_arch(1, prec=52)
1.09861228866811>>> from sage.all import *>>> # needs sage.rings.number_field>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> K = NumberField(x**Integer(2) - Integer(5), names=( k ,)); (k,) = K._
˓→first_ngens(1)>>> T = K[ t, w ]; (t, w,) = T._first_ngens(2)>>> f = Integer(1)/Integer(2)*t*w + Integer(3)>>> f.local_height_arch(Integer(1), prec=Integer(52))
1.09861228866811
sage: R.<x,y> = QQ[]
sage: f = 1/2*x*y + 3
sage: f.local_height_arch(0, prec=2)
1.0>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(1)/Integer(2)*x*y + Integer(3)>>> f.local_height_arch(Integer(0), prec=Integer(2))
1.0

3.1. Multivariate Polynomials and Polynomial Rings

759

Polynomials, Release 10.4

lt()
Leading term of this polynomial. In Sage a term is a product of variables in some power and a coefficient.
EXAMPLES:
sage: R.<x,y,z> = PolynomialRing(GF(7), 3, order= lex )sage: f = 3*x^1*y^2 + 2*y^3*z^4sage: f.lt()
3*x*y^2sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1
sage: f.lt()-2*x^3*y^2*z^4>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(7)), Integer(3), order= lex , names=( x ,˓→ ,z ,)); (x, y, z,) = R._first_ngens(3)>>> f = Integer(3)*x**Integer(1)*y**Integer(2) +␣˓→Integer(2)*y**Integer(3)*z**Integer(4)>>> f.lt()
3*x*y^2y>>> f = Integer(5)*x**Integer(3)*y**Integer(2)*z**Integer(4) +␣˓→Integer(4)*x**Integer(3)*y**Integer(2)*z**Integer(1)>>> f.lt()-2*x^3*y^2*z^4monomial_coefficient(mon)Return the coefficient in the base ring of the monomial mon in self, where mon must have the same parent
as self.
This function contrasts with the function coefficient which returns the coefficient of a monomial viewing
this polynomial in a polynomial ring over a base ring having fewer variables.
INPUT:• mon – a monomial
OUTPUT:
coefficient in base ring
See also:
For coefficients in a base ring of fewer variables, look at coefficient.
EXAMPLES:
sage: P.<x,y> = QQ[]
The parent of the return is a member of the base ring.
sage: f = 2 * x * ysage: c = f.monomial_coefficient(x*y); c2
sage: c.parent()
Rational Field
sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y
sage: f.monomial_coefficient(y^2)
1(continues on next page)

760

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f.monomial_coefficient(x*y)
5
sage: f.monomial_coefficient(x^9)-1sage: f.monomial_coefficient(x^10)0>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)The parent of the return is a member of the base ring.
>>> f = Integer(2) * x * y>>> c = f.monomial_coefficient(x*y); c
2>>> c.parent()
Rational Field>>> f = y**Integer(2) + y**Integer(2)*x - x**Integer(9) - Integer(7)*x +␣˓→Integer(5)*x*y>>> f.monomial_coefficient(y**Integer(2))
1>>> f.monomial_coefficient(x*y)
5>>> f.monomial_coefficient(x**Integer(9))-1>>> f.monomial_coefficient(x**Integer(10))
0monomials()
Return the list of monomials in self. The returned list is decreasingly ordered by the term ordering of self.
parent().
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: f = x + 3/2*y*z^2 + 2/3
sage: f.monomials()[y*z^2, x, 1]
sage: f = P(3/2)
sage: f.monomials()[1]>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = x + Integer(3)/Integer(2)*y*z**Integer(2) + Integer(2)/Integer(3)>>> f.monomials()[y*z^2, x, 1]>>> f = P(Integer(3)/Integer(2))>>> f.monomials()[1]

number_of_terms()
Return the number of non-zero coefficients of this polynomial.
This is also called weight, hamming_weight() or sparsity.
EXAMPLES:
3.1. Multivariate Polynomials and Polynomial Rings

761

Polynomials, Release 10.4

sage: R.<x, y> = ZZ[]
sage: f = x^3 - ysage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x+y)^100
sage: f.number_of_terms()
101>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) - y>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x+y)**Integer(100)>>> f.number_of_terms()
101

The method hamming_weight() is an alias:
sage: f.hamming_weight()
101>>> from sage.all import *>>> f.hamming_weight()
101

numerator()
Return a numerator of self computed as self * self.denominator()
If the base_field of self is the Rational Field then the numerator is a polynomial whose base_ring is the Integer
Ring, this is done for compatibility to the univariate case.
Warning: This is not the numerator of the rational function defined by self, which would always be self
since self is a polynomial.
EXAMPLES:First we compute the numerator of a polynomial with integer coefficients, which is of course self.
sage: R.<x, y> = ZZ[]
sage: f = x^3 + 17*y + 1
sage: f.numerator()x^3 + 17*y + 1
sage: f == f.numerator()
True>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(3) + Integer(17)*y + Integer(1)>>> f.numerator()(continues on next page)

762

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)x^3 + 17*y + 1>>> f == f.numerator()
True

Next we compute the numerator of a polynomial with rational coefficients.
sage: R.<x,y> = PolynomialRing(QQ)
sage: f = (1/17)*x^19 - (2/3)*y + 1/3; f
1/17*x^19 - 2/3*y + 1/3
sage: f.numerator()
3*x^19 - 34*y + 17
sage: f == f.numerator()
False
sage: f.numerator().base_ring()
Integer Ring>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = (Integer(1)/Integer(17))*x**Integer(19) - (Integer(2)/Integer(3))*y +␣˓→Integer(1)/Integer(3); f
1/17*x^19 - 2/3*y + 1/3>>> f.numerator()
3*x^19 - 34*y + 17>>> f == f.numerator()
False>>> f.numerator().base_ring()
Integer Ring

We check that the computation of numerator and denominator is valid.
sage: K=QQ[ x,y ]sage: f=K.random_element()
sage: f.numerator() / f.denominator() == f
True>>> from sage.all import *>>> K=QQ[ x,y ]>>> f=K.random_element()>>> f.numerator() / f.denominator() == f
True

The following tests against a bug fixed in Issue #11780:
sage: P.<foo,bar> = ZZ[]
sage: Q.<foo,bar> = QQ[]
sage: f = Q.random_element()
sage: f.numerator().parent() is P
True>>> from sage.all import *>>> P = ZZ[ foo, bar ]; (foo, bar,) = P._first_ngens(2)>>> Q = QQ[ foo, bar ]; (foo, bar,) = Q._first_ngens(2)>>> f = Q.random_element()>>> f.numerator().parent() is P
True

3.1. Multivariate Polynomials and Polynomial Rings

763

Polynomials, Release 10.4

nvariables()Return the number variables in this polynomial.
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(GF(127))
sage: f = x*y + z
sage: f.nvariables()3sage: f = x + y
sage: f.nvariables()2>>> from sage.all import *>>> P = PolynomialRing(GF(Integer(127)), names=( x ,˓→= P._first_ngens(3)>>> f = x*y + z>>> f.nvariables()3>>> f = x + y>>> f.nvariables()2y ,z ,)); (x, y, z,)␣quo_rem(right)
Return quotient and remainder of self and right.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = y*x^2 + x + 1
sage: f.quo_rem(x)(x*y + 1, 1)
sage: f.quo_rem(y)(x^2, x + 1)
sage: R.<x,y> = ZZ[]
sage: f = 2*y*x^2 + x + 1
sage: f.quo_rem(x)(2*x*y + 1, 1)
sage: f.quo_rem(y)(2*x^2, x + 1)
sage: f.quo_rem(3*x)(0, 2*x^2*y + x + 1)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = y*x**Integer(2) + x + Integer(1)>>> f.quo_rem(x)(x*y + 1, 1)>>> f.quo_rem(y)(x^2, x + 1)>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(2)*y*x**Integer(2) + x + Integer(1)>>> f.quo_rem(x)(2*x*y + 1, 1)>>> f.quo_rem(y)(continues on next page)

764

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(2*x^2, x + 1)>>> f.quo_rem(Integer(3)*x)(0, 2*x^2*y + x + 1)

reduce(I)Return a remainder of this polynomial modulo the polynomials in I.
INPUT:• I – an ideal or a list/set/iterable of polynomials.
OUTPUT:
A polynomial r such that:• self – r is in the ideal generated by I.
• No term in r is divisible by any of the leading monomials of I.
The result r is canonical if:• I is an ideal, and Sage can compute a Groebner basis of it.
• I is a list/set/iterable that is a (strong) Groebner basis for the term order of self. (A strong Groebnerbasis is such that for every leading term t of the ideal generated by I, there exists an element g of I
such that the leading term of g divides t.)
The result r is implementation-dependent (and possibly order-dependent) otherwise. If I is an ideal and no
Groebner basis can be computed, its list of generators I.gens() is used for the reduction.
EXAMPLES:
sage: P.<x,y,z> = QQ[]
sage: f1 = -2 * x^2 + x^3
sage: f2 = -2 * y + x* y
sage: f3 = -x^2 + y^2
sage: F = Ideal([f1,f2,f3])
sage: g = x*y - 3*x*y^2
sage: g.reduce(F)-6*y^2 + 2*ysage: g.reduce(F.gens())-6*y^2 + 2*y>>> from sage.all import *>>> P = QQ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f1 = -Integer(2) * x**Integer(2) + x**Integer(3)>>> f2 = -Integer(2) * y + x* y>>> f3 = -x**Integer(2) + y**Integer(2)>>> F = Ideal([f1,f2,f3])>>> g = x*y - Integer(3)*x*y**Integer(2)>>> g.reduce(F)-6*y^2 + 2*y>>> g.reduce(F.gens())-6*y^2 + 2*y

Z is also supported.
sage: P.<x,y,z> = ZZ[]
sage: f1 = -2 * x^2 + x^3
sage: f2 = -2 * y + x* y(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

765

Polynomials, Release 10.4

(continued from previous page)

sage: f3 = -x^2 + y^2
sage: F = Ideal([f1,f2,f3])
sage: g = x*y - 3*x*y^2
sage: g.reduce(F)-6*y^2 + 2*ysage: g.reduce(F.gens())-6*y^2 + 2*ysage: f = 3*x
sage: f.reduce([2*x,y])x>>> from sage.all import *>>> P = ZZ[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f1 = -Integer(2) * x**Integer(2) + x**Integer(3)>>> f2 = -Integer(2) * y + x* y>>> f3 = -x**Integer(2) + y**Integer(2)>>> F = Ideal([f1,f2,f3])>>> g = x*y - Integer(3)*x*y**Integer(2)>>> g.reduce(F)-6*y^2 + 2*y>>> g.reduce(F.gens())-6*y^2 + 2*y>>> f = Integer(3)*x>>> f.reduce([Integer(2)*x,y])x

The reduction is not canonical when I is not a Groebner basis:sage: A.<x,y> = QQ[]
sage: (x+y).reduce([x+y, x-y])
2*ysage: (x+y).reduce([x-y, x+y])0>>> from sage.all import *>>> A = QQ[ x, y ]; (x, y,) = A._first_ngens(2)>>> (x+y).reduce([x+y, x-y])2*y>>> (x+y).reduce([x-y, x+y])0

resultant(other, variable=None)
Compute the resultant of this polynomial and the first argument with respect to the variable given as thesecond argument.
If a second argument is not provide the first variable of the parent is chosen.
INPUT:• other – polynomial• variable – optional variable (default: None)
EXAMPLES:

766

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: P.<x,y> = PolynomialRing(QQ,2)
sage: a = x+y
sage: b = x^3-y^3sage: c = a.resultant(b); c-2*y^3sage: d = a.resultant(b,y); d2*x^3>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(2), names=( x ,˓→ngens(2)>>> a = x+y>>> b = x**Integer(3)-y**Integer(3)>>> c = a.resultant(b); c-2*y^3>>> d = a.resultant(b,y); d2*x^3y ,)); (x, y,) = P._first_

The SINGULAR example:
sage: R.<x,y,z> = PolynomialRing(GF(32003), 3)#␣˓→needs sage.rings.finite_rings
sage: f = 3 * (x+2)^3 + ysage: g = x + y + z#␣˓→needs sage.rings.finite_rings
sage: f.resultant(g, x)#␣˓→needs sage.rings.finite_rings
3*y^3 + 9*y^2*z + 9*y*z^2 + 3*z^3 - 18*y^2 - 36*y*z - 18*z^2 + 35*y + 36*z -␣˓→24>>> from sage.all import *>>> R = PolynomialRing(GF(Integer(32003)), Integer(3), names=( x , y , z ,˓→)); (x, y, z,) = R._first_ngens(3)# needs sage.rings.finite_rings>>> f = Integer(3) * (x+Integer(2))**Integer(3) + y>>> g = x + y + z#␣˓→needs sage.rings.finite_rings>>> f.resultant(g, x)#␣˓→needs sage.rings.finite_rings
3*y^3 + 9*y^2*z + 9*y*z^2 + 3*z^3 - 18*y^2 - 36*y*z - 18*z^2 + 35*y + 36*z -␣˓→24Resultants are also supported over the Integers:
sage: R.<x,y,a,b,u> = PolynomialRing(ZZ, 5, order= lex )sage: r = (x^4*y^2 + x^2*y - y).resultant(x*y - y*a - x*b + a*b + u, x)
sage: ry^6*a^4 - 4*y^5*a^4*b - 4*y^5*a^3*u + y^5*a^2 - y^5 + 6*y^4*a^4*b^2 + 12*y^
˓→4*a^3*b*u - 4*y^4*a^2*b + 6*y^4*a^2*u^2 - 2*y^4*a*u + 4*y^4*b - 4*y^3*a^4*b^
˓→3 - 12*y^3*a^3*b^2*u + 6*y^3*a^2*b^2 - 12*y^3*a^2*b*u^2 + 6*y^3*a*b*u - 4*y^
˓→3*a*u^3 - 6*y^3*b^2 + y^3*u^2 + y^2*a^4*b^4 + 4*y^2*a^3*b^3*u - 4*y^2*a^2*b^
˓→3 + 6*y^2*a^2*b^2*u^2 - 6*y^2*a*b^2*u + 4*y^2*a*b*u^3 + 4*y^2*b^3 - 2*y^˓→2*b*u^2 + y^2*u^4 + y*a^2*b^4 + 2*y*a*b^3*u - y*b^4 + y*b^2*u^2>>> from sage.all import *>>> R = PolynomialRing(ZZ, Integer(5), order= lex , names=( x ,˓→u ,)); (x, y, a, b, u,) = R._first_ngens(5)

y ,

a ,

b ,

(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

767

Polynomials, Release 10.4

(continued from previous page)>>> r = (x**Integer(4)*y**Integer(2) + x**Integer(2)*y - y).resultant(x*y -␣
˓→y*a - x*b + a*b + u, x)>>> ry^6*a^4 - 4*y^5*a^4*b - 4*y^5*a^3*u + y^5*a^2 - y^5 + 6*y^4*a^4*b^2 + 12*y^
˓→4*a^3*b*u - 4*y^4*a^2*b + 6*y^4*a^2*u^2 - 2*y^4*a*u + 4*y^4*b - 4*y^3*a^4*b^
˓→3 - 12*y^3*a^3*b^2*u + 6*y^3*a^2*b^2 - 12*y^3*a^2*b*u^2 + 6*y^3*a*b*u - 4*y^
˓→3*a*u^3 - 6*y^3*b^2 + y^3*u^2 + y^2*a^4*b^4 + 4*y^2*a^3*b^3*u - 4*y^2*a^2*b^
˓→3 + 6*y^2*a^2*b^2*u^2 - 6*y^2*a*b^2*u + 4*y^2*a*b*u^3 + 4*y^2*b^3 - 2*y^˓→2*b*u^2 + y^2*u^4 + y*a^2*b^4 + 2*y*a*b^3*u - y*b^4 + y*b^2*u^2sub_m_mul_q(m, q)
Return self - m*q, where m must be a monomial and q a polynomial.
INPUT:• m – a monomial• q – a polynomial
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(QQ,3)
sage: x.sub_m_mul_q(y, z)-y*z + x>>> from sage.all import *>>> P = PolynomialRing(QQ,Integer(3), names=( x ,˓→_first_ngens(3)>>> x.sub_m_mul_q(y, z)-y*z + xy ,z ,)); (x, y, z,) = P.

subs(fixed=None, **kw)
Fixes some given variables in a given multivariate polynomial and returns the changed multivariate polynomials. The polynomial itself is not affected. The variable,value pairs for fixing are to be provided as dictionaryof the form {variable:value}.
This is a special case of evaluating the polynomial with some of the variables constants and the others theoriginal variables, but should be much faster if only few variables are to be fixed.
INPUT:• fixed – (optional) dict with variable:value pairs• **kw – names parameters
OUTPUT: a new multivariate polynomial
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: f = x^2 + y + x^2*y^2 + 5
sage: f(5,y)
25*y^2 + y + 30
sage: f.subs({x: 5})25*y^2 + y + 30
sage: f.subs(x=5)
25*y^2 + y + 30
sage: P.<x,y,z> = PolynomialRing(GF(2), 3)(continues on next page)

768

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = x + y + 1
sage: f.subs({x:y+1})
0
sage: f.subs(x=y)
1
sage: f.subs(x=x)
x + y + 1
sage: f.subs({x: z})
y + z + 1
sage: f.subs(x=z + 1)
y + z
sage: f.subs(x=1/y)(y^2 + y + 1)/ysage: f.subs({x: 1/y})(y^2 + y + 1)/y>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x**Integer(2) + y + x**Integer(2)*y**Integer(2) + Integer(5)>>> f(Integer(5),y)25*y^2 + y + 30>>> f.subs({x: Integer(5)})
25*y^2 + y + 30>>> f.subs(x=Integer(5))
25*y^2 + y + 30>>> P = PolynomialRing(GF(Integer(2)), Integer(3), names=( x ,˓→(x, y, z,) = P._first_ngens(3)>>> f = x + y + Integer(1)>>> f.subs({x:y+Integer(1)})
0>>> f.subs(x=y)
1>>> f.subs(x=x)
x + y + 1>>> f.subs({x: z})
y + z + 1>>> f.subs(x=z + Integer(1))
y + z

y ,

z ,));␣

>>> f.subs(x=Integer(1)/y)(y^2 + y + 1)/y>>> f.subs({x: Integer(1)/y})(y^2 + y + 1)/y

The parameters are substituted in order and without side effects:
sage: R.<x,y>=QQ[]
sage: g=x+ysage: g.subs({x:x+1,y:x*y})
x*y + x + 1
sage: g.subs({x:x+1}).subs({y:x*y})
x*y + x + 1
sage: g.subs({y:x*y}).subs({x:x+1})
x*y + x + y + 1

3.1. Multivariate Polynomials and Polynomial Rings

769

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> g=x+y>>> g.subs({x:x+Integer(1),y:x*y})
x*y + x + 1>>> g.subs({x:x+Integer(1)}).subs({y:x*y})
x*y + x + 1>>> g.subs({y:x*y}).subs({x:x+Integer(1)})
x*y + x + y + 1
sage: R.<x,y> = QQ[]
sage: f = x + 2*ysage: f.subs(x=y,y=x)
2*x + y>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x + Integer(2)*y>>> f.subs(x=y,y=x)
2*x + ytotal_degree(std_grading=False)
Return the total degree of self, which is the maximum degree of all monomials in self.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: f = 2*x*y^3*z^2sage: f.total_degree()6
sage: f = 4*x^2*y^2*z^3sage: f.total_degree()7
sage: f = 99*x^6*y^3*z^9sage: f.total_degree()18
sage: f = x*y^3*z^6+3*x^2
sage: f.total_degree()10
sage: f = z^3+8*x^4*y^5*z
sage: f.total_degree()10
sage: f = z^9+10*x^4+y^8*x^2
sage: f.total_degree()10>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> f = Integer(2)*x*y**Integer(3)*z**Integer(2)>>> f.total_degree()6>>> f = Integer(4)*x**Integer(2)*y**Integer(2)*z**Integer(3)>>> f.total_degree()7>>> f = Integer(99)*x**Integer(6)*y**Integer(3)*z**Integer(9)>>> f.total_degree()(continues on next page)

770

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)18>>> f = x*y**Integer(3)*z**Integer(6)+Integer(3)*x**Integer(2)>>> f.total_degree()10>>> f = z**Integer(3)+Integer(8)*x**Integer(4)*y**Integer(5)*z>>> f.total_degree()10>>> f = z**Integer(9)+Integer(10)*x**Integer(4)+y**Integer(8)*x**Integer(2)>>> f.total_degree()10

A matrix term ordering changes the grading. To get the total degree using the standard grading, use
std_grading=True:
sage: tord = TermOrder(matrix(3, [3,2,1,1,1,0,1,0,0]))
sage: tord
Matrix term order with matrix[3 2 1][1 1 0][1 0 0]sage: R.<x,y,z> = PolynomialRing(QQ, order=tord)
sage: f = x^2*ysage: f.total_degree()8
sage: f.total_degree(std_grading=True)
3>>> from sage.all import *>>> tord = TermOrder(matrix(Integer(3), [Integer(3),Integer(2),Integer(1),˓→Integer(1),Integer(1),Integer(0),Integer(1),Integer(0),Integer(0)]))>>> tord
Matrix term order with matrix[3 2 1][1 1 0][1 0 0]>>> R = PolynomialRing(QQ, order=tord, names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> f = x**Integer(2)*y>>> f.total_degree()8>>> f.total_degree(std_grading=True)
3

univariate_polynomial(R=None)
Returns a univariate polynomial associated to this multivariate polynomial.
INPUT:• R – (default: None) PolynomialRing
If this polynomial is not in at most one variable, then a ValueError exception is raised. This is checked using the is_univariate() method. The new Polynomial is over the same base ring as the given MPolynomial and in the variable x if no ring R is provided.
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

771

Polynomials, Release 10.4

sage: R.<x, y> = QQ[]
sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5
sage: f.univariate_polynomial()
Traceback (most recent call last):...
TypeError: polynomial must involve at most one variable
sage: g = f.subs({x:10}); g
700*y^2 - 2*y + 305
sage: g.univariate_polynomial ()700*y^2 - 2*y + 305
sage: g.univariate_polynomial(PolynomialRing(QQ, z ))700*z^2 - 2*z + 305>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = Integer(3)*x**Integer(2) - Integer(2)*y +␣˓→Integer(7)*x**Integer(2)*y**Integer(2) + Integer(5)>>> f.univariate_polynomial()
Traceback (most recent call last):...
TypeError: polynomial must involve at most one variable>>> g = f.subs({x:Integer(10)}); g
700*y^2 - 2*y + 305>>> g.univariate_polynomial ()700*y^2 - 2*y + 305>>> g.univariate_polynomial(PolynomialRing(QQ, z ))700*z^2 - 2*z + 305

Here’s an example with a constant multivariate polynomial:
sage: g = R(1)sage: h = g.univariate_polynomial(); h1sage: h.parent()
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> g = R(Integer(1))>>> h = g.univariate_polynomial(); h1>>> h.parent()
Univariate Polynomial Ring in x over Rational Field

variable(i=0)
Return the 𝑖-th variable occurring in self. The index 𝑖 is the index in self.variables().
EXAMPLES:
sage: P.<x,y,z> = GF(2)[]sage: f = x*z^2 + z + 1
sage: f.variables()(x, z)
sage: f.variable(1)z772

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = x*z**Integer(2) + z + Integer(1)>>> f.variables()(x, z)>>> f.variable(Integer(1))
zvariables()Return a tuple of all variables occurring in self.
EXAMPLES:
sage: P.<x,y,z> = GF(2)[]sage: f = x*z^2 + z + 1
sage: f.variables()(x, z)>>> from sage.all import *>>> P = GF(Integer(2))[ x, y, z ]; (x, y, z,) = P._first_ngens(3)>>> f = x*z**Integer(2) + z + Integer(1)>>> f.variables()(x, z)

sage.rings.polynomial.multi_polynomial_libsingular.unpickle_MPolynomialRing_libsingular(base
nam
term
der)
inverse function for MPolynomialRing_libsingular.__reduce__
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ)
sage: loads(dumps(P)) is P # indirect doctest
True>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> loads(dumps(P)) is P # indirect doctest
Truesage.rings.polynomial.multi_polynomial_libsingular.unpickle_MPolynomial_libsingular(R,d)
Deserialize an MPolynomial_libsingular object
INPUT:• R – the base ring• d – a Python dictionary as returned by MPolynomial_libsingular.dict()
EXAMPLES:
sage: P.<x,y> = PolynomialRing(QQ)
sage: loads(dumps(x)) == x # indirect doctest
True

3.1. Multivariate Polynomials and Polynomial Rings

773

Polynomials, Release 10.4>>> from sage.all import *>>> P = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = P._first_ngens(2)>>> loads(dumps(x)) == x # indirect doctest
True

3.1.9 Direct low-level access to SINGULAR’s Groebner basis engine via libSINGULAR
AUTHOR:• Martin Albrecht (2007-08-08): initial version
EXAMPLES:
sage: x,y,z = QQ[ x,y,z ].gens()
sage: I = ideal(x^5 + y^4 + z^3 - 1, x^3 + y^3 + z^2 - 1)sage: I.groebner_basis( libsingular:std )[y^6 + x*y^4 + 2*y^3*z^2 + x*z^3 + z^4 - 2*y^3 - 2*z^2 - x + 1,x^2*y^3 - y^4 + x^2*z^2 - z^3 - x^2 + 1, x^3 + y^3 + z^2 - 1]>>> from sage.all import *>>> x,y,z = QQ[ x,y,z ].gens()>>> I = ideal(x**Integer(5) + y**Integer(4) + z**Integer(3) - Integer(1), ␣
˓→x**Integer(3) + y**Integer(3) + z**Integer(2) - Integer(1))>>> I.groebner_basis( libsingular:std )[y^6 + x*y^4 + 2*y^3*z^2 + x*z^3 + z^4 - 2*y^3 - 2*z^2 - x + 1,x^2*y^3 - y^4 + x^2*z^2 - z^3 - x^2 + 1, x^3 + y^3 + z^2 - 1]

We compute a Groebner basis for cyclic 6, which is a standard benchmark and test ideal:
sage: R.<x,y,z,t,u,v> = QQ[ x,y,z,t,u,v ]sage: I = sage.rings.ideal.Cyclic(R,6)
sage: B = I.groebner_basis( libsingular:std )sage: len(B)45>>> from sage.all import *>>> R = QQ[ x,y,z,t,u,v ]; (x, y, z, t, u, v,) = R._first_ngens(6)>>> I = sage.rings.ideal.Cyclic(R,Integer(6))>>> B = I.groebner_basis( libsingular:std )>>> len(B)45

Two examples from the Mathematica documentation (done in Sage):• We compute a Groebner basis:sage: R.<x,y> = PolynomialRing(QQ, order= lex )sage: ideal(x^2 - 2*y^2, x*y - 3).groebner_basis( libsingular:slimgb )[x - 2/3*y^3, y^4 - 9/2]>>> from sage.all import *>>> R = PolynomialRing(QQ, order= lex , names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> ideal(x**Integer(2) - Integer(2)*y**Integer(2), x*y - Integer(3)).groebner_(continues on next page)

774

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)basis( libsingular:slimgb )[x - 2/3*y^3, y^4 - 9/2]
˓→

• We show that three polynomials have no common root:
sage: R.<x,y> = QQ[]
sage: ideal(x+y, x^2 - 1, y^2 - 2*x).groebner_basis( libsingular:slimgb )[1]>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> ideal(x+y, x**Integer(2) - Integer(1), y**Integer(2) - Integer(2)*x).groebner_
˓→basis( libsingular:slimgb )[1]

sage.rings.polynomial.multi_polynomial_ideal_libsingular.interred_libsingular(I)SINGULAR’s interred() command.
INPUT:• I – a Sage ideal
EXAMPLES:
sage: P.<x,y,z> = PolynomialRing(ZZ)
sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )sage: I.interreduced_basis()[y*z^2 - 81*x*y - 9*y - z, z^3 - x, x^2 - 3*y, 9*y^2 - y*z + 1]
sage: P.<x,y,z> = PolynomialRing(QQ)
sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )sage: I.interreduced_basis()[y*z^2 - 81*x*y - 9*y - z, z^3 - x, x^2 - 3*y, y^2 - 1/9*y*z + 1/9]>>> from sage.all import *>>> P = PolynomialRing(ZZ, names=( x , y , z ,)); (x, y, z,) = P._first_ngens(3)>>> I = ideal( x**Integer(2) - Integer(3)*y, y**Integer(3) - x*y, z**Integer(3) -␣˓→x, x**Integer(4) - y*z + Integer(1) )>>> I.interreduced_basis()[y*z^2 - 81*x*y - 9*y - z, z^3 - x, x^2 - 3*y, 9*y^2 - y*z + 1]>>> P = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = P._first_ngens(3)>>> I = ideal( x**Integer(2) - Integer(3)*y, y**Integer(3) - x*y, z**Integer(3) -␣˓→x, x**Integer(4) - y*z + Integer(1) )>>> I.interreduced_basis()[y*z^2 - 81*x*y - 9*y - z, z^3 - x, x^2 - 3*y, y^2 - 1/9*y*z + 1/9]

sage.rings.polynomial.multi_polynomial_ideal_libsingular.kbase_libsingular(I,degree=None)SINGULAR’s kbase() algorithm.
INPUT:• I – a groebner basis of an ideal• degree – integer (default: None); if not None, return only the monomials of the given degree

3.1. Multivariate Polynomials and Polynomial Rings

775

Polynomials, Release 10.4

OUTPUT:
Computes a vector space basis (consisting of monomials) of the quotient ring by the ideal, resp. of a free moduleby the module, in case it is finite dimensional and if the input is a standard basis with respect to the ring ordering.
If the input is not a standard basis, the leading terms of the input are used and the result may have no meaning.
With two arguments: computes the part of a vector space basis of the respective quotient with degree of themonomials equal to the second argument. Here, the quotient does not need to be finite dimensional.
EXAMPLES:
sage: R.<x,y> = PolynomialRing(QQ, order= lex )sage: I = R.ideal(x^2-2*y^2, x*y-3)
sage: I.normal_basis() # indirect doctest[y^3, y^2, y, 1]
sage: J = R.ideal(x^2-2*y^2)
sage: [J.normal_basis(d) for d in (0..4)] # indirect doctest[[1], [y, x], [y^2, x*y], [y^3, x*y^2], [y^4, x*y^3]]>>> from sage.all import *>>> R = PolynomialRing(QQ, order= lex , names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = R.ideal(x**Integer(2)-Integer(2)*y**Integer(2), x*y-Integer(3))>>> I.normal_basis() # indirect doctest[y^3, y^2, y, 1]>>> J = R.ideal(x**Integer(2)-Integer(2)*y**Integer(2))>>> [J.normal_basis(d) for d in (ellipsis_iter(Integer(0),Ellipsis,Integer(4)))]
˓→# indirect doctest[[1], [y, x], [y^2, x*y], [y^3, x*y^2], [y^4, x*y^3]]

sage.rings.polynomial.multi_polynomial_ideal_libsingular.slimgb_libsingular(I)SINGULAR’s slimgb() algorithm.
INPUT:• I – a Sage ideal
sage.rings.polynomial.multi_polynomial_ideal_libsingular.std_libsingular(I)SINGULAR’s std() algorithm.
INPUT:• I – a Sage ideal

3.1.10 Solution of polynomial systems using msolve
msolve is a multivariate polynomial system solver based on Gröbner bases.
This module provide implementations of some operations on polynomial ideals based on msolve.
Note that the optional package msolve must be installed.
See also:• sage.features.msolve• sage.rings.polynomial.multi_polynomial_ideal

776

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.msolve.groebner_basis_degrevlex(ideal, proof=True)
Compute a degrevlex Gröbner basis using msolve
EXAMPLES:
sage: from sage.rings.polynomial.msolve import groebner_basis_degrevlex
sage: R.<a,b,c> = PolynomialRing(GF(101), 3, order= lex )sage: I = sage.rings.ideal.Katsura(R,3)
sage: gb = groebner_basis_degrevlex(I); gb # optional - msolve[a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]
sage: gb.universe() is R # optional - msolve
False
sage: gb.universe().term_order() # optional - msolve
Degree reverse lexicographic term ordersage: ideal(gb).transformed_basis(other_ring=R) # optional - msolve[c^4 + 38*c^3 - 6*c^2 - 6*c, 30*c^3 + 32*c^2 + b - 14*c,
a + 2*b + 2*c - 1]>>> from sage.all import *>>> from sage.rings.polynomial.msolve import groebner_basis_degrevlex>>> R = PolynomialRing(GF(Integer(101)), Integer(3), order= lex , names=( a ,˓→c ,)); (a, b, c,) = R._first_ngens(3)>>> I = sage.rings.ideal.Katsura(R,Integer(3))>>> gb = groebner_basis_degrevlex(I); gb # optional - msolve[a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]>>> gb.universe() is R # optional - msolve
False>>> gb.universe().term_order() # optional - msolve
Degree reverse lexicographic term order>>> ideal(gb).transformed_basis(other_ring=R) # optional - msolve[c^4 + 38*c^3 - 6*c^2 - 6*c, 30*c^3 + 32*c^2 + b - 14*c,
a + 2*b + 2*c - 1]b ,Gröbner bases over the rationals require 𝑝𝑟𝑜𝑜𝑓 = 𝐹 𝑎𝑙𝑠𝑒:
sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1])sage: I.groebner_basis(algorithm= msolve ) # optional - msolve
Traceback (most recent call last):...
ValueError: msolve relies on heuristics; please use proof=False
sage: I.groebner_basis(algorithm= msolve , proof=False) # optional - msolve[x*y - 1, x^2 + y^2 - 4*x - 2*y + 4, y^3 - 2*y^2 + x + 4*y - 4]>>> from sage.all import *>>> R = PolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = Ideal([ x*y - Integer(1), (x-Integer(2))**Integer(2) + (y˓→Integer(1))**Integer(2) - Integer(1)])>>> I.groebner_basis(algorithm= msolve ) # optional - msolve
Traceback (most recent call last):...
ValueError: msolve relies on heuristics; please use proof=False(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

777

Polynomials, Release 10.4

(continued from previous page)>>> I.groebner_basis(algorithm= msolve , proof=False) # optional - msolve[x*y - 1, x^2 + y^2 - 4*x - 2*y + 4, y^3 - 2*y^2 + x + 4*y - 4]sage.rings.polynomial.msolve.variety(ideal, ring, proof)
Compute the variety of a zero-dimensional ideal using msolve.
Part of the initial implementation was loosely based on the example interfaces available as part of msolve, with theauthors’ permission.
EXAMPLES:
sage: from sage.rings.polynomial.msolve import variety
sage: p = 536870909
sage: R.<x, y> = PolynomialRing(GF(p), 2, order= lex )sage: I = Ideal([ x*y - 1, (x-2)^2 + (y-1)^2 - 1])sage: sorted(variety(I, GF(p^2), proof=False), key=str) # optional - msolve[{x: 1, y: 1},{x: 254228855*z2 + 114981228, y: 232449571*z2 + 402714189},{x: 267525699, y: 473946006},{x: 282642054*z2 + 154363985, y: 304421338*z2 + 197081624}]>>> from sage.all import *>>> from sage.rings.polynomial.msolve import variety>>> p = Integer(536870909)>>> R = PolynomialRing(GF(p), Integer(2), order= lex , names=( x , y ,)); (x, y,˓→) = R._first_ngens(2)>>> I = Ideal([ x*y - Integer(1), (x-Integer(2))**Integer(2) + (y˓→Integer(1))**Integer(2) - Integer(1)])>>> sorted(variety(I, GF(p**Integer(2)), proof=False), key=str) # optional -␣˓→msolve[{x: 1, y: 1},{x: 254228855*z2 + 114981228, y: 232449571*z2 + 402714189},{x: 267525699, y: 473946006},{x: 282642054*z2 + 154363985, y: 304421338*z2 + 197081624}]

3.1.11 Generic data structures for multivariate polynomials
This module provides an implementation of a generic data structure PolyDict and the underlying arithmetic for
multi-variate polynomial rings. It uses a sparse representation of polynomials encoded as a Python dictionary where
keys are exponents and values coefficients.
{(e1,...,er):c1,...} <-> c1*x1^e1*...*xr^er+...,The exponent (e1,...,er) in this representation is an instance of the class ETuple.
AUTHORS:• William Stein• David Joyner• Martin Albrecht (ETuple)• Joel B. Mohler (2008-03-17) – ETuple rewrite as sparse C arrayclass sage.rings.polynomial.polydict.ETuple
Bases: object

778

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Representation of the exponents of a polydict monomial. If (0,0,3,0,5) is the exponent tuple of x_2^3*x_4^5 thenthis class only stores {2:3, 4:5} instead of the full tuple. This sparse information may be obtained by provided
methods.
The index/value data is all stored in the _data C int array member variable. For the example above, the C array
would contain 2,3,4,5. The indices are interlaced with the values.
This data structure is very nice to work with for some functions implemented in this class, but tricky for others.
One reason that I really like the format is that it requires a single memory allocation for all of the values. A hashtable would require more allocations and presumably be slower. I didn’t benchmark this question (although, there
is no question that this is much faster than the prior use of python dicts).
combine_to_positives(other)
Given a pair of ETuples (self, other), returns a triple of ETuples (a, b, c) so that self = a + b, other = a + c
and b and c have all positive entries.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([-2, 1, -5, 3, 1, 0])
sage: f = ETuple([1, -3, -3, 4, 0, 2])
sage: e.combine_to_positives(f)((-2, -3, -5, 3, 0, 0), (0, 4, 0, 0, 1, 0), (3, 0, 2, 1, 0, 2))>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([-Integer(2), Integer(1), -Integer(5), Integer(3), Integer(1),␣
˓→Integer(0)])>>> f = ETuple([Integer(1), -Integer(3), -Integer(3), Integer(4), Integer(0),␣
˓→Integer(2)])>>> e.combine_to_positives(f)((-2, -3, -5, 3, 0, 0), (0, 4, 0, 0, 1, 0), (3, 0, 2, 1, 0, 2))common_nonzero_positions(other, sort=False)
Returns an optionally sorted list of non zero positions either in self or other, i.e. the only positions that need
to be considered for any vector operation.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 0, 1])
sage: e.common_nonzero_positions(f){0, 2}
sage: e.common_nonzero_positions(f, sort=True)[0, 2]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(0), Integer(1)])>>> e.common_nonzero_positions(f){0, 2}>>> e.common_nonzero_positions(f, sort=True)[0, 2]

divide_by_gcd(other)
Return self / gcd(self, other).
3.1. Multivariate Polynomials and Polynomial Rings

779

Polynomials, Release 10.4

The entries of the result are the maximum of 0 and the difference of the corresponding entries of self andother.
divide_by_var(pos)Return division of self by the variable with index pos.
If self[pos] == 0 then a ArithmeticError is raised. Otherwise, an ETuple is returned that iszero in position pos and coincides with self in the other positions.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 2, 0, 1])
sage: e.divide_by_var(0)(0, 2, 0, 1)
sage: e.divide_by_var(1)(1, 1, 0, 1)
sage: e.divide_by_var(3)(1, 2, 0, 0)
sage: e.divide_by_var(2)Traceback (most recent call last):...
ArithmeticError: not divisible by this variable>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(2), Integer(0), Integer(1)])>>> e.divide_by_var(Integer(0))(0, 2, 0, 1)>>> e.divide_by_var(Integer(1))(1, 1, 0, 1)>>> e.divide_by_var(Integer(3))(1, 2, 0, 0)>>> e.divide_by_var(Integer(2))
Traceback (most recent call last):...
ArithmeticError: not divisible by this variabledivides(other)
Return whether self divides other, i.e., no entry of self exceeds that of other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: ETuple([1, 1, 0, 1, 0]).divides(ETuple([2, 2, 2, 2, 2]))True
sage: ETuple([0, 3, 0, 1, 0]).divides(ETuple([2, 2, 2, 2, 2]))False
sage: ETuple([0, 3, 0, 1, 0]).divides(ETuple([0, 3, 2, 2, 2]))True
sage: ETuple([0, 0, 0, 0, 0]).divides(ETuple([2, 2, 2, 2, 2]))True
sage: ETuple({104: 18, 256: 25, 314:78}, length=400r).divides(ETuple({104: 19,
˓→ 105: 20, 106: 21}, length=400r))
False
sage: ETuple({104: 18, 256: 25, 314:78}, length=400r).divides(ETuple({104: 19,
˓→ 105: 20, 106: 21, 255: 2, 256: 25, 312: 5, 314: 79, 315: 28}, length=400r))
True

780

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> ETuple([Integer(1), Integer(1), Integer(0), Integer(1), Integer(0)]).
˓→divides(ETuple([Integer(2), Integer(2), Integer(2), Integer(2),␣
˓→Integer(2)]))True>>> ETuple([Integer(0), Integer(3), Integer(0), Integer(1), Integer(0)]).
˓→divides(ETuple([Integer(2), Integer(2), Integer(2), Integer(2),␣
˓→Integer(2)]))
False>>> ETuple([Integer(0), Integer(3), Integer(0), Integer(1), Integer(0)]).
˓→divides(ETuple([Integer(0), Integer(3), Integer(2), Integer(2),␣
˓→Integer(2)]))True>>> ETuple([Integer(0), Integer(0), Integer(0), Integer(0), Integer(0)]).
˓→divides(ETuple([Integer(2), Integer(2), Integer(2), Integer(2),␣
˓→Integer(2)]))True>>> ETuple({Integer(104): Integer(18), Integer(256): Integer(25),␣
˓→Integer(314):Integer(78)}, length=400).divides(ETuple({Integer(104):␣
˓→Integer(19), Integer(105): Integer(20), Integer(106): Integer(21)},␣
˓→length=400))
False>>> ETuple({Integer(104): Integer(18), Integer(256): Integer(25),␣
˓→Integer(314):Integer(78)}, length=400).divides(ETuple({Integer(104):␣
˓→Integer(19), Integer(105): Integer(20), Integer(106): Integer(21),␣
˓→Integer(255): Integer(2), Integer(256): Integer(25), Integer(312):␣
˓→Integer(5), Integer(314): Integer(79), Integer(315): Integer(28)},␣
˓→length=400))
True

dotprod(other)
Return the dot product of this tuple by other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 1, 1])
sage: e.dotprod(f)2sage: e = ETuple([1, 1, -1])
sage: f = ETuple([0, -2, 1])
sage: e.dotprod(f)-3>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.dotprod(f)2>>> e = ETuple([Integer(1), Integer(1), -Integer(1)])>>> f = ETuple([Integer(0), -Integer(2), Integer(1)])>>> e.dotprod(f)-3

3.1. Multivariate Polynomials and Polynomial Rings

781

Polynomials, Release 10.4

eadd(other)
Return the vector addition of self with other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 1, 1])
sage: e.eadd(f)(1, 1, 3)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.eadd(f)(1, 1, 3)

Verify that Issue #6428 has been addressed:
sage: # needs sage.libs.singularsage: R.<y, z> = Frac(QQ[ x ])[]
sage: type(y)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_
˓→libsingular >sage: y^(2^32)
Traceback (most recent call last):...
OverflowError: exponent overflow (...)# 64-bit
OverflowError: Python int too large to convert to C unsigned long # 32-bit>>> from sage.all import *>>> # needs sage.libs.singular>>> R = Frac(QQ[ x ])[ y, z ]; (y, z,) = R._first_ngens(2)>>> type(y)<class sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_
˓→libsingular >>>> y**(Integer(2)**Integer(32))
Traceback (most recent call last):...
OverflowError: exponent overflow (...)# 64-bit
OverflowError: Python int too large to convert to C unsigned long # 32-bit

eadd_p(other, pos)
Add other to self at position pos.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: e.eadd_p(5, 1)(1, 5, 2)
sage: e = ETuple([0]*7)
sage: e.eadd_p(5, 4)(0, 0, 0, 0, 5, 0, 0)
sage: ETuple([0,1]).eadd_p(1, 0) == ETuple([1,1])(continues on next page)782

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True
sage: e = ETuple([0, 1, 0])
sage: e.eadd_p(0, 0).nonzero_positions()[1]
sage: e.eadd_p(0, 1).nonzero_positions()[1]
sage: e.eadd_p(0, 2).nonzero_positions()[1]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> e.eadd_p(Integer(5), Integer(1))(1, 5, 2)>>> e = ETuple([Integer(0)]*Integer(7))>>> e.eadd_p(Integer(5), Integer(4))(0, 0, 0, 0, 5, 0, 0)>>> ETuple([Integer(0),Integer(1)]).eadd_p(Integer(1), Integer(0)) ==␣
˓→ETuple([Integer(1),Integer(1)])
True>>> e = ETuple([Integer(0), Integer(1), Integer(0)])>>> e.eadd_p(Integer(0), Integer(0)).nonzero_positions()[1]>>> e.eadd_p(Integer(0), Integer(1)).nonzero_positions()[1]>>> e.eadd_p(Integer(0), Integer(2)).nonzero_positions()[1]

eadd_scaled(other, scalar)
Vector addition of self with scalar * other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 1, 1])
sage: e.eadd_scaled(f, 3)(1, 3, 5)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.eadd_scaled(f, Integer(3))(1, 3, 5)emax(other)
Vector of maximum of components of self and other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

783

Polynomials, Release 10.4

(continued from previous page)

sage: f = ETuple([0, 1, 1])
sage: e.emax(f)(1, 1, 2)
sage: e = ETuple((1, 2, 3, 4))
sage: f = ETuple((4, 0, 2, 1))
sage: f.emax(e)(4, 2, 3, 4)
sage: e = ETuple((1, -2, -2, 4))
sage: f = ETuple((4, 0, 0, 0))
sage: f.emax(e)(4, 0, 0, 4)
sage: f.emax(e).nonzero_positions()[0, 3]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.emax(f)(1, 1, 2)>>> e = ETuple((Integer(1), Integer(2), Integer(3), Integer(4)))>>> f = ETuple((Integer(4), Integer(0), Integer(2), Integer(1)))>>> f.emax(e)(4, 2, 3, 4)>>> e = ETuple((Integer(1), -Integer(2), -Integer(2), Integer(4)))>>> f = ETuple((Integer(4), Integer(0), Integer(0), Integer(0)))>>> f.emax(e)(4, 0, 0, 4)>>> f.emax(e).nonzero_positions()[0, 3]emin(other)
Vector of minimum of components of self and other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 1, 1])
sage: e.emin(f)(0, 0, 1)
sage: e = ETuple([1, 0, -1])
sage: f = ETuple([0, -2, 1])
sage: e.emin(f)(0, -2, -1)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.emin(f)(0, 0, 1)>>> e = ETuple([Integer(1), Integer(0), -Integer(1)])>>> f = ETuple([Integer(0), -Integer(2), Integer(1)])>>> e.emin(f)(0, -2, -1)

784

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

emul(factor)
Scalar Vector multiplication of self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: e.emul(2)(2, 0, 4)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> e.emul(Integer(2))(2, 0, 4)escalar_div(n)Divide each exponent by n.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: ETuple([1, 0, 2]).escalar_div(2)(0, 0, 1)
sage: ETuple([0, 3, 12]).escalar_div(3)(0, 1, 4)
sage: ETuple([1, 5, 2]).escalar_div(0)Traceback (most recent call last):...
ZeroDivisionError>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> ETuple([Integer(1), Integer(0), Integer(2)]).escalar_div(Integer(2))(0, 0, 1)>>> ETuple([Integer(0), Integer(3), Integer(12)]).escalar_div(Integer(3))(0, 1, 4)>>> ETuple([Integer(1), Integer(5), Integer(2)]).escalar_div(Integer(0))
Traceback (most recent call last):...
ZeroDivisionErroresub(other)
Vector subtraction of self with other.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: f = ETuple([0, 1, 1])
sage: e.esub(f)(1, -1, 1)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

785

Polynomials, Release 10.4

(continued from previous page)>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> f = ETuple([Integer(0), Integer(1), Integer(1)])>>> e.esub(f)(1, -1, 1)

is_constant()
Return if all exponents are zero in the tuple.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: e.is_constant()
False
sage: e = ETuple([0, 0])
sage: e.is_constant()
True>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> e.is_constant()
False>>> e = ETuple([Integer(0), Integer(0)])>>> e.is_constant()True

is_multiple_of(n)Test whether each entry is a multiple of n.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: ETuple([0, 0]).is_multiple_of(3)True
sage: ETuple([0, 3, 12, 0, 6]).is_multiple_of(3)True
sage: ETuple([0, 0, 2]).is_multiple_of(3)False>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> ETuple([Integer(0), Integer(0)]).is_multiple_of(Integer(3))
True>>> ETuple([Integer(0), Integer(3), Integer(12), Integer(0), Integer(6)]).is_˓→multiple_of(Integer(3))
True>>> ETuple([Integer(0), Integer(0), Integer(2)]).is_multiple_of(Integer(3))
False

nonzero_positions(sort=False)
Return the positions of non-zero exponents in the tuple.
INPUT:

786

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• sort – (default: False) if True a sorted list is returned; if False an unsorted list is returned
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2])
sage: e.nonzero_positions()[0, 2]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2)])>>> e.nonzero_positions()[0, 2]

nonzero_values(sort=True)
Return the non-zero values of the tuple.
INPUT:• sort – (default: True) if True the values are sorted by their indices; otherwise the values are returned
unsorted
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([2, 0, 1])
sage: e.nonzero_values()[2, 1]
sage: f = ETuple([0, -1, 1])
sage: f.nonzero_values(sort=True)[-1, 1]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(2), Integer(0), Integer(1)])>>> e.nonzero_values()[2, 1]>>> f = ETuple([Integer(0), -Integer(1), Integer(1)])>>> f.nonzero_values(sort=True)[-1, 1]

reversed()
Return the reversed ETuple of self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 2, 3])
sage: e.reversed()(3, 2, 1)>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(2), Integer(3)])>>> e.reversed()(3, 2, 1)

3.1. Multivariate Polynomials and Polynomial Rings

787

Polynomials, Release 10.4

sparse_iter()
Iterator over the elements of self where the elements are returned as (i, e) where i is the position of ein the tuple.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 0, 2, 0, 3])
sage: list(e.sparse_iter())[(0, 1), (2, 2), (4, 3)]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(0), Integer(2), Integer(0), Integer(3)])>>> list(e.sparse_iter())[(0, 1), (2, 2), (4, 3)]

unweighted_degree()Return the sum of entries.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: ETuple([1, 1, 0, 2, 0]).unweighted_degree()4
sage: ETuple([-1, 1]).unweighted_degree()0>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> ETuple([Integer(1), Integer(1), Integer(0), Integer(2), Integer(0)]).
˓→unweighted_degree()4>>> ETuple([-Integer(1), Integer(1)]).unweighted_degree()0

unweighted_quotient_degree(other)
Return the degree of self divided by its gcd with other.
It amounts to counting the non-negative entries of self.esub(other).
weighted_degree(w)Return the weighted sum of entries.
INPUT:• w – tuple of non-negative integers
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple
sage: e = ETuple([1, 1, 0, 2, 0])
sage: e.weighted_degree((1, 2, 3, 4, 5))11
sage: ETuple([-1, 1]).weighted_degree((1, 2))1
sage: ETuple([1, 0]).weighted_degree((1, 2, 3))(continues on next page)

788

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Traceback (most recent call last):...
ValueError: w must be of the same length as the ETuple>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple>>> e = ETuple([Integer(1), Integer(1), Integer(0), Integer(2), Integer(0)])>>> e.weighted_degree((Integer(1), Integer(2), Integer(3), Integer(4),␣
˓→Integer(5)))
11>>> ETuple([-Integer(1), Integer(1)]).weighted_degree((Integer(1),␣
˓→Integer(2)))
1>>> ETuple([Integer(1), Integer(0)]).weighted_degree((Integer(1), Integer(2),␣
˓→Integer(3)))
Traceback (most recent call last):...
ValueError: w must be of the same length as the ETuple

weighted_quotient_degree(other, w)
Return the weighted degree of self divided by its gcd with other.
INPUT:• other – an ETuple• w – tuple of non-negative integers.
class sage.rings.polynomial.polydict.PolyDict
Bases: object
Data structure for multivariate polynomials.
A PolyDict holds a dictionary all of whose keys are ETuple and whose values are coefficients on which it is
implicitely assumed that arithmetic operations can be performed.
No arithmetic operation on PolyDict clear zero coefficients as of now there is no reliable way of testing it in themost general setting, see Issue #35319. For removing zero coefficients from a PolyDict you can use the method
remove_zeros() which can be parametrized by a zero test.
apply_map(f)Apply the map f on the coefficients (inplace).
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(1, 0): 1, (1, 1): -2})
sage: f.apply_map(lambda x: x^2)
sage: fPolyDict with representation {(1, 0): 1, (1, 1): 4}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(1), Integer(0)): Integer(1), (Integer(1),␣
˓→Integer(1)): -Integer(2)})>>> f.apply_map(lambda x: x**Integer(2))(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

789

Polynomials, Release 10.4

(continued from previous page)>>> f
PolyDict with representation {(1, 0): 1, (1, 1): 4}

coefficient(mon)Return a polydict that defines a polynomial in 1 less number of variables that gives the coefficient of mon inthis polynomial.
The coefficient is defined as follows. If f is this polynomial, then the coefficient is the sum T/mon where thesum is over terms T in f that are exactly divisible by mon.
coefficients()
Return the coefficients of self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: sorted(f.coefficients())[2, 3, 4]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> sorted(f.coefficients())[2, 3, 4]

coerce_coefficients(A)Coerce the coefficients in the parent A
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 0})sage: fPolyDict with representation {(2, 3): 0}
sage: f.coerce_coefficients(QQ)
doctest:warning...
DeprecationWarning: coerce_cefficients is deprecated; use apply_map instead
See https://github.com/sagemath/sage/issues/34000 for details.
sage: fPolyDict with representation {(2, 3): 0}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(0)})>>> fPolyDict with representation {(2, 3): 0}>>> f.coerce_coefficients(QQ)
doctest:warning...
DeprecationWarning: coerce_cefficients is deprecated; use apply_map instead
See https://github.com/sagemath/sage/issues/34000 for details.
>>> f
PolyDict with representation {(2, 3): 0}790

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

degree(x=None)
Return the total degree or the maximum degree in the variable x.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.degree()5
sage: f.degree(PolyDict({(1, 0): 1}))2
sage: f.degree(PolyDict({(0, 1): 1}))
3>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.degree()5>>> f.degree(PolyDict({(Integer(1), Integer(0)): Integer(1)}))
2>>> f.degree(PolyDict({(Integer(0), Integer(1)): Integer(1)}))
3

derivative(x)Return the derivative of self with respect to x
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.derivative(PolyDict({(1, 0): 1}))
PolyDict with representation {(0, 2): 3, (1, 1): 8, (1, 3): 4}
sage: f.derivative(PolyDict({(0, 1): 1}))
PolyDict with representation {(1, 1): 6, (2, 0): 4, (2, 2): 6}
sage: PolyDict({(-1,): 1}).derivative(PolyDict({(1,): 1}))
PolyDict with representation {(-2,): -1}
sage: PolyDict({(-2,): 1}).derivative(PolyDict({(1,): 1}))
PolyDict with representation {(-3,): -2}
sage: PolyDict({}).derivative(PolyDict({(1, 1): 1}))
Traceback (most recent call last):...
ValueError: x must be a generator>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.derivative(PolyDict({(Integer(1), Integer(0)): Integer(1)}))
PolyDict with representation {(0, 2): 3, (1, 1): 8, (1, 3): 4}>>> f.derivative(PolyDict({(Integer(0), Integer(1)): Integer(1)}))
PolyDict with representation {(1, 1): 6, (2, 0): 4, (2, 2): 6}>>> PolyDict({(-Integer(1),): Integer(1)}).derivative(PolyDict({(Integer(1),(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

791

Polynomials, Release 10.4

(continued from previous page)): Integer(1)}))
PolyDict with representation {(-2,): -1}>>> PolyDict({(-Integer(2),): Integer(1)}).derivative(PolyDict({(Integer(1),˓→): Integer(1)}))
PolyDict with representation {(-3,): -2}
˓→>>> PolyDict({}).derivative(PolyDict({(Integer(1), Integer(1)): Integer(1)}))
Traceback (most recent call last):...
ValueError: x must be a generator

derivative_i(i)Return the derivative of self with respect to the i-th variable.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: PolyDict({(1, 1): 1}).derivative_i(0)PolyDict with representation {(0, 1): 1}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> PolyDict({(Integer(1), Integer(1)): Integer(1)}).derivative_i(Integer(0))
PolyDict with representation {(0, 1): 1}

dict()
Return a copy of the dict that defines self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.dict(){(1, 2): 3, (2, 1): 4, (2, 3): 2}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.dict(){(1, 2): 3, (2, 1): 4, (2, 3): 2}

exponents()
Return the exponents of self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: sorted(f.exponents())[(1, 2), (2, 1), (2, 3)]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
(continues on next page)

792

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> sorted(f.exponents())[(1, 2), (2, 1), (2, 3)]˓→get(e, default=None)
Return the coefficient of the ETuple e if present and default otherwise.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict, ETuple
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.get(ETuple([1,2]))3
sage: f.get(ETuple([1,1]), hello )hello>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict, ETuple>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.get(ETuple([Integer(1),Integer(2)]))
3>>> f.get(ETuple([Integer(1),Integer(1)]), hello )hellohomogenize(var)
Return the homogeneization of self by increasing the degree of the variable var.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(0, 0): 1, (2, 1): 3, (1, 1): 5})sage: f.homogenize(0)PolyDict with representation {(2, 1): 8, (3, 0): 1}
sage: f.homogenize(1)PolyDict with representation {(0, 3): 1, (1, 2): 5, (2, 1): 3}
sage: PolyDict({(0, 1): 1, (1, 1): -1}).homogenize(0)PolyDict with representation {(1, 1): 0}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(0), Integer(0)): Integer(1), (Integer(2),␣
˓→Integer(1)): Integer(3), (Integer(1), Integer(1)): Integer(5)})>>> f.homogenize(Integer(0))
PolyDict with representation {(2, 1): 8, (3, 0): 1}>>> f.homogenize(Integer(1))
PolyDict with representation {(0, 3): 1, (1, 2): 5, (2, 1): 3}>>> PolyDict({(Integer(0), Integer(1)): Integer(1), (Integer(1), Integer(1)):␣
˓→-Integer(1)}).homogenize(Integer(0))
PolyDict with representation {(1, 1): 0}

integral(x)Return the integral of self with respect to x
EXAMPLES:
3.1. Multivariate Polynomials and Polynomial Rings

793

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.integral(PolyDict({(1, 0): 1}))
PolyDict with representation {(2, 2): 3/2, (3, 1): 4/3, (3, 3): 2/3}
sage: f.integral(PolyDict({(0, 1): 1}))
PolyDict with representation {(1, 3): 1, (2, 2): 2, (2, 4): 1/2}
sage: PolyDict({(-1,): 1}).integral(PolyDict({(1,): 1}))
Traceback (most recent call last):...
ArithmeticError: integral of monomial with exponent -1
sage: PolyDict({(-2,): 1}).integral(PolyDict({(1,): 1}))
PolyDict with representation {(-1,): -1}
sage: PolyDict({}).integral(PolyDict({(1, 1): 1}))
Traceback (most recent call last):...
ValueError: x must be a generator>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.integral(PolyDict({(Integer(1), Integer(0)): Integer(1)}))
PolyDict with representation {(2, 2): 3/2, (3, 1): 4/3, (3, 3): 2/3}>>> f.integral(PolyDict({(Integer(0), Integer(1)): Integer(1)}))
PolyDict with representation {(1, 3): 1, (2, 2): 2, (2, 4): 1/2}>>> PolyDict({(-Integer(1),): Integer(1)}).integral(PolyDict({(Integer(1),):␣
˓→Integer(1)}))
Traceback (most recent call last):...
ArithmeticError: integral of monomial with exponent -1>>> PolyDict({(-Integer(2),): Integer(1)}).integral(PolyDict({(Integer(1),):␣
˓→Integer(1)}))
PolyDict with representation {(-1,): -1}>>> PolyDict({}).integral(PolyDict({(Integer(1), Integer(1)): Integer(1)}))
Traceback (most recent call last):...
ValueError: x must be a generator

integral_i(i)Return the derivative of self with respect to the i-th variable.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: PolyDict({(1, 1): 1}).integral_i(0)PolyDict with representation {(2, 1): 1/2}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> PolyDict({(Integer(1), Integer(1)): Integer(1)}).integral_i(Integer(0))
PolyDict with representation {(2, 1): 1/2}

is_constant()
Return whether this polynomial is constant.
EXAMPLES:
794

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.is_constant()
False
sage: g = PolyDict({(0, 0): 2})sage: g.is_constant()
True
sage: h = PolyDict({})
sage: h.is_constant()
True>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.is_constant()
False>>> g = PolyDict({(Integer(0), Integer(0)): Integer(2)})>>> g.is_constant()
True>>> h = PolyDict({})>>> h.is_constant()
True

is_homogeneous()
Return whether this polynomial is homogeneous.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: PolyDict({}).is_homogeneous()
True
sage: PolyDict({(1, 2): 1, (0, 3): -2}).is_homogeneous()
True
sage: PolyDict({(1, 0): 1, (1, 2): 3}).is_homogeneous()
False>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> PolyDict({}).is_homogeneous()
True>>> PolyDict({(Integer(1), Integer(2)): Integer(1), (Integer(0), Integer(3)):␣
˓→-Integer(2)}).is_homogeneous()
True>>> PolyDict({(Integer(1), Integer(0)): Integer(1), (Integer(1), Integer(2)):␣
˓→Integer(3)}).is_homogeneous()
False

latex(vars, atomic_exponents=True, atomic_coefficients=True, sortkey=None)
Return a nice polynomial latex representation of this PolyDict, where the vars are substituted in.
INPUT:• vars – list
• atomic_exponents – bool (default: True)• atomic_coefficients – bool (default: True)

3.1. Multivariate Polynomials and Polynomial Rings

795

Polynomials, Release 10.4

EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.latex([ a , WW ])2 a^{2} WW^{3} + 4 a^{2} WW + 3 a WW^{2}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.latex([ a , WW ])2 a^{2} WW^{3} + 4 a^{2} WW + 3 a WW^{2}

lcmt(greater_etuple)
Provides functionality of lc, lm, and lt by calling the tuple compare function on the provided term order T.
INPUT:• greater_etuple – a term orderlist()
Return a list that defines self.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: sorted(f.list())[[2, [2, 3]], [3, [1, 2]], [4, [2, 1]]]>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> sorted(f.list())[[2, [2, 3]], [3, [1, 2]], [4, [2, 1]]]

max_exp()
Returns an ETuple containing the maximum exponents appearing. If there are no terms at all in the PolyDict,
it returns None.
The nvars parameter is necessary because a PolyDict doesn’t know it from the data it has (and an empty
PolyDict offers no clues).
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.max_exp()(2, 3)
sage: PolyDict({}).max_exp() # returns None>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.max_exp()(continues on next page)

796

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)(2, 3)>>> PolyDict({}).max_exp() # returns Nonemin_exp()
Returns an ETuple containing the minimum exponents appearing. If there are no terms at all in the PolyDict,
it returns None.
The nvars parameter is necessary because a PolyDict doesn’t know it from the data it has (and an empty
PolyDict offers no clues).
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.min_exp()(1, 1)
sage: PolyDict({}).min_exp() # returns None>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.min_exp()(1, 1)>>> PolyDict({}).min_exp() # returns Nonemonomial_coefficient(mon)Return the coefficient of the monomial mon.
INPUT:• mon – a PolyDict with a single key
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
sage: f.monomial_coefficient(PolyDict({(2,1):1}).dict())
doctest:warning...
DeprecationWarning: PolyDict.monomial_coefficient is deprecated; use PolyDict.
˓→get instead
See https://github.com/sagemath/sage/issues/34000 for details.
4>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2),Integer(3)):Integer(2), (Integer(1),˓→Integer(2)):Integer(3), (Integer(2),Integer(1)):Integer(4)})>>> f.monomial_coefficient(PolyDict({(Integer(2),Integer(1)):Integer(1)}).
˓→dict())
doctest:warning...
DeprecationWarning: PolyDict.monomial_coefficient is deprecated; use PolyDict.
˓→get instead
See https://github.com/sagemath/sage/issues/34000 for details.
4

3.1. Multivariate Polynomials and Polynomial Rings

797

Polynomials, Release 10.4

poly_repr(vars, atomic_exponents=True, atomic_coefficients=True, sortkey=None)
Return a nice polynomial string representation of this PolyDict, where the vars are substituted in.
INPUT:• vars – list
• atomic_exponents – bool (default: True)• atomic_coefficients – bool (default: True)
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
sage: f.poly_repr([ a , WW ])2*a^2*WW^3 + 4*a^2*WW + 3*a*WW^2>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2),Integer(3)):Integer(2), (Integer(1),˓→Integer(2)):Integer(3), (Integer(2),Integer(1)):Integer(4)})>>> f.poly_repr([ a , WW ])2*a^2*WW^3 + 4*a^2*WW + 3*a*WW^2

We check to make sure that when we are in characteristic two, we don’t put negative signs on the generators.
sage: Integers(2)[ x, y ].gens()(x, y)>>> from sage.all import *>>> Integers(Integer(2))[ x, y ].gens()(x, y)

We make sure that intervals are correctly represented.
sage: f = PolyDict({(2, 3): RIF(1/2,3/2), (1, 2): RIF(-1,1)})
˓→needs sage.rings.real_interval_fieldsage: f.poly_repr([ x , y ])˓→needs sage.rings.real_interval_field
1.?*x^2*y^3 + 0.?*x*y^2>>> from sage.all import *>>> f = PolyDict({(Integer(2), Integer(3)): RIF(Integer(1)/Integer(2),˓→Integer(3)/Integer(2)), (Integer(1), Integer(2)): RIF(-Integer(1),˓→Integer(1))})# needs sage.rings.real_interval_field>>> f.poly_repr([ x , y ])˓→needs sage.rings.real_interval_field
1.?*x^2*y^3 + 0.?*x*y^2

#␣
#␣

#␣

polynomial_coefficient(degrees)
Return a polydict that defines the coefficient in the current polynomial viewed as a tower of polynomial extensions.
INPUT:• degrees – a list of degree restrictions; list elements are None if the variable in that position should beunrestricted
EXAMPLES:
798

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.polynomial_coefficient([2, None])
PolyDict with representation {(0, 1): 4, (0, 3): 2}
sage: f = PolyDict({(0, 3): 2, (0, 2): 3, (2, 1): 4})sage: f.polynomial_coefficient([0, None])
PolyDict with representation {(0, 2): 3, (0, 3): 2}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.polynomial_coefficient([Integer(2), None])
PolyDict with representation {(0, 1): 4, (0, 3): 2}>>> f = PolyDict({(Integer(0), Integer(3)): Integer(2), (Integer(0),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.polynomial_coefficient([Integer(0), None])
PolyDict with representation {(0, 2): 3, (0, 3): 2}

remove_zeros(zero_test=None)
Remove the entries with zero coefficients.
INPUT:• zero_test – optional function that performs test to zero of a coefficient
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3):0})
sage: fPolyDict with representation {(2, 3): 0}
sage: f.remove_zeros()sage: fPolyDict with representation {}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)):Integer(0)})>>> fPolyDict with representation {(2, 3): 0}>>> f.remove_zeros()>>> f
PolyDict with representation {}The following example shows how to remove only exact zeros from a PolyDict containing univariate power
series:sage: R.<t> = PowerSeriesRing(QQ)
sage: f = PolyDict({(1, 1): O(t), (1, 0): R.zero()})
sage: f.remove_zeros(lambda s: s.is_zero() and s.prec() is Infinity)
sage: fPolyDict with representation {(1, 1): O(t^1)}>>> from sage.all import *>>> R = PowerSeriesRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> f = PolyDict({(Integer(1), Integer(1)): O(t), (Integer(1), Integer(0)): R.
(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

799

Polynomials, Release 10.4

(continued from previous page)zero()})>>> f.remove_zeros(lambda s: s.is_zero() and s.prec() is Infinity)>>> f
PolyDict with representation {(1, 1): O(t^1)}
˓→rich_compare(other, op, sortkey=None)
Compare two 𝑃 𝑜𝑙𝑦𝐷𝑖𝑐𝑡`𝑠𝑢𝑠𝑖𝑛𝑔𝑎𝑠𝑝𝑒𝑐𝑖𝑓 𝑖𝑒𝑑𝑡𝑒𝑟𝑚𝑜𝑟𝑑𝑒𝑟𝑖𝑛𝑔``𝑠𝑜𝑟𝑡𝑘𝑒𝑦`.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: from sage.structure.richcmp import op_EQ, op_NE, op_LT
sage: p1 = PolyDict({(0,): 1})sage: p2 = PolyDict({(0,): 2})sage: O = TermOrder()sage: p1.rich_compare(PolyDict({(0,): 1}), op_EQ, O.sortkey)
Truesage: p1.rich_compare(p2, op_EQ, O.sortkey)
False
sage: p1.rich_compare(p2, op_NE, O.sortkey)
Truesage: p1.rich_compare(p2, op_LT, O.sortkey)
Truesage: p3 = PolyDict({(3, 2, 4): 1, (3, 2, 5): 2})sage: p4 = PolyDict({(3, 2, 4): 1, (3, 2, 3): 2})sage: p3.rich_compare(p4, op_LT, O.sortkey)
False>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> from sage.structure.richcmp import op_EQ, op_NE, op_LT>>> p1 = PolyDict({(Integer(0),): Integer(1)})>>> p2 = PolyDict({(Integer(0),): Integer(2)})>>> O = TermOrder()>>> p1.rich_compare(PolyDict({(Integer(0),): Integer(1)}), op_EQ, O.sortkey)
True>>> p1.rich_compare(p2, op_EQ, O.sortkey)
False>>> p1.rich_compare(p2, op_NE, O.sortkey)
True>>> p1.rich_compare(p2, op_LT, O.sortkey)
True>>> p3 = PolyDict({(Integer(3), Integer(2), Integer(4)): Integer(1),␣
˓→(Integer(3), Integer(2), Integer(5)): Integer(2)})>>> p4 = PolyDict({(Integer(3), Integer(2), Integer(4)): Integer(1),␣
˓→(Integer(3), Integer(2), Integer(3)): Integer(2)})>>> p3.rich_compare(p4, op_LT, O.sortkey)
False

scalar_lmult(s)Return the left scalar multiplication of self by s.
EXAMPLES:

800

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: from sage.rings.polynomial.polydict import PolyDict
sage: x, y = FreeMonoid(2, x, y ).gens() # a strange object to live in a␣˓→polydict, but non-commutative!
# needs sage.combinat
sage: f = PolyDict({(2,3):x})#␣
˓→needs sage.combinat
sage: f.scalar_lmult(y)#␣˓→needs sage.combinat
PolyDict with representation {(2, 3): y*x}
sage: f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
sage: f.scalar_lmult(-2)
PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4}
sage: f.scalar_lmult(RIF(-1,1))
˓→needs sage.rings.real_interval_field
PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1}#␣>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> x, y = FreeMonoid(Integer(2), x, y ).gens() # a strange object to live␣˓→in a polydict, but non-commutative!
# needs sage.combinat>>> f = PolyDict({(Integer(2),Integer(3)):x})␣˓→# needs sage.combinat>>> f.scalar_lmult(y)#␣˓→needs sage.combinat
PolyDict with representation {(2, 3): y*x}>>> f = PolyDict({(Integer(2),Integer(3)):Integer(2), (Integer(1),˓→Integer(2)):Integer(3), (Integer(2),Integer(1)):Integer(4)})>>> f.scalar_lmult(-Integer(2))
PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4}>>> f.scalar_lmult(RIF(-Integer(1),Integer(1)))˓→# needs sage.rings.real_interval_field
PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1}␣scalar_rmult(s)Return the right scalar multiplication of self by s.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: x, y = FreeMonoid(2, x, y ).gens() # a strange object to live in a␣˓→polydict, but non-commutative!
# needs sage.combinat
sage: f = PolyDict({(2, 3): x})#␣˓→needs sage.combinat
sage: f.scalar_rmult(y)#␣˓→needs sage.combinat
PolyDict with representation {(2, 3): x*y}
sage: f = PolyDict({(2,3):2, (1, 2): 3, (2, 1): 4})sage: f.scalar_rmult(-2)
PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4}
sage: f.scalar_rmult(RIF(-1,1))
˓→needs sage.rings.real_interval_field
PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1}

3.1. Multivariate Polynomials and Polynomial Rings

#␣

801

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> x, y = FreeMonoid(Integer(2), x, y ).gens() # a strange object to live␣˓→in a polydict, but non-commutative!
# needs sage.combinat>>> f = PolyDict({(Integer(2), Integer(3)): x})␣˓→# needs sage.combinat>>> f.scalar_rmult(y)#␣˓→needs sage.combinat
PolyDict with representation {(2, 3): x*y}>>> f = PolyDict({(Integer(2),Integer(3)):Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.scalar_rmult(-Integer(2))
PolyDict with representation {(1, 2): -6, (2, 1): -8, (2, 3): -4}>>> f.scalar_rmult(RIF(-Integer(1),Integer(1)))˓→# needs sage.rings.real_interval_field
PolyDict with representation {(1, 2): 0.?e1, (2, 1): 0.?e1, (2, 3): 0.?e1}␣

term_lmult(exponent, s)
Return this element multiplied by s on the left and with exponents shifted by exponent.
INPUT:• exponent – a ETuple• s – a scalar
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple, PolyDict
sage: x, y = FreeMonoid(2, x, y ).gens() # a strange object to live in a␣˓→polydict, but non-commutative!
# needs sage.combinat
sage: f = PolyDict({(2, 3): x})#␣˓→needs sage.combinat
sage: f.term_lmult(ETuple((1, 2)), y)#␣˓→needs sage.combinat
PolyDict with representation {(3, 5): y*x}
sage: f = PolyDict({(2,3): 2, (1,2): 3, (2,1): 4})sage: f.term_lmult(ETuple((1, 2)), -2)
PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple, PolyDict>>> x, y = FreeMonoid(Integer(2), x, y ).gens() # a strange object to live␣˓→in a polydict, but non-commutative!
# needs sage.combinat>>> f = PolyDict({(Integer(2), Integer(3)): x})␣˓→# needs sage.combinat>>> f.term_lmult(ETuple((Integer(1), Integer(2))), y)␣˓→# needs sage.combinat
PolyDict with representation {(3, 5): y*x}>>> f = PolyDict({(Integer(2),Integer(3)): Integer(2), (Integer(1),˓→Integer(2)): Integer(3), (Integer(2),Integer(1)): Integer(4)})>>> f.term_lmult(ETuple((Integer(1), Integer(2))), -Integer(2))(continues on next page)802

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4}

term_rmult(exponent, s)
Return this element multiplied by s on the right and with exponents shifted by exponent.
INPUT:• exponent – a ETuple• s – a scalar
EXAMPLES:
sage: from sage.rings.polynomial.polydict import ETuple, PolyDict
sage: x, y = FreeMonoid(2, x, y ).gens() # a strange object to live in a␣˓→polydict, but non-commutative!
# needs sage.combinat
sage: f = PolyDict({(2, 3): x})#␣˓→needs sage.combinat
sage: f.term_rmult(ETuple((1, 2)), y)#␣˓→needs sage.combinat
PolyDict with representation {(3, 5): x*y}
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.term_rmult(ETuple((1, 2)), -2)
PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4}>>> from sage.all import *>>> from sage.rings.polynomial.polydict import ETuple, PolyDict>>> x, y = FreeMonoid(Integer(2), x, y ).gens() # a strange object to live␣˓→in a polydict, but non-commutative!
# needs sage.combinat>>> f = PolyDict({(Integer(2), Integer(3)): x})␣˓→# needs sage.combinat>>> f.term_rmult(ETuple((Integer(1), Integer(2))), y)␣˓→# needs sage.combinat
PolyDict with representation {(3, 5): x*y}>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.term_rmult(ETuple((Integer(1), Integer(2))), -Integer(2))
PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4}

total_degree(w=None)
Return the total degree.
INPUT:• w – (optional) a tuple of weights
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict
sage: f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})sage: f.total_degree()5
sage: f.total_degree((3, 1))
9(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

803

Polynomials, Release 10.4

(continued from previous page)

sage: PolyDict({}).degree()-1>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict>>> f = PolyDict({(Integer(2), Integer(3)): Integer(2), (Integer(1),␣
˓→Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})>>> f.total_degree()5>>> f.total_degree((Integer(3), Integer(1)))
9>>> PolyDict({}).degree()-1

sage.rings.polynomial.polydict.gen_index(x)Return the index of the variable represented by x or -1 if x is not a monomial of degree one.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict, gen_index
sage: gen_index(PolyDict({(1, 0): 1}))0
sage: gen_index(PolyDict({(0, 1): 1}))1
sage: gen_index(PolyDict({}))-1>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict, gen_index>>> gen_index(PolyDict({(Integer(1), Integer(0)): Integer(1)}))0>>> gen_index(PolyDict({(Integer(0), Integer(1)): Integer(1)}))
1>>> gen_index(PolyDict({}))-1sage.rings.polynomial.polydict.make_ETuple(data, length)
Ensure support for pickled data from older sage versions.
sage.rings.polynomial.polydict.make_PolyDict(data)
Ensure support for pickled data from older sage versions.
sage.rings.polynomial.polydict.monomial_exponent(p)Return the unique exponent of p if it is a monomial or raise a ValueError.
EXAMPLES:
sage: from sage.rings.polynomial.polydict import PolyDict, monomial_exponent
sage: monomial_exponent(PolyDict({(2, 3): 1}))(2, 3)
sage: monomial_exponent(PolyDict({(2, 3): 3}))
Traceback (most recent call last):...
ValueError: not a monomial
sage: monomial_exponent(PolyDict({(1, 0): 1, (0, 1): 1}))
Traceback (most recent call last):(continues on next page)

804

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)...
ValueError: not a monomial>>> from sage.all import *>>> from sage.rings.polynomial.polydict import PolyDict, monomial_exponent>>> monomial_exponent(PolyDict({(Integer(2), Integer(3)): Integer(1)}))(2, 3)>>> monomial_exponent(PolyDict({(Integer(2), Integer(3)): Integer(3)}))
Traceback (most recent call last):...
ValueError: not a monomial>>> monomial_exponent(PolyDict({(Integer(1), Integer(0)): Integer(1), (Integer(0),˓→ Integer(1)): Integer(1)}))
Traceback (most recent call last):...
ValueError: not a monomial

3.1.12 Compute Hilbert series of monomial ideals
This implementation was provided at Issue #26243 and is supposed to be a way out when Singular fails with an int
overflow, which will regularly be the case in any example with more than 34 variables.
class sage.rings.polynomial.hilbert.Node
Bases: object
A node of a binary tree
It has slots for data that allow to recursively compute the first Hilbert series of a monomial ideal.
sage.rings.polynomial.hilbert.first_hilbert_series(I, grading=None, return_grading=False)
Return the first Hilbert series of the given monomial ideal.
INPUT:• I – a monomial ideal (possibly defined in singular)• grading – (optional) a list or tuple of integers used as degree weights• return_grading – (default: False) whether to return the grading
OUTPUT:
A univariate polynomial, namely the first Hilbert function of I, and if return_grading==True also thegrading used to compute the series.
EXAMPLES:
sage: from sage.rings.polynomial.hilbert import first_hilbert_series
sage: # needs sage.libs.singularsage: R = singular.ring(0, (x,y,z) , dp )sage: I = singular.ideal([ x^2 , y^2 , z^2 ])sage: first_hilbert_series(I)-t^6 + 3*t^4 - 3*t^2 + 1
sage: first_hilbert_series(I, return_grading=True)(-t^6 + 3*t^4 - 3*t^2 + 1, (1, 1, 1))
sage: first_hilbert_series(I, grading=(1,2,3))-t^12 + t^10 + t^8 - t^4 - t^2 + 1

3.1. Multivariate Polynomials and Polynomial Rings

805

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.polynomial.hilbert import first_hilbert_series>>> # needs sage.libs.singular>>> R = singular.ring(Integer(0), (x,y,z) , dp )>>> I = singular.ideal([ x^2 , y^2 , z^2 ])>>> first_hilbert_series(I)-t^6 + 3*t^4 - 3*t^2 + 1>>> first_hilbert_series(I, return_grading=True)(-t^6 + 3*t^4 - 3*t^2 + 1, (1, 1, 1))>>> first_hilbert_series(I, grading=(Integer(1),Integer(2),Integer(3)))-t^12 + t^10 + t^8 - t^4 - t^2 + 1

sage.rings.polynomial.hilbert.hilbert_poincare_series(I, grading=None)
Return the Hilbert Poincaré series of the given monomial ideal.
INPUT:• I – a monomial ideal (possibly defined in Singular)• grading – (optional) a tuple of degree weights
EXAMPLES:
sage: # needs sage.libs.singularsage: from sage.rings.polynomial.hilbert import hilbert_poincare_series
sage: R = PolynomialRing(QQ, x ,9)
sage: I = [m.lm()....:
for m in ((matrix(R, 3, R.gens())^2).list() * R).groebner_basis()] * R
sage: hilbert_poincare_series(I)(t^7 - 3*t^6 + 2*t^5 + 2*t^4 - 2*t^3 + 6*t^2 + 5*t + 1)/(t^4 - 4*t^3 + 6*t^2 -␣
˓→4*t + 1)
sage: hilbert_poincare_series((R * R.gens())^2, grading=range(1,10))t^9 + t^8 + t^7 + t^6 + t^5 + t^4 + t^3 + t^2 + t + 1>>> from sage.all import *>>> # needs sage.libs.singular>>> from sage.rings.polynomial.hilbert import hilbert_poincare_series>>> R = PolynomialRing(QQ, x ,Integer(9))>>> I = [m.lm()...
for m in ((matrix(R, Integer(3), R.gens())**Integer(2)).list() * R).
˓→groebner_basis()] * R>>> hilbert_poincare_series(I)(t^7 - 3*t^6 + 2*t^5 + 2*t^4 - 2*t^3 + 6*t^2 + 5*t + 1)/(t^4 - 4*t^3 + 6*t^2 -␣
˓→4*t + 1)>>> hilbert_poincare_series((R * R.gens())**Integer(2), grading=range(Integer(1),˓→Integer(10)))t^9 + t^8 + t^7 + t^6 + t^5 + t^4 + t^3 + t^2 + t + 1

The following example is taken from Issue #20145:
sage: # needs sage.libs.singularsage: n=4; m=11; P = PolynomialRing(QQ, n*m, "x"); x = P.gens(); M = Matrix(n, x)
sage: from sage.rings.polynomial.hilbert import first_hilbert_series
sage: I = P.ideal(M.minors(2))
sage: J = P * [m.lm() for m in I.groebner_basis()]sage: hilbert_poincare_series(J).numerator()
120*t^3 + 135*t^2 + 30*t + 1(continues on next page)

806

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: hilbert_poincare_series(J).denominator().factor()(t - 1)^14>>> from sage.all import *>>> # needs sage.libs.singular>>> n=Integer(4); m=Integer(11); P = PolynomialRing(QQ, n*m, "x"); x = P.gens();␣
˓→M = Matrix(n, x)>>> from sage.rings.polynomial.hilbert import first_hilbert_series>>> I = P.ideal(M.minors(Integer(2)))>>> J = P * [m.lm() for m in I.groebner_basis()]>>> hilbert_poincare_series(J).numerator()
120*t^3 + 135*t^2 + 30*t + 1>>> hilbert_poincare_series(J).denominator().factor()(t - 1)^14

3.1.13 Class to flatten polynomial rings over polynomial ring
For example QQ[ a , b ],[ x , y ] flattens to QQ[ a , b , x , y ].
EXAMPLES:
sage: R = QQ[ x ][ y ][ s , t ][ X ]sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: phi = FlatteningMorphism(R); phi
Flattening morphism:
From: Univariate Polynomial Ring in X
over Multivariate Polynomial Ring in s, tover Univariate Polynomial Ring in yover Univariate Polynomial Ring in x over Rational Field
To:
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
sage: phi( x*y*s + t*X ).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field>>> from sage.all import *>>> R = QQ[ x ][ y ][ s , t ][ X ]>>> from sage.rings.polynomial.flatten import FlatteningMorphism>>> phi = FlatteningMorphism(R); phi
Flattening morphism:
From: Univariate Polynomial Ring in X
over Multivariate Polynomial Ring in s, tover Univariate Polynomial Ring in yover Univariate Polynomial Ring in x over Rational Field
To:
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field>>> phi( x*y*s + t*X ).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field

Authors:
Vincent Delecroix, Ben Hutz (July 2016): initial implementation
class sage.rings.polynomial.flatten.FlatteningMorphism(domain)
Bases: Morphism
EXAMPLES:

3.1. Multivariate Polynomials and Polynomial Rings

807

Polynomials, Release 10.4

sage: R = QQ[ a , b ][ x , y , z ][ t1 , t2 ]sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: f = FlatteningMorphism(R)sage: f.codomain()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field
sage: p = R( (a+b)*x + (a^2-b)*t2*(z+y) )sage: p((a^2 - b)*y + (a^2 - b)*z)*t2 + (a + b)*x
sage: f(p)a^2*y*t2 + a^2*z*t2 - b*y*t2 - b*z*t2 + a*x + b*x
sage: f(p).parent()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field>>> from sage.all import *>>> R = QQ[ a , b ][ x , y , z ][ t1 , t2 ]>>> from sage.rings.polynomial.flatten import FlatteningMorphism>>> f = FlatteningMorphism(R)>>> f.codomain()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field>>> p = R( (a+b)*x + (a^2-b)*t2*(z+y) )>>> p((a^2 - b)*y + (a^2 - b)*z)*t2 + (a + b)*x>>> f(p)a^2*y*t2 + a^2*z*t2 - b*y*t2 - b*z*t2 + a*x + b*x>>> f(p).parent()
Multivariate Polynomial Ring in a, b, x, y, z, t1, t2 over Rational Field

Also works when univariate polynomial ring are involved:
sage: R = QQ[ x ][ y ][ s , t ][ X ]sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: f = FlatteningMorphism(R)sage: f.codomain()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field
sage: p = R( ((x^2 + 1) + (x+2)*y + x*y^3)*(s+t) + x*y*X )sage: px*y*X + (x*y^3 + (x + 2)*y + x^2 + 1)*s + (x*y^3 + (x + 2)*y + x^2 + 1)*t
sage: f(p)x*y^3*s + x*y^3*t + x^2*s + x*y*s + x^2*t + x*y*t + x*y*X + 2*y*s + 2*y*t + s + t
sage: f(p).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field>>> from sage.all import *>>> R = QQ[ x ][ y ][ s , t ][ X ]>>> from sage.rings.polynomial.flatten import FlatteningMorphism>>> f = FlatteningMorphism(R)>>> f.codomain()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field>>> p = R( ((x^2 + 1) + (x+2)*y + x*y^3)*(s+t) + x*y*X )>>> p
x*y*X + (x*y^3 + (x + 2)*y + x^2 + 1)*s + (x*y^3 + (x + 2)*y + x^2 + 1)*t>>> f(p)x*y^3*s + x*y^3*t + x^2*s + x*y*s + x^2*t + x*y*t + x*y*X + 2*y*s + 2*y*t + s + t>>> f(p).parent()
Multivariate Polynomial Ring in x, y, s, t, X over Rational Field

inverse()808

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

Return the inverse of this flattening morphism.
This is the same as calling section().
EXAMPLES:
sage: f = QQ[ x,y ][ u,v ].flattening_morphism()
sage: f.inverse()
Unflattening morphism:
From: Multivariate Polynomial Ring in x, y, u, v over Rational Field
To:
Multivariate Polynomial Ring in u, v
over Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> f = QQ[ x,y ][ u,v ].flattening_morphism()>>> f.inverse()
Unflattening morphism:
From: Multivariate Polynomial Ring in x, y, u, v over Rational Field
To:
Multivariate Polynomial Ring in u, v
over Multivariate Polynomial Ring in x, y over Rational Field

section()Inverse of this flattening morphism.
EXAMPLES:
sage: R = QQ[ a , b , c ][ x , y , z ]sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: h = FlatteningMorphism(R)sage: h.section()
Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field
To:
Multivariate Polynomial Ring in x, y, z
over Multivariate Polynomial Ring in a, b, c over Rational Field>>> from sage.all import *>>> R = QQ[ a , b , c ][ x , y , z ]>>> from sage.rings.polynomial.flatten import FlatteningMorphism>>> h = FlatteningMorphism(R)>>> h.section()
Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, c, x, y, z over Rational Field
To:
Multivariate Polynomial Ring in x, y, z
over Multivariate Polynomial Ring in a, b, c over Rational Field
sage: R = ZZ[ a ][ b ][ c ]sage: from sage.rings.polynomial.flatten import FlatteningMorphism
sage: FlatteningMorphism(R).section()
Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, c over Integer RingTo:
Univariate Polynomial Ring in c over Univariate Polynomial Ring in b
over Univariate Polynomial Ring in a over Integer Ring>>> from sage.all import *>>> R = ZZ[ a ][ b ][ c ]>>> from sage.rings.polynomial.flatten import FlatteningMorphism>>> FlatteningMorphism(R).section()(continues on next page)

3.1. Multivariate Polynomials and Polynomial Rings

809

Polynomials, Release 10.4

(continued from previous page)

Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, c over Integer RingTo:
Univariate Polynomial Ring in c over Univariate Polynomial Ring in b
over Univariate Polynomial Ring in a over Integer Ringclass sage.rings.polynomial.flatten.FractionSpecializationMorphism(domain, D)
Bases: Morphism
A specialization morphism for fraction fields over (stacked) polynomial rings
class sage.rings.polynomial.flatten.SpecializationMorphism(domain, D)
Bases: Morphism
Morphisms to specialize parameters in (stacked) polynomial rings
EXAMPLES:
sage: R.<c> = PolynomialRing(QQ)
sage: S.<x,y,z> = PolynomialRing(R)sage: D = dict({c:1})
sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: f = SpecializationMorphism(S, D)
sage: g = f(x^2 + c*y^2 - z^2); gx^2 + y^2 - z^2sage: g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( c ,)); (c,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( x , y , z ,)); (x, y, z,) = S._first_ngens(3)>>> D = dict({c:Integer(1)})>>> from sage.rings.polynomial.flatten import SpecializationMorphism>>> f = SpecializationMorphism(S, D)>>> g = f(x**Integer(2) + c*y**Integer(2) - z**Integer(2)); gx^2 + y^2 - z^2>>> g.parent()
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: R.<c> = PolynomialRing(QQ)
sage: S.<z> = PolynomialRing(R)sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: xi = SpecializationMorphism(S, {c:0}); xi
Specialization morphism:
From: Univariate Polynomial Ring in z
over Univariate Polynomial Ring in c over Rational Field
To:
Univariate Polynomial Ring in z over Rational Field
sage: xi(z^2+c)z^2>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( c ,)); (c,) = R._first_ngens(1)>>> S = PolynomialRing(R, names=( z ,)); (z,) = S._first_ngens(1)>>> from sage.rings.polynomial.flatten import SpecializationMorphism>>> xi = SpecializationMorphism(S, {c:Integer(0)}); xi
Specialization morphism:
From: Univariate Polynomial Ring in z
(continues on next page)

810

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

over Univariate Polynomial Ring in c over Rational Field
To:
Univariate Polynomial Ring in z over Rational Field>>> xi(z**Integer(2)+c)z^2
sage: R1.<u,v> = PolynomialRing(QQ)
sage: R2.<a,b,c> = PolynomialRing(R1)sage: S.<x,y,z> = PolynomialRing(R2)sage: D = dict({a:1, b:2, x:0, u:1})
sage: from sage.rings.polynomial.flatten import SpecializationMorphism
sage: xi = SpecializationMorphism(S, D); xi
Specialization morphism:
From: Multivariate Polynomial Ring in x, y, z
over Multivariate Polynomial Ring in a, b, cover Multivariate Polynomial Ring in u, v over Rational Field
To:
Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in cover Univariate Polynomial Ring in v over Rational Field
sage: xi(a*(x*z+y^2)*u+b*v*u*(x*z+y^2)*y^2*c+c*y^2*z^2)
2*v*c*y^4 + c*y^2*z^2 + y^2>>> from sage.all import *>>> R1 = PolynomialRing(QQ, names=( u , v ,)); (u, v,) = R1._first_ngens(2)>>> R2 = PolynomialRing(R1, names=( a , b , c ,)); (a, b, c,) = R2._first_
˓→ngens(3)>>> S = PolynomialRing(R2, names=( x , y , z ,)); (x, y, z,) = S._first_ngens(3)>>> D = dict({a:Integer(1), b:Integer(2), x:Integer(0), u:Integer(1)})>>> from sage.rings.polynomial.flatten import SpecializationMorphism>>> xi = SpecializationMorphism(S, D); xi
Specialization morphism:
From: Multivariate Polynomial Ring in x, y, z
over Multivariate Polynomial Ring in a, b, cover Multivariate Polynomial Ring in u, v over Rational Field
To:
Multivariate Polynomial Ring in y, z over Univariate Polynomial Ring in cover Univariate Polynomial Ring in v over Rational Field>>> xi(a*(x*z+y**Integer(2))*u+b*v*u*(x*z+y**Integer(2))*y**Integer(2)*c+c*y**Integer(2)*z**Integer(2))
2*v*c*y^4 + c*y^2*z^2 + y^2

class sage.rings.polynomial.flatten.UnflatteningMorphism(domain, codomain)
Bases: Morphism
Inverses for FlatteningMorphism
EXAMPLES:
sage: R = QQ[ c , x , y , z ]sage: S = QQ[ c ][ x , y , z ]sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
sage: f = UnflatteningMorphism(R, S)
sage: g = f(R( x^2 + c*y^2 - z^2 ));gx^2 + c*y^2 - z^2sage: g.parent()
Multivariate Polynomial Ring in x, y, z
over Univariate Polynomial Ring in c over Rational Field

3.1. Multivariate Polynomials and Polynomial Rings

811

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ c , x , y , z ]>>> S = QQ[ c ][ x , y , z ]>>> from sage.rings.polynomial.flatten import UnflatteningMorphism>>> f = UnflatteningMorphism(R, S)>>> g = f(R( x^2 + c*y^2 - z^2 ));gx^2 + c*y^2 - z^2>>> g.parent()
Multivariate Polynomial Ring in x, y, z
over Univariate Polynomial Ring in c over Rational Field
sage: R = QQ[ a , b , x , y ]sage: S = QQ[ a , b ][ x , y ]sage: from sage.rings.polynomial.flatten import UnflatteningMorphism
sage: UnflatteningMorphism(R, S)
Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, x, y over Rational Field
To:
Multivariate Polynomial Ring in x, yover Multivariate Polynomial Ring in a, b over Rational Field>>> from sage.all import *>>> R = QQ[ a , b , x , y ]>>> S = QQ[ a , b ][ x , y ]>>> from sage.rings.polynomial.flatten import UnflatteningMorphism>>> UnflatteningMorphism(R, S)
Unflattening morphism:
From: Multivariate Polynomial Ring in a, b, x, y over Rational Field
To:
Multivariate Polynomial Ring in x, yover Multivariate Polynomial Ring in a, b over Rational Field

3.1.14 Monomials
sage.rings.monomials.monomials(v, n)Given two lists v and n, of exactly the same length, return all monomials in the elements of v, where variable i(i.e., v[i]) in the monomial appears to degree strictly less than n[i].
INPUT:• v – list of ring elements• n – list of integers
EXAMPLES:
sage: monomials([x], [3])#␣˓→needs sage.symbolic[1, x, x^2]
sage: R.<x,y,z> = QQ[]
sage: monomials([x,y], [5,5])[1, y, y^2, y^3, y^4, x, x*y, x*y^2, x*y^3, x*y^4, x^2, x^2*y, x^2*y^2, x^2*y^3,␣˓→x^2*y^4, x^3, x^3*y, x^3*y^2, x^3*y^3, x^3*y^4, x^4, x^4*y, x^4*y^2, x^4*y^3, x^
˓→4*y^4]sage: monomials([x,y,z], [2,3,2])[1, z, y, y*z, y^2, y^2*z, x, x*z, x*y, x*y*z, x*y^2, x*y^2*z]

812

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> monomials([x], [Integer(3)])␣˓→# needs sage.symbolic[1, x, x^2]>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> monomials([x,y], [Integer(5),Integer(5)])[1, y, y^2, y^3, y^4, x, x*y, x*y^2, x*y^3, x*y^4, x^2, x^2*y, x^2*y^2, x^2*y^3,␣˓→x^2*y^4, x^3, x^3*y, x^3*y^2, x^3*y^3, x^3*y^4, x^4, x^4*y, x^4*y^2, x^4*y^3, x^
˓→4*y^4]>>> monomials([x,y,z], [Integer(2),Integer(3),Integer(2)])[1, z, y, y*z, y^2, y^2*z, x, x*z, x*y, x*y*z, x*y^2, x*y^2*z]

3.2 Classical Invariant Theory
3.2.1 Classical Invariant Theory
This module lists classical invariants and covariants of homogeneous polynomials (also called algebraic forms) under theaction of the special linear group. That is, we are dealing with polynomials of degree 𝑑 in 𝑛 variables. The special linear
group 𝑆𝐿(𝑛, C) acts on the variables (𝑥1 , . . . , 𝑥𝑛 ) linearly,
𝐴 ∈ 𝑆𝐿(𝑛, C)(𝑥1 , . . . , 𝑥𝑛 )𝑡 → 𝐴(𝑥1 , . . . , 𝑥𝑛 )𝑡 ,The linear action on the variables transforms a polynomial 𝑝 generally into a different polynomial 𝑔𝑝. We can think of it
as an action on the space of coefficients in 𝑝. An invariant is a polynomial in the coefficients that is invariant under thisaction. A covariant is a polynomial in the coefficients and the variables (𝑥1 , . . . , 𝑥𝑛 ) that is invariant under the combined
action.
For example, the binary quadratic 𝑝(𝑥, 𝑦) = 𝑎𝑥2 + 𝑏𝑥𝑦 + 𝑐𝑦 2 has as its invariant the discriminant 𝑑𝑖𝑠𝑐(𝑝) = 𝑏2 − 4𝑎𝑐.
This means that for any 𝑆𝐿(2, C) coordinate change(︂ ′ )︂ (︂)︂ (︂ )︂𝑥
𝛼 𝛽𝑥=
𝛼𝛿 − 𝛽𝛾 = 1
𝑦′
𝛾 𝛿
𝑦
(︀
)︀
(︀
)︀
the discriminant is invariant, 𝑑𝑖𝑠𝑐 𝑝(𝑥′ , 𝑦 ′ ) = 𝑑𝑖𝑠𝑐 𝑝(𝑥, 𝑦) .
To use this module, you should use the factory object invariant_theory. For example, take the quartic:
sage: R.<x,y> = QQ[]
sage: q = x^4 + y^4
sage: quartic = invariant_theory.binary_quartic(q);Binary quartic with coefficients (1, 0, 0, 0, 1)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> q = x**Integer(4) + y**Integer(4)>>> quartic = invariant_theory.binary_quartic(q);Binary quartic with coefficients (1, 0, 0, 0, 1)

quartic

quartic

One invariant of a quartic is known as the Eisenstein D-invariant. Since it is an invariant, it is a polynomial in thecoefficients (which are integers in this example):sage: quartic.EisensteinD()
1

3.2. Classical Invariant Theory813

Polynomials, Release 10.4>>> from sage.all import *>>> quartic.EisensteinD()
1

One example of a covariant of a quartic is the so-called g-covariant (actually, the Hessian). As with all covariants, it is apolynomial in 𝑥, 𝑦 and the coefficients:
sage: quartic.g_covariant()-x^2*y^2>>> from sage.all import *>>> quartic.g_covariant()-x^2*y^2

As usual, use tab completion and the online help to discover the implemented invariants and covariants.
In general, the variables of the defining polynomial cannot be guessed. For example, the zero polynomial can be thoughtof as a homogeneous polynomial of any degree. Also, since we also want to allow polynomial coefficients we cannot justtake all variables of the polynomial ring as the variables of the form. This is why you will have to specify the variables
explicitly if there is any potential ambiguity. For example:
sage: invariant_theory.binary_quartic(R.zero(), [x,y])
Binary quartic with coefficients (0, 0, 0, 0, 0)
sage: invariant_theory.binary_quartic(x^4, [x,y])
Binary quartic with coefficients (0, 0, 0, 0, 1)
sage: R.<x,y,t> = QQ[]
sage: invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y])
Binary quartic with coefficients (1, 0, t, 0, 1)>>> from sage.all import *>>> invariant_theory.binary_quartic(R.zero(), [x,y])
Binary quartic with coefficients (0, 0, 0, 0, 0)>>> invariant_theory.binary_quartic(x**Integer(4), [x,y])
Binary quartic with coefficients (0, 0, 0, 0, 1)>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4) +␣˓→t*x**Integer(2)*y**Integer(2), [x,y])
Binary quartic with coefficients (1, 0, t, 0, 1)

Finally, it is often convenient to use inhomogeneous polynomials where it is understood that one wants to homogenize
them. This is also supported, just define the form with an inhomogeneous polynomial and specify one less variable:
sage: R.<x,t> = QQ[]
sage: invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x])Binary quartic with coefficients (1, 0, t, 0, 1)>>> from sage.all import *>>> R = QQ[ x, t ]; (x, t,) = R._first_ngens(2)>>> invariant_theory.binary_quartic(x**Integer(4) + Integer(1) + t*x**Integer(2), [x])Binary quartic with coefficients (1, 0, t, 0, 1)

REFERENCES:

814

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• Wikipedia article Glossary_of_invariant_theory
AUTHORS:• Volker Braun (2013-01-24): initial version• Jesper Noordsij (2018-05-18): support for binary quintics addedclass sage.rings.invariants.invariant_theory.AlgebraicForm(n, d, polynomial, *args,**kwds)Bases: FormsBase
The base class of algebraic forms (i.e. homogeneous polynomials).
You should only instantiate the derived classes of this base class.
Derived classes must implement coeffs() and scaled_coeffs()
INPUT:• n – The number of variables.
• d – The degree of the polynomial.
• polynomial – The polynomial.
• *args – The variables, as a single list/tuple, multiple arguments, or None to use all variables of the polynomial.
Derived classes must implement the same arguments for the constructor.
EXAMPLES:
sage: from sage.rings.invariants.invariant_theory import AlgebraicForm
sage: R.<x,y> = QQ[]
sage: p = x^2 + y^2
sage: AlgebraicForm(2, 2, p).variables()(x, y)
sage: AlgebraicForm(2, 2, p, None).variables()(x, y)
sage: AlgebraicForm(3, 2, p).variables()(x, y, None)sage: AlgebraicForm(3, 2, p, None).variables()(x, y, None)sage: from sage.rings.invariants.invariant_theory import AlgebraicForm
sage: R.<x,y,s,t> = QQ[]
sage: p = s*x^2 + t*y^2
sage: AlgebraicForm(2, 2, p, [x,y]).variables()(x, y)
sage: AlgebraicForm(2, 2, p, x,y).variables()(x, y)
sage: AlgebraicForm(3, 2, p, [x,y,None]).variables()(x, y, None)sage: AlgebraicForm(3, 2, p, x,y,None).variables()(x, y, None)sage: AlgebraicForm(2, 1, p, [x,y]).variables()Traceback (most recent call last):...
ValueError: polynomial is of the wrong degree(continues on next page)3.2. Classical Invariant Theory815

Polynomials, Release 10.4

(continued from previous page)

sage: AlgebraicForm(2, 2, x^2 + y, [x,y]).variables()Traceback (most recent call last):...
ValueError: polynomial is not homogeneous>>> from sage.all import *>>> from sage.rings.invariants.invariant_theory import AlgebraicForm>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> p = x**Integer(2) + y**Integer(2)>>> AlgebraicForm(Integer(2), Integer(2), p).variables()(x, y)>>> AlgebraicForm(Integer(2), Integer(2), p, None).variables()(x, y)>>> AlgebraicForm(Integer(3), Integer(2), p).variables()(x, y, None)>>> AlgebraicForm(Integer(3), Integer(2), p, None).variables()(x, y, None)>>> from sage.rings.invariants.invariant_theory import AlgebraicForm>>> R = QQ[ x, y, s, t ]; (x, y, s, t,) = R._first_ngens(4)>>> p = s*x**Integer(2) + t*y**Integer(2)>>> AlgebraicForm(Integer(2), Integer(2), p, [x,y]).variables()(x, y)>>> AlgebraicForm(Integer(2), Integer(2), p, x,y).variables()(x, y)>>> AlgebraicForm(Integer(3), Integer(2), p, [x,y,None]).variables()(x, y, None)>>> AlgebraicForm(Integer(3), Integer(2), p, x,y,None).variables()(x, y, None)>>> AlgebraicForm(Integer(2), Integer(1), p, [x,y]).variables()Traceback (most recent call last):...
ValueError: polynomial is of the wrong degree>>> AlgebraicForm(Integer(2), Integer(2), x**Integer(2) + y, [x,y]).variables()Traceback (most recent call last):...
ValueError: polynomial is not homogeneous

coefficients()
Alias for coeffs().
See the documentation for coeffs() for details.
EXAMPLES:
sage: R.<a,b,c,d,e,f,g, x,y,z> = QQ[]
sage: p = a*x^2 + b*y^2 + c*z^2 + d*x*y + e*x*z + f*y*z
sage: q = invariant_theory.quadratic_form(p, x,y,z)
sage: q.coefficients()(a, b, c, d, e, f)
sage: q.coeffs()(a, b, c, d, e, f)

816

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ a, b, c, d, e, f, g, x, y, z ]; (a, b, c, d, e, f, g, x, y, z,) =␣
˓→R._first_ngens(10)>>> p = a*x**Integer(2) + b*y**Integer(2) + c*z**Integer(2) + d*x*y + e*x*z +␣
˓→f*y*z>>> q = invariant_theory.quadratic_form(p, x,y,z)>>> q.coefficients()(a, b, c, d, e, f)>>> q.coeffs()(a, b, c, d, e, f)form()
Return the defining polynomial.
OUTPUT:
The polynomial used to define the algebraic form.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4)
sage: quartic.form()x^4 + y^4
sage: quartic.polynomial()x^4 + y^4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4))>>> quartic.form()x^4 + y^4>>> quartic.polynomial()x^4 + y^4homogenized(var='h')Return form as defined by a homogeneous polynomial.
INPUT:• var – either a variable name, variable index or a variable (default: h ).
OUTPUT:
The same algebraic form, but defined by a homogeneous polynomial.
EXAMPLES:
sage: T.<t> = QQ[]
sage: quadratic = invariant_theory.binary_quadratic(t^2 + 2*t + 3)
sage: quadratic
Binary quadratic with coefficients (1, 3, 2)
sage: quadratic.homogenized()
Binary quadratic with coefficients (1, 3, 2)
sage: quadratic == quadratic.homogenized()True
sage: quadratic.form()t^2 + 2*t + 3
sage: quadratic.homogenized().form()(continues on next page)3.2. Classical Invariant Theory817

Polynomials, Release 10.4

(continued from previous page)t^2 + 2*t*h + 3*h^2
sage: R.<x,y,z> = QQ[]
sage: quadratic = invariant_theory.ternary_quadratic(x^2 + 1, [x,y])
sage: quadratic.homogenized().form()x^2 + h^2
sage: R.<x> = QQ[]
sage: quintic = invariant_theory.binary_quintic(x^4 + 1, x)
sage: quintic.homogenized().form()x^4*h + h^5>>> from sage.all import *>>> T = QQ[ t ]; (t,) = T._first_ngens(1)>>> quadratic = invariant_theory.binary_quadratic(t**Integer(2) +␣˓→Integer(2)*t + Integer(3))>>> quadratic
Binary quadratic with coefficients (1, 3, 2)>>> quadratic.homogenized()
Binary quadratic with coefficients (1, 3, 2)>>> quadratic == quadratic.homogenized()True>>> quadratic.form()t^2 + 2*t + 3>>> quadratic.homogenized().form()t^2 + 2*t*h + 3*h^2>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quadratic = invariant_theory.ternary_quadratic(x**Integer(2) + Integer(1),˓→ [x,y])>>> quadratic.homogenized().form()x^2 + h^2>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> quintic = invariant_theory.binary_quintic(x**Integer(4) + Integer(1), x)>>> quintic.homogenized().form()x^4*h + h^5polynomial()
Return the defining polynomial.
OUTPUT:
The polynomial used to define the algebraic form.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4)
sage: quartic.form()x^4 + y^4
sage: quartic.polynomial()x^4 + y^4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4))(continues on next page)

818

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> quartic.form()x^4 + y^4>>> quartic.polynomial()x^4 + y^4transformed(g)Return the image under a linear transformation of the variables.
INPUT:• g – a 𝐺𝐿(𝑛, C) matrix or a dictionary with thevariables as keys. A matrix is used to define the linear transformation of homogeneous variables, adictionary acts by substitution of the variables.
OUTPUT:
A new instance of a subclass of AlgebraicForm obtained by replacing the variables of the homogeneouspolynomial by their image under g.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + 2*y^3 + 3*z^3 + 4*x*y*z)
sage: cubic.transformed({x: y, y: z, z: x}).form()
3*x^3 + y^3 + 4*x*y*z + 2*z^3sage: cyc = matrix([[0,1,0], [0,0,1], [1,0,0]])
sage: cubic.transformed(cyc) == cubic.transformed({x:y, y:z, z:x})
True
sage: g = matrix(QQ, [[1, 0, 0], [-1, 1, -3], [-5, -5, 16]])
sage: cubic.transformed(g)Ternary cubic with coefficients (-356, -373, 12234, -1119, 3578, -1151,
3582, -11766, -11466, 7360)
sage: cubic.transformed(g).transformed(g.inverse()) == cubicTrue>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) +␣˓→Integer(2)*y**Integer(3) + Integer(3)*z**Integer(3) + Integer(4)*x*y*z)>>> cubic.transformed({x: y, y: z, z: x}).form()
3*x^3 + y^3 + 4*x*y*z + 2*z^3>>> cyc = matrix([[Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),˓→Integer(1)], [Integer(1),Integer(0),Integer(0)]])>>> cubic.transformed(cyc) == cubic.transformed({x:y, y:z, z:x})
True>>> g = matrix(QQ, [[Integer(1), Integer(0), Integer(0)], [-Integer(1),␣
˓→Integer(1), -Integer(3)], [-Integer(5), -Integer(5), Integer(16)]])>>> cubic.transformed(g)Ternary cubic with coefficients (-356, -373, 12234, -1119, 3578, -1151,
3582, -11766, -11466, 7360)>>> cubic.transformed(g).transformed(g.inverse()) == cubic
Trueclass sage.rings.invariants.invariant_theory.BinaryQuartic(n, d, polynomial, *args)
Bases: AlgebraicForm
Invariant theory of a binary quartic.

3.2. Classical Invariant Theory819

Polynomials, Release 10.4

You should use the invariant_theory factory object to construct instances of this class.
nary_quartic() for details.

See bi-EisensteinD()
One of the Eisenstein invariants of a binary quartic.
OUTPUT:
The Eisenstein D-invariant of the quartic.
𝑓 (𝑥) = 𝑎0 𝑥41 + 4𝑎1 𝑥0 𝑥31 + 6𝑎2 𝑥20 𝑥21 + 4𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40⇒ 𝐷(𝑓 ) = 𝑎0 𝑎4 + 3𝑎22 − 4𝑎1 𝑎3
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x0, x1> = QQ[]
sage: f = a0*x1^4 + 4*a1*x0*x1^3 + 6*a2*x0^2*x1^2 + 4*a3*x0^3*x1 + a4*x0^4
sage: inv = invariant_theory.binary_quartic(f, x0, x1)
sage: inv.EisensteinD()
3*a2^2 - 4*a1*a3 + a0*a4>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x0, x1 ]; (a0, a1, a2, a3, a4, x0, x1,) = R._
˓→first_ngens(7)>>> f = a0*x1**Integer(4) + Integer(4)*a1*x0*x1**Integer(3) +␣˓→Integer(6)*a2*x0**Integer(2)*x1**Integer(2) +␣˓→Integer(4)*a3*x0**Integer(3)*x1 + a4*x0**Integer(4)>>> inv = invariant_theory.binary_quartic(f, x0, x1)>>> inv.EisensteinD()
3*a2^2 - 4*a1*a3 + a0*a4

EisensteinE()
One of the Eisenstein invariants of a binary quartic.
OUTPUT:
The Eisenstein E-invariant of the quartic.
𝑓 (𝑥) = 𝑎0 𝑥41 + 4𝑎1 𝑥0 𝑥31 + 6𝑎2 𝑥20 𝑥21 + 4𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40⇒ 𝐸(𝑓 ) = 𝑎0 𝑎23 + 𝑎21 𝑎4 − 𝑎0 𝑎2 𝑎4 − 2𝑎1 𝑎2 𝑎3 + 𝑎32
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x0, x1> = QQ[]
sage: f = a0*x1^4 + 4*a1*x0*x1^3 + 6*a2*x0^2*x1^2 + 4*a3*x0^3*x1 + a4*x0^4
sage: inv = invariant_theory.binary_quartic(f, x0, x1)
sage: inv.EisensteinE()
a2^3 - 2*a1*a2*a3 + a0*a3^2 + a1^2*a4 - a0*a2*a4>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x0, x1 ]; (a0, a1, a2, a3, a4, x0, x1,) = R._
˓→first_ngens(7)>>> f = a0*x1**Integer(4) + Integer(4)*a1*x0*x1**Integer(3) +␣˓→Integer(6)*a2*x0**Integer(2)*x1**Integer(2) +␣˓→Integer(4)*a3*x0**Integer(3)*x1 + a4*x0**Integer(4)>>> inv = invariant_theory.binary_quartic(f, x0, x1)>>> inv.EisensteinE()
a2^3 - 2*a1*a2*a3 + a0*a3^2 + a1^2*a4 - a0*a2*a4

820

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

coeffs()
The coefficients of a binary quartic.
Given𝑓 (𝑥) = 𝑎0 𝑥41 + 𝑎1 𝑥0 𝑥31 + 𝑎2 𝑥20 𝑥21 + 𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40
this function returns 𝑎 = (𝑎0 , 𝑎1 , 𝑎2 , 𝑎3 , 𝑎4 )EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x0, x1> = QQ[]
sage: p = a0*x1^4 + a1*x1^3*x0 + a2*x1^2*x0^2 + a3*x1*x0^3 + a4*x0^4
sage: quartic = invariant_theory.binary_quartic(p, x0, x1)
sage: quartic.coeffs()(a0, a1, a2, a3, a4)
sage: R.<a0, a1, a2, a3, a4, x> = QQ[]
sage: p = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4sage: quartic = invariant_theory.binary_quartic(p, x)
sage: quartic.coeffs()(a0, a1, a2, a3, a4)>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x0, x1 ]; (a0, a1, a2, a3, a4, x0, x1,) = R._
˓→first_ngens(7)>>> p = a0*x1**Integer(4) + a1*x1**Integer(3)*x0 +␣
˓→a2*x1**Integer(2)*x0**Integer(2) + a3*x1*x0**Integer(3) + a4*x0**Integer(4)>>> quartic = invariant_theory.binary_quartic(p, x0, x1)>>> quartic.coeffs()(a0, a1, a2, a3, a4)>>> R = QQ[ a0, a1, a2, a3, a4, x ]; (a0, a1, a2, a3, a4, x,) = R._first_
˓→ngens(6)>>> p = a0 + a1*x + a2*x**Integer(2) + a3*x**Integer(3) + a4*x**Integer(4)>>> quartic = invariant_theory.binary_quartic(p, x)>>> quartic.coeffs()(a0, a1, a2, a3, a4)

g_covariant()
The g-covariant of a binary quartic.
OUTPUT:
The g-covariant of the quartic.
𝑓 (𝑥) = 𝑎0 𝑥41 + 4𝑎1 𝑥0 𝑥31 + 6𝑎2 𝑥20 𝑥21 + 4𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40
1 (︁ 𝜕 2 𝑓 )︁⇒ 𝐷(𝑓 ) =144 𝜕𝑥𝜕𝑥
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x, y> = QQ[]
sage: p = a0*x^4 + 4*a1*x^3*y + 6*a2*x^2*y^2 + 4*a3*x*y^3 + a4*y^4sage: inv = invariant_theory.binary_quartic(p, x, y)
sage: g = inv.g_covariant(); ga1^2*x^4 - a0*a2*x^4 + 2*a1*a2*x^3*y - 2*a0*a3*x^3*y + 3*a2^2*x^2*y^2- 2*a1*a3*x^2*y^2 - a0*a4*x^2*y^2 + 2*a2*a3*x*y^3(continues on next page)3.2. Classical Invariant Theory

821

Polynomials, Release 10.4

(continued from previous page)- 2*a1*a4*x*y^3 + a3^2*y^4 - a2*a4*y^4sage: inv_inhomogeneous = invariant_theory.binary_quartic(p.subs(y=1), x)
sage: inv_inhomogeneous.g_covariant()
a1^2*x^4 - a0*a2*x^4 + 2*a1*a2*x^3 - 2*a0*a3*x^3 + 3*a2^2*x^2- 2*a1*a3*x^2 - a0*a4*x^2 + 2*a2*a3*x - 2*a1*a4*x + a3^2 - a2*a4
sage: g == 1/144 * (p.derivative(x,y)^2 - p.derivative(x,x)*p.derivative(y,y))True>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x, y ]; (a0, a1, a2, a3, a4, x, y,) = R._
˓→first_ngens(7)>>> p = a0*x**Integer(4) + Integer(4)*a1*x**Integer(3)*y +␣˓→Integer(6)*a2*x**Integer(2)*y**Integer(2) + Integer(4)*a3*x*y**Integer(3) +␣˓→a4*y**Integer(4)>>> inv = invariant_theory.binary_quartic(p, x, y)>>> g = inv.g_covariant(); ga1^2*x^4 - a0*a2*x^4 + 2*a1*a2*x^3*y - 2*a0*a3*x^3*y + 3*a2^2*x^2*y^2- 2*a1*a3*x^2*y^2 - a0*a4*x^2*y^2 + 2*a2*a3*x*y^3- 2*a1*a4*x*y^3 + a3^2*y^4 - a2*a4*y^4>>> inv_inhomogeneous = invariant_theory.binary_quartic(p.subs(y=Integer(1)),␣
˓→x)>>> inv_inhomogeneous.g_covariant()
a1^2*x^4 - a0*a2*x^4 + 2*a1*a2*x^3 - 2*a0*a3*x^3 + 3*a2^2*x^2- 2*a1*a3*x^2 - a0*a4*x^2 + 2*a2*a3*x - 2*a1*a4*x + a3^2 - a2*a4>>> g == Integer(1)/Integer(144) * (p.derivative(x,y)**Integer(2) - p.
˓→derivative(x,x)*p.derivative(y,y))Trueh_covariant()
The h-covariant of a binary quartic.
OUTPUT:
The h-covariant of the quartic.
𝑓 (𝑥) = 𝑎0 𝑥41 + 4𝑎1 𝑥0 𝑥31 + 6𝑎2 𝑥20 𝑥21 + 4𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40
1 (︁ 𝜕 2 𝑓 )︁⇒ 𝐷(𝑓 ) =144 𝜕𝑥𝜕𝑥
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x, y> = QQ[]
sage: p = a0*x^4 + 4*a1*x^3*y + 6*a2*x^2*y^2 + 4*a3*x*y^3 + a4*y^4sage: inv = invariant_theory.binary_quartic(p, x, y)
sage: h = inv.h_covariant();h-2*a1^3*x^6 + 3*a0*a1*a2*x^6 - a0^2*a3*x^6 - 6*a1^2*a2*x^5*y + 9*a0*a2^2*x^5*y- 2*a0*a1*a3*x^5*y - a0^2*a4*x^5*y - 10*a1^2*a3*x^4*y^2 + 15*a0*a2*a3*x^4*y^2- 5*a0*a1*a4*x^4*y^2 + 10*a0*a3^2*x^3*y^3 - 10*a1^2*a4*x^3*y^3+ 10*a1*a3^2*x^2*y^4 - 15*a1*a2*a4*x^2*y^4 + 5*a0*a3*a4*x^2*y^4+ 6*a2*a3^2*x*y^5 - 9*a2^2*a4*x*y^5 + 2*a1*a3*a4*x*y^5 + a0*a4^2*x*y^5+ 2*a3^3*y^6 - 3*a2*a3*a4*y^6 + a1*a4^2*y^6
sage: inv_inhomogeneous = invariant_theory.binary_quartic(p.subs(y=1), x)(continues on next page)

822

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: inv_inhomogeneous.h_covariant()-2*a1^3*x^6 + 3*a0*a1*a2*x^6 - a0^2*a3*x^6 - 6*a1^2*a2*x^5 + 9*a0*a2^2*x^5- 2*a0*a1*a3*x^5 - a0^2*a4*x^5 - 10*a1^2*a3*x^4 + 15*a0*a2*a3*x^4- 5*a0*a1*a4*x^4 + 10*a0*a3^2*x^3 - 10*a1^2*a4*x^3 + 10*a1*a3^2*x^2- 15*a1*a2*a4*x^2 + 5*a0*a3*a4*x^2 + 6*a2*a3^2*x - 9*a2^2*a4*x+ 2*a1*a3*a4*x + a0*a4^2*x + 2*a3^3 - 3*a2*a3*a4 + a1*a4^2
sage: g = inv.g_covariant()
sage: h == 1/8 * (p.derivative(x)*g.derivative(y) - p.derivative(y)*g.
˓→derivative(x))
True>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x, y ]; (a0, a1, a2, a3, a4, x, y,) = R._
˓→first_ngens(7)>>> p = a0*x**Integer(4) + Integer(4)*a1*x**Integer(3)*y +␣˓→Integer(6)*a2*x**Integer(2)*y**Integer(2) + Integer(4)*a3*x*y**Integer(3) +␣˓→a4*y**Integer(4)>>> inv = invariant_theory.binary_quartic(p, x, y)>>> h = inv.h_covariant();h-2*a1^3*x^6 + 3*a0*a1*a2*x^6 - a0^2*a3*x^6 - 6*a1^2*a2*x^5*y + 9*a0*a2^2*x^5*y- 2*a0*a1*a3*x^5*y - a0^2*a4*x^5*y - 10*a1^2*a3*x^4*y^2 + 15*a0*a2*a3*x^4*y^2- 5*a0*a1*a4*x^4*y^2 + 10*a0*a3^2*x^3*y^3 - 10*a1^2*a4*x^3*y^3+ 10*a1*a3^2*x^2*y^4 - 15*a1*a2*a4*x^2*y^4 + 5*a0*a3*a4*x^2*y^4+ 6*a2*a3^2*x*y^5 - 9*a2^2*a4*x*y^5 + 2*a1*a3*a4*x*y^5 + a0*a4^2*x*y^5+ 2*a3^3*y^6 - 3*a2*a3*a4*y^6 + a1*a4^2*y^6>>> inv_inhomogeneous = invariant_theory.binary_quartic(p.subs(y=Integer(1)),␣
˓→x)>>> inv_inhomogeneous.h_covariant()-2*a1^3*x^6 + 3*a0*a1*a2*x^6 - a0^2*a3*x^6 - 6*a1^2*a2*x^5 + 9*a0*a2^2*x^5- 2*a0*a1*a3*x^5 - a0^2*a4*x^5 - 10*a1^2*a3*x^4 + 15*a0*a2*a3*x^4- 5*a0*a1*a4*x^4 + 10*a0*a3^2*x^3 - 10*a1^2*a4*x^3 + 10*a1*a3^2*x^2- 15*a1*a2*a4*x^2 + 5*a0*a3*a4*x^2 + 6*a2*a3^2*x - 9*a2^2*a4*x+ 2*a1*a3*a4*x + a0*a4^2*x + 2*a3^3 - 3*a2*a3*a4 + a1*a4^2>>> g = inv.g_covariant()>>> h == Integer(1)/Integer(8) * (p.derivative(x)*g.derivative(y) - p.
˓→derivative(y)*g.derivative(x))
Truemonomials()
List the basis monomials in the form.
OUTPUT:
A tuple of monomials. They are in the same order as coeffs().
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4)
sage: quartic.monomials()(y^4, x*y^3, x^2*y^2, x^3*y, x^4)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)(continues on next page)3.2. Classical Invariant Theory823

Polynomials, Release 10.4

(continued from previous page)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4))>>> quartic.monomials()(y^4, x*y^3, x^2*y^2, x^3*y, x^4)

scaled_coeffs()
The coefficients of a binary quartic.
Given𝑓 (𝑥) = 𝑎0 𝑥41 + 4𝑎1 𝑥0 𝑥31 + 6𝑎2 𝑥20 𝑥21 + 4𝑎3 𝑥30 𝑥1 + 𝑎4 𝑥40
this function returns 𝑎 = (𝑎0 , 𝑎1 , 𝑎2 , 𝑎3 , 𝑎4 )EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, x0, x1> = QQ[]
sage: quartic = a0*x1^4 + 4*a1*x1^3*x0 + 6*a2*x1^2*x0^2 + 4*a3*x1*x0^3 +␣
˓→a4*x0^4
sage: inv = invariant_theory.binary_quartic(quartic, x0, x1)
sage: inv.scaled_coeffs()(a0, a1, a2, a3, a4)
sage: R.<a0, a1, a2, a3, a4, x> = QQ[]
sage: quartic = a0 + 4*a1*x + 6*a2*x^2 + 4*a3*x^3 + a4*x^4sage: inv = invariant_theory.binary_quartic(quartic, x)
sage: inv.scaled_coeffs()(a0, a1, a2, a3, a4)>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, x0, x1 ]; (a0, a1, a2, a3, a4, x0, x1,) = R._
˓→first_ngens(7)>>> quartic = a0*x1**Integer(4) + Integer(4)*a1*x1**Integer(3)*x0 +␣˓→Integer(6)*a2*x1**Integer(2)*x0**Integer(2) +␣˓→Integer(4)*a3*x1*x0**Integer(3) + a4*x0**Integer(4)>>> inv = invariant_theory.binary_quartic(quartic, x0, x1)>>> inv.scaled_coeffs()(a0, a1, a2, a3, a4)>>> R = QQ[ a0, a1, a2, a3, a4, x ]; (a0, a1, a2, a3, a4, x,) = R._first_
˓→ngens(6)>>> quartic = a0 + Integer(4)*a1*x + Integer(6)*a2*x**Integer(2) +␣˓→Integer(4)*a3*x**Integer(3) + a4*x**Integer(4)>>> inv = invariant_theory.binary_quartic(quartic, x)>>> inv.scaled_coeffs()(a0, a1, a2, a3, a4)class sage.rings.invariants.invariant_theory.BinaryQuintic(n, d, polynomial, *args)
Bases: AlgebraicForm
Invariant theory of a binary quintic form.
You should use the invariant_theory factory object to construct instances of this class.
nary_quintic() for details.

See bi-REFERENCES:
For a description of all invariants and covariants of a binary quintic, see section 73 of [Cle1872].

824

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

A_invariant()
Return the invariant 𝐴 of a binary quintic.
OUTPUT:
The 𝐴-invariant of the binary quintic.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.A_invariant()
4/625*a2^2*a3^2 - 12/625*a1*a3^3 - 12/625*a2^3*a4+ 38/625*a1*a2*a3*a4 + 6/125*a0*a3^2*a4 - 18/625*a1^2*a4^2- 16/125*a0*a2*a4^2 + 6/125*a1*a2^2*a5 - 16/125*a1^2*a3*a5- 2/25*a0*a2*a3*a5 + 4/5*a0*a1*a4*a5 - 2*a0^2*a5^2>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.A_invariant()
4/625*a2^2*a3^2 - 12/625*a1*a3^3 - 12/625*a2^3*a4+ 38/625*a1*a2*a3*a4 + 6/125*a0*a3^2*a4 - 18/625*a1^2*a4^2- 16/125*a0*a2*a4^2 + 6/125*a1*a2^2*a5 - 16/125*a1^2*a3*a5- 2/25*a0*a2*a3*a5 + 4/5*a0*a1*a4*a5 - 2*a0^2*a5^2

B_invariant()
Return the invariant 𝐵 of a binary quintic.
OUTPUT:
The 𝐵-invariant of the binary quintic.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.B_invariant()
1/1562500*a2^4*a3^4 - 3/781250*a1*a2^2*a3^5 + 9/1562500*a1^2*a3^6- 3/781250*a2^5*a3^2*a4 + 37/1562500*a1*a2^3*a3^3*a4- 57/1562500*a1^2*a2*a3^4*a4 + 3/312500*a0*a2^2*a3^4*a4...
+ 8/625*a0^2*a1^2*a4^2*a5^2 - 4/125*a0^3*a2*a4^2*a5^2 - 16/3125*a1^5*a5^3+ 4/125*a0*a1^3*a2*a5^3 - 6/125*a0^2*a1*a2^2*a5^3- 4/125*a0^2*a1^2*a3*a5^3 + 2/25*a0^3*a2*a3*a5^3>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣
(continues on next page)3.2. Classical Invariant Theory

825

Polynomials, Release 10.4

(continued from previous page)

a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.B_invariant()
1/1562500*a2^4*a3^4 - 3/781250*a1*a2^2*a3^5 + 9/1562500*a1^2*a3^6- 3/781250*a2^5*a3^2*a4 + 37/1562500*a1*a2^3*a3^3*a4- 57/1562500*a1^2*a2*a3^4*a4 + 3/312500*a0*a2^2*a3^4*a4...
+ 8/625*a0^2*a1^2*a4^2*a5^2 - 4/125*a0^3*a2*a4^2*a5^2 - 16/3125*a1^5*a5^3+ 4/125*a0*a1^3*a2*a5^3 - 6/125*a0^2*a1*a2^2*a5^3- 4/125*a0^2*a1^2*a3*a5^3 + 2/25*a0^3*a2*a3*a5^3˓→C_invariant()
Return the invariant 𝐶 of a binary quintic.
OUTPUT:
The 𝐶-invariant of the binary quintic.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.C_invariant()-3/1953125000*a2^6*a3^6 + 27/1953125000*a1*a2^4*a3^7- 249/7812500000*a1^2*a2^2*a3^8 - 3/78125000*a0*a2^3*a3^8+ 3/976562500*a1^3*a3^9 + 27/156250000*a0*a1*a2*a3^9...
+ 192/15625*a0^2*a1^3*a2^2*a3*a5^4 - 36/3125*a0^3*a1*a2^3*a3*a5^4+ 24/15625*a0^2*a1^4*a3^2*a5^4 - 24/3125*a0^3*a1^2*a2*a3^2*a5^4+ 6/625*a0^4*a2^2*a3^2*a5^4>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.C_invariant()-3/1953125000*a2^6*a3^6 + 27/1953125000*a1*a2^4*a3^7- 249/7812500000*a1^2*a2^2*a3^8 - 3/78125000*a0*a2^3*a3^8+ 3/976562500*a1^3*a3^9 + 27/156250000*a0*a1*a2*a3^9...
+ 192/15625*a0^2*a1^3*a2^2*a3*a5^4 - 36/3125*a0^3*a1*a2^3*a3*a5^4+ 24/15625*a0^2*a1^4*a3^2*a5^4 - 24/3125*a0^3*a1^2*a2*a3^2*a5^4+ 6/625*a0^4*a2^2*a3^2*a5^4

H_covariant(as_form=False)
Return the covariant 𝐻 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:

826

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

The 𝐻-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.H_covariant()-2/25*a4^2*x0^6 + 1/5*a3*a5*x0^6 - 3/25*a3*a4*x0^5*x1+ 3/5*a2*a5*x0^5*x1 - 3/25*a3^2*x0^4*x1^2 + 3/25*a2*a4*x0^4*x1^2+ 6/5*a1*a5*x0^4*x1^2 - 4/25*a2*a3*x0^3*x1^3 + 14/25*a1*a4*x0^3*x1^3+ 2*a0*a5*x0^3*x1^3 - 3/25*a2^2*x0^2*x1^4 + 3/25*a1*a3*x0^2*x1^4+ 6/5*a0*a4*x0^2*x1^4 - 3/25*a1*a2*x0*x1^5 + 3/5*a0*a3*x0*x1^5- 2/25*a1^2*x1^6 + 1/5*a0*a2*x1^6sage: quintic.H_covariant(as_form=True)
Binary sextic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.H_covariant()-2/25*a4^2*x0^6 + 1/5*a3*a5*x0^6 - 3/25*a3*a4*x0^5*x1+ 3/5*a2*a5*x0^5*x1 - 3/25*a3^2*x0^4*x1^2 + 3/25*a2*a4*x0^4*x1^2+ 6/5*a1*a5*x0^4*x1^2 - 4/25*a2*a3*x0^3*x1^3 + 14/25*a1*a4*x0^3*x1^3+ 2*a0*a5*x0^3*x1^3 - 3/25*a2^2*x0^2*x1^4 + 3/25*a1*a3*x0^2*x1^4+ 6/5*a0*a4*x0^2*x1^4 - 3/25*a1*a2*x0*x1^5 + 3/5*a0*a3*x0*x1^5- 2/25*a1^2*x1^6 + 1/5*a0*a2*x1^6>>> quintic.H_covariant(as_form=True)
Binary sextic given by ...

R_invariant()
Return the invariant 𝑅 of a binary quintic.
OUTPUT:The 𝑅-invariant of the binary quintic.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.R_invariant()
3/3906250000000*a1^2*a2^5*a3^11 - 3/976562500000*a0*a2^6*a3^11- 51/7812500000000*a1^3*a2^3*a3^12 + 27/976562500000*a0*a1*a2^4*a3^12+ 27/1953125000000*a1^4*a2*a3^13 - 81/1562500000000*a0*a1^2*a2^2*a3^13...
+ 384/9765625*a0*a1^10*a5^7 - 192/390625*a0^2*a1^8*a2*a5^7+ 192/78125*a0^3*a1^6*a2^2*a5^7 - 96/15625*a0^4*a1^4*a2^3*a5^7+ 24/3125*a0^5*a1^2*a2^4*a5^7 - 12/3125*a0^6*a2^5*a5^7

3.2. Classical Invariant Theory

827

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.R_invariant()
3/3906250000000*a1^2*a2^5*a3^11 - 3/976562500000*a0*a2^6*a3^11- 51/7812500000000*a1^3*a2^3*a3^12 + 27/976562500000*a0*a1*a2^4*a3^12+ 27/1953125000000*a1^4*a2*a3^13 - 81/1562500000000*a0*a1^2*a2^2*a3^13...
+ 384/9765625*a0*a1^10*a5^7 - 192/390625*a0^2*a1^8*a2*a5^7+ 192/78125*a0^3*a1^6*a2^2*a5^7 - 96/15625*a0^4*a1^4*a2^3*a5^7+ 24/3125*a0^5*a1^2*a2^4*a5^7 - 12/3125*a0^6*a2^5*a5^7T_covariant(as_form=False)
Return the covariant 𝑇 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:
The 𝑇 -covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.T_covariant()
2/125*a4^3*x0^9 - 3/50*a3*a4*a5*x0^9 + 1/10*a2*a5^2*x0^9+ 9/250*a3*a4^2*x0^8*x1 - 3/25*a3^2*a5*x0^8*x1 + 1/50*a2*a4*a5*x0^8*x1+ 2/5*a1*a5^2*x0^8*x1 + 3/250*a3^2*a4*x0^7*x1^2 + 8/125*a2*a4^2*x0^7*x1^2...
11/25*a0*a1*a4*x0^2*x1^7 - a0^2*a5*x0^2*x1^7 - 9/250*a1^2*a2*x0*x1^8+ 3/25*a0*a2^2*x0*x1^8 - 1/50*a0*a1*a3*x0*x1^8 - 2/5*a0^2*a4*x0*x1^8- 2/125*a1^3*x1^9 + 3/50*a0*a1*a2*x1^9 - 1/10*a0^2*a3*x1^9sage: quintic.T_covariant(as_form=True)
Binary nonic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.T_covariant()
2/125*a4^3*x0^9 - 3/50*a3*a4*a5*x0^9 + 1/10*a2*a5^2*x0^9+ 9/250*a3*a4^2*x0^8*x1 - 3/25*a3^2*a5*x0^8*x1 + 1/50*a2*a4*a5*x0^8*x1+ 2/5*a1*a5^2*x0^8*x1 + 3/250*a3^2*a4*x0^7*x1^2 + 8/125*a2*a4^2*x0^7*x1^2...
(continues on next page)

828

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

11/25*a0*a1*a4*x0^2*x1^7 - a0^2*a5*x0^2*x1^7 - 9/250*a1^2*a2*x0*x1^8+ 3/25*a0*a2^2*x0*x1^8 - 1/50*a0*a1*a3*x0*x1^8 - 2/5*a0^2*a4*x0*x1^8- 2/125*a1^3*x1^9 + 3/50*a0*a1*a2*x1^9 - 1/10*a0^2*a3*x1^9>>> quintic.T_covariant(as_form=True)
Binary nonic given by ...

alpha_covariant(as_form=False)
Return the covariant 𝛼 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:The 𝛼-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.alpha_covariant()
1/2500*a2^2*a3^3*x0 - 3/2500*a1*a3^4*x0 - 1/625*a2^3*a3*a4*x0+ 3/625*a1*a2*a3^2*a4*x0 + 3/625*a0*a3^3*a4*x0 + 2/625*a1*a2^2*a4^2*x0- 6/625*a1^2*a3*a4^2*x0 - 12/625*a0*a2*a3*a4^2*x0 + 24/625*a0*a1*a4^3*x0...
- 12/625*a1^2*a2*a3*a5*x1 - 1/125*a0*a2^2*a3*a5*x1+ 8/125*a0*a1*a3^2*a5*x1 + 24/625*a1^3*a4*a5*x1 - 8/125*a0*a1*a2*a4*a5*x1- 4/25*a0^2*a3*a4*a5*x1 - 4/25*a0*a1^2*a5^2*x1 + 2/5*a0^2*a2*a5^2*x1
sage: quintic.alpha_covariant(as_form=True)
Binary monic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.alpha_covariant()
1/2500*a2^2*a3^3*x0 - 3/2500*a1*a3^4*x0 - 1/625*a2^3*a3*a4*x0+ 3/625*a1*a2*a3^2*a4*x0 + 3/625*a0*a3^3*a4*x0 + 2/625*a1*a2^2*a4^2*x0- 6/625*a1^2*a3*a4^2*x0 - 12/625*a0*a2*a3*a4^2*x0 + 24/625*a0*a1*a4^3*x0...
- 12/625*a1^2*a2*a3*a5*x1 - 1/125*a0*a2^2*a3*a5*x1+ 8/125*a0*a1*a3^2*a5*x1 + 24/625*a1^3*a4*a5*x1 - 8/125*a0*a1*a2*a4*a5*x1- 4/25*a0^2*a3*a4*a5*x1 - 4/25*a0*a1^2*a5^2*x1 + 2/5*a0^2*a2*a5^2*x1>>> quintic.alpha_covariant(as_form=True)
Binary monic given by ...

arithmetic_invariants()
Return a set of generating arithmetic invariants of a binary quintic.
3.2. Classical Invariant Theory

829

Polynomials, Release 10.4

An arithmetic invariants is an invariant whose coefficients are integers for a general binary quintic. They arelinear combinations of the Clebsch invariants, such that they still generate the ring of invariants.
OUTPUT:
The arithmetic invariants of the binary quintic. They are given by
𝐼4 = 2−1 · 54 · 𝐴
𝐼8 = 55 · (2−1 · 47 · 𝐴2 − 22 · 𝐵)
𝐼12 = 510 · (2−1 · 3 · 𝐴3 − 25 · 3−1 · 𝐶)
𝐼18 = 28 · 3−1 · 515 · 𝑅
where 𝐴, 𝐵, 𝐶 and 𝑅 are the BinaryQuintic.clebsch_invariants().
EXAMPLES:
sage: R.<x0, x1> = QQ[]
sage: p = 2*x1^5 + 4*x1^4*x0 + 5*x1^3*x0^2 + 7*x1^2*x0^3 - 11*x1*x0^4 + x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.arithmetic_invariants(){ I12 : -1156502613073152,
I18 : -12712872348048797642752,
I4 : -138016,
I8 : 14164936192}>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(2)*x1**Integer(5) + Integer(4)*x1**Integer(4)*x0 +␣˓→Integer(5)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(7)*x1**Integer(2)*x0**Integer(3) - Integer(11)*x1*x0**Integer(4) +␣˓→x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.arithmetic_invariants(){ I12 : -1156502613073152,
I18 : -12712872348048797642752,
I4 : -138016,
I8 : 14164936192}

We can check that the coefficients of the invariants have no common divisor for a general quintic form:
sage: R.<a0,a1,a2,a3,a4,a5,x0,x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: invs = quintic.arithmetic_invariants()
sage: [invs[x].content() for x in invs][1, 1, 1, 1]>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> invs = quintic.arithmetic_invariants()>>> [invs[x].content() for x in invs][1, 1, 1, 1]

830

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

beta_covariant(as_form=False)
Return the covariant 𝛽 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:
The 𝛽-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.beta_covariant()-1/62500*a2^3*a3^4*x0 + 9/125000*a1*a2*a3^5*x0 - 27/125000*a0*a3^6*x0+ 13/125000*a2^4*a3^2*a4*x0 - 31/62500*a1*a2^2*a3^3*a4*x0- 3/62500*a1^2*a3^4*a4*x0 + 27/15625*a0*a2*a3^4*a4*x0...
- 16/125*a0^2*a1*a3^2*a5^2*x1 - 28/625*a0*a1^3*a4*a5^2*x1+ 6/125*a0^2*a1*a2*a4*a5^2*x1 + 8/25*a0^3*a3*a4*a5^2*x1+ 4/25*a0^2*a1^2*a5^3*x1 - 2/5*a0^3*a2*a5^3*x1
sage: quintic.beta_covariant(as_form=True)
Binary monic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.beta_covariant()-1/62500*a2^3*a3^4*x0 + 9/125000*a1*a2*a3^5*x0 - 27/125000*a0*a3^6*x0+ 13/125000*a2^4*a3^2*a4*x0 - 31/62500*a1*a2^2*a3^3*a4*x0- 3/62500*a1^2*a3^4*a4*x0 + 27/15625*a0*a2*a3^4*a4*x0...
- 16/125*a0^2*a1*a3^2*a5^2*x1 - 28/625*a0*a1^3*a4*a5^2*x1+ 6/125*a0^2*a1*a2*a4*a5^2*x1 + 8/25*a0^3*a3*a4*a5^2*x1+ 4/25*a0^2*a1^2*a5^3*x1 - 2/5*a0^3*a2*a5^3*x1>>> quintic.beta_covariant(as_form=True)
Binary monic given by ...

canonical_form(reduce_gcd=False)
Return a canonical representative of the quintic.
¯
Given a binary quintic 𝑓 with coefficients in a field 𝐾, returns a canonical representative of the 𝐺𝐿(2, 𝐾)-orbit¯
of the quintic, where 𝐾 is an algebraic closure of 𝐾. This means that two binary quintics 𝑓 and 𝑔 are¯
𝐺𝐿(2, 𝐾)-equivalent
if and only if their canonical forms are the same.
INPUT:• reduce_gcd – If set to True, then a variant of this canonical form is computed where the coefficients are coprime integers. The obtained form is then unique up to multiplication by a unit. See also
3.2. Classical Invariant Theory

831

Polynomials, Release 10.4

binary_quintic_from_invariants()’.
OUTPUT:¯
A canonical 𝐺𝐿(2, 𝐾)-equivalentbinary quintic.
EXAMPLES:
sage: R.<x0, x1> = QQ[]
sage: p = 2*x1^5 + 4*x1^4*x0 + 5*x1^3*x0^2 + 7*x1^2*x0^3 - 11*x1*x0^4 + x0^5
sage: f = invariant_theory.binary_quintic(p, x0, x1)
sage: g = matrix(QQ, [[11,5],[7,2]])
sage: gf = f.transformed(g)sage: f.canonical_form() == gf.canonical_form()True
sage: h = f.canonical_form(reduce_gcd=True)
sage: gcd(h.coeffs())
1>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(2)*x1**Integer(5) + Integer(4)*x1**Integer(4)*x0 +␣˓→Integer(5)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(7)*x1**Integer(2)*x0**Integer(3) - Integer(11)*x1*x0**Integer(4) +␣˓→x0**Integer(5)>>> f = invariant_theory.binary_quintic(p, x0, x1)>>> g = matrix(QQ, [[Integer(11),Integer(5)],[Integer(7),Integer(2)]])>>> gf = f.transformed(g)>>> f.canonical_form() == gf.canonical_form()True>>> h = f.canonical_form(reduce_gcd=True)>>> gcd(h.coeffs())
1

clebsch_invariants(as_tuple=False)
Return the invariants of a binary quintic as described by Clebsch.
The following invariants are returned: 𝐴, 𝐵, 𝐶 and 𝑅.
OUTPUT:
The Clebsch invariants of the binary quintic.
EXAMPLES:
sage: R.<x0, x1> = QQ[]
sage: p = 2*x1^5 + 4*x1^4*x0 + 5*x1^3*x0^2 + 7*x1^2*x0^3 - 11*x1*x0^4 + x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.clebsch_invariants(){ A : -276032/625,
B : 4983526016/390625,
C : -247056495846408/244140625,
R : -148978972828696847376/30517578125}
sage: quintic.clebsch_invariants(as_tuple=True)(-276032/625,
4983526016/390625,-247056495846408/244140625,-148978972828696847376/30517578125)

832

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(2)*x1**Integer(5) + Integer(4)*x1**Integer(4)*x0 +␣˓→Integer(5)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(7)*x1**Integer(2)*x0**Integer(3) - Integer(11)*x1*x0**Integer(4) +␣˓→x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.clebsch_invariants(){ A : -276032/625,
B : 4983526016/390625,
C : -247056495846408/244140625,
R : -148978972828696847376/30517578125}>>> quintic.clebsch_invariants(as_tuple=True)(-276032/625,
4983526016/390625,-247056495846408/244140625,-148978972828696847376/30517578125)

coeffs()
The coefficients of a binary quintic.
Given𝑓 (𝑥) = 𝑎0 𝑥51 + 𝑎1 𝑥0 𝑥41 + 𝑎2 𝑥20 𝑥31 + 𝑎3 𝑥30 𝑥21 + 𝑎4 𝑥40 𝑥1 + 𝑎5 𝑥51
this function returns 𝑎 = (𝑎0 , 𝑎1 , 𝑎2 , 𝑎3 , 𝑎4 , 𝑎5 )EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.coeffs()(a0, a1, a2, a3, a4, a5)sage: R.<a0, a1, a2, a3, a4, a5, x> = QQ[]
sage: p = a0 + a1*x + a2*x^2 + a3*x^3 + a4*x^4 + a5*x^5sage: quintic = invariant_theory.binary_quintic(p, x)
sage: quintic.coeffs()(a0, a1, a2, a3, a4, a5)>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.coeffs()(a0, a1, a2, a3, a4, a5)>>> R = QQ[ a0, a1, a2, a3, a4, a5, x ]; (a0, a1, a2, a3, a4, a5, x,) = R._
˓→first_ngens(7)>>> p = a0 + a1*x + a2*x**Integer(2) + a3*x**Integer(3) + a4*x**Integer(4) +␣˓→a5*x**Integer(5)(continues on next page)3.2. Classical Invariant Theory833

Polynomials, Release 10.4

(continued from previous page)>>> quintic = invariant_theory.binary_quintic(p, x)>>> quintic.coeffs()(a0, a1, a2, a3, a4, a5)delta_covariant(as_form=False)
Return the covariant 𝛿 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:The 𝛿-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.delta_covariant()
1/1562500000*a2^6*a3^7*x0 - 9/1562500000*a1*a2^4*a3^8*x0+ 9/625000000*a1^2*a2^2*a3^9*x0 + 9/781250000*a0*a2^3*a3^9*x0- 9/1562500000*a1^3*a3^10*x0 - 81/1562500000*a0*a1*a2*a3^10*x0...
+ 64/3125*a0^3*a1^3*a2^2*a5^5*x1 - 12/625*a0^4*a1*a2^3*a5^5*x1+ 16/3125*a0^3*a1^4*a3*a5^5*x1 - 16/625*a0^4*a1^2*a2*a3*a5^5*x1+ 4/125*a0^5*a2^2*a3*a5^5*x1
sage: quintic.delta_covariant(as_form=True)
Binary monic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.delta_covariant()
1/1562500000*a2^6*a3^7*x0 - 9/1562500000*a1*a2^4*a3^8*x0+ 9/625000000*a1^2*a2^2*a3^9*x0 + 9/781250000*a0*a2^3*a3^9*x0- 9/1562500000*a1^3*a3^10*x0 - 81/1562500000*a0*a1*a2*a3^10*x0...
+ 64/3125*a0^3*a1^3*a2^2*a5^5*x1 - 12/625*a0^4*a1*a2^3*a5^5*x1+ 16/3125*a0^3*a1^4*a3*a5^5*x1 - 16/625*a0^4*a1^2*a2*a3*a5^5*x1+ 4/125*a0^5*a2^2*a3*a5^5*x1>>> quintic.delta_covariant(as_form=True)
Binary monic given by ...

classmethod from_invariants(invariants, x, z, *args, **kwargs)
Construct a binary quintic from its invariants.
This function constructs a binary quintic whose invariants equal the ones provided as argument up to scaling.
INPUT:
834

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• invariants – A list or tuple of invariants that are used to reconstruct the binary quintic.
OUTPUT:
A BinaryQuintic.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: from sage.rings.invariants.invariant_theory import BinaryQuintic
sage: BinaryQuintic.from_invariants([3,6,12], x, y)
Binary quintic with coefficients (0, 1, 0, 0, 1, 0)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> from sage.rings.invariants.invariant_theory import BinaryQuintic>>> BinaryQuintic.from_invariants([Integer(3),Integer(6),Integer(12)], x, y)
Binary quintic with coefficients (0, 1, 0, 0, 1, 0)

gamma_covariant(as_form=False)
Return the covariant 𝛾 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:The 𝛾-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.gamma_covariant()
1/156250000*a2^5*a3^6*x0 - 3/62500000*a1*a2^3*a3^7*x0+ 27/312500000*a1^2*a2*a3^8*x0 + 27/312500000*a0*a2^2*a3^8*x0- 81/312500000*a0*a1*a3^9*x0 - 19/312500000*a2^6*a3^4*a4*x0...
- 32/3125*a0^2*a1^3*a2^2*a5^4*x1 + 6/625*a0^3*a1*a2^3*a5^4*x1- 8/3125*a0^2*a1^4*a3*a5^4*x1 + 8/625*a0^3*a1^2*a2*a3*a5^4*x1- 2/125*a0^4*a2^2*a3*a5^4*x1
sage: quintic.gamma_covariant(as_form=True)
Binary monic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.gamma_covariant()
1/156250000*a2^5*a3^6*x0 - 3/62500000*a1*a2^3*a3^7*x0+ 27/312500000*a1^2*a2*a3^8*x0 + 27/312500000*a0*a2^2*a3^8*x0- 81/312500000*a0*a1*a3^9*x0 - 19/312500000*a2^6*a3^4*a4*x0(continues on next page)3.2. Classical Invariant Theory835

Polynomials, Release 10.4

(continued from previous page)...
- 32/3125*a0^2*a1^3*a2^2*a5^4*x1 + 6/625*a0^3*a1*a2^3*a5^4*x1- 8/3125*a0^2*a1^4*a3*a5^4*x1 + 8/625*a0^3*a1^2*a2*a3*a5^4*x1- 2/125*a0^4*a2^2*a3*a5^4*x1>>> quintic.gamma_covariant(as_form=True)
Binary monic given by ...

i_covariant(as_form=False)
Return the covariant 𝑖 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:
The 𝑖-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.i_covariant()
3/50*a3^2*x0^2 - 4/25*a2*a4*x0^2 + 2/5*a1*a5*x0^2 + 1/25*a2*a3*x0*x1- 6/25*a1*a4*x0*x1 + 2*a0*a5*x0*x1 + 3/50*a2^2*x1^2 - 4/25*a1*a3*x1^2+ 2/5*a0*a4*x1^2
sage: quintic.i_covariant(as_form=True)
Binary quadratic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.i_covariant()
3/50*a3^2*x0^2 - 4/25*a2*a4*x0^2 + 2/5*a1*a5*x0^2 + 1/25*a2*a3*x0*x1- 6/25*a1*a4*x0*x1 + 2*a0*a5*x0*x1 + 3/50*a2^2*x1^2 - 4/25*a1*a3*x1^2+ 2/5*a0*a4*x1^2>>> quintic.i_covariant(as_form=True)
Binary quadratic given by ...

invariants(type='clebsch')
Return a tuple of invariants of a binary quintic.
INPUT:• type – The type of invariants to return. The default choice is to return the Clebsch invariants.
OUTPUT:
The invariants of the binary quintic.

836

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x0, x1> = QQ[]
sage: p = 2*x1^5 + 4*x1^4*x0 + 5*x1^3*x0^2 + 7*x1^2*x0^3 - 11*x1*x0^4 + x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.invariants()(-276032/625,
4983526016/390625,-247056495846408/244140625,-148978972828696847376/30517578125)
sage: quintic.invariants( unknown )Traceback (most recent call last):...
ValueError: unknown type of invariants unknown for a binary quintic>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(2)*x1**Integer(5) + Integer(4)*x1**Integer(4)*x0 +␣˓→Integer(5)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(7)*x1**Integer(2)*x0**Integer(3) - Integer(11)*x1*x0**Integer(4) +␣˓→x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.invariants()(-276032/625,
4983526016/390625,-247056495846408/244140625,-148978972828696847376/30517578125)>>> quintic.invariants( unknown )Traceback (most recent call last):...
ValueError: unknown type of invariants unknown for a binary quintic

j_covariant(as_form=False)
Return the covariant 𝑗 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:
The 𝑗-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.j_covariant()-3/500*a3^3*x0^3 + 3/125*a2*a3*a4*x0^3 - 6/125*a1*a4^2*x0^3- 3/50*a2^2*a5*x0^3 + 3/25*a1*a3*a5*x0^3 - 3/500*a2*a3^2*x0^2*x1+ 3/250*a2^2*a4*x0^2*x1 + 3/125*a1*a3*a4*x0^2*x1 - 6/25*a0*a4^2*x0^2*x1- 3/25*a1*a2*a5*x0^2*x1 + 3/5*a0*a3*a5*x0^2*x1 - 3/500*a2^2*a3*x0*x1^2+ 3/250*a1*a3^2*x0*x1^2 + 3/125*a1*a2*a4*x0*x1^2 - 3/25*a0*a3*a4*x0*x1^2- 6/25*a1^2*a5*x0*x1^2 + 3/5*a0*a2*a5*x0*x1^2 - 3/500*a2^3*x1^3+ 3/125*a1*a2*a3*x1^3 - 3/50*a0*a3^2*x1^3 - 6/125*a1^2*a4*x1^3+ 3/25*a0*a2*a4*x1^3(continues on next page)3.2. Classical Invariant Theory

837

Polynomials, Release 10.4

(continued from previous page)

sage: quintic.j_covariant(as_form=True)
Binary cubic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.j_covariant()-3/500*a3^3*x0^3 + 3/125*a2*a3*a4*x0^3 - 6/125*a1*a4^2*x0^3- 3/50*a2^2*a5*x0^3 + 3/25*a1*a3*a5*x0^3 - 3/500*a2*a3^2*x0^2*x1+ 3/250*a2^2*a4*x0^2*x1 + 3/125*a1*a3*a4*x0^2*x1 - 6/25*a0*a4^2*x0^2*x1- 3/25*a1*a2*a5*x0^2*x1 + 3/5*a0*a3*a5*x0^2*x1 - 3/500*a2^2*a3*x0*x1^2+ 3/250*a1*a3^2*x0*x1^2 + 3/125*a1*a2*a4*x0*x1^2 - 3/25*a0*a3*a4*x0*x1^2- 6/25*a1^2*a5*x0*x1^2 + 3/5*a0*a2*a5*x0*x1^2 - 3/500*a2^3*x1^3+ 3/125*a1*a2*a3*x1^3 - 3/50*a0*a3^2*x1^3 - 6/125*a1^2*a4*x1^3+ 3/25*a0*a2*a4*x1^3>>> quintic.j_covariant(as_form=True)
Binary cubic given by ...

monomials()
List the basis monomials of the form.
This function lists a basis of monomials of the space of binary quintics of which this form is an element.
OUTPUT:
A tuple of monomials. They are in the same order as coeffs().
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quintic = invariant_theory.binary_quintic(x^5 + y^5)
sage: quintic.monomials()(y^5, x*y^4, x^2*y^3, x^3*y^2, x^4*y, x^5)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + y**Integer(5))>>> quintic.monomials()(y^5, x*y^4, x^2*y^3, x^3*y^2, x^4*y, x^5)

scaled_coeffs()
The coefficients of a binary quintic.
Given𝑓 (𝑥) = 𝑎0 𝑥51 + 5𝑎1 𝑥0 𝑥41 + 10𝑎2 𝑥20 𝑥31 + 10𝑎3 𝑥30 𝑥21 + 5𝑎4 𝑥40 𝑥1 + 𝑎5 𝑥51
this function returns 𝑎 = (𝑎0 , 𝑎1 , 𝑎2 , 𝑎3 , 𝑎4 , 𝑎5 )EXAMPLES:

838

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + 5*a1*x1^4*x0 + 10*a2*x1^3*x0^2 + 10*a3*x1^2*x0^3 +␣
˓→5*a4*x1*x0^4 + a5*x0^5sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.scaled_coeffs()(a0, a1, a2, a3, a4, a5)sage: R.<a0, a1, a2, a3, a4, a5, x> = QQ[]
sage: p = a0 + 5*a1*x + 10*a2*x^2 + 10*a3*x^3 + 5*a4*x^4 + a5*x^5sage: quintic = invariant_theory.binary_quintic(p, x)
sage: quintic.scaled_coeffs()(a0, a1, a2, a3, a4, a5)>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + Integer(5)*a1*x1**Integer(4)*x0 +␣˓→Integer(10)*a2*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(10)*a3*x1**Integer(2)*x0**Integer(3) +␣˓→Integer(5)*a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.scaled_coeffs()(a0, a1, a2, a3, a4, a5)>>> R = QQ[ a0, a1, a2, a3, a4, a5, x ]; (a0, a1, a2, a3, a4, a5, x,) = R._
˓→first_ngens(7)>>> p = a0 + Integer(5)*a1*x + Integer(10)*a2*x**Integer(2) +␣˓→Integer(10)*a3*x**Integer(3) + Integer(5)*a4*x**Integer(4) +␣˓→a5*x**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x)>>> quintic.scaled_coeffs()(a0, a1, a2, a3, a4, a5)

tau_covariant(as_form=False)
Return the covariant 𝜏 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:The 𝜏 -covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.tau_covariant()
1/62500*a2^2*a3^4*x0^2 - 3/62500*a1*a3^5*x0^2- 1/15625*a2^3*a3^2*a4*x0^2 + 1/6250*a1*a2*a3^3*a4*x0^2+ 3/6250*a0*a3^4*a4*x0^2 - 1/31250*a2^4*a4^2*x0^2...
- 2/125*a0*a1*a2^2*a4*a5*x1^2 - 4/125*a0*a1^2*a3*a4*a5*x1^2+ 2/25*a0^2*a2*a3*a4*a5*x1^2 - 8/625*a1^4*a5^2*x1^2(continues on next page)3.2. Classical Invariant Theory

839

Polynomials, Release 10.4

(continued from previous page)+ 8/125*a0*a1^2*a2*a5^2*x1^2 - 2/25*a0^2*a2^2*a5^2*x1^2
sage: quintic.tau_covariant(as_form=True)
Binary quadratic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.tau_covariant()
1/62500*a2^2*a3^4*x0^2 - 3/62500*a1*a3^5*x0^2- 1/15625*a2^3*a3^2*a4*x0^2 + 1/6250*a1*a2*a3^3*a4*x0^2+ 3/6250*a0*a3^4*a4*x0^2 - 1/31250*a2^4*a4^2*x0^2...
- 2/125*a0*a1*a2^2*a4*a5*x1^2 - 4/125*a0*a1^2*a3*a4*a5*x1^2+ 2/25*a0^2*a2*a3*a4*a5*x1^2 - 8/625*a1^4*a5^2*x1^2+ 8/125*a0*a1^2*a2*a5^2*x1^2 - 2/25*a0^2*a2^2*a5^2*x1^2>>> quintic.tau_covariant(as_form=True)
Binary quadratic given by ...

theta_covariant(as_form=False)
Return the covariant 𝜃 of a binary quintic.
INPUT:• as_form – if as_form is False, the result will be returned as polynomial (default). If it is True
the result is returned as an object of the class AlgebraicForm.
OUTPUT:The 𝜃-covariant of the binary quintic as polynomial or as binary form.
EXAMPLES:
sage: R.<a0, a1, a2, a3, a4, a5, x0, x1> = QQ[]
sage: p = a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2 + a3*x1^2*x0^3 + a4*x1*x0^4 +␣
˓→a5*x0^5
sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: quintic.theta_covariant()-1/625000*a2^3*a3^5*x0^2 + 9/1250000*a1*a2*a3^6*x0^2- 27/1250000*a0*a3^7*x0^2 + 3/250000*a2^4*a3^3*a4*x0^2- 7/125000*a1*a2^2*a3^4*a4*x0^2 - 3/312500*a1^2*a3^5*a4*x0^2...
+ 6/625*a0^2*a1*a2^2*a4*a5^2*x1^2 + 24/625*a0^2*a1^2*a3*a4*a5^2*x1^2- 12/125*a0^3*a2*a3*a4*a5^2*x1^2 + 8/625*a0*a1^4*a5^3*x1^2- 8/125*a0^2*a1^2*a2*a5^3*x1^2 + 2/25*a0^3*a2^2*a5^3*x1^2
sage: quintic.theta_covariant(as_form=True)
Binary quadratic given by ...
>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,
˓→) = R._first_ngens(8)(continues on next page)

840

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> p = a0*x1**Integer(5) + a1*x1**Integer(4)*x0 +␣
˓→a2*x1**Integer(3)*x0**Integer(2) + a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> quintic.theta_covariant()-1/625000*a2^3*a3^5*x0^2 + 9/1250000*a1*a2*a3^6*x0^2- 27/1250000*a0*a3^7*x0^2 + 3/250000*a2^4*a3^3*a4*x0^2- 7/125000*a1*a2^2*a3^4*a4*x0^2 - 3/312500*a1^2*a3^5*a4*x0^2...
+ 6/625*a0^2*a1*a2^2*a4*a5^2*x1^2 + 24/625*a0^2*a1^2*a3*a4*a5^2*x1^2- 12/125*a0^3*a2*a3*a4*a5^2*x1^2 + 8/625*a0*a1^4*a5^3*x1^2- 8/125*a0^2*a1^2*a2*a5^3*x1^2 + 2/25*a0^3*a2^2*a5^3*x1^2>>> quintic.theta_covariant(as_form=True)
Binary quadratic given by ...

class sage.rings.invariants.invariant_theory.FormsBase(n, homogeneous, ring, variables)
Bases: SageObject
The common base class of AlgebraicForm and SeveralAlgebraicForms.
This is an abstract base class to provide common methods. It does not make much sense to instantiate it.
is_homogeneous()
Return whether the forms were defined by homogeneous polynomials.
OUTPUT:
Boolean. Whether the user originally defined the form via homogeneous variables.
EXAMPLES:
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y])
sage: quartic.is_homogeneous()
True
sage: quartic.form()x^2*y^2*t + x^4 + y^4
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x])sage: quartic.is_homogeneous()
False
sage: quartic.form()x^4 + x^2*t + 1>>> from sage.all import *>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4) +␣˓→t*x**Integer(2)*y**Integer(2), [x,y])>>> quartic.is_homogeneous()
True>>> quartic.form()x^2*y^2*t + x^4 + y^4>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + Integer(1) +␣˓→t*x**Integer(2), [x])(continues on next page)3.2. Classical Invariant Theory

841

Polynomials, Release 10.4

(continued from previous page)>>> quartic.is_homogeneous()
False>>> quartic.form()x^4 + x^2*t + 1ring()
Return the polynomial ring.
OUTPUT:
A polynomial ring. This is where the defining polynomial(s) live. Note that the polynomials may be homogeneous or inhomogeneous, depending on how the user constructed the object.
EXAMPLES:
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y])
sage: quartic.ring()
Multivariate Polynomial Ring in x, y, t over Rational Field
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x])sage: quartic.ring()
Multivariate Polynomial Ring in x, y, t over Rational Field>>> from sage.all import *>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4) +␣˓→t*x**Integer(2)*y**Integer(2), [x,y])>>> quartic.ring()
Multivariate Polynomial Ring in x, y, t over Rational Field>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + Integer(1) +␣˓→t*x**Integer(2), [x])>>> quartic.ring()
Multivariate Polynomial Ring in x, y, t over Rational Field

variables()Return the variables of the form.
OUTPUT:
A tuple of variables. If inhomogeneous notation is used for the defining polynomial then the last entry willbe None.
EXAMPLES:
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4 + t*x^2*y^2, [x,y])
sage: quartic.variables()(x, y)
sage: R.<x,y,t> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + 1 + t*x^2, [x])sage: quartic.variables()(x, None)

842

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4) +␣˓→t*x**Integer(2)*y**Integer(2), [x,y])>>> quartic.variables()(x, y)>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + Integer(1) +␣˓→t*x**Integer(2), [x])>>> quartic.variables()(x, None)class sage.rings.invariants.invariant_theory.InvariantTheoryFactory
Bases: object
Factory object for invariants of multilinear forms.
Use the invariant_theory object to construct algebraic forms. These can then be queried for invariant and covariants.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
Ternary cubic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0)
sage: invariant_theory.ternary_cubic(x^3 + y^3 + z^3).J_covariant()x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) + z**Integer(3))
Ternary cubic with coefficients (1, 1, 1, 0, 0, 0, 0, 0, 0, 0)>>> invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) + z**Integer(3)).
˓→J_covariant()x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6binary_form_from_invariants(degree, invariants, variables=None, as_form=True, *args, **kwargs)
Reconstruct a binary form from the values of its invariants.
INPUT:• degree – The degree of the binary form.
• invariants – A list or tuple of values of the invariants of the binary form.
• variables – A list or tuple of two variables that are used for the resulting form (only if as_form isTrue). If no variables are provided, two abstract variables x and z will be used.
• as_form – boolean. If False, the function will return a tuple of coefficients of a binary form.
OUTPUT:
A binary form or a tuple of its coefficients, whose invariants are equal to the given invariants up to ascaling.
EXAMPLES:In the case of binary quadratics and cubics, the form is reconstructed based on the value of the discriminant. See also binary_quadratic_coefficients_from_invariants() and binary_cu3.2. Classical Invariant Theory

843

Polynomials, Release 10.4

bic_coefficients_from_invariants(). These methods will always return the same result if thediscriminant is non-zero:sage: discriminant = 1
sage: invariant_theory.binary_form_from_invariants(2, [discriminant])
Binary quadratic with coefficients (1, -1/4, 0)
sage: invariant_theory.binary_form_from_invariants(3, [discriminant], as_˓→form=false)(0, 1, -1, 0)>>> from sage.all import *>>> discriminant = Integer(1)>>> invariant_theory.binary_form_from_invariants(Integer(2), [discriminant])
Binary quadratic with coefficients (1, -1/4, 0)>>> invariant_theory.binary_form_from_invariants(Integer(3), [discriminant],␣
˓→as_form=false)(0, 1, -1, 0)

For binary cubics, there is no class implemented yet, so as_form=True will yield an NotImplementedError:
sage: invariant_theory.binary_form_from_invariants(3, [discriminant])
Traceback (most recent call last):...
NotImplementedError: no class for binary cubics implemented>>> from sage.all import *>>> invariant_theory.binary_form_from_invariants(Integer(3), [discriminant])
Traceback (most recent call last):...
NotImplementedError: no class for binary cubics implemented

For binary quintics, the three Clebsch invariants of the form should be provided to reconstruct the form. For
more details about these invariants, see clebsch_invariants():
sage: invariants = [1, 0, 0]
sage: invariant_theory.binary_form_from_invariants(5, invariants)
Binary quintic with coefficients (1, 0, 0, 0, 0, 1)>>> from sage.all import *>>> invariants = [Integer(1), Integer(0), Integer(0)]>>> invariant_theory.binary_form_from_invariants(Integer(5), invariants)
Binary quintic with coefficients (1, 0, 0, 0, 0, 1)

An optional scaling argument may be provided in order to scale the resulting quintic. For more details,
see binary_quintic_coefficients_from_invariants():
sage: invariants = [3, 4, 7]
sage: invariant_theory.binary_form_from_invariants(5, invariants)
Binary quintic with coefficients (-37725479487783/1048576,
565882192316745/8388608, 0, 1033866765362693115/67108864,
12849486940936328715/268435456, -23129076493685391687/2147483648)
sage: invariant_theory.binary_form_from_invariants(5, invariants,....:
scaling= normalized )Binary quintic with coefficients (24389/892616806656,
4205/11019960576, 0, 1015/209952, -145/1296, -3/16)(continues on next page)

844

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: invariant_theory.binary_form_from_invariants(5, invariants,....:
scaling= coprime )Binary quintic with coefficients (-2048, 3840, 0, 876960, 2724840, -613089)>>> from sage.all import *>>> invariants = [Integer(3), Integer(4), Integer(7)]>>> invariant_theory.binary_form_from_invariants(Integer(5), invariants)
Binary quintic with coefficients (-37725479487783/1048576,
565882192316745/8388608, 0, 1033866765362693115/67108864,
12849486940936328715/268435456, -23129076493685391687/2147483648)>>> invariant_theory.binary_form_from_invariants(Integer(5), invariants,...
scaling= normalized )Binary quintic with coefficients (24389/892616806656,
4205/11019960576, 0, 1015/209952, -145/1296, -3/16)>>> invariant_theory.binary_form_from_invariants(Integer(5), invariants,...
scaling= coprime )Binary quintic with coefficients (-2048, 3840, 0, 876960, 2724840, -613089)

The invariants can also be computed using the invariants of a given binary quintic. The resulting form has thesame invariants up to scaling, is 𝐺𝐿(2, )-equivalent to the provided form and hence has the same canonicalform (see canonical_form()):
sage: R.<x0, x1> = QQ[]
sage: p = 3*x1^5 + 6*x1^4*x0 + 3*x1^3*x0^2 + 4*x1^2*x0^3 - 5*x1*x0^4 + 4*x0^5sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: invariants = quintic.clebsch_invariants(as_tuple=True)
sage: newquintic = invariant_theory.binary_form_from_invariants(....:
5, invariants, variables=quintic.variables())
sage: newquintic
Binary quintic with coefficients (9592267437341790539005557/244140625000000,
2149296928207625556323004064707/610351562500000000,
11149651890347700974453304786783/76293945312500000,
122650775751894638395648891202734239/47683715820312500000,
323996630945706528474286334593218447/11920928955078125000,
1504506503644608395841632538558481466127/14901161193847656250000)
sage: quintic.canonical_form() == newquintic.canonical_form()True>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(3)*x1**Integer(5) + Integer(6)*x1**Integer(4)*x0 +␣˓→Integer(3)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(4)*x1**Integer(2)*x0**Integer(3) - Integer(5)*x1*x0**Integer(4) +␣˓→Integer(4)*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> invariants = quintic.clebsch_invariants(as_tuple=True)>>> newquintic = invariant_theory.binary_form_from_invariants(...
Integer(5), invariants, variables=quintic.variables())>>> newquintic
Binary quintic with coefficients (9592267437341790539005557/244140625000000,
2149296928207625556323004064707/610351562500000000,
11149651890347700974453304786783/76293945312500000,
122650775751894638395648891202734239/47683715820312500000,
323996630945706528474286334593218447/11920928955078125000,
1504506503644608395841632538558481466127/14901161193847656250000)>>> quintic.canonical_form() == newquintic.canonical_form()(continues on next page)3.2. Classical Invariant Theory

845

Polynomials, Release 10.4

(continued from previous page)True

For binary forms of other degrees, no reconstruction has been implemented yet. For forms of degree 6, seeIssue #26462:
sage: invariant_theory.binary_form_from_invariants(6, invariants)
Traceback (most recent call last):...
NotImplementedError: no reconstruction for binary forms of degree 6␣
˓→implemented>>> from sage.all import *>>> invariant_theory.binary_form_from_invariants(Integer(6), invariants)
Traceback (most recent call last):...
NotImplementedError: no reconstruction for binary forms of degree 6␣
˓→implemented

binary_quadratic(quadratic, *args)
Invariant theory of a quadratic in two variables.
INPUT:• quadratic – a quadratic form.
• x, y – the homogeneous variables. If y is None, the quadratic is assumed to be inhomogeneous.
REFERENCES:• Wikipedia article Invariant_of_a_binary_form
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: invariant_theory.binary_quadratic(x^2 + y^2)
Binary quadratic with coefficients (1, 1, 0)
sage: T.<t> = QQ[]
sage: invariant_theory.binary_quadratic(t^2 + 2*t + 1, [t])Binary quadratic with coefficients (1, 1, 2)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> invariant_theory.binary_quadratic(x**Integer(2) + y**Integer(2))
Binary quadratic with coefficients (1, 1, 0)>>> T = QQ[ t ]; (t,) = T._first_ngens(1)>>> invariant_theory.binary_quadratic(t**Integer(2) + Integer(2)*t +␣˓→Integer(1), [t])Binary quadratic with coefficients (1, 1, 2)

binary_quartic(quartic, *args, **kwds)
Invariant theory of a quartic in two variables.
The algebra of invariants of a quartic form is generated by invariants 𝑖, 𝑗 of degrees 2, 3. This ring isnaturally isomorphic to the ring of modular forms of level 1, with the two generators corresponding to the
Eisenstein series 𝐸4 (see EisensteinD()) and 𝐸6 (see EisensteinE()). The algebra of covariants
is generated by these two invariants together with the form 𝑓 of degree 1 and order 4, the Hessian 𝑔 (see846

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

g_covariant()) of degree 2 and order 4, and a covariant ℎ (see h_covariant()) of degree 3 andorder 6. They are related by a syzygy
𝑗𝑓 3 − 𝑔𝑓 2 𝑖 + 4𝑔 3 + ℎ2 = 0
of degree 6 and order 12.
INPUT:• quartic – a quartic.
• x, y – the homogeneous variables. If y is None, the quartic is assumed to be inhomogeneous.
REFERENCES:• Wikipedia article Invariant_of_a_binary_form
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quartic = invariant_theory.binary_quartic(x^4 + y^4)
sage: quartic
Binary quartic with coefficients (1, 0, 0, 0, 1)
sage: type(quartic)<class sage.rings.invariants.invariant_theory.BinaryQuartic >>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quartic = invariant_theory.binary_quartic(x**Integer(4) + y**Integer(4))>>> quartic
Binary quartic with coefficients (1, 0, 0, 0, 1)>>> type(quartic)<class sage.rings.invariants.invariant_theory.BinaryQuartic >binary_quintic(quintic, *args, **kwds)
Create a binary quintic for computing invariants.
A binary quintic is a homogeneous polynomial of degree 5 in two variables. The algebra of invariants of abinary quintic is generated by the invariants 𝐴, 𝐵 and 𝐶 of respective degrees 4, 8 and 12 (see A_invariant(), B_invariant() and C_invariant()).
INPUT:• quintic – a homogeneous polynomial of degree five in two variables or a (possibly inhomogeneous)polynomial of degree at most five in one variable.
• *args – the two homogeneous variables. If only one variable is given, the polynomial quintic is
assumed to be univariate. If no variables are given, they are guessed.
REFERENCES:• Wikipedia article Invariant_of_a_binary_form• [Cle1872]
EXAMPLES:
If no variables are provided, they will be guessed:
sage: R.<x,y> = QQ[]
sage: quintic = invariant_theory.binary_quintic(x^5 + y^5)
sage: quintic
Binary quintic with coefficients (1, 0, 0, 0, 0, 1)

3.2. Classical Invariant Theory

847

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + y**Integer(5))>>> quintic
Binary quintic with coefficients (1, 0, 0, 0, 0, 1)

If only one variable is given, the quintic is the homogenisation of the provided polynomial:
sage: quintic = invariant_theory.binary_quintic(x^5 + y^5, x)
sage: quintic
Binary quintic with coefficients (y^5, 0, 0, 0, 0, 1)
sage: quintic.is_homogeneous()
False>>> from sage.all import *>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + y**Integer(5),␣
˓→x)>>> quintic
Binary quintic with coefficients (y^5, 0, 0, 0, 0, 1)>>> quintic.is_homogeneous()
False

If the polynomial has three or more variables, the variables should be specified:sage: R.<x,y,z> = QQ[]
sage: quintic = invariant_theory.binary_quintic(x^5 + z*y^5)
Traceback (most recent call last):...
ValueError: need 2 or 1 variables, got (x, y, z)
sage: quintic = invariant_theory.binary_quintic(x^5 + z*y^5, x, y)
sage: quintic
Binary quintic with coefficients (z, 0, 0, 0, 0, 1)
sage: type(quintic)<class sage.rings.invariants.invariant_theory.BinaryQuintic >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + z*y**Integer(5))
Traceback (most recent call last):...
ValueError: need 2 or 1 variables, got (x, y, z)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + z*y**Integer(5),˓→ x, y)>>> quintic
Binary quintic with coefficients (z, 0, 0, 0, 0, 1)>>> type(quintic)<class sage.rings.invariants.invariant_theory.BinaryQuintic >inhomogeneous_quadratic_form(polynomial, *args)
Invariants of an inhomogeneous quadratic form.
INPUT:• polynomial – an inhomogeneous quadratic form.
• *args – the variables as multiple arguments, or as a single list/tuple.
848

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: quadratic = x^2 + 2*y^2 + 3*x*y + 4*x + 5*y + 6
sage: inv3 = invariant_theory.inhomogeneous_quadratic_form(quadratic)
sage: type(inv3)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >sage: inv4 = invariant_theory.inhomogeneous_quadratic_form(x^2 + y^2 + z^2)
sage: type(inv4)<class sage.rings.invariants.invariant_theory.QuadraticForm >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quadratic = x**Integer(2) + Integer(2)*y**Integer(2) + Integer(3)*x*y +␣˓→Integer(4)*x + Integer(5)*y + Integer(6)>>> inv3 = invariant_theory.inhomogeneous_quadratic_form(quadratic)>>> type(inv3)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >>>> inv4 = invariant_theory.inhomogeneous_quadratic_form(x**Integer(2) +␣˓→y**Integer(2) + z**Integer(2))>>> type(inv4)<class sage.rings.invariants.invariant_theory.QuadraticForm >quadratic_form(polynomial, *args)
Invariants of a homogeneous quadratic form.
INPUT:• polynomial – a homogeneous or inhomogeneous quadratic form.
• *args – the variables as multiple arguments, or as a single list/tuple. If the last argument is None, thecubic is assumed to be inhomogeneous.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: quadratic = x^2 + y^2 + z^2
sage: inv = invariant_theory.quadratic_form(quadratic)
sage: type(inv)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quadratic = x**Integer(2) + y**Integer(2) + z**Integer(2)>>> inv = invariant_theory.quadratic_form(quadratic)>>> type(inv)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >If some of the ring variables are to be treated as coefficients you need to specify the polynomial variables:sage: R.<x,y,z, a,b> = QQ[]
sage: quadratic = a*x^2 + b*y^2 + z^2 + 2*y*z
sage: invariant_theory.quadratic_form(quadratic, x,y,z)Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)
sage: invariant_theory.quadratic_form(quadratic, [x,y,z])Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)

3.2. Classical Invariant Theory# alternate syntax

849

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y, z, a, b ]; (x, y, z, a, b,) = R._first_ngens(5)>>> quadratic = a*x**Integer(2) + b*y**Integer(2) + z**Integer(2) +␣˓→Integer(2)*y*z>>> invariant_theory.quadratic_form(quadratic, x,y,z)Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)>>> invariant_theory.quadratic_form(quadratic, [x,y,z])# alternate syntax
Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)

Inhomogeneous quadratic forms (see also inhomogeneous_quadratic_form()) can be specified bypassing None as the last variable:
sage: inhom = quadratic.subs(z=1)
sage: invariant_theory.quadratic_form(inhom, x,y,None)
Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)>>> from sage.all import *>>> inhom = quadratic.subs(z=Integer(1))>>> invariant_theory.quadratic_form(inhom, x,y,None)
Ternary quadratic with coefficients (a, b, 1, 0, 0, 2)

quaternary_biquadratic(quadratic1, quadratic2, *args, **kwds)
Invariants of two quadratics in four variables.
INPUT:• quadratic1, quadratic2 – two polynomials. Either homogeneous quadratic in 4 homogeneous
variables, or inhomogeneous quadratic in 3 variables.
• w, x, y, z – the variables. If z is None, the quadratics are assumed to be inhomogeneous.
EXAMPLES:
sage: R.<w,x,y,z> = QQ[]
sage: q1 = w^2 + x^2 + y^2 + z^2
sage: q2 = w*x + y*z
sage: inv = invariant_theory.quaternary_biquadratic(q1, q2)
sage: type(inv)<class sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics >>>> from sage.all import *>>> R = QQ[ w, x, y, z ]; (w, x, y, z,) = R._first_ngens(4)>>> q1 = w**Integer(2) + x**Integer(2) + y**Integer(2) + z**Integer(2)>>> q2 = w*x + y*z>>> inv = invariant_theory.quaternary_biquadratic(q1, q2)>>> type(inv)<class sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics >Distance between two spheres [Sal1958], [Sal1965]
sage: R.<x,y,z, a,b,c, r1,r2> = QQ[]
sage: S1 = -r1^2 + x^2 + y^2 + z^2
sage: S2 = -r2^2 + (x-a)^2 + (y-b)^2 + (z-c)^2
sage: inv = invariant_theory.quaternary_biquadratic(S1, S2, [x, y, z])sage: inv.Delta_invariant()-r1^2
sage: inv.Delta_prime_invariant()(continues on next page)

850

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)-r2^2
sage: inv.Theta_invariant()a^2 + b^2 + c^2 - 3*r1^2 - r2^2
sage: inv.Theta_prime_invariant()a^2 + b^2 + c^2 - r1^2 - 3*r2^2
sage: inv.Phi_invariant()
2*a^2 + 2*b^2 + 2*c^2 - 3*r1^2 - 3*r2^2
sage: inv.J_covariant()
0>>> from sage.all import *>>> R = QQ[ x, y, z, a, b, c, r1, r2 ]; (x, y, z, a, b, c, r1, r2,) = R._
˓→first_ngens(8)>>> S1 = -r1**Integer(2) + x**Integer(2) + y**Integer(2) + z**Integer(2)>>> S2 = -r2**Integer(2) + (x-a)**Integer(2) + (y-b)**Integer(2) + (z˓→c)**Integer(2)>>> inv = invariant_theory.quaternary_biquadratic(S1, S2, [x, y, z])>>> inv.Delta_invariant()-r1^2>>> inv.Delta_prime_invariant()-r2^2>>> inv.Theta_invariant()a^2 + b^2 + c^2 - 3*r1^2 - r2^2>>> inv.Theta_prime_invariant()a^2 + b^2 + c^2 - r1^2 - 3*r2^2>>> inv.Phi_invariant()
2*a^2 + 2*b^2 + 2*c^2 - 3*r1^2 - 3*r2^2>>> inv.J_covariant()0

quaternary_quadratic(quadratic, *args)
Invariant theory of a quadratic in four variables.
INPUT:• quadratic – a quadratic form.
• w, x, y, z – the homogeneous variables. If z is None, the quadratic is assumed to be inhomogeneous.
REFERENCES:• Wikipedia article Invariant_of_a_binary_form
EXAMPLES:
sage: R.<w,x,y,z> = QQ[]
sage: invariant_theory.quaternary_quadratic(w^2 + x^2 + y^2 + z^2)
Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0)
sage: R.<x,y,z> = QQ[]
sage: invariant_theory.quaternary_quadratic(1 + x^2 + y^2 + z^2)
Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0)>>> from sage.all import *>>> R = QQ[ w, x, y, z ]; (w, x, y, z,) = R._first_ngens(4)>>> invariant_theory.quaternary_quadratic(w**Integer(2) + x**Integer(2) +␣˓→y**Integer(2) + z**Integer(2))
Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0)(continues on next page)3.2. Classical Invariant Theory851

Polynomials, Release 10.4

(continued from previous page)>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> invariant_theory.quaternary_quadratic(Integer(1) + x**Integer(2) +␣˓→y**Integer(2) + z**Integer(2))
Quaternary quadratic with coefficients (1, 1, 1, 1, 0, 0, 0, 0, 0, 0)

ternary_biquadratic(quadratic1, quadratic2, *args, **kwds)
Invariants of two quadratics in three variables.
INPUT:• quadratic1, quadratic2 – two polynomials. Either homogeneous quadratic in 3 homogeneous
variables, or inhomogeneous quadratic in 2 variables.
• x, y, z – the variables. If z is None, the quadratics are assumed to be inhomogeneous.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: q1 = x^2 + y^2 + z^2
sage: q2 = x*y + y*z + x*z
sage: inv = invariant_theory.ternary_biquadratic(q1, q2)
sage: type(inv)<class sage.rings.invariants.invariant_theory.TwoTernaryQuadratics >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> q1 = x**Integer(2) + y**Integer(2) + z**Integer(2)>>> q2 = x*y + y*z + x*z>>> inv = invariant_theory.ternary_biquadratic(q1, q2)>>> type(inv)<class sage.rings.invariants.invariant_theory.TwoTernaryQuadratics >Distance between two circles:
sage: R.<x,y, a,b, r1,r2> = QQ[]
sage: S1 = -r1^2 + x^2 + y^2
sage: S2 = -r2^2 + (x-a)^2 + (y-b)^2
sage: inv = invariant_theory.ternary_biquadratic(S1, S2, [x, y])sage: inv.Delta_invariant()-r1^2
sage: inv.Delta_prime_invariant()-r2^2
sage: inv.Theta_invariant()a^2 + b^2 - 2*r1^2 - r2^2
sage: inv.Theta_prime_invariant()a^2 + b^2 - r1^2 - 2*r2^2
sage: inv.F_covariant()
2*x^2*a^2 + y^2*a^2 - 2*x*a^3 + a^4 + 2*x*y*a*b - 2*y*a^2*b + x^2*b^2 +2*y^2*b^2 - 2*x*a*b^2 + 2*a^2*b^2 - 2*y*b^3 + b^4 - 2*x^2*r1^2 - 2*y^2*r1^2 +2*x*a*r1^2 - 2*a^2*r1^2 + 2*y*b*r1^2 - 2*b^2*r1^2 + r1^4 - 2*x^2*r2^2 2*y^2*r2^2 + 2*x*a*r2^2 - 2*a^2*r2^2 + 2*y*b*r2^2 - 2*b^2*r2^2 + 2*r1^2*r2^2 +r2^4
sage: inv.J_covariant()-8*x^2*y*a^3 + 8*x*y*a^4 + 8*x^3*a^2*b - 16*x*y^2*a^2*b - 8*x^2*a^3*b +8*y^2*a^3*b + 16*x^2*y*a*b^2 - 8*y^3*a*b^2 + 8*x*y^2*b^3 - 8*x^2*a*b^3 +8*y^2*a*b^3 - 8*x*y*b^4 + 8*x*y*a^2*r1^2 - 8*y*a^3*r1^2 - 8*x^2*a*b*r1^2 +(continues on next page)852

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

8*y^2*a*b*r1^2 + 8*x*a^2*b*r1^2 - 8*x*y*b^2*r1^2 - 8*y*a*b^2*r1^2 + 8*x*b^
˓→3*r1^2 8*x*y*a^2*r2^2 + 8*x^2*a*b*r2^2 - 8*y^2*a*b*r2^2 + 8*x*y*b^2*r2^2>>> from sage.all import *>>> R = QQ[ x, y, a, b, r1, r2 ]; (x, y, a, b, r1, r2,) = R._first_ngens(6)>>> S1 = -r1**Integer(2) + x**Integer(2) + y**Integer(2)>>> S2 = -r2**Integer(2) + (x-a)**Integer(2) + (y-b)**Integer(2)>>> inv = invariant_theory.ternary_biquadratic(S1, S2, [x, y])>>> inv.Delta_invariant()-r1^2>>> inv.Delta_prime_invariant()-r2^2>>> inv.Theta_invariant()a^2 + b^2 - 2*r1^2 - r2^2>>> inv.Theta_prime_invariant()a^2 + b^2 - r1^2 - 2*r2^2>>> inv.F_covariant()
2*x^2*a^2 + y^2*a^2 - 2*x*a^3 + a^4 + 2*x*y*a*b - 2*y*a^2*b + x^2*b^2 +2*y^2*b^2 - 2*x*a*b^2 + 2*a^2*b^2 - 2*y*b^3 + b^4 - 2*x^2*r1^2 - 2*y^2*r1^2 +2*x*a*r1^2 - 2*a^2*r1^2 + 2*y*b*r1^2 - 2*b^2*r1^2 + r1^4 - 2*x^2*r2^2 2*y^2*r2^2 + 2*x*a*r2^2 - 2*a^2*r2^2 + 2*y*b*r2^2 - 2*b^2*r2^2 + 2*r1^2*r2^2 +r2^4>>> inv.J_covariant()-8*x^2*y*a^3 + 8*x*y*a^4 + 8*x^3*a^2*b - 16*x*y^2*a^2*b - 8*x^2*a^3*b +8*y^2*a^3*b + 16*x^2*y*a*b^2 - 8*y^3*a*b^2 + 8*x*y^2*b^3 - 8*x^2*a*b^3 +8*y^2*a*b^3 - 8*x*y*b^4 + 8*x*y*a^2*r1^2 - 8*y*a^3*r1^2 - 8*x^2*a*b*r1^2 +8*y^2*a*b*r1^2 + 8*x*a^2*b*r1^2 - 8*x*y*b^2*r1^2 - 8*y*a*b^2*r1^2 + 8*x*b^
˓→3*r1^2 8*x*y*a^2*r2^2 + 8*x^2*a*b*r2^2 - 8*y^2*a*b*r2^2 + 8*x*y*b^2*r2^2

ternary_cubic(cubic, *args, **kwds)
Invariants of a cubic in three variables.
The algebra of invariants of a ternary cubic under 𝑆𝐿3 (C) is a polynomial algebra generated by two invariants
𝑆 (see S_invariant()) and T (see T_invariant()) of degrees 4 and 6, called Aronhold invariants.
The ring of covariants is given as follows. The identity covariant U of a ternary cubic has degree 1 and order
3. The Hessian 𝐻 (see Hessian()) is a covariant of ternary cubics of degree 3 and order 3. There is acovariant Θ (see Theta_covariant()) of ternary cubics of degree 8 and order 6 that vanishes on points
𝑥 lying on the Salmon conic of the polar of 𝑥 with respect to the curve and its Hessian curve. The Brioschi
covariant 𝐽 (see J_covariant()) is the Jacobian of 𝑈 , Θ, and 𝐻 of degree 12, order 9. The algebra ofcovariants of a ternary cubic is generated over the ring of invariants by 𝑈 , Θ, 𝐻, and 𝐽, with a relation
𝐽 2 =4Θ3 + 𝑇 𝑈 2 Θ2 + Θ(−4𝑆 3 𝑈 4 + 2𝑆𝑇 𝑈 3 𝐻 − 72𝑆 2 𝑈 2 𝐻 2− 18𝑇 𝑈 𝐻 3 + 108𝑆𝐻 4 ) − 16𝑆 4 𝑈 5 𝐻 − 11𝑆 2 𝑇 𝑈 4 𝐻 2− 4𝑇 2 𝑈 3 𝐻 3 + 54𝑆𝑇 𝑈 2 𝐻 4 − 432𝑆 2 𝑈 𝐻 5 − 27𝑇 𝐻 6
REFERENCES:• Wikipedia article Ternary_cubic
INPUT:• cubic – a homogeneous cubic in 3 homogeneous variables, or an inhomogeneous cubic in 2 variables.
• x, y, z – the variables. If z is None, the cubic is assumed to be inhomogeneous.

3.2. Classical Invariant Theory853

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
sage: type(cubic)<class sage.rings.invariants.invariant_theory.TernaryCubic >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3))>>> type(cubic)<class sage.rings.invariants.invariant_theory.TernaryCubic >ternary_quadratic(quadratic, *args, **kwds)
Invariants of a quadratic in three variables.
INPUT:• quadratic – a homogeneous quadratic in 3 homogeneous variables, or an inhomogeneous quadratic
in 2 variables.
• x, y, z – the variables. If z is None, the quadratic is assumed to be inhomogeneous.
REFERENCES:• Wikipedia article Invariant_of_a_binary_form
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: invariant_theory.ternary_quadratic(x^2 + y^2 + z^2)
Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0)
sage: T.<u, v> = QQ[]
sage: invariant_theory.ternary_quadratic(1 + u^2 + v^2)
Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0)
sage: quadratic = x^2 + y^2 + z^2
sage: inv = invariant_theory.ternary_quadratic(quadratic)
sage: type(inv)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> invariant_theory.ternary_quadratic(x**Integer(2) + y**Integer(2) +␣˓→z**Integer(2))
Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0)>>> T = QQ[ u, v ]; (u, v,) = T._first_ngens(2)>>> invariant_theory.ternary_quadratic(Integer(1) + u**Integer(2) +␣˓→v**Integer(2))
Ternary quadratic with coefficients (1, 1, 1, 0, 0, 0)>>> quadratic = x**Integer(2) + y**Integer(2) + z**Integer(2)>>> inv = invariant_theory.ternary_quadratic(quadratic)>>> type(inv)<class sage.rings.invariants.invariant_theory.TernaryQuadratic >854

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4class sage.rings.invariants.invariant_theory.QuadraticForm(n, d, polynomial, *args)
Bases: AlgebraicForm
Invariant theory of a multivariate quadratic form.
You should use the invariant_theory factory object to construct instances of this class.
quadratic_form() for details.

See

as_QuadraticForm()
Convert into a QuadraticForm.
OUTPUT:
Sage has a special quadratic forms subsystem. This method converts self into this QuadraticForm
representation.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: p = x^2 + y^2 + z^2 + 2*x*y + 3*x*z
sage: quadratic = invariant_theory.ternary_quadratic(p)sage: matrix(quadratic)[ 1
1 3/2]
[ 1
1
0]
[3/2
0
1]
sage: quadratic.as_QuadraticForm()
Quadratic form in 3 variables over Multivariate Polynomial
Ring in x, y, z over Rational Field with coefficients:[ 1 2 3 ][ * 1 0 ][ * * 1 ]sage: _.polynomial( X,Y,Z )X^2 + 2*X*Y + Y^2 + 3*X*Z + Z^2>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> p = x**Integer(2) + y**Integer(2) + z**Integer(2) + Integer(2)*x*y +␣˓→Integer(3)*x*z>>> quadratic = invariant_theory.ternary_quadratic(p)>>> matrix(quadratic)[ 1
1 3/2]
[ 1
1
0]
[3/2
0
1]
>>> quadratic.as_QuadraticForm()
Quadratic form in 3 variables over Multivariate Polynomial
Ring in x, y, z over Rational Field with coefficients:[ 1 2 3 ][ * 1 0 ][ * * 1 ]>>> _.polynomial( X,Y,Z )X^2 + 2*X*Y + Y^2 + 3*X*Z + Z^2

coeffs()
The coefficients of a quadratic form.
Given𝑓 (𝑥) =

∑︁0≤𝑖<𝑛3.2. Classical Invariant Theory

𝑎𝑖 𝑥2𝑖 +∑︁

𝑎𝑗𝑘 𝑥𝑗 𝑥𝑘

0≤𝑗<𝑘<𝑛855Polynomials, Release 10.4

this function returns 𝑎 = (𝑎0 , . . . , 𝑎𝑛 , 𝑎00 , 𝑎01 , . . . , 𝑎𝑛−1,𝑛 )EXAMPLES:
sage: R.<a,b,c,d,e,f,g, x,y,z> = QQ[]
sage: p = a*x^2 + b*y^2 + c*z^2 + d*x*y + e*x*z + f*y*z
sage: inv = invariant_theory.quadratic_form(p, x,y,z); inv
Ternary quadratic with coefficients (a, b, c, d, e, f)
sage: inv.coeffs()(a, b, c, d, e, f)
sage: inv.scaled_coeffs()(a, b, c, 1/2*d, 1/2*e, 1/2*f)>>> from sage.all import *>>> R = QQ[ a, b, c, d, e, f, g, x, y, z ]; (a, b, c, d, e, f, g, x, y, z,) =␣
˓→R._first_ngens(10)>>> p = a*x**Integer(2) + b*y**Integer(2) + c*z**Integer(2) + d*x*y + e*x*z +␣
˓→f*y*z>>> inv = invariant_theory.quadratic_form(p, x,y,z); inv
Ternary quadratic with coefficients (a, b, c, d, e, f)>>> inv.coeffs()(a, b, c, d, e, f)>>> inv.scaled_coeffs()(a, b, c, 1/2*d, 1/2*e, 1/2*f)

discriminant()
Return the discriminant of the quadratic form.
Up to an overall constant factor, this is just the determinant of the defining matrix, see matrix(). For aquadratic form in 𝑛 variables, the overall constant is 2𝑛−1 if 𝑛 is odd and (−1)𝑛/2 2𝑛 if 𝑛 is even.
EXAMPLES:
sage: R.<a,b,c, x,y> = QQ[]
sage: p = a*x^2 + b*x*y + c*y^2
sage: quadratic = invariant_theory.quadratic_form(p, x,y)
sage: quadratic.discriminant()b^2 - 4*a*c
sage: R.<a,b,c,d,e,f,g, x,y,z> = QQ[]
sage: p = a*x^2 + b*y^2 + c*z^2 + d*x*y + e*x*z + f*y*z
sage: quadratic = invariant_theory.quadratic_form(p, x,y,z)
sage: quadratic.discriminant()
4*a*b*c - c*d^2 - b*e^2 + d*e*f - a*f^2>>> from sage.all import *>>> R = QQ[ a, b, c, x, y ]; (a, b, c, x, y,) = R._first_ngens(5)>>> p = a*x**Integer(2) + b*x*y + c*y**Integer(2)>>> quadratic = invariant_theory.quadratic_form(p, x,y)>>> quadratic.discriminant()b^2 - 4*a*c>>> R = QQ[ a, b, c, d, e, f, g, x, y, z ]; (a, b, c, d, e, f, g, x, y, z,) =␣
˓→R._first_ngens(10)>>> p = a*x**Integer(2) + b*y**Integer(2) + c*z**Integer(2) + d*x*y + e*x*z +␣
˓→f*y*z>>> quadratic = invariant_theory.quadratic_form(p, x,y,z)(continues on next page)

856

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> quadratic.discriminant()
4*a*b*c - c*d^2 - b*e^2 + d*e*f - a*f^2

dual()
Return the dual quadratic form.
OUTPUT:
A new quadratic form (with the same number of variables) defined by the adjoint matrix.
EXAMPLES:
sage: R.<a,b,c,x,y,z> = QQ[]
sage: cubic = x^2+y^2+z^2sage: quadratic = invariant_theory.ternary_quadratic(a*x^2+b*y^2+c*z^2, [x,y,˓→z])sage: quadratic.form()a*x^2 + b*y^2 + c*z^2
sage: quadratic.dual().form()
b*c*x^2 + a*c*y^2 + a*b*z^2
sage: R.<x,y,z, t> = QQ[]
sage: cubic = x^2+y^2+z^2sage: quadratic = invariant_theory.ternary_quadratic(x^2+y^2+z^2 + t*x*y, [x,˓→y,z])
sage: quadratic.dual()
Ternary quadratic with coefficients (1, 1, -1/4*t^2 + 1, -t, 0, 0)
sage: R.<x,y, t> = QQ[]
sage: quadratic = invariant_theory.ternary_quadratic(x^2+y^2+1 + t*x*y, [x,y])
sage: quadratic.dual()
Ternary quadratic with coefficients (1, 1, -1/4*t^2 + 1, -t, 0, 0)>>> from sage.all import *>>> R = QQ[ a, b, c, x, y, z ]; (a, b, c, x, y, z,) = R._first_ngens(6)>>> cubic = x**Integer(2)+y**Integer(2)+z**Integer(2)>>> quadratic = invariant_theory.ternary_
˓→quadratic(a*x**Integer(2)+b*y**Integer(2)+c*z**Integer(2), [x,y,z])>>> quadratic.form()a*x^2 + b*y^2 + c*z^2>>> quadratic.dual().form()
b*c*x^2 + a*c*y^2 + a*b*z^2>>> R = QQ[ x, y, z, t ]; (x, y, z, t,) = R._first_ngens(4)>>> cubic = x**Integer(2)+y**Integer(2)+z**Integer(2)>>> quadratic = invariant_theory.ternary_
˓→quadratic(x**Integer(2)+y**Integer(2)+z**Integer(2) + t*x*y, [x,y,z])>>> quadratic.dual()
Ternary quadratic with coefficients (1, 1, -1/4*t^2 + 1, -t, 0, 0)>>> R = QQ[ x, y, t ]; (x, y, t,) = R._first_ngens(3)>>> quadratic = invariant_theory.ternary_
˓→quadratic(x**Integer(2)+y**Integer(2)+Integer(1) + t*x*y, [x,y])>>> quadratic.dual()
Ternary quadratic with coefficients (1, 1, -1/4*t^2 + 1, -t, 0, 0)

classmethod from_invariants(discriminant, x, z, *args, **kwargs)
Construct a binary quadratic from its discriminant.
3.2. Classical Invariant Theory

857

Polynomials, Release 10.4

This function constructs a binary quadratic whose discriminant equal the one provided as argument up toscaling.
INPUT:• discriminant – Value of the discriminant used to reconstruct the binary quadratic.
OUTPUT:
A QuadraticForm with 2 variables.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: from sage.rings.invariants.invariant_theory import QuadraticForm
sage: QuadraticForm.from_invariants(1, x, y)
Binary quadratic with coefficients (1, -1/4, 0)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> from sage.rings.invariants.invariant_theory import QuadraticForm>>> QuadraticForm.from_invariants(Integer(1), x, y)
Binary quadratic with coefficients (1, -1/4, 0)

invariants(type='discriminant')
Return a tuple of invariants of a binary quadratic.
INPUT:• type – The type of invariants to return. The default choice is to return the discriminant.
OUTPUT:
The invariants of the binary quadratic.
EXAMPLES:
sage: R.<x0, x1> = QQ[]
sage: p = 2*x1^2 + 5*x0*x1 + 3*x0^2
sage: quadratic = invariant_theory.binary_quadratic(p, x0, x1)
sage: quadratic.invariants()(1,)
sage: quadratic.invariants( unknown )Traceback (most recent call last):...
ValueError: unknown type of invariants unknown for a binary quadratic>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(2)*x1**Integer(2) + Integer(5)*x0*x1 +␣˓→Integer(3)*x0**Integer(2)>>> quadratic = invariant_theory.binary_quadratic(p, x0, x1)>>> quadratic.invariants()(1,)>>> quadratic.invariants( unknown )Traceback (most recent call last):...
ValueError: unknown type of invariants unknown for a binary quadratic

858

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

matrix()Return the quadratic form as a symmetric matrix
OUTPUT:
This method returns a symmetric matrix 𝐴 such that the quadratic 𝑄 equals
𝑄(𝑥, 𝑦, 𝑧, . . . ) = (𝑥, 𝑦, . . . )𝐴(𝑥, 𝑦, . . . )𝑡
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: quadratic = invariant_theory.ternary_quadratic(x^2+y^2+z^2+x*y)
sage: matrix(quadratic)[ 1 1/2
0]
[1/2
1
0]
[ 0
0
1]
sage: quadratic._matrix_() == matrix(quadratic)True>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quadratic = invariant_theory.ternary_
˓→quadratic(x**Integer(2)+y**Integer(2)+z**Integer(2)+x*y)>>> matrix(quadratic)[ 1 1/2
0]
[1/2
1
0]
[ 0
0
1]
>>> quadratic._matrix_() == matrix(quadratic)
Truemonomials()
List the basis monomials in the form.
OUTPUT:
A tuple of monomials. They are in the same order as coeffs().
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: quadratic = invariant_theory.quadratic_form(x^2 + y^2)
sage: quadratic.monomials()(x^2, y^2, x*y)
sage: quadratic = invariant_theory.inhomogeneous_quadratic_form(x^2 + y^2)
sage: quadratic.monomials()(x^2, y^2, 1, x*y, x, y)>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quadratic = invariant_theory.quadratic_form(x**Integer(2) + y**Integer(2))>>> quadratic.monomials()(x^2, y^2, x*y)>>> quadratic = invariant_theory.inhomogeneous_quadratic_form(x**Integer(2) +␣˓→y**Integer(2))>>> quadratic.monomials()(x^2, y^2, 1, x*y, x, y)3.2. Classical Invariant Theory

859

Polynomials, Release 10.4

scaled_coeffs()
The scaled coefficients of a quadratic form.
Given𝑓 (𝑥) =

∑︁0≤𝑖<𝑛𝑎𝑖 𝑥2𝑖 +∑︁

2𝑎𝑗𝑘 𝑥𝑗 𝑥𝑘

0≤𝑗<𝑘<𝑛this function returns 𝑎 = (𝑎0 , · · · , 𝑎𝑛 , 𝑎00 , 𝑎01 , . . . , 𝑎𝑛−1,𝑛 )EXAMPLES:
sage: R.<a,b,c,d,e,f,g, x,y,z> = QQ[]
sage: p = a*x^2 + b*y^2 + c*z^2 + d*x*y + e*x*z + f*y*z
sage: inv = invariant_theory.quadratic_form(p, x,y,z); inv
Ternary quadratic with coefficients (a, b, c, d, e, f)
sage: inv.coeffs()(a, b, c, d, e, f)
sage: inv.scaled_coeffs()(a, b, c, 1/2*d, 1/2*e, 1/2*f)>>> from sage.all import *>>> R = QQ[ a, b, c, d, e, f, g, x, y, z ]; (a, b, c, d, e, f, g, x, y, z,) =␣
˓→R._first_ngens(10)>>> p = a*x**Integer(2) + b*y**Integer(2) + c*z**Integer(2) + d*x*y + e*x*z +␣
˓→f*y*z>>> inv = invariant_theory.quadratic_form(p, x,y,z); inv
Ternary quadratic with coefficients (a, b, c, d, e, f)>>> inv.coeffs()(a, b, c, d, e, f)>>> inv.scaled_coeffs()(a, b, c, 1/2*d, 1/2*e, 1/2*f)class sage.rings.invariants.invariant_theory.SeveralAlgebraicForms(forms)
Bases: FormsBase
The base class of multiple algebraic forms (i.e. homogeneous polynomials).
You should only instantiate the derived classes of this base class.
See AlgebraicForm for the base class of a single algebraic form.
INPUT:• forms – a list/tuple/iterable of at least one AlgebraicForm object, all with the same number of variables.
Interpreted as multiple homogeneous polynomials in a common polynomial ring.
EXAMPLES:
sage: from sage.rings.invariants.invariant_theory import AlgebraicForm,␣
˓→SeveralAlgebraicForms
sage: R.<x,y> = QQ[]
sage: p = AlgebraicForm(2, 2, x^2, (x,y))
sage: q = AlgebraicForm(2, 2, y^2, (x,y))
sage: pq = SeveralAlgebraicForms([p, q])>>> from sage.all import *>>> from sage.rings.invariants.invariant_theory import AlgebraicForm,␣
˓→SeveralAlgebraicForms(continues on next page)

860

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> p = AlgebraicForm(Integer(2), Integer(2), x**Integer(2), (x,y))>>> q = AlgebraicForm(Integer(2), Integer(2), y**Integer(2), (x,y))>>> pq = SeveralAlgebraicForms([p, q])

get_form(i)Return the 𝑖-th form.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: q1 = invariant_theory.quadratic_form(x^2 + y^2)
sage: q2 = invariant_theory.quadratic_form(x*y)
sage: from sage.rings.invariants.invariant_theory import SeveralAlgebraicForms
sage: q12 = SeveralAlgebraicForms([q1, q2])
sage: q12.get_form(0) is q1
True
sage: q12.get_form(1) is q2
True
sage: q12[0] is q12.get_form(0)# syntactic sugar
True
sage: q12[1] is q12.get_form(1)# syntactic sugar
True>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> q1 = invariant_theory.quadratic_form(x**Integer(2) + y**Integer(2))>>> q2 = invariant_theory.quadratic_form(x*y)>>> from sage.rings.invariants.invariant_theory import SeveralAlgebraicForms>>> q12 = SeveralAlgebraicForms([q1, q2])>>> q12.get_form(Integer(0)) is q1
True>>> q12.get_form(Integer(1)) is q2
True>>> q12[Integer(0)] is q12.get_form(Integer(0))# syntactic sugar
True>>> q12[Integer(1)] is q12.get_form(Integer(1))# syntactic sugar
Truehomogenized(var='h')Return form as defined by a homogeneous polynomial.
INPUT:• var – either a variable name, variable index or a variable (default: h ).
OUTPUT:
The same algebraic form, but defined by a homogeneous polynomial.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: q = invariant_theory.quaternary_biquadratic(x^2 + 1, y^2 + 1, [x,y,z])
sage: q
Joint quaternary quadratic with coefficients (1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
and quaternary quadratic with coefficients (0, 1, 0, 1, 0, 0, 0, 0, 0, 0)
sage: q.homogenized()(continues on next page)3.2. Classical Invariant Theory861

Polynomials, Release 10.4

(continued from previous page)

Joint quaternary quadratic with coefficients (1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
and quaternary quadratic with coefficients (0, 1, 0, 1, 0, 0, 0, 0, 0, 0)
sage: type(q) is type(q.homogenized())
True>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> q = invariant_theory.quaternary_biquadratic(x**Integer(2) + Integer(1),␣
˓→y**Integer(2) + Integer(1), [x,y,z])>>> q
Joint quaternary quadratic with coefficients (1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
and quaternary quadratic with coefficients (0, 1, 0, 1, 0, 0, 0, 0, 0, 0)>>> q.homogenized()
Joint quaternary quadratic with coefficients (1, 0, 0, 1, 0, 0, 0, 0, 0, 0)
and quaternary quadratic with coefficients (0, 1, 0, 1, 0, 0, 0, 0, 0, 0)>>> type(q) is type(q.homogenized())
True

n_forms()
Return the number of forms.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: q1 = invariant_theory.quadratic_form(x^2 + y^2)
sage: q2 = invariant_theory.quadratic_form(x*y)
sage: from sage.rings.invariants.invariant_theory import SeveralAlgebraicForms
sage: q12 = SeveralAlgebraicForms([q1, q2])
sage: q12.n_forms()2
sage: len(q12) == q12.n_forms()# syntactic sugar
True>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> q1 = invariant_theory.quadratic_form(x**Integer(2) + y**Integer(2))>>> q2 = invariant_theory.quadratic_form(x*y)>>> from sage.rings.invariants.invariant_theory import SeveralAlgebraicForms>>> q12 = SeveralAlgebraicForms([q1, q2])>>> q12.n_forms()
2>>> len(q12) == q12.n_forms()# syntactic sugar
Trueclass sage.rings.invariants.invariant_theory.TernaryCubic(n, d, polynomial, *args)
Bases: AlgebraicForm
Invariant theory of a ternary cubic.
You should use the invariant_theory factory object to construct instances of this class. See ternary_cubic() for details.
Hessian()Return the Hessian covariant.
OUTPUT:
The Hessian matrix multiplied with the conventional normalization factor 1/216.
862

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
sage: cubic.Hessian()x*y*z
sage: R.<x,y> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1)
sage: cubic.Hessian()x*y>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3))>>> cubic.Hessian()x*y*z>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→Integer(1))>>> cubic.Hessian()x*y

J_covariant()
Return the J-covariant of the ternary cubic.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
sage: cubic.J_covariant()x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6
sage: R.<x,y> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1)
sage: cubic.J_covariant()x^6*y^3 - x^3*y^6 - x^6 + y^6 + x^3 - y^3>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3))>>> cubic.J_covariant()x^6*y^3 - x^3*y^6 - x^6*z^3 + y^6*z^3 + x^3*z^6 - y^3*z^6>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→Integer(1))>>> cubic.J_covariant()x^6*y^3 - x^3*y^6 - x^6 + y^6 + x^3 - y^3

S_invariant()
Return the S-invariant.
EXAMPLES:

3.2. Classical Invariant Theory863

Polynomials, Release 10.4

sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^2*y + y^3 + z^3 + x*y*z)
sage: cubic.S_invariant()-1/1296>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(2)*y + y**Integer(3) +␣˓→z**Integer(3) + x*y*z)>>> cubic.S_invariant()-1/1296

T_invariant()
Return the T-invariant.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
sage: cubic.T_invariant()
1sage: R.<x,y,z,t> = GF(7)[]sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3 + t*x*y*z, [x,y,˓→z])sage: cubic.T_invariant()-t^6 - t^3 + 1>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3))>>> cubic.T_invariant()
1>>> R = GF(Integer(7))[ x, y, z, t ]; (x, y, z, t,) = R._first_ngens(4)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3) + t*x*y*z, [x,y,z])>>> cubic.T_invariant()-t^6 - t^3 + 1

Theta_covariant()
Return the Θ covariant.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + z^3)
sage: cubic.Theta_covariant()-x^3*y^3 - x^3*z^3 - y^3*z^3sage: R.<x,y> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3 + y^3 + 1)
sage: cubic.Theta_covariant()-x^3*y^3 - x^3 - y^3sage: R.<x,y,z,a30,a21,a12,a03,a20,a11,a02,a10,a01,a00> = QQ[]
(continues on next page)

864

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: p = ( a30*x^3 + a21*x^2*y + a12*x*y^2 + a03*y^3 + a20*x^2*z +....:a11*x*y*z + a02*y^2*z + a10*x*z^2 + a01*y*z^2 + a00*z^3 )sage: cubic = invariant_theory.ternary_cubic(p, x,y,z)
sage: len(list(cubic.Theta_covariant()))
6952>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→z**Integer(3))>>> cubic.Theta_covariant()-x^3*y^3 - x^3*z^3 - y^3*z^3>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3) + y**Integer(3) +␣˓→Integer(1))>>> cubic.Theta_covariant()-x^3*y^3 - x^3 - y^3>>> R = QQ[ x, y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00 ]; (x,␣˓→y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00,) = R._first_
˓→ngens(13)>>> p = ( a30*x**Integer(3) + a21*x**Integer(2)*y + a12*x*y**Integer(2) +␣˓→a03*y**Integer(3) + a20*x**Integer(2)*z +...
a11*x*y*z + a02*y**Integer(2)*z + a10*x*z**Integer(2) +␣˓→a01*y*z**Integer(2) + a00*z**Integer(3) )>>> cubic = invariant_theory.ternary_cubic(p, x,y,z)>>> len(list(cubic.Theta_covariant()))
6952

coeffs()Return the coefficients of a cubic.
Given𝑝(𝑥, 𝑦) = 𝑎30 𝑥3 + 𝑎21 𝑥2 𝑦 + 𝑎12 𝑥𝑦 2 + 𝑎03 𝑦 3 + 𝑎20 𝑥2 +𝑎11 𝑥𝑦 + 𝑎02 𝑦 2 + 𝑎10 𝑥 + 𝑎01 𝑦 + 𝑎00
this function returns 𝑎 = (𝑎30 , 𝑎03 , 𝑎00 , 𝑎21 , 𝑎20 , 𝑎12 , 𝑎02 , 𝑎10 , 𝑎01 , 𝑎11 )EXAMPLES:
sage: R.<x,y,z,a30,a21,a12,a03,a20,a11,a02,a10,a01,a00> = QQ[]
sage: p = ( a30*x^3 + a21*x^2*y + a12*x*y^2 + a03*y^3 + a20*x^2*z +....:a11*x*y*z + a02*y^2*z + a10*x*z^2 + a01*y*z^2 + a00*z^3 )sage: invariant_theory.ternary_cubic(p, x,y,z).coeffs()(a30, a03, a00, a21, a20, a12, a02, a10, a01, a11)
sage: invariant_theory.ternary_cubic(p.subs(z=1), x, y).coeffs()(a30, a03, a00, a21, a20, a12, a02, a10, a01, a11)>>> from sage.all import *>>> R = QQ[ x, y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00 ]; (x,␣˓→y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00,) = R._first_
˓→ngens(13)>>> p = ( a30*x**Integer(3) + a21*x**Integer(2)*y + a12*x*y**Integer(2) +␣˓→a03*y**Integer(3) + a20*x**Integer(2)*z +(continues on next page)3.2. Classical Invariant Theory865

Polynomials, Release 10.4

(continued from previous page)...
a11*x*y*z + a02*y**Integer(2)*z + a10*x*z**Integer(2) +␣˓→a01*y*z**Integer(2) + a00*z**Integer(3) )>>> invariant_theory.ternary_cubic(p, x,y,z).coeffs()(a30, a03, a00, a21, a20, a12, a02, a10, a01, a11)>>> invariant_theory.ternary_cubic(p.subs(z=Integer(1)), x, y).coeffs()(a30, a03, a00, a21, a20, a12, a02, a10, a01, a11)

monomials()
List the basis monomials of the form.
OUTPUT:
A tuple of monomials. They are in the same order as coeffs().
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: cubic = invariant_theory.ternary_cubic(x^3+y*z^2)
sage: cubic.monomials()(x^3, y^3, z^3, x^2*y, x^2*z, x*y^2, y^2*z, x*z^2, y*z^2, x*y*z)>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> cubic = invariant_theory.ternary_cubic(x**Integer(3)+y*z**Integer(2))>>> cubic.monomials()(x^3, y^3, z^3, x^2*y, x^2*z, x*y^2, y^2*z, x*z^2, y*z^2, x*y*z)

polar_conic()
Return the polar conic of the cubic.
OUTPUT:
Given the ternary cubic 𝑓 (𝑋, 𝑌, 𝑍), this method returns the symmetric matrix 𝐴(𝑥, 𝑦, 𝑧) defined by
𝑥𝑓𝑋 + 𝑦𝑓𝑌 + 𝑧𝑓𝑍 = (𝑋, 𝑌, 𝑍) · 𝐴(𝑥, 𝑦, 𝑧) · (𝑋, 𝑌, 𝑍)𝑡
EXAMPLES:
sage: R.<x,y,z,X,Y,Z,a30,a21,a12,a03,a20,a11,a02,a10,a01,a00> = QQ[]
sage: p = ( a30*x^3 + a21*x^2*y + a12*x*y^2 + a03*y^3 + a20*x^2*z +....:a11*x*y*z + a02*y^2*z + a10*x*z^2 + a01*y*z^2 + a00*z^3 )sage: cubic = invariant_theory.ternary_cubic(p, x,y,z)
sage: cubic.polar_conic()[ 3*x*a30 + y*a21 + z*a20 x*a21 + y*a12 + 1/2*z*a11 x*a20 + 1/2*y*a11 +␣˓→z*a10][x*a21 + y*a12 + 1/2*z*a11
x*a12 + 3*y*a03 + z*a02 1/2*x*a11 + y*a02 +␣˓→z*a01][x*a20 + 1/2*y*a11 + z*a10 1/2*x*a11 + y*a02 + z*a01
x*a10 + y*a01 +␣
˓→3*z*a00]
sage: polar_eqn = X*p.derivative(x) + Y*p.derivative(y) + Z*p.derivative(z)sage: polar = invariant_theory.ternary_quadratic(polar_eqn, [x,y,z])
sage: polar.matrix().subs(X=x,Y=y,Z=z) == cubic.polar_conic()True>>> from sage.all import *>>> R = QQ[ x, y, z, X, Y, Z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00(continues on next page)

866

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)]; (x, y, z, X, Y, Z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00,) =␣
˓→R._first_ngens(16)>>> p = ( a30*x**Integer(3) + a21*x**Integer(2)*y + a12*x*y**Integer(2) +␣˓→a03*y**Integer(3) + a20*x**Integer(2)*z +...
a11*x*y*z + a02*y**Integer(2)*z + a10*x*z**Integer(2) +␣˓→a01*y*z**Integer(2) + a00*z**Integer(3) )>>> cubic = invariant_theory.ternary_cubic(p, x,y,z)>>> cubic.polar_conic()[ 3*x*a30 + y*a21 + z*a20 x*a21 + y*a12 + 1/2*z*a11 x*a20 + 1/2*y*a11 +␣˓→z*a10][x*a21 + y*a12 + 1/2*z*a11
x*a12 + 3*y*a03 + z*a02 1/2*x*a11 + y*a02 +␣˓→z*a01][x*a20 + 1/2*y*a11 + z*a10 1/2*x*a11 + y*a02 + z*a01
x*a10 + y*a01 +␣
˓→3*z*a00]˓→>>> polar_eqn = X*p.derivative(x) + Y*p.derivative(y) + Z*p.derivative(z)>>> polar = invariant_theory.ternary_quadratic(polar_eqn, [x,y,z])>>> polar.matrix().subs(X=x,Y=y,Z=z) == cubic.polar_conic()Truescaled_coeffs()
Return the coefficients of a cubic.
Compared to coeffs(), this method returns rescaled coefficients that are often used in invariant theory.
Given𝑝(𝑥, 𝑦) = 𝑎30 𝑥3 + 𝑎21 𝑥2 𝑦 + 𝑎12 𝑥𝑦 2 + 𝑎03 𝑦 3 + 𝑎20 𝑥2 +𝑎11 𝑥𝑦 + 𝑎02 𝑦 2 + 𝑎10 𝑥 + 𝑎01 𝑦 + 𝑎00
this function returns 𝑎 = (𝑎30 , 𝑎03 , 𝑎00 , 𝑎21 /3, 𝑎20 /3, 𝑎12 /3, 𝑎02 /3, 𝑎10 /3, 𝑎01 /3, 𝑎11 /6)
EXAMPLES:
sage: R.<x,y,z,a30,a21,a12,a03,a20,a11,a02,a10,a01,a00> = QQ[]
sage: p = ( a30*x^3 + a21*x^2*y + a12*x*y^2 + a03*y^3 + a20*x^2*z +....:a11*x*y*z + a02*y^2*z + a10*x*z^2 + a01*y*z^2 + a00*z^3 )sage: invariant_theory.ternary_cubic(p, x,y,z).scaled_coeffs()(a30, a03, a00, 1/3*a21, 1/3*a20, 1/3*a12, 1/3*a02, 1/3*a10, 1/3*a01, 1/6*a11)>>> from sage.all import *>>> R = QQ[ x, y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00 ]; (x,␣˓→y, z, a30, a21, a12, a03, a20, a11, a02, a10, a01, a00,) = R._first_
˓→ngens(13)>>> p = ( a30*x**Integer(3) + a21*x**Integer(2)*y + a12*x*y**Integer(2) +␣˓→a03*y**Integer(3) + a20*x**Integer(2)*z +...
a11*x*y*z + a02*y**Integer(2)*z + a10*x*z**Integer(2) +␣˓→a01*y*z**Integer(2) + a00*z**Integer(3) )>>> invariant_theory.ternary_cubic(p, x,y,z).scaled_coeffs()(a30, a03, a00, 1/3*a21, 1/3*a20, 1/3*a12, 1/3*a02, 1/3*a10, 1/3*a01, 1/6*a11)

syzygy(U, S, T, H, Theta, J)
Return the syzygy of the cubic evaluated on the invariants and covariants.
INPUT:• U, S, T, H, Theta, J – polynomials from the same polynomial ring.

3.2. Classical Invariant Theory867

Polynomials, Release 10.4

OUTPUT:0 if evaluated for the form, the S invariant, the T invariant, the Hessian, the Θ covariant and the J-covariantof a ternary cubic.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: monomials = (x^3, y^3, z^3, x^2*y, x^2*z, x*y^2,....:y^2*z, x*z^2, y*z^2, x*y*z)
sage: random_poly = sum([ randint(0,10000) * m for m in monomials ])sage: cubic = invariant_theory.ternary_cubic(random_poly)
sage: U = cubic.form()
sage: S = cubic.S_invariant()
sage: T = cubic.T_invariant()
sage: H = cubic.Hessian()sage: Theta = cubic.Theta_covariant()
sage: J = cubic.J_covariant()
sage: cubic.syzygy(U, S, T, H, Theta, J)
0>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> monomials = (x**Integer(3), y**Integer(3), z**Integer(3), x**Integer(2)*y,
˓→ x**Integer(2)*z, x*y**Integer(2),...
y**Integer(2)*z, x*z**Integer(2), y*z**Integer(2), x*y*z)>>> random_poly = sum([ randint(Integer(0),Integer(10000)) * m for m in␣˓→monomials ])>>> cubic = invariant_theory.ternary_cubic(random_poly)>>> U = cubic.form()>>> S = cubic.S_invariant()>>> T = cubic.T_invariant()>>> H = cubic.Hessian()>>> Theta = cubic.Theta_covariant()>>> J = cubic.J_covariant()>>> cubic.syzygy(U, S, T, H, Theta, J)
0class sage.rings.invariants.invariant_theory.TernaryQuadratic(n, d, polynomial, *args)
Bases: QuadraticForm
Invariant theory of a ternary quadratic.
You should use the invariant_theory factory object to construct instances of this class.
ternary_quadratic() for details.

Seecoeffs()Return the coefficients of a quadratic.
Given𝑝(𝑥, 𝑦) = 𝑎20 𝑥2 + 𝑎11 𝑥𝑦 + 𝑎02 𝑦 2 + 𝑎10 𝑥 + 𝑎01 𝑦 + 𝑎00
this function returns 𝑎 = (𝑎20 , 𝑎02 , 𝑎00 , 𝑎11 , 𝑎10 , 𝑎01 )EXAMPLES:
sage: R.<x,y,z,a20,a11,a02,a10,a01,a00> = QQ[]
sage: p = ( a20*x^2 + a11*x*y + a02*y^2 +(continues on next page)

868

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)....:a10*x*z + a01*y*z + a00*z^2 )sage: invariant_theory.ternary_quadratic(p, x,y,z).coeffs()(a20, a02, a00, a11, a10, a01)
sage: invariant_theory.ternary_quadratic(p.subs(z=1), x, y).coeffs()(a20, a02, a00, a11, a10, a01)>>> from sage.all import *>>> R = QQ[ x, y, z, a20, a11, a02, a10, a01, a00 ]; (x, y, z, a20, a11, a02,␣
˓→a10, a01, a00,) = R._first_ngens(9)>>> p = ( a20*x**Integer(2) + a11*x*y + a02*y**Integer(2) +...
a10*x*z + a01*y*z + a00*z**Integer(2) )>>> invariant_theory.ternary_quadratic(p, x,y,z).coeffs()(a20, a02, a00, a11, a10, a01)>>> invariant_theory.ternary_quadratic(p.subs(z=Integer(1)), x, y).coeffs()(a20, a02, a00, a11, a10, a01)

covariant_conic(other)
Return the ternary quadratic covariant to self and other.
INPUT:• other – Another ternary quadratic.
OUTPUT:
The so-called covariant conic, a ternary quadratic. It is symmetric under exchange of self and other.
EXAMPLES:
sage: ring.<x,y,z> = QQ[]
sage: Q = invariant_theory.ternary_quadratic(x^2 + y^2 + z^2)
sage: R = invariant_theory.ternary_quadratic(x*y + x*z + y*z)
sage: Q.covariant_conic(R)-x*y - x*z - y*z
sage: R.covariant_conic(Q)-x*y - x*z - y*z>>> from sage.all import *>>> ring = QQ[ x, y, z ]; (x, y, z,) = ring._first_ngens(3)>>> Q = invariant_theory.ternary_quadratic(x**Integer(2) + y**Integer(2) +␣˓→z**Integer(2))>>> R = invariant_theory.ternary_quadratic(x*y + x*z + y*z)>>> Q.covariant_conic(R)-x*y - x*z - y*z>>> R.covariant_conic(Q)-x*y - x*z - y*z

monomials()
List the basis monomials of the form.
OUTPUT:
A tuple of monomials. They are in the same order as coeffs().
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: quadratic = invariant_theory.ternary_quadratic(x^2 + y*z)
(continues on next page)3.2. Classical Invariant Theory869

Polynomials, Release 10.4

(continued from previous page)

sage: quadratic.monomials()(x^2, y^2, z^2, x*y, x*z, y*z)>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> quadratic = invariant_theory.ternary_quadratic(x**Integer(2) + y*z)>>> quadratic.monomials()(x^2, y^2, z^2, x*y, x*z, y*z)

scaled_coeffs()
Return the scaled coefficients of a quadratic.
Given𝑝(𝑥, 𝑦) = 𝑎20 𝑥2 + 𝑎11 𝑥𝑦 + 𝑎02 𝑦 2 + 𝑎10 𝑥 + 𝑎01 𝑦 + 𝑎00
this function returns 𝑎 = (𝑎20 , 𝑎02 , 𝑎00 , 𝑎11 /2, 𝑎10 /2, 𝑎01 /2, )EXAMPLES:
sage: R.<x,y,z,a20,a11,a02,a10,a01,a00> = QQ[]
sage: p = ( a20*x^2 + a11*x*y + a02*y^2 +....:a10*x*z + a01*y*z + a00*z^2 )sage: invariant_theory.ternary_quadratic(p, x,y,z).scaled_coeffs()(a20, a02, a00, 1/2*a11, 1/2*a10, 1/2*a01)
sage: invariant_theory.ternary_quadratic(p.subs(z=1), x, y).scaled_coeffs()(a20, a02, a00, 1/2*a11, 1/2*a10, 1/2*a01)>>> from sage.all import *>>> R = QQ[ x, y, z, a20, a11, a02, a10, a01, a00 ]; (x, y, z, a20, a11, a02,␣
˓→a10, a01, a00,) = R._first_ngens(9)>>> p = ( a20*x**Integer(2) + a11*x*y + a02*y**Integer(2) +...
a10*x*z + a01*y*z + a00*z**Integer(2) )>>> invariant_theory.ternary_quadratic(p, x,y,z).scaled_coeffs()(a20, a02, a00, 1/2*a11, 1/2*a10, 1/2*a01)>>> invariant_theory.ternary_quadratic(p.subs(z=Integer(1)), x, y).scaled_
˓→coeffs()(a20, a02, a00, 1/2*a11, 1/2*a10, 1/2*a01)

class sage.rings.invariants.invariant_theory.TwoAlgebraicForms(forms)
Bases: SeveralAlgebraicForms
first()
Return the first of the two forms.
OUTPUT:
The first algebraic form used in the definition.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: q0 = invariant_theory.quadratic_form(x^2 + y^2)
sage: q1 = invariant_theory.quadratic_form(x*y)
sage: from sage.rings.invariants.invariant_theory import TwoAlgebraicForms
sage: q = TwoAlgebraicForms([q0, q1])
sage: q.first() is q0(continues on next page)

870

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)True
sage: q.get_form(0) is q0
True
sage: q.first().polynomial()x^2 + y^2>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> q0 = invariant_theory.quadratic_form(x**Integer(2) + y**Integer(2))>>> q1 = invariant_theory.quadratic_form(x*y)>>> from sage.rings.invariants.invariant_theory import TwoAlgebraicForms>>> q = TwoAlgebraicForms([q0, q1])>>> q.first() is q0
True>>> q.get_form(Integer(0)) is q0
True>>> q.first().polynomial()x^2 + y^2

second()Return the second of the two forms.
OUTPUT:
The second form used in the definition.
EXAMPLES:
sage: R.<x,y> = QQ[]
sage: q0 = invariant_theory.quadratic_form(x^2 + y^2)
sage: q1 = invariant_theory.quadratic_form(x*y)
sage: from sage.rings.invariants.invariant_theory import TwoAlgebraicForms
sage: q = TwoAlgebraicForms([q0, q1])
sage: q.second() is q1
True
sage: q.get_form(1) is q1
True
sage: q.second().polynomial()
x*y>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> q0 = invariant_theory.quadratic_form(x**Integer(2) + y**Integer(2))>>> q1 = invariant_theory.quadratic_form(x*y)>>> from sage.rings.invariants.invariant_theory import TwoAlgebraicForms>>> q = TwoAlgebraicForms([q0, q1])>>> q.second() is q1
True>>> q.get_form(Integer(1)) is q1
True>>> q.second().polynomial()
x*yclass sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics(forms)
Bases: TwoAlgebraicForms
Invariant theory of two quaternary quadratics.

3.2. Classical Invariant Theory871

Polynomials, Release 10.4

You should use the invariant_theory factory object to construct instances of this class. See quaternary_biquadratics() for details.
REFERENCES:• section on “Invariants and Covariants of Systems of Quadrics” in [Sal1958], [Sal1965]
Delta_invariant()
Return the Δ invariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Delta_invariant() == coeffs[4]True>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Delta_invariant() == coeffs[Integer(4)]True

Delta_prime_invariant()
Return the Δ′ invariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Delta_prime_invariant() == coeffs[0]True>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣(continues on next page)872

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Delta_prime_invariant() == coeffs[Integer(0)]True˓→

J_covariant()
The 𝐽-covariant.
This is the Jacobian determinant of the two biquadratics, the 𝑇 -covariant, and the 𝑇 ′ -covariant with respect
to the four homogeneous variables.
EXAMPLES:
sage: R.<w,x,y,z,a0,a1,a2,a3,A0,A1,A2,A3> = QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3*w^2
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3*w^2
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [w, x, y, z])sage: q.J_covariant().factor()z * y * x * w * (a3*A2 - a2*A3) * (a3*A1 - a1*A3) * (-a2*A1 + a1*A2)* (a3*A0 - a0*A3) * (-a2*A0 + a0*A2) * (-a1*A0 + a0*A1)>>> from sage.all import *>>> R = QQ[ w, x, y, z, a0, a1, a2, a3, A0, A1, A2, A3 ]; (w, x, y, z, a0, a1,
˓→ a2, a3, A0, A1, A2, A3,) = R._first_ngens(12)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) +␣˓→a3*w**Integer(2)>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) +␣˓→A3*w**Integer(2)>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [w, x, y, z])>>> q.J_covariant().factor()z * y * x * w * (a3*A2 - a2*A3) * (a3*A1 - a1*A3) * (-a2*A1 + a1*A2)* (a3*A0 - a0*A3) * (-a2*A0 + a0*A2) * (-a1*A0 + a0*A1)

Phi_invariant()
Return the Φ′ invariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Phi_invariant() == coeffs[2]True

3.2. Classical Invariant Theory873

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Phi_invariant() == coeffs[Integer(2)]True

T_covariant()
The 𝑇 -covariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: T = invariant_theory.quaternary_quadratic(q.T_covariant(), [x,y,z]).
˓→matrix()
sage: M = q[0].matrix().adjugate() + t*q[1].matrix().adjugate()sage: M = M.adjugate().apply_map(# long time (4s on my thinkpad␣
˓→W530)....:lambda m: m.coefficient(t))
sage: M == q.Delta_invariant()*T# long timeTrue>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> T = invariant_theory.quaternary_quadratic(q.T_covariant(), [x,y,z]).
˓→matrix()>>> M = q[Integer(0)].matrix().adjugate() + t*q[Integer(1)].matrix().
˓→adjugate()>>> M = M.adjugate().apply_map(# long time (4s on my thinkpad␣
˓→W530)...
lambda m: m.coefficient(t))>>> M == q.Delta_invariant()*T# long timeTrue

T_prime_covariant()
The 𝑇 ′ -covariant.
EXAMPLES:
874

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: Tprime = invariant_theory.quaternary_quadratic(....:
q.T_prime_covariant(), [x,y,z]).matrix()
sage: M = q[0].matrix().adjugate() + t*q[1].matrix().adjugate()sage: M = M.adjugate().apply_map(# long time (4s on my␣˓→thinkpad W530)....:
lambda m: m.coefficient(t^2))
sage: M == q.Delta_prime_invariant() * Tprime# long timeTrue>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> Tprime = invariant_theory.quaternary_quadratic(...
q.T_prime_covariant(), [x,y,z]).matrix()>>> M = q[Integer(0)].matrix().adjugate() + t*q[Integer(1)].matrix().
˓→adjugate()>>> M = M.adjugate().apply_map(# long time (4s on my thinkpad␣
˓→W530)...
lambda m: m.coefficient(t**Integer(2)))>>> M == q.Delta_prime_invariant() * Tprime# long time
True

Theta_invariant()
Return the Θ invariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Theta_invariant() == coeffs[3]True>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3
(continues on next page)3.2. Classical Invariant Theory875

Polynomials, Release 10.4

(continued from previous page)>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Theta_invariant() == coeffs[Integer(3)]True

Theta_prime_invariant()
Return the Θ′ invariant.
EXAMPLES:
sage: R.<x,y,z,t,a0,a1,a2,a3,b0,b1,b2,b3,b4,b5,A0,A1,A2,A3,B0,B1,B2,B3,B4,B5>␣
˓→= QQ[]
sage: p1 = a0*x^2 + a1*y^2 + a2*z^2 + a3
sage: p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z
sage: p2 = A0*x^2 + A1*y^2 + A2*z^2 + A3
sage: p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z
sage: q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Theta_prime_invariant() == coeffs[1]True>>> from sage.all import *>>> R = QQ[ x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3, b4, b5, A0, A1, A2,␣
˓→A3, B0, B1, B2, B3, B4, B5 ]; (x, y, z, t, a0, a1, a2, a3, b0, b1, b2, b3,␣˓→b4, b5, A0, A1, A2, A3, B0, B1, B2, B3, B4, B5,) = R._first_ngens(24)>>> p1 = a0*x**Integer(2) + a1*y**Integer(2) + a2*z**Integer(2) + a3>>> p1 += b0*x*y + b1*x*z + b2*x + b3*y*z + b4*y + b5*z>>> p2 = A0*x**Integer(2) + A1*y**Integer(2) + A2*z**Integer(2) + A3>>> p2 += B0*x*y + B1*x*z + B2*x + B3*y*z + B4*y + B5*z>>> q = invariant_theory.quaternary_biquadratic(p1, p2, [x, y, z])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Theta_prime_invariant() == coeffs[Integer(1)]Truesyzygy(Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, J)
Return the syzygy evaluated on the invariants and covariants.
INPUT:• Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T, T_prime, J – polynomials fromthe same polynomial ring.
OUTPUT:
Zero if the U is the first polynomial, V the second polynomial, and the remaining input are the invariants andcovariants of a quaternary biquadratic.
EXAMPLES:
sage: R.<w,x,y,z> = QQ[]
sage: monomials = [x^2, x*y, y^2, x*z, y*z, z^2, x*w, y*w, z*w, w^2]
(continues on next page)876

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: def q_rnd(): return sum(randint(-1000,1000)*m for m in monomials)
sage: biquadratic = invariant_theory.quaternary_biquadratic(q_rnd(), q_rnd())
sage: Delta = biquadratic.Delta_invariant()
sage: Theta = biquadratic.Theta_invariant()
sage: Phi = biquadratic.Phi_invariant()
sage: Theta_prime = biquadratic.Theta_prime_invariant()
sage: Delta_prime = biquadratic.Delta_prime_invariant()
sage: U = biquadratic.first().polynomial()
sage: V = biquadratic.second().polynomial()
sage: T = biquadratic.T_covariant()
sage: T_prime = biquadratic.T_prime_covariant()
sage: J = biquadratic.J_covariant()
sage: biquadratic.syzygy(Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T,
˓→ T_prime, J)
0>>> from sage.all import *>>> R = QQ[ w, x, y, z ]; (w, x, y, z,) = R._first_ngens(4)>>> monomials = [x**Integer(2), x*y, y**Integer(2), x*z, y*z, z**Integer(2),␣
˓→x*w, y*w, z*w, w**Integer(2)]>>> def q_rnd(): return sum(randint(-Integer(1000),Integer(1000))*m for m in␣˓→monomials)>>> biquadratic = invariant_theory.quaternary_biquadratic(q_rnd(), q_rnd())>>> Delta = biquadratic.Delta_invariant()>>> Theta = biquadratic.Theta_invariant()>>> Phi = biquadratic.Phi_invariant()>>> Theta_prime = biquadratic.Theta_prime_invariant()>>> Delta_prime = biquadratic.Delta_prime_invariant()>>> U = biquadratic.first().polynomial()>>> V = biquadratic.second().polynomial()>>> T = biquadratic.T_covariant()>>> T_prime = biquadratic.T_prime_covariant()>>> J = biquadratic.J_covariant()>>> biquadratic.syzygy(Delta, Theta, Phi, Theta_prime, Delta_prime, U, V, T,␣
˓→T_prime, J)
0

If the arguments are not the invariants and covariants then the output is some (generically non-zero) polynomial:
sage: biquadratic.syzygy(1, 1, 1, 1, 1, 1, 1, 1, 1, x)-x^2 + 1>>> from sage.all import *>>> biquadratic.syzygy(Integer(1), Integer(1), Integer(1), Integer(1),␣
˓→Integer(1), Integer(1), Integer(1), Integer(1), Integer(1), x)-x^2 + 1

class sage.rings.invariants.invariant_theory.TwoTernaryQuadratics(forms)
Bases: TwoAlgebraicForms
Invariant theory of two ternary quadratics.
You should use the invariant_theory factory object to construct instances of this class. See ternary_biquadratics() for details.
REFERENCES:
3.2. Classical Invariant Theory877

Polynomials, Release 10.4

• Section on “Invariants and Covariants of Systems of Conics”, Art. 388 (a) in [Sal1954]
Delta_invariant()
Return the Δ invariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0, y1,␣˓→y2, t> = QQ[]
sage: p1 = a00*y0^2 + 2*a01*y0*y1 + a11*y1^2 + 2*a02*y0*y2 + 2*a12*y1*y2 +␣˓→a22*y2^2
sage: p2 = b00*y0^2 + 2*b01*y0*y1 + b11*y1^2 + 2*b02*y0*y2 + 2*b12*y1*y2 +␣˓→b22*y2^2
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Delta_invariant() == coeffs[3]True>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0,␣˓→y1, y2, t ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22,␣
˓→y0, y1, y2, t,) = R._first_ngens(16)>>> p1 = a00*y0**Integer(2) + Integer(2)*a01*y0*y1 + a11*y1**Integer(2) +␣˓→Integer(2)*a02*y0*y2 + Integer(2)*a12*y1*y2 + a22*y2**Integer(2)>>> p2 = b00*y0**Integer(2) + Integer(2)*b01*y0*y1 + b11*y1**Integer(2) +␣˓→Integer(2)*b02*y0*y2 + Integer(2)*b12*y1*y2 + b22*y2**Integer(2)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Delta_invariant() == coeffs[Integer(3)]True

Delta_prime_invariant()
Return the Δ′ invariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0, y1,␣˓→y2, t> = QQ[]
sage: p1 = a00*y0^2 + 2*a01*y0*y1 + a11*y1^2 + 2*a02*y0*y2 + 2*a12*y1*y2 +␣˓→a22*y2^2
sage: p2 = b00*y0^2 + 2*b01*y0*y1 + b11*y1^2 + 2*b02*y0*y2 + 2*b12*y1*y2 +␣˓→b22*y2^2
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Delta_prime_invariant() == coeffs[0]True>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0,␣˓→y1, y2, t ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22,␣
˓→y0, y1, y2, t,) = R._first_ngens(16)>>> p1 = a00*y0**Integer(2) + Integer(2)*a01*y0*y1 + a11*y1**Integer(2) +␣˓→Integer(2)*a02*y0*y2 + Integer(2)*a12*y1*y2 + a22*y2**Integer(2)>>> p2 = b00*y0**Integer(2) + Integer(2)*b01*y0*y1 + b11*y1**Integer(2) +␣˓→Integer(2)*b02*y0*y2 + Integer(2)*b12*y1*y2 + b22*y2**Integer(2)(continues on next page)

878

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Delta_prime_invariant() == coeffs[Integer(0)]True

F_covariant()
Return the 𝐹 covariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y> =␣˓→QQ[]
sage: p1 = 73*x^2 + 96*x*y - 11*y^2 + 4*x + 63*y + 57
sage: p2 = 61*x^2 - 100*x*y - 72*y^2 - 81*x + 39*y - 7
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [x, y])sage: q.F_covariant()-32566577*x^2 + 29060637/2*x*y + 20153633/4*y^2 30250497/2*x - 241241273/4*y - 323820473/16>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y
˓→ ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y,) = R.
˓→_first_ngens(14)>>> p1 = Integer(73)*x**Integer(2) + Integer(96)*x*y -␣˓→Integer(11)*y**Integer(2) + Integer(4)*x + Integer(63)*y + Integer(57)>>> p2 = Integer(61)*x**Integer(2) - Integer(100)*x*y -␣˓→Integer(72)*y**Integer(2) - Integer(81)*x + Integer(39)*y - Integer(7)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [x, y])>>> q.F_covariant()-32566577*x^2 + 29060637/2*x*y + 20153633/4*y^2 30250497/2*x - 241241273/4*y - 323820473/16

J_covariant()
Return the 𝐽 covariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y> =␣˓→QQ[]
sage: p1 = 73*x^2 + 96*x*y - 11*y^2 + 4*x + 63*y + 57
sage: p2 = 61*x^2 - 100*x*y - 72*y^2 - 81*x + 39*y - 7
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [x, y])sage: q.J_covariant()
1057324024445*x^3 + 1209531088209*x^2*y + 942116599708*x*y^2 +984553030871*y^3 + 543715345505/2*x^2 - 3065093506021/2*x*y +755263948570*y^2 - 1118430692650*x - 509948695327/4*y + 3369951531745/8>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y
˓→ ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, x, y,) = R.
˓→_first_ngens(14)>>> p1 = Integer(73)*x**Integer(2) + Integer(96)*x*y -␣˓→Integer(11)*y**Integer(2) + Integer(4)*x + Integer(63)*y + Integer(57)>>> p2 = Integer(61)*x**Integer(2) - Integer(100)*x*y -␣˓→Integer(72)*y**Integer(2) - Integer(81)*x + Integer(39)*y - Integer(7)(continues on next page)3.2. Classical Invariant Theory879

Polynomials, Release 10.4

(continued from previous page)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [x, y])>>> q.J_covariant()
1057324024445*x^3 + 1209531088209*x^2*y + 942116599708*x*y^2 +984553030871*y^3 + 543715345505/2*x^2 - 3065093506021/2*x*y +755263948570*y^2 - 1118430692650*x - 509948695327/4*y + 3369951531745/8

Theta_invariant()
Return the Θ invariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0, y1,␣˓→y2, t> = QQ[]
sage: p1 = a00*y0^2 + 2*a01*y0*y1 + a11*y1^2 + 2*a02*y0*y2 + 2*a12*y1*y2 +␣˓→a22*y2^2
sage: p2 = b00*y0^2 + 2*b01*y0*y1 + b11*y1^2 + 2*b02*y0*y2 + 2*b12*y1*y2 +␣˓→b22*y2^2
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Theta_invariant() == coeffs[2]True>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0,␣˓→y1, y2, t ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22,␣
˓→y0, y1, y2, t,) = R._first_ngens(16)>>> p1 = a00*y0**Integer(2) + Integer(2)*a01*y0*y1 + a11*y1**Integer(2) +␣˓→Integer(2)*a02*y0*y2 + Integer(2)*a12*y1*y2 + a22*y2**Integer(2)>>> p2 = b00*y0**Integer(2) + Integer(2)*b01*y0*y1 + b11*y1**Integer(2) +␣˓→Integer(2)*b02*y0*y2 + Integer(2)*b12*y1*y2 + b22*y2**Integer(2)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Theta_invariant() == coeffs[Integer(2)]True

Theta_prime_invariant()
Return the Θ′ invariant.
EXAMPLES:
sage: R.<a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0, y1,␣˓→y2, t> = QQ[]
sage: p1 = a00*y0^2 + 2*a01*y0*y1 + a11*y1^2 + 2*a02*y0*y2 + 2*a12*y1*y2 +␣˓→a22*y2^2
sage: p2 = b00*y0^2 + 2*b01*y0*y1 + b11*y1^2 + 2*b02*y0*y2 + 2*b12*y1*y2 +␣˓→b22*y2^2
sage: q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])sage: coeffs = det(t * q[0].matrix() + q[1].matrix()).polynomial(t).
˓→coefficients(sparse=False)
sage: q.Theta_prime_invariant() == coeffs[1]True>>> from sage.all import *>>> R = QQ[ a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22, y0,␣(continues on next page)

880

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)y1, y2, t ]; (a00, a01, a11, a02, a12, a22, b00, b01, b11, b02, b12, b22,␣
˓→y0, y1, y2, t,) = R._first_ngens(16)>>> p1 = a00*y0**Integer(2) + Integer(2)*a01*y0*y1 + a11*y1**Integer(2) +␣˓→Integer(2)*a02*y0*y2 + Integer(2)*a12*y1*y2 + a22*y2**Integer(2)>>> p2 = b00*y0**Integer(2) + Integer(2)*b01*y0*y1 + b11*y1**Integer(2) +␣˓→Integer(2)*b02*y0*y2 + Integer(2)*b12*y1*y2 + b22*y2**Integer(2)>>> q = invariant_theory.ternary_biquadratic(p1, p2, [y0, y1, y2])>>> coeffs = det(t * q[Integer(0)].matrix() + q[Integer(1)].matrix()).
˓→polynomial(t).coefficients(sparse=False)>>> q.Theta_prime_invariant() == coeffs[Integer(1)]True˓→syzygy(Delta, Theta, Theta_prime, Delta_prime, S, S_prime, F, J)
Return the syzygy evaluated on the invariants and covariants.
INPUT:• Delta, Theta, Theta_prime, Delta_prime, S, S_prime, F, J – polynomials from the samepolynomial ring.
OUTPUT:
Zero if S is the first polynomial, S_prime the second polynomial, and the remaining input are the invariants
and covariants of a ternary biquadratic.
EXAMPLES:
sage: R.<x,y,z> = QQ[]
sage: monomials = [x^2, x*y, y^2, x*z, y*z, z^2]
sage: def q_rnd(): return sum(randint(-1000,1000)*m for m in monomials)
sage: biquadratic = invariant_theory.ternary_biquadratic(q_rnd(), q_rnd(), [x,˓→y,z])
sage: Delta = biquadratic.Delta_invariant()
sage: Theta = biquadratic.Theta_invariant()
sage: Theta_prime = biquadratic.Theta_prime_invariant()
sage: Delta_prime = biquadratic.Delta_prime_invariant()
sage: S = biquadratic.first().polynomial()
sage: S_prime = biquadratic.second().polynomial()
sage: F = biquadratic.F_covariant()
sage: J = biquadratic.J_covariant()
sage: biquadratic.syzygy(Delta, Theta, Theta_prime, Delta_prime, S, S_prime,␣
˓→F, J)0>>> from sage.all import *>>> R = QQ[ x, y, z ]; (x, y, z,) = R._first_ngens(3)>>> monomials = [x**Integer(2), x*y, y**Integer(2), x*z, y*z, z**Integer(2)]>>> def q_rnd(): return sum(randint(-Integer(1000),Integer(1000))*m for m in␣˓→monomials)>>> biquadratic = invariant_theory.ternary_biquadratic(q_rnd(), q_rnd(), [x,y,˓→z])>>> Delta = biquadratic.Delta_invariant()>>> Theta = biquadratic.Theta_invariant()>>> Theta_prime = biquadratic.Theta_prime_invariant()>>> Delta_prime = biquadratic.Delta_prime_invariant()>>> S = biquadratic.first().polynomial()>>> S_prime = biquadratic.second().polynomial()>>> F = biquadratic.F_covariant()(continues on next page)3.2. Classical Invariant Theory881

Polynomials, Release 10.4

(continued from previous page)>>> J = biquadratic.J_covariant()>>> biquadratic.syzygy(Delta, Theta, Theta_prime, Delta_prime, S, S_prime, F,␣
˓→J)0

If the arguments are not the invariants and covariants then the output is some (generically non-zero) polynomial:
sage: biquadratic.syzygy(1, 1, 1, 1, 1, 1, 1, x)
1/64*x^2 + 1>>> from sage.all import *>>> biquadratic.syzygy(Integer(1), Integer(1), Integer(1), Integer(1),␣
˓→Integer(1), Integer(1), Integer(1), x)
1/64*x^2 + 1

sage.rings.invariants.invariant_theory.transvectant(f, g, h=1, scale='default')
Return the h-th transvectant of f and g.
INPUT:• f, g – two homogeneous binary forms in the same polynomial ring.
• h – the order of the transvectant. If it is not specified, the first transvectant is returned.
• scale – the scaling factor applied to the result. Possible values are default and none . The
default scaling factor is the one that appears in the output statement below, if the scaling factor isnone the quotient of factorials is left out.
OUTPUT:
The h-th transvectant of the listed forms 𝑓 and 𝑔:
(︃(︂
)︃
)︂ℎ
(𝑑𝑓 − ℎ)! · (𝑑𝑔 − ℎ)!
𝜕 𝜕𝜕 𝜕(𝑓, 𝑔)ℎ =−(𝑓 (𝑥, 𝑧) · 𝑔(𝑥′ , 𝑧 ′ ))𝑑𝑓 ! · 𝑑𝑔 !
𝜕𝑥 𝜕𝑧 ′
𝜕𝑥′ 𝜕𝑧(𝑥′ ,𝑧 ′ )=(𝑥,𝑧)EXAMPLES:
sage: from sage.rings.invariants.invariant_theory import AlgebraicForm,␣
˓→transvectant
sage: R.<x,y> = QQ[]
sage: f = AlgebraicForm(2, 5, x^5 + 5*x^4*y + 5*x*y^4 + y^5)
sage: transvectant(f, f, 4)
Binary quadratic given by 2*x^2 - 4*x*y + 2*y^2
sage: transvectant(f, f, 8)
Binary form of degree -6 given by 0>>> from sage.all import *>>> from sage.rings.invariants.invariant_theory import AlgebraicForm, transvectant>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = AlgebraicForm(Integer(2), Integer(5), x**Integer(5) +␣˓→Integer(5)*x**Integer(4)*y + Integer(5)*x*y**Integer(4) + y**Integer(5))>>> transvectant(f, f, Integer(4))
Binary quadratic given by 2*x^2 - 4*x*y + 2*y^2>>> transvectant(f, f, Integer(8))
Binary form of degree -6 given by 0882

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

The default scaling will yield an error for fields of positive characteristic below 𝑑𝑓 ! or 𝑑𝑔 ! as the denominator of
the scaling factor will not be invertible in that case. The scale argument none can be used to compute thetransvectant in this case:sage: # needs sage.rings.finite_rings
sage: R.<a0,a1,a2,a3,a4,a5,x0,x1> = GF(5)[]sage: f = AlgebraicForm(2, 5, a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2....:+ a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5, x0, x1)
sage: transvectant(f, f, 4)Traceback (most recent call last):...
ZeroDivisionError
sage: transvectant(f, f, 4, scale= none )Binary quadratic given by -a3^2*x0^2 + a2*a4*x0^2 + a2*a3*x0*x1- a1*a4*x0*x1 - a2^2*x1^2 + a1*a3*x1^2>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> R = GF(Integer(5))[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5,
˓→ x0, x1,) = R._first_ngens(8)>>> f = AlgebraicForm(Integer(2), Integer(5), a0*x1**Integer(5) +␣˓→a1*x1**Integer(4)*x0 + a2*x1**Integer(3)*x0**Integer(2)...
+ a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5), x0, x1)>>> transvectant(f, f, Integer(4))
Traceback (most recent call last):...
ZeroDivisionError>>> transvectant(f, f, Integer(4), scale= none )Binary quadratic given by -a3^2*x0^2 + a2*a4*x0^2 + a2*a3*x0*x1- a1*a4*x0*x1 - a2^2*x1^2 + a1*a3*x1^2

The additional factors that appear when scale= none is used can be seen if we consider the same transvectant
over the rationals and compare it to the scaled version:
sage: R.<a0,a1,a2,a3,a4,a5,x0,x1> = QQ[]
sage: f = AlgebraicForm(2, 5, a0*x1^5 + a1*x1^4*x0 + a2*x1^3*x0^2....:+ a3*x1^2*x0^3 + a4*x1*x0^4 + a5*x0^5, x0, x1)
sage: transvectant(f, f, 4)
Binary quadratic given by 3/50*a3^2*x0^2 - 4/25*a2*a4*x0^2+ 2/5*a1*a5*x0^2 + 1/25*a2*a3*x0*x1 - 6/25*a1*a4*x0*x1 + 2*a0*a5*x0*x1+ 3/50*a2^2*x1^2 - 4/25*a1*a3*x1^2 + 2/5*a0*a4*x1^2
sage: transvectant(f, f, 4, scale= none )Binary quadratic given by 864*a3^2*x0^2 - 2304*a2*a4*x0^2+ 5760*a1*a5*x0^2 + 576*a2*a3*x0*x1 - 3456*a1*a4*x0*x1+ 28800*a0*a5*x0*x1 + 864*a2^2*x1^2 - 2304*a1*a3*x1^2 + 5760*a0*a4*x1^2>>> from sage.all import *>>> R = QQ[ a0, a1, a2, a3, a4, a5, x0, x1 ]; (a0, a1, a2, a3, a4, a5, x0, x1,) =␣
˓→R._first_ngens(8)>>> f = AlgebraicForm(Integer(2), Integer(5), a0*x1**Integer(5) +␣˓→a1*x1**Integer(4)*x0 + a2*x1**Integer(3)*x0**Integer(2)...
+ a3*x1**Integer(2)*x0**Integer(3) +␣˓→a4*x1*x0**Integer(4) + a5*x0**Integer(5), x0, x1)>>> transvectant(f, f, Integer(4))
Binary quadratic given by 3/50*a3^2*x0^2 - 4/25*a2*a4*x0^2+ 2/5*a1*a5*x0^2 + 1/25*a2*a3*x0*x1 - 6/25*a1*a4*x0*x1 + 2*a0*a5*x0*x1(continues on next page)3.2. Classical Invariant Theory883

Polynomials, Release 10.4

(continued from previous page)+ 3/50*a2^2*x1^2 - 4/25*a1*a3*x1^2 + 2/5*a0*a4*x1^2>>> transvectant(f, f, Integer(4), scale= none )Binary quadratic given by 864*a3^2*x0^2 - 2304*a2*a4*x0^2+ 5760*a1*a5*x0^2 + 576*a2*a3*x0*x1 - 3456*a1*a4*x0*x1+ 28800*a0*a5*x0*x1 + 864*a2^2*x1^2 - 2304*a1*a3*x1^2 + 5760*a0*a4*x1^2

If the forms are given as inhomogeneous polynomials, the homogenisation might fail if the polynomial ring has
multiple variables. You can circumvent this by making sure the base ring of the polynomial has only one variable:
sage: R.<x,y> = QQ[]
sage: quintic = invariant_theory.binary_quintic(x^5 + x^3 + 2*x^2 + y^5, x)
sage: transvectant(quintic, quintic, 2)Traceback (most recent call last):...
ValueError: polynomial is not homogeneous
sage: R.<y> = QQ[]
sage: S.<x> = R[]
sage: quintic = invariant_theory.binary_quintic(x^5 + x^3 + 2*x^2 + y^5, x)
sage: transvectant(quintic, quintic, 2)Binary sextic given by 1/5*x^6 + 6/5*x^5*h - 3/25*x^4*h^2+ (50*y^5 - 8)/25*x^3*h^3 - 12/25*x^2*h^4 + (3*y^5)/5*x*h^5+ (2*y^5)/5*h^6>>> from sage.all import *>>> R = QQ[ x, y ]; (x, y,) = R._first_ngens(2)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + x**Integer(3) +␣˓→Integer(2)*x**Integer(2) + y**Integer(5), x)>>> transvectant(quintic, quintic, Integer(2))
Traceback (most recent call last):...
ValueError: polynomial is not homogeneous>>> R = QQ[ y ]; (y,) = R._first_ngens(1)>>> S = R[ x ]; (x,) = S._first_ngens(1)>>> quintic = invariant_theory.binary_quintic(x**Integer(5) + x**Integer(3) +␣˓→Integer(2)*x**Integer(2) + y**Integer(5), x)>>> transvectant(quintic, quintic, Integer(2))
Binary sextic given by 1/5*x^6 + 6/5*x^5*h - 3/25*x^4*h^2+ (50*y^5 - 8)/25*x^3*h^3 - 12/25*x^2*h^4 + (3*y^5)/5*x*h^5+ (2*y^5)/5*h^63.2.2 Reconstruction of Algebraic Forms
This module reconstructs algebraic forms from the values of their invariants. Given a set of (classical) invariants, it returns
a form that attains this values as invariants (up to scaling).
AUTHORS:• Jesper Noordsij (2018-06): initial version

884

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage.rings.invariants.reconstruction.binary_cubic_coefficients_from_invariants(discriminant,invariant_choice='default')
Reconstruct a binary cubic from the value of its discriminant.
INPUT:• discriminant – The value of the discriminant of the binary cubic.
• invariant_choice – The type of invariants provided. The accepted options are discriminantand default , which are the same. No other options are implemented.
OUTPUT:
A set of coefficients of a binary cubic, whose discriminant is equal to the given discriminant up to a scaling.
EXAMPLES:
sage: from sage.rings.invariants.reconstruction import binary_cubic_coefficients_
˓→from_invariants
sage: coeffs = binary_cubic_coefficients_from_invariants(1)sage: coeffs(0, 1, -1, 0)
sage: R.<x> = QQ[]
sage: R(coeffs).discriminant()#␣˓→needs sage.libs.pari
1>>> from sage.all import *>>> from sage.rings.invariants.reconstruction import binary_cubic_coefficients_
˓→from_invariants>>> coeffs = binary_cubic_coefficients_from_invariants(Integer(1))>>> coeffs(0, 1, -1, 0)>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R(coeffs).discriminant()#␣˓→needs sage.libs.pari
1

The two non-equivalent cubics 𝑥3 and 𝑥2 * 𝑧 with discriminant 0 can’t be distinguished based on their discriminant,hence an error is raised:sage: binary_cubic_coefficients_from_invariants(0)Traceback (most recent call last):...
ValueError: no unique reconstruction possible for binary cubics with a double root>>> from sage.all import *>>> binary_cubic_coefficients_from_invariants(Integer(0))
Traceback (most recent call last):...
ValueError: no unique reconstruction possible for binary cubics with a double root

3.2. Classical Invariant Theory885

Polynomials, Release 10.4

sage.rings.invariants.reconstruction.binary_quadratic_coefficients_from_invariants(discriminant,invariant_choice=fault')
Reconstruct a binary quadratic from the value of its discriminant.
INPUT:• discriminant – The value of the discriminant of the binary quadratic.
• invariant_choice – The type of invariants provided. The accepted options are discriminantand default , which are the same. No other options are implemented.
OUTPUT:
A set of coefficients of a binary quadratic, whose discriminant is equal to the given discriminant up to ascaling.
EXAMPLES:
sage: from sage.rings.invariants.reconstruction import binary_quadratic_
˓→coefficients_from_invariants
sage: quadratic = invariant_theory.binary_form_from_invariants(2, [24]) #␣˓→indirect doctest
sage: quadratic
Binary quadratic with coefficients (1, -6, 0)
sage: quadratic.discriminant()
24
sage: binary_quadratic_coefficients_from_invariants(0)(1, 0, 0)>>> from sage.all import *>>> from sage.rings.invariants.reconstruction import binary_quadratic_
˓→coefficients_from_invariants>>> quadratic = invariant_theory.binary_form_from_invariants(Integer(2),␣
˓→[Integer(24)])# indirect doctest>>> quadratic
Binary quadratic with coefficients (1, -6, 0)>>> quadratic.discriminant()
24>>> binary_quadratic_coefficients_from_invariants(Integer(0))(1, 0, 0)sage.rings.invariants.reconstruction.binary_quintic_coefficients_from_invariants(invariants,
K=None,invariant_choice='default',
scaling='none')
Reconstruct a binary quintic from the values of its (Clebsch) invariants.
886

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

INPUT:• invariants – A list or tuple of values of the three or four invariants. The default option requires theClebsch invariants 𝐴, 𝐵, 𝐶 and 𝑅 of the binary quintic.
• K – The field over which the quintic is defined.
• invariant_choice – The type of invariants provided. The accepted options are clebsch anddefault , which are the same. No other options are implemented.
• scaling – How the coefficients should be scaled. The accepted values are none for no scaling,normalized to scale in such a way that the resulting coefficients are independent of the scaling of
the input invariants and coprime which scales the input invariants by dividing them by their gcd.
OUTPUT:
A set of coefficients of a binary quintic, whose invariants are equal to the given invariants up to a scaling.
EXAMPLES:First we check the general case, where the invariant 𝑀 is non-zero:sage: R.<x0, x1> = QQ[]
sage: p = 3*x1^5 + 6*x1^4*x0 + 3*x1^3*x0^2 + 4*x1^2*x0^3 - 5*x1*x0^4 + 4*x0^5sage: quintic = invariant_theory.binary_quintic(p, x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)
sage: reconstructed = invariant_theory.binary_form_from_invariants( # indirect␣
˓→doctest....:
5, invs, variables=quintic.variables())
sage: reconstructed
Binary quintic with coefficients (9592267437341790539005557/244140625000000,
2149296928207625556323004064707/610351562500000000,
11149651890347700974453304786783/76293945312500000,
122650775751894638395648891202734239/47683715820312500000,
323996630945706528474286334593218447/11920928955078125000,
1504506503644608395841632538558481466127/14901161193847656250000)>>> from sage.all import *>>> R = QQ[ x0, x1 ]; (x0, x1,) = R._first_ngens(2)>>> p = Integer(3)*x1**Integer(5) + Integer(6)*x1**Integer(4)*x0 +␣˓→Integer(3)*x1**Integer(3)*x0**Integer(2) +␣˓→Integer(4)*x1**Integer(2)*x0**Integer(3) - Integer(5)*x1*x0**Integer(4) +␣˓→Integer(4)*x0**Integer(5)>>> quintic = invariant_theory.binary_quintic(p, x0, x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> reconstructed = invariant_theory.binary_form_from_invariants( # indirect␣
˓→doctest...
Integer(5), invs, variables=quintic.variables())>>> reconstructed
Binary quintic with coefficients (9592267437341790539005557/244140625000000,
2149296928207625556323004064707/610351562500000000,
11149651890347700974453304786783/76293945312500000,
122650775751894638395648891202734239/47683715820312500000,
323996630945706528474286334593218447/11920928955078125000,
1504506503644608395841632538558481466127/14901161193847656250000)

We can see that the invariants of the reconstructed form match the ones of the original form by scaling the invariants
𝐵 and 𝐶:3.2. Classical Invariant Theory887

Polynomials, Release 10.4

sage: scale = invs[0]/reconstructed.A_invariant()
sage: invs[1] == reconstructed.B_invariant()*scale^2
Truesage: invs[2] == reconstructed.C_invariant()*scale^3
True>>> from sage.all import *>>> scale = invs[Integer(0)]/reconstructed.A_invariant()>>> invs[Integer(1)] == reconstructed.B_invariant()*scale**Integer(2)True>>> invs[Integer(2)] == reconstructed.C_invariant()*scale**Integer(3)True

If we compare the form obtained by this reconstruction to the one found by letting the covariants 𝛼 and 𝛽 be thecoordinates of the form, we find the forms are the same up to a power of the determinant of 𝛼 and 𝛽:
sage: alpha = quintic.alpha_covariant()
sage: beta = quintic.beta_covariant()
sage: g = matrix([[alpha(x0=1,x1=0), alpha(x0=0,x1=1)],....:[beta(x0=1,x1=0), beta(x0=0,x1=1)]])^-1
sage: transformed = tuple([g.determinant()^-5*x....:
for x in quintic.transformed(g).coeffs()])
sage: transformed == reconstructed.coeffs()
True>>> from sage.all import *>>> alpha = quintic.alpha_covariant()>>> beta = quintic.beta_covariant()>>> g = matrix([[alpha(x0=Integer(1),x1=Integer(0)), alpha(x0=Integer(0),˓→x1=Integer(1))],...
[beta(x0=Integer(1),x1=Integer(0)), beta(x0=Integer(0),˓→x1=Integer(1))]])**-Integer(1)>>> transformed = tuple([g.determinant()**-Integer(5)*x...
for x in quintic.transformed(g).coeffs()])>>> transformed == reconstructed.coeffs()
True

This can also be seen by computing the 𝛼 covariant of the obtained form:
sage: reconstructed.alpha_covariant().coefficient(x1)0sage: reconstructed.alpha_covariant().coefficient(x0) != 0
True>>> from sage.all import *>>> reconstructed.alpha_covariant().coefficient(x1)0>>> reconstructed.alpha_covariant().coefficient(x0) != Integer(0)True

If the invariant 𝑀 vanishes, then the coefficients are computed in a different way:sage: [A,B,C] = [3,1,2]
sage: M = 2*A*B - 3*C
sage: M
0(continues on next page)

888

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: from sage.rings.invariants.reconstruction import binary_quintic_
˓→coefficients_from_invariants
sage: reconstructed = binary_quintic_coefficients_from_invariants([A,B,C])
sage: reconstructed(-66741943359375/2097152,-125141143798828125/134217728,
0,52793920040130615234375/34359738368,
19797720015048980712890625/1099511627776,-4454487003386020660400390625/17592186044416)
sage: newform = sum([ reconstructed[i]*x0^i*x1^(5-i) for i in range(6) ])sage: newquintic = invariant_theory.binary_quintic(newform, x0, x1)
sage: scale = 3/newquintic.A_invariant()
sage: [3, newquintic.B_invariant()*scale^2, newquintic.C_invariant()*scale^3][3, 1, 2]>>> from sage.all import *>>> [A,B,C] = [Integer(3),Integer(1),Integer(2)]>>> M = Integer(2)*A*B - Integer(3)*C>>> M
0>>> from sage.rings.invariants.reconstruction import binary_quintic_coefficients_
˓→from_invariants>>> reconstructed = binary_quintic_coefficients_from_invariants([A,B,C])>>> reconstructed(-66741943359375/2097152,-125141143798828125/134217728,
0,52793920040130615234375/34359738368,
19797720015048980712890625/1099511627776,-4454487003386020660400390625/17592186044416)>>> newform = sum([ reconstructed[i]*x0**i*x1**(Integer(5)-i) for i in␣
˓→range(Integer(6)) ])>>> newquintic = invariant_theory.binary_quintic(newform, x0, x1)>>> scale = Integer(3)/newquintic.A_invariant()>>> [Integer(3), newquintic.B_invariant()*scale**Integer(2), newquintic.C_
˓→invariant()*scale**Integer(3)][3, 1, 2]

Several special cases:
sage: quintic = invariant_theory.binary_quintic(x0^5 - x1^5, x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)
sage: binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 0, 0, 1)
sage: quintic = invariant_theory.binary_quintic(x0*x1*(x0^3-x1^3), x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)
sage: binary_quintic_coefficients_from_invariants(invs)(0, 1, 0, 0, 1, 0)
sage: quintic = invariant_theory.binary_quintic(x0^5 + 10*x0^3*x1^2 - 15*x0*x1^4,␣
˓→x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)
sage: binary_quintic_coefficients_from_invariants(invs)(1, 0, 10, 0, -15, 0)
sage: quintic = invariant_theory.binary_quintic(x0^2*(x0^3 + x1^3), x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)(continues on next page)3.2. Classical Invariant Theory889

Polynomials, Release 10.4

(continued from previous page)

sage: binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 1, 0, 0)
sage: quintic = invariant_theory.binary_quintic(x0*(x0^4 + x1^4), x0, x1)
sage: invs = quintic.clebsch_invariants(as_tuple=True)
sage: binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 0, 1, 0)>>> from sage.all import *>>> quintic = invariant_theory.binary_quintic(x0**Integer(5) - x1**Integer(5), x0,
˓→ x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 0, 0, 1)>>> quintic = invariant_theory.binary_quintic(x0*x1*(x0**Integer(3)˓→x1**Integer(3)), x0, x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> binary_quintic_coefficients_from_invariants(invs)(0, 1, 0, 0, 1, 0)>>> quintic = invariant_theory.binary_quintic(x0**Integer(5) +␣˓→Integer(10)*x0**Integer(3)*x1**Integer(2) - Integer(15)*x0*x1**Integer(4), x0,␣˓→x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> binary_quintic_coefficients_from_invariants(invs)(1, 0, 10, 0, -15, 0)>>> quintic = invariant_theory.binary_quintic(x0**Integer(2)*(x0**Integer(3) +␣˓→x1**Integer(3)), x0, x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 1, 0, 0)>>> quintic = invariant_theory.binary_quintic(x0*(x0**Integer(4) +␣˓→x1**Integer(4)), x0, x1)>>> invs = quintic.clebsch_invariants(as_tuple=True)>>> binary_quintic_coefficients_from_invariants(invs)(1, 0, 0, 0, 1, 0)

For fields of characteristic 2, 3 or 5, there is no reconstruction implemented. This is part of Issue #26786.:
sage: binary_quintic_coefficients_from_invariants([3,1,2], K=GF(5))
Traceback (most recent call last):...
NotImplementedError: no reconstruction of binary quintics implemented
for fields of characteristic 2, 3 or 5>>> from sage.all import *>>> binary_quintic_coefficients_from_invariants([Integer(3),Integer(1),˓→Integer(2)], K=GF(Integer(5)))
Traceback (most recent call last):...
NotImplementedError: no reconstruction of binary quintics implemented
for fields of characteristic 2, 3 or 5

890

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

3.3 Educational Versions of Groebner Basis Related Algorithms
3.3.1 Educational versions of Groebner basis algorithms
Following [BW1993], the original Buchberger algorithm (algorithm GROEBNER in [BW1993]) and an improved version
of Buchberger’s algorithm (algorithm GROEBNERNEW2 in [BW1993]) are implemented.
No attempt was made to optimize either algorithm as the emphasis of these implementations is a clean and easy presentation. To compute a Groebner basis most efficiently in Sage, use the MPolynomialIdeal.groebner_basis()
method on multivariate polynomial objects instead.
Note: The notion of ‘term’ and ‘monomial’ in [BW1993] is swapped from the notion of those words in Sage (or theother way around, however you prefer it). In Sage a term is a monomial multiplied by a coefficient, while in [BW1993] amonomial is a term multiplied by a coefficient. Also, what is called LM (the leading monomial) in Sage is called HT (thehead term) in [BW1993].
EXAMPLES:
Consider Katsura-6 with respect to a degrevlex ordering.
sage: # needs sage.libs.singular sage.rings.finite_rings
sage: from sage.rings.polynomial.toy_buchberger import *sage: P.<a,b,c,e,f,g,h,i,j,k> = PolynomialRing(GF(32003))
sage: I = sage.rings.ideal.Katsura(P, 6)
sage: g1 = buchberger(I)sage: g2 = buchberger_improved(I)sage: g3 = I.groebner_basis()>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> from sage.rings.polynomial.toy_buchberger import *>>> P = PolynomialRing(GF(Integer(32003)), names=( a , b , c , e , f ,˓→ i ,
j , k ,)); (a, b, c, e, f, g, h, i, j, k,) = P._first_ngens(10)>>> I = sage.rings.ideal.Katsura(P, Integer(6))>>> g1 = buchberger(I)>>> g2 = buchberger_improved(I)>>> g3 = I.groebner_basis()

g ,

h ,

All algorithms actually compute a Groebner basis:sage: # needs sage.libs.singular sage.rings.finite_rings
sage: Ideal(g1).basis_is_groebner()True
sage: Ideal(g2).basis_is_groebner()True
sage: Ideal(g3).basis_is_groebner()True>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> Ideal(g1).basis_is_groebner()
True>>> Ideal(g2).basis_is_groebner()
True(continues on next page)3.3. Educational Versions of Groebner Basis Related Algorithms

891

Polynomials, Release 10.4

(continued from previous page)>>> Ideal(g3).basis_is_groebner()
True

The results are correct:
sage: # needs sage.libs.singular sage.rings.finite_rings
sage: Ideal(g1) == Ideal(g2) == Ideal(g3)True>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> Ideal(g1) == Ideal(g2) == Ideal(g3)True

If get_verbose() is ≥ 1, a protocol is provided:
sage: # needs sage.libs.singular sage.rings.finite_rings
sage: from sage.misc.verbose import set_verbose
sage: set_verbose(1)sage: P.<a,b,c> = PolynomialRing(GF(127))
sage: I = sage.rings.ideal.Katsura(P)// sage... ideal
sage: I
Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b)of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
sage: buchberger(I) # random(a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a) => -2*b^2 - 6*b*c - 6*c^2 + b + 2*c
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c␣
˓→- 6*c^2 + b + 2*c])(a^2 + 2*b^2 + 2*c^2 - a, a + 2*b + 2*c - 1) => 0
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c␣
˓→- 6*c^2 + b + 2*c])(a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b) => -5*b*c - 6*c^2 - 63*b + 2*c
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c, a^2 + 2*b^
˓→2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c])(2*a*b + 2*b*c - b, a + 2*b + 2*c - 1) => 0
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c, a^2 + 2*b^
˓→2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c])(2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c) => -22*c^3 + 24*c^2 - 60*b - 62*c
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(2*a*b + 2*b*c - b, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a + 2*b + 2*c - 1, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
(continues on next page)892

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)˓→

2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(-2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a + 2*b + 2*c - 1, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a^2 + 2*b^2 + 2*c^2 - a, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(-5*b*c - 6*c^2 - 63*b + 2*c, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(-2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(2*a*b + 2*b*c - b, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(a^2 + 2*b^2 + 2*c^2 - a, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])
15 reductions to zero.
[a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 + 2*b^2 +␣
˓→2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c]>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> from sage.misc.verbose import set_verbose>>> set_verbose(Integer(1))>>> P = PolynomialRing(GF(Integer(127)), names=( a , b , c ,)); (a, b, c,) = P._
˓→first_ngens(3)>>> I = sage.rings.ideal.Katsura(P)// sage... ideal>>> I
Ideal (a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b)(continues on next page)3.3. Educational Versions of Groebner Basis Related Algorithms

893

Polynomials, Release 10.4

(continued from previous page)of Multivariate Polynomial Ring in a, b, c over Finite Field of size 127>>> buchberger(I) # random(a + 2*b + 2*c - 1, a^2 + 2*b^2 + 2*c^2 - a) => -2*b^2 - 6*b*c - 6*c^2 + b + 2*c
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c␣
˓→- 6*c^2 + b + 2*c])<BLANKLINE>(a^2 + 2*b^2 + 2*c^2 - a, a + 2*b + 2*c - 1) => 0
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c␣
˓→- 6*c^2 + b + 2*c])<BLANKLINE>(a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b) => -5*b*c - 6*c^2 - 63*b + 2*c
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c, a^2 + 2*b^
˓→2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c])<BLANKLINE>(2*a*b + 2*b*c - b, a + 2*b + 2*c - 1) => 0
G: set([a + 2*b + 2*c - 1, 2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c, a^2 + 2*b^
˓→2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c])<BLANKLINE>(2*a*b + 2*b*c - b, -5*b*c - 6*c^2 - 63*b + 2*c) => -22*c^3 + 24*c^2 - 60*b - 62*c
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(2*a*b + 2*b*c - b, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(2*a*b + 2*b*c - b, a^2 + 2*b^2 + 2*c^2 - a) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a + 2*b + 2*c - 1, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a^2 + 2*b^2 + 2*c^2 - a, 2*a*b + 2*b*c - b) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(-2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a + 2*b + 2*c - 1, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a^2 + 2*b^2 + 2*c^2 - a, -5*b*c - 6*c^2 - 63*b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(-5*b*c - 6*c^2 - 63*b + 2*c, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])(continues on next page)894

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)<BLANKLINE>(a^2 + 2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(-2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(2*a*b + 2*b*c - b, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>(a^2 + 2*b^2 + 2*c^2 - a, -22*c^3 + 24*c^2 - 60*b - 62*c) => 0
G: set([a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 +␣
˓→2*b^2 + 2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c])<BLANKLINE>
15 reductions to zero.
[a + 2*b + 2*c - 1, -22*c^3 + 24*c^2 - 60*b - 62*c, 2*a*b + 2*b*c - b, a^2 + 2*b^2 +␣
˓→2*c^2 - a, -2*b^2 - 6*b*c - 6*c^2 + b + 2*c, -5*b*c - 6*c^2 - 63*b + 2*c]

The original Buchberger algorithm performs 15 useless reductions to zero for this example:
sage: # needs sage.libs.singular sage.rings.finite_rings
sage: gb = buchberger(I)...
15 reductions to zero.
>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> gb = buchberger(I)...
15 reductions to zero.

The ‘improved’ Buchberger algorithm in contrast only performs 1 reduction to zero:sage: # needs sage.libs.singular sage.rings.finite_rings
sage: gb = buchberger_improved(I)...
1 reductions to zero.
sage: sorted(gb)[a + 2*b + 2*c - 1, b*c + 52*c^2 + 38*b + 25*c,b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c]>>> from sage.all import *>>> # needs sage.libs.singular sage.rings.finite_rings>>> gb = buchberger_improved(I)...
1 reductions to zero.
>>> sorted(gb)[a + 2*b + 2*c - 1, b*c + 52*c^2 + 38*b + 25*c,b^2 - 26*c^2 - 51*b + 51*c, c^3 + 22*c^2 - 55*b + 49*c]

AUTHORS:• Martin Albrecht (2007-05-24): initial version

3.3. Educational Versions of Groebner Basis Related Algorithms

895

Polynomials, Release 10.4

• Marshall Hampton (2009-07-08): some doctest additions
sage.rings.polynomial.toy_buchberger.LCM(f, g)
sage.rings.polynomial.toy_buchberger.LM(f)sage.rings.polynomial.toy_buchberger.LT(f)sage.rings.polynomial.toy_buchberger.buchberger(F)Compute a Groebner basis using the original version of Buchberger’s algorithm as presented in [BW1993], page214.
INPUT:• F – an ideal in a multivariate polynomial ring
OUTPUT: a Groebner basis for F
Note: The verbosity of this function may be controlled with a set_verbose() call. Any value >=1 will resultin this function printing intermediate bases.
EXAMPLES:
sage: from sage.rings.polynomial.toy_buchberger import buchberger
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: I = R.ideal([x^2 - z - 1, z^2 - y - 1, x*y^2 - x - 1])sage: set_verbose(0)sage: gb = buchberger(I)˓→needs sage.libs.singularsage: gb.is_groebner()
˓→needs sage.libs.singularTrue
sage: gb.ideal() == I˓→needs sage.libs.singular
True

#␣
#␣

#␣

>>> from sage.all import *>>> from sage.rings.polynomial.toy_buchberger import buchberger>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_ngens(3)>>> I = R.ideal([x**Integer(2) - z - Integer(1), z**Integer(2) - y - Integer(1),␣
˓→x*y**Integer(2) - x - Integer(1)])>>> set_verbose(Integer(0))>>> gb = buchberger(I)#␣˓→needs sage.libs.singular>>> gb.is_groebner()#␣˓→needs sage.libs.singularTrue>>> gb.ideal() == I#␣˓→needs sage.libs.singularTruesage.rings.polynomial.toy_buchberger.buchberger_improved(F)Compute a Groebner basis using an improved version of Buchberger’s algorithm as presented in [BW1993], page
232.
This variant uses the Gebauer-Moeller Installation to apply Buchberger’s first and second criterion to avoid uselesspairs.
INPUT:
896

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• F – an ideal in a multivariate polynomial ring
OUTPUT: a Groebner basis for F
Note: The verbosity of this function may be controlled with a set_verbose() call. Any value >=1 will resultin this function printing intermediate Groebner bases.
EXAMPLES:
sage: from sage.rings.polynomial.toy_buchberger import buchberger_improved
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: set_verbose(0)sage: sorted(buchberger_improved(R.ideal([x^4 - y - z, x*y*z - 1])))
˓→needs sage.libs.singular[x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2]

#␣>>> from sage.all import *>>> from sage.rings.polynomial.toy_buchberger import buchberger_improved>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_ngens(3)>>> set_verbose(Integer(0))>>> sorted(buchberger_improved(R.ideal([x**Integer(4) - y - z, x*y*z -␣˓→Integer(1)])))# needs sage.libs.singular[x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2]

sage.rings.polynomial.toy_buchberger.inter_reduction(Q)Compute inter-reduced polynomials from a set of polynomials.
INPUT:• Q – a set of polynomials
OUTPUT:
if Q is the set 𝑓1 , ..., 𝑓𝑛 , this method returns 𝑔1 , ..., 𝑔𝑠 such that:• (𝑓1 , ..., 𝑓𝑛 ) = (𝑔1 , ..., 𝑔𝑠 )• 𝐿𝑀 (𝑔𝑖 ) ̸= 𝐿𝑀 (𝑔𝑗 ) for all 𝑖 ̸= 𝑗
• 𝐿𝑀 (𝑔𝑖 ) does not divide 𝑚 for all monomials 𝑚 of {𝑔1 , ..., 𝑔𝑖−1 , 𝑔𝑖+1 , ..., 𝑔𝑠 }• 𝐿𝐶(𝑔𝑖 ) = 1 for all 𝑖.
EXAMPLES:
sage: from sage.rings.polynomial.toy_buchberger import inter_reduction
sage: inter_reduction(set())set()>>> from sage.all import *>>> from sage.rings.polynomial.toy_buchberger import inter_reduction>>> inter_reduction(set())set()
sage: P.<x,y> = QQ[]
sage: reduced = inter_reduction(set([x^2 - 5*y^2, x^3]))
˓→needs sage.libs.singularsage: reduced == set([x*y^2, x^2 - 5*y^2])#␣#␣(continues on next page)3.3. Educational Versions of Groebner Basis Related Algorithms

897

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.singularTrue
sage: reduced == inter_reduction(set([2*(x^2 - 5*y^2), x^3]))
˓→needs sage.libs.singular
True
˓→

#␣

>>> from sage.all import *>>> P = QQ[ x, y ]; (x, y,) = P._first_ngens(2)>>> reduced = inter_reduction(set([x**Integer(2) - Integer(5)*y**Integer(2),␣
˓→x**Integer(3)]))# needs sage.libs.singular>>> reduced == set([x*y**Integer(2), x**Integer(2) - Integer(5)*y**Integer(2)]) ␣˓→# needs sage.libs.singularTrue>>> reduced == inter_reduction(set([Integer(2)*(x**Integer(2) -␣˓→Integer(5)*y**Integer(2)), x**Integer(3)]))# needs sage.libs.
˓→singularTruesage.rings.polynomial.toy_buchberger.select(P)Select a polynomial using the normal selection strategy.
INPUT:• P – a list of critical pairs
OUTPUT: an element of P
EXAMPLES:
sage: from sage.rings.polynomial.toy_buchberger import selectsage: R.<x,y,z> = PolynomialRing(QQ, order= lex )sage: ps = [x^3 - z - 1, z^3 - y - 1, x^5 - y - 2]sage: pairs = [[ps[i], ps[j]] for i in range(3) for j in range(i + 1, 3)]
sage: select(pairs)[x^3 - z - 1, -y + z^3 - 1]>>> from sage.all import *>>> from sage.rings.polynomial.toy_buchberger import select>>> R = PolynomialRing(QQ, order= lex , names=( x , y , z ,)); (x, y, z,) = R._
˓→first_ngens(3)>>> ps = [x**Integer(3) - z - Integer(1), z**Integer(3) - y - Integer(1),␣
˓→x**Integer(5) - y - Integer(2)]>>> pairs = [[ps[i], ps[j]] for i in range(Integer(3)) for j in range(i +␣˓→Integer(1), Integer(3))]>>> select(pairs)[x^3 - z - 1, -y + z^3 - 1]sage.rings.polynomial.toy_buchberger.spol(f, g)
Compute the S-polynomial of f and g.
INPUT:• f, g – polynomials
OUTPUT: the S-polynomial of f and g
EXAMPLES:

898

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage: R.<x,y,z> = PolynomialRing(QQ)
sage: from sage.rings.polynomial.toy_buchberger import spol
sage: spol(x^2 - z - 1, z^2 - y - 1)x^2*y - z^3 + x^2 - z^2>>> from sage.all import *>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_ngens(3)>>> from sage.rings.polynomial.toy_buchberger import spol>>> spol(x**Integer(2) - z - Integer(1), z**Integer(2) - y - Integer(1))
x^2*y - z^3 + x^2 - z^2sage.rings.polynomial.toy_buchberger.update(G, B, h)Update G using the set of critical pairs B and the polynomial h as presented in [BW1993], page 230. For this,Buchberger’s first and second criterion are tested.
This function implements the Gebauer-Moeller Installation.
INPUT:• G – an intermediate Groebner basis• B – a set of critical pairs• h – a polynomial
OUTPUT: a tuple of• an intermediate Groebner basis• a set of critical pairs
EXAMPLES:
sage: from sage.rings.polynomial.toy_buchberger import update
sage: R.<x,y,z> = PolynomialRing(QQ)
sage: set_verbose(0)sage: update(set(), set(), x*y*z)({x*y*z}, set())
sage: G, B = update(set(), set(), x*y*z - 1)sage: G, B = update(G, B, x*y^2 - 1)sage: G, B({x*y*z - 1, x*y^2 - 1}, {(x*y^2 - 1, x*y*z - 1)})>>> from sage.all import *>>> from sage.rings.polynomial.toy_buchberger import update>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_ngens(3)>>> set_verbose(Integer(0))>>> update(set(), set(), x*y*z)({x*y*z}, set())>>> G, B = update(set(), set(), x*y*z - Integer(1))>>> G, B = update(G, B, x*y**Integer(2) - Integer(1))>>> G, B({x*y*z - 1, x*y^2 - 1}, {(x*y^2 - 1, x*y*z - 1)})3.3. Educational Versions of Groebner Basis Related Algorithms

899

Polynomials, Release 10.4

3.3.2 Educational versions of Groebner basis algorithms: triangular factorization
In this file is the implementation of two algorithms in [Laz1992].
The main algorithm is Triangular; a secondary algorithm, necessary for the first, is ElimPolMin. As per Lazard’s
formulation, the implementation works with any term ordering, not only lexicographic.
Lazard does not specify a few of the subalgorithms implemented as the functions• is_triangular,• is_linearly_dependent, and• linear_representation.
The implementations are not hard, and the choice of algorithm is described with the relevant function.
No attempt was made to optimize these algorithms as the emphasis of this implementation is a clean and easy presentation.
Examples appear with the appropriate function.
AUTHORS:• John Perry (2009-02-24): initial version, but some words of documentation were stolen shamelessly from Martin
Albrecht’s toy_buchberger.py.
sage.rings.polynomial.toy_variety.coefficient_matrix(polys)
Generate the matrix M whose entries are the coefficients of polys.
The entries of row i of M consist of the coefficients of polys[i].
INPUT:• polys – a list/tuple of polynomials
OUTPUT:
A matrix M of the coefficients of polys
EXAMPLES:
sage: from sage.rings.polynomial.toy_variety import coefficient_matrix
sage: R.<x,y> = PolynomialRing(QQ)
sage: coefficient_matrix([x^2 + 1, y^2 + 1, x*y + 1])
˓→needs sage.modules[1 0 0 1][0 0 1 1][0 1 0 1]#␣>>> from sage.all import *>>> from sage.rings.polynomial.toy_variety import coefficient_matrix>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> coefficient_matrix([x**Integer(2) + Integer(1), y**Integer(2) + Integer(1),␣
˓→x*y + Integer(1)])# needs sage.modules[1 0 0 1][0 0 1 1][0 1 0 1]

Note:
This
functionmay
bemergedwithsage.rings.polynomial.
multi_polynomial_sequence.PolynomialSequence_generic.coefficient_matrix()in the future.

900

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

sage.rings.polynomial.toy_variety.elim_pol(B, n=-1)
Find the unique monic polynomial of lowest degree and lowest variable in the ideal described by B.
For the purposes of the triangularization algorithm, it is necessary to preserve the ring, so n specifies which variable
to check. By default, we check the last one, which should also be the smallest.
The algorithm may not work if you are trying to cheat: B should describe the Groebner basis of a zero-dimensional
ideal. However, it is not necessary for the Groebner basis to be lexicographic.
The algorithm is taken from a 1993 paper by Lazard [Laz1992].
INPUT:• B – a list/tuple of polynomials or a multivariate polynomial ideal• n – the variable to check (see above) (default: -1)
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: from sage.misc.verbose import set_verbose
sage: set_verbose(0)sage: from sage.rings.polynomial.toy_variety import elim_pol
sage: R.<x,y,z> = PolynomialRing(GF(32003))
sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3
sage: p2 = z^2 - z
sage: p3 = (x-2)^2*(y-1)^3
sage: I = R.ideal(p1,p2,p3)
sage: elim_pol(I.groebner_basis())˓→needs sage.libs.singularz^2 - z#␣>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> from sage.misc.verbose import set_verbose>>> set_verbose(Integer(0))>>> from sage.rings.polynomial.toy_variety import elim_pol>>> R = PolynomialRing(GF(Integer(32003)), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> p1 = x**Integer(2)*(x-Integer(1))**Integer(3)*y**Integer(2)*(z˓→Integer(3))**Integer(3)>>> p2 = z**Integer(2) - z>>> p3 = (x-Integer(2))**Integer(2)*(y-Integer(1))**Integer(3)>>> I = R.ideal(p1,p2,p3)>>> elim_pol(I.groebner_basis())#␣˓→needs sage.libs.singularz^2 - zsage.rings.polynomial.toy_variety.is_linearly_dependent(polys)
Decide whether the polynomials of polys are linearly dependent.
Here polys is a collection of polynomials.
The algorithm creates a matrix of coefficients of the monomials of polys. It computes the echelon form of thematrix, then checks whether any of the rows is the zero vector.
Essentially this relies on the fact that the monomials are linearly independent, and therefore is building a linear map
from the vector space of the monomials to the canonical basis of R^n, where n is the number of distinct monomialsin polys. There is a zero vector iff there is a linear dependence among polys.
The case where polys=[] is considered to be not linearly dependent.
3.3. Educational Versions of Groebner Basis Related Algorithms

901

Polynomials, Release 10.4

INPUT:• polys – a list/tuple of polynomials
OUTPUT:
True if the elements of polys are linearly dependent; False otherwise.
EXAMPLES:
sage: from sage.rings.polynomial.toy_variety import is_linearly_dependentsage: R.<x,y> = PolynomialRing(QQ)
sage: B = [x^2 + 1, y^2 + 1, x*y + 1]
sage: p = 3*B[0] - 2*B[1] + B[2]sage: is_linearly_dependent(B + [p])˓→needs sage.modules
True
sage: p = x*B[0]sage: is_linearly_dependent(B + [p])˓→needs sage.modules
False
sage: is_linearly_dependent([])
False
sage: R.<x> = PolynomialRing(QQ)
sage: B = [x^147 + x^99,....:
2*x^123 + x^75,....:
x^147 + 2*x^123 + 2*x^75,....:
2*x^147 + x^99 + x^75]
sage: is_linearly_dependent(B)
True

#␣

#␣

>>> from sage.all import *>>> from sage.rings.polynomial.toy_variety import is_linearly_dependent>>> R = PolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> B = [x**Integer(2) + Integer(1), y**Integer(2) + Integer(1), x*y + Integer(1)]>>> p = Integer(3)*B[Integer(0)] - Integer(2)*B[Integer(1)] + B[Integer(2)]>>> is_linearly_dependent(B + [p])#␣˓→needs sage.modules
True>>> p = x*B[Integer(0)]>>> is_linearly_dependent(B + [p])#␣˓→needs sage.modules
False>>> is_linearly_dependent([])
False>>> R = PolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> B = [x**Integer(147) + x**Integer(99),...
Integer(2)*x**Integer(123) + x**Integer(75),...
x**Integer(147) + Integer(2)*x**Integer(123) + Integer(2)*x**Integer(75),...
Integer(2)*x**Integer(147) + x**Integer(99) + x**Integer(75)]>>> is_linearly_dependent(B)Truesage.rings.polynomial.toy_variety.is_triangular(B)Check whether the basis B of an ideal is triangular.
That is: check whether the largest variable in B[i] with respect to the ordering of the base ring R is R.
gens()[i].
The algorithm is based on the definition of a triangular basis, given by Lazard in 1992 in [Laz1992].
902

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

INPUT:• B – a list/tuple of polynomials or a multivariate polynomial ideal
OUTPUT:
True if the basis is triangular; False otherwise.
EXAMPLES:
sage: from sage.rings.polynomial.toy_variety import is_triangularsage: R.<x,y,z> = PolynomialRing(QQ)
sage: p1 = x^2*y + z^2
sage: p2 = y*z + z^3
sage: p3 = y+z
sage: is_triangular(R.ideal(p1,p2,p3))
False
sage: p3 = z^2 - 3
sage: is_triangular(R.ideal(p1,p2,p3))
True>>> from sage.all import *>>> from sage.rings.polynomial.toy_variety import is_triangular>>> R = PolynomialRing(QQ, names=( x , y , z ,)); (x, y, z,) = R._first_ngens(3)>>> p1 = x**Integer(2)*y + z**Integer(2)>>> p2 = y*z + z**Integer(3)>>> p3 = y+z>>> is_triangular(R.ideal(p1,p2,p3))
False>>> p3 = z**Integer(2) - Integer(3)>>> is_triangular(R.ideal(p1,p2,p3))
Truesage.rings.polynomial.toy_variety.linear_representation(p, polys)
Assuming that p is a linear combination of polys, determine coefficients that describe the linear combination.
This probably does not work for any inputs except p, a polynomial, and polys, a sequence of polynomials. If p
is not in fact a linear combination of polys, the function raises an exception.
The algorithm creates a matrix of coefficients of the monomials of polys and p, with the coefficients of p in
the last row. It augments this matrix with the appropriate identity matrix, then computes the echelon form of theaugmented matrix. The last row should contain zeroes in the first columns, and the last columns contain a linear
dependence relation. Solving for the desired linear relation is straightforward.
INPUT:• p – a polynomial• polys – a list/tuple of polynomials
OUTPUT:
If n == len(polys), returns [a[0],a[1],...,a[n-1]] such that p == a[0]*poly[0] + ...
+ a[n-1]*poly[n-1].
EXAMPLES:
sage: # needs sage.modules sage.rings.finite_rings
sage: from sage.rings.polynomial.toy_variety import linear_representation
sage: R.<x,y> = PolynomialRing(GF(32003))
sage: B = [x^2 + 1, y^2 + 1, x*y + 1]
(continues on next page)3.3. Educational Versions of Groebner Basis Related Algorithms

903

Polynomials, Release 10.4

(continued from previous page)

sage: p = 3*B[0] - 2*B[1] + B[2]sage: linear_representation(p, B)[3, 32001, 1]>>> from sage.all import *>>> # needs sage.modules sage.rings.finite_rings>>> from sage.rings.polynomial.toy_variety import linear_representation>>> R = PolynomialRing(GF(Integer(32003)), names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> B = [x**Integer(2) + Integer(1), y**Integer(2) + Integer(1), x*y + Integer(1)]>>> p = Integer(3)*B[Integer(0)] - Integer(2)*B[Integer(1)] + B[Integer(2)]>>> linear_representation(p, B)[3, 32001, 1]

sage.rings.polynomial.toy_variety.triangular_factorization(B, n=-1)
Compute the triangular factorization of the Groebner basis B of an ideal.
This will not work properly if B is not a Groebner basis!
The algorithm used is that described in a 1992 paper by Daniel Lazard [Laz1992]. It is not necessary for the termordering to be lexicographic.
INPUT:• B – a list/tuple of polynomials or a multivariate polynomial ideal• n – the recursion parameter (default: -1)
OUTPUT:
A list T of triangular sets T_0, T_1, etc.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: from sage.misc.verbose import set_verbose
sage: set_verbose(0)sage: from sage.rings.polynomial.toy_variety import triangular_factorization
sage: R.<x,y,z> = PolynomialRing(GF(32003))
sage: p1 = x^2*(x-1)^3*y^2*(z-3)^3
sage: p2 = z^2 - z
sage: p3 = (x-2)^2*(y-1)^3
sage: I = R.ideal(p1,p2,p3)
sage: triangular_factorization(I.groebner_basis())˓→needs sage.libs.singular[[x^2 - 4*x + 4, y, z],[x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z],[x^2 - 4*x + 4, y, z - 1],[x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z - 1]]#␣>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> from sage.misc.verbose import set_verbose>>> set_verbose(Integer(0))>>> from sage.rings.polynomial.toy_variety import triangular_factorization>>> R = PolynomialRing(GF(Integer(32003)), names=( x , y , z ,)); (x, y, z,) =␣
˓→R._first_ngens(3)>>> p1 = x**Integer(2)*(x-Integer(1))**Integer(3)*y**Integer(2)*(z(continues on next page)

904

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)

Integer(3))**Integer(3)>>> p2 = z**Integer(2) - z>>> p3 = (x-Integer(2))**Integer(2)*(y-Integer(1))**Integer(3)>>> I = R.ideal(p1,p2,p3)>>> triangular_factorization(I.groebner_basis())˓→needs sage.libs.singular[[x^2 - 4*x + 4, y, z],[x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z],[x^2 - 4*x + 4, y, z - 1],[x^5 - 3*x^4 + 3*x^3 - x^2, y - 1, z - 1]]
˓→#␣

3.3.3 Educational version of the 𝑑-Groebner basis algorithm over PIDs
No attempt was made to optimize this algorithm as the emphasis of this implementation is a clean and easy presentation.
Note: The notion of ‘term’ and ‘monomial’ in [BW1993] is swapped from the notion of those words in Sage (or theother way around, however you prefer it). In Sage a term is a monomial multiplied by a coefficient, while in [BW1993] amonomial is a term multiplied by a coefficient. Also, what is called LM (the leading monomial) in Sage is called HT (thehead term) in [BW1993].
EXAMPLES:
sage: from sage.rings.polynomial.toy_d_basis import d_basis>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import d_basis

First, consider an example from arithmetic geometry:sage: A.<x,y> = PolynomialRing(ZZ, 2)
sage: B.<X,Y> = PolynomialRing(Rationals(), 2)
sage: f = -y^2 - y + x^3 + 7*x + 1
sage: fx = f.derivative(x)sage: fy = f.derivative(y)sage: I = B.ideal([B(f), B(fx), B(fy)])
sage: I.groebner_basis()
˓→needs sage.libs.singular[1]#␣>>> from sage.all import *>>> A = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = A._first_ngens(2)>>> B = PolynomialRing(Rationals(), Integer(2), names=( X , Y ,)); (X, Y,) = B._
˓→first_ngens(2)>>> f = -y**Integer(2) - y + x**Integer(3) + Integer(7)*x + Integer(1)>>> fx = f.derivative(x)>>> fy = f.derivative(y)>>> I = B.ideal([B(f), B(fx), B(fy)])>>> I.groebner_basis()#␣˓→needs sage.libs.singular[1]

Since the output is 1, we know that there are no generic singularities.
To look at the singularities of the arithmetic surface, we need to do the corresponding computation over Z:
3.3. Educational Versions of Groebner Basis Related Algorithms

905

Polynomials, Release 10.4

sage: I = A.ideal([f, fx, fy])
sage: gb = d_basis(I); gb
˓→needs sage.libs.singular[x - 2020, y - 11313, 22627]#␣sage: gb[-1].factor()˓→needs sage.libs.singular11^3 * 17#␣>>> from sage.all import *>>> I = A.ideal([f, fx, fy])>>> gb = d_basis(I); gb
˓→needs sage.libs.singular[x - 2020, y - 11313, 22627]#␣>>> gb[-Integer(1)].factor()˓→# needs sage.libs.singular11^3 * 17␣This Groebner Basis gives a lot of information. First, the only fibers (over Z) that are not smooth are at 11 = 0, and
17 = 0. Examining the Groebner Basis, we see that we have a simple node in both the fiber at 11 and at 17. From thefactorization, we see that the node at 17 is regular on the surface (an 𝐼1 node), but the node at 11 is not. After blowing
up this non-regular point, we find that it is an 𝐼3 node.
Another example. This one is from the Magma Handbook:
sage: # needs sage.libs.singularsage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order= lex )sage: I = ideal(x^2 - 1, y^2 - 1, 2*x*y - z)sage: I = Ideal(d_basis(I))
sage: x.reduce(I)xsage: (2*x).reduce(I)y*z>>> from sage.all import *>>> # needs sage.libs.singular>>> P = PolynomialRing(IntegerRing(), Integer(3), order= lex , names=( x , y , z ,˓→)); (x, y, z,) = P._first_ngens(3)>>> I = ideal(x**Integer(2) - Integer(1), y**Integer(2) - Integer(1), Integer(2)*x*y ˓→ z)>>> I = Ideal(d_basis(I))>>> x.reduce(I)x>>> (Integer(2)*x).reduce(I)y*z

To compute modulo 4, we can add the generator 4 to our basis.:
sage: # needs sage.libs.singularsage: I = ideal(x^2 - 1, y^2 - 1, 2*x*y - z, 4)
sage: gb = d_basis(I)sage: R = P.change_ring(IntegerModRing(4))
sage: gb = [R(f) for f in gb if R(f)]; gb[x^2 - 1, x*z + 2*y, 2*x - y*z, y^2 - 1, z^2, 2*z]

906

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.libs.singular>>> I = ideal(x**Integer(2) - Integer(1), y**Integer(2) - Integer(1), Integer(2)*x*y ˓→ z, Integer(4))>>> gb = d_basis(I)>>> R = P.change_ring(IntegerModRing(Integer(4)))>>> gb = [R(f) for f in gb if R(f)]; gb[x^2 - 1, x*z + 2*y, 2*x - y*z, y^2 - 1, z^2, 2*z]

A third example is also from the Magma Handbook.
This example shows how one can use Groebner bases over the integers to find the primes modulo which a system of
equations has a solution, when the system has no solutions over the rationals.
We first form a certain ideal 𝐼 in Z[𝑥, 𝑦, 𝑧], and note that the Groebner basis of 𝐼 over contains 1, so there are no
solutions over or an algebraic closure of it (this is not surprising as there are 4 equations in 3 unknowns).
sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order= degneglex )sage: I = ideal(x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1)
sage: I.change_ring(P.change_ring(RationalField())).groebner_basis()
˓→needs sage.libs.singular[1]#␣>>> from sage.all import *>>> P = PolynomialRing(IntegerRing(), Integer(3), order= degneglex , names=( x , y ,˓→ z ,)); (x, y, z,) = P._first_ngens(3)>>> I = ideal(x**Integer(2) - Integer(3)*y, y**Integer(3) - x*y, z**Integer(3) - x,␣
˓→x**Integer(4) - y*z + Integer(1))>>> I.change_ring(P.change_ring(RationalField())).groebner_basis()#␣˓→needs sage.libs.singular[1]

However, when we compute the Groebner basis of I (defined over Z), we note that there is a certain integer in the ideal
which is not 1:
sage: gb = d_basis(I); gb
˓→needs sage.libs.singular[z ..., y ..., x ..., 282687803443]>>> from sage.all import *>>> gb = d_basis(I); gb
˓→needs sage.libs.singular[z ..., y ..., x ..., 282687803443]#␣#␣

Now for each prime 𝑝 dividing this integer 282687803443, the Groebner basis of I modulo 𝑝 will be non-trivial and willthus give a solution of the original system modulo 𝑝.:
sage: factor(282687803443)
101 * 103 * 27173681
sage: I.change_ring(P.change_ring(GF(101))).groebner_basis()
˓→needs sage.libs.singular[z - 33, y + 48, x + 19]#␣sage: I.change_ring(P.change_ring(GF(103))).groebner_basis()
˓→needs sage.libs.singular[z - 18, y + 8, x + 39]#␣(continues on next page)3.3. Educational Versions of Groebner Basis Related Algorithms

907

Polynomials, Release 10.4

(continued from previous page)

sage: I.change_ring(P.change_ring(GF(27173681))).groebner_basis()
˓→needs sage.libs.singular sage.rings.finite_rings[z + 10380032, y + 3186055, x - 536027]#␣>>> from sage.all import *>>> factor(Integer(282687803443))
101 * 103 * 27173681>>> I.change_ring(P.change_ring(GF(Integer(101)))).groebner_basis()˓→# needs sage.libs.singular[z - 33, y + 48, x + 19]

␣>>> I.change_ring(P.change_ring(GF(Integer(103)))).groebner_basis()˓→# needs sage.libs.singular[z - 18, y + 8, x + 39]

␣>>> I.change_ring(P.change_ring(GF(Integer(27173681)))).groebner_basis()˓→# needs sage.libs.singular sage.rings.finite_rings[z + 10380032, y + 3186055, x - 536027]

␣

Of course, modulo any other prime the Groebner basis is trivial so there are no other solutions. For example:
sage: I.change_ring(P.change_ring(GF(3))).groebner_basis()
˓→needs sage.libs.singular[1]>>> from sage.all import *>>> I.change_ring(P.change_ring(GF(Integer(3)))).groebner_basis()˓→# needs sage.libs.singular
[1]

#␣

␣

AUTHOR:• Martin Albrecht (2008-08): initial version
sage.rings.polynomial.toy_d_basis.LC(f)sage.rings.polynomial.toy_d_basis.LM(f)sage.rings.polynomial.toy_d_basis.d_basis(F, strat=True)
Return the 𝑑-basis for the Ideal F as defined in [BW1993].
INPUT:• F – an ideal• strat – use update strategy (default: True)
EXAMPLES:
sage: from sage.rings.polynomial.toy_d_basis import d_basis
sage: A.<x,y> = PolynomialRing(ZZ, 2)
sage: f = -y^2 - y + x^3 + 7*x + 1
sage: fx = f.derivative(x)sage: fy = f.derivative(y)sage: I = A.ideal([f,fx,fy])
sage: gb = d_basis(I); gb#␣(continues on next page)

908

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.libs.singular[x - 2020, y - 11313, 22627]
˓→>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import d_basis>>> A = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> f = -y**Integer(2) - y + x**Integer(3) + Integer(7)*x + Integer(1)>>> fx = f.derivative(x)>>> fy = f.derivative(y)>>> I = A.ideal([f,fx,fy])>>> gb = d_basis(I); gb#␣˓→needs sage.libs.singular[x - 2020, y - 11313, 22627]

sage.rings.polynomial.toy_d_basis.gpol(g1, g2)
Return the G-Polynomial of g_1 and g_2.
Let 𝑎𝑖 𝑡𝑖 be 𝐿𝑇 (𝑔𝑖 ), 𝑎 = 𝑎𝑖 * 𝑐𝑖 + 𝑎𝑗 * 𝑐𝑗 with 𝑎 = 𝐺𝐶𝐷(𝑎𝑖 , 𝑎𝑗 ), and 𝑠𝑖 = 𝑡/𝑡𝑖 with 𝑡 = 𝐿𝐶𝑀 (𝑡𝑖 , 𝑡𝑗 ). Thenthe G-Polynomial is defined as: 𝑐1 𝑠1 𝑔1 − 𝑐2 𝑠2 𝑔2 .
INPUT:• g1 – polynomial• g2 – polynomial
EXAMPLES:
sage: from sage.rings.polynomial.toy_d_basis import gpol
sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order= lex )sage: f = x^2 - 1
sage: g = 2*x*y - z
sage: gpol(f,g)
x^2*y - y>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import gpol>>> P = PolynomialRing(IntegerRing(), Integer(3), order= lex , names=( x ,˓→ ,)); (x, y, z,) = P._first_ngens(3)>>> f = x**Integer(2) - Integer(1)>>> g = Integer(2)*x*y - z>>> gpol(f,g)
x^2*y - yy ,zsage.rings.polynomial.toy_d_basis.select(P)The normal selection strategy.
INPUT:• P – a list of critical pairs
OUTPUT:an element of P
EXAMPLES:

3.3. Educational Versions of Groebner Basis Related Algorithms

909

Polynomials, Release 10.4

sage: from sage.rings.polynomial.toy_d_basis import selectsage: A.<x,y> = PolynomialRing(ZZ, 2)
sage: f = -y^2 - y + x^3 + 7*x + 1
sage: fx = f.derivative(x)sage: fy = f.derivative(y)sage: G = [f, fx, fy]
sage: B = set((f1, f2) for f1 in G for f2 in G if f1 != f2)
sage: select(B)(-2*y - 1, 3*x^2 + 7)>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import select>>> A = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> f = -y**Integer(2) - y + x**Integer(3) + Integer(7)*x + Integer(1)>>> fx = f.derivative(x)>>> fy = f.derivative(y)>>> G = [f, fx, fy]>>> B = set((f1, f2) for f1 in G for f2 in G if f1 != f2)>>> select(B)(-2*y - 1, 3*x^2 + 7)

sage.rings.polynomial.toy_d_basis.spol(g1, g2)
Return the S-Polynomial of g_1 and g_2.
Let 𝑎𝑖 𝑡𝑖 be 𝐿𝑇 (𝑔𝑖 ), 𝑏𝑖 = 𝑎/𝑎𝑖 with 𝑎 = 𝐿𝐶𝑀 (𝑎𝑖 , 𝑎𝑗 ), and 𝑠𝑖 = 𝑡/𝑡𝑖 with 𝑡 = 𝐿𝐶𝑀 (𝑡𝑖 , 𝑡𝑗 ). Then the
S-Polynomial is defined as: 𝑏1 𝑠1 𝑔1 − 𝑏2 𝑠2 𝑔2 .
INPUT:• g1 – polynomial• g2 – polynomial
EXAMPLES:
sage: from sage.rings.polynomial.toy_d_basis import spol
sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order= lex )sage: f = x^2 - 1
sage: g = 2*x*y - z
sage: spol(f,g)
x*z - 2*y>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import spol>>> P = PolynomialRing(IntegerRing(), Integer(3), order= lex , names=( x ,˓→ ,)); (x, y, z,) = P._first_ngens(3)>>> f = x**Integer(2) - Integer(1)>>> g = Integer(2)*x*y - z>>> spol(f,g)
x*z - 2*yy ,zsage.rings.polynomial.toy_d_basis.update(G, B, h)Update G using the list of critical pairs B and the polynomial h as presented in [BW1993], page 230. For this,Buchberger’s first and second criterion are tested.
This function uses the Gebauer-Moeller Installation.
INPUT:
910

Chapter 3. Multivariate Polynomials

Polynomials, Release 10.4

• G – an intermediate Groebner basis• B – a list of critical pairs• h – a polynomial
OUTPUT:
G,B where G and B are updated
EXAMPLES:
sage: from sage.rings.polynomial.toy_d_basis import update
sage: A.<x,y> = PolynomialRing(ZZ, 2)
sage: G = set([3*x^2 + 7, 2*y + 1, x^3 - y^2 + 7*x - y + 1])
sage: B = set()sage: h = x^2*y - x^2 + y - 3
sage: update(G,B,h)({2*y + 1, 3*x^2 + 7, x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1},{(x^2*y - x^2 + y - 3, 2*y + 1),(x^2*y - x^2 + y - 3, 3*x^2 + 7),(x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1)})>>> from sage.all import *>>> from sage.rings.polynomial.toy_d_basis import update>>> A = PolynomialRing(ZZ, Integer(2), names=( x , y ,)); (x, y,) = A._first_
˓→ngens(2)>>> G = set([Integer(3)*x**Integer(2) + Integer(7), Integer(2)*y + Integer(1),␣
˓→x**Integer(3) - y**Integer(2) + Integer(7)*x - y + Integer(1)])>>> B = set()>>> h = x**Integer(2)*y - x**Integer(2) + y - Integer(3)>>> update(G,B,h)({2*y + 1, 3*x^2 + 7, x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1},{(x^2*y - x^2 + y - 3, 2*y + 1),(x^2*y - x^2 + y - 3, 3*x^2 + 7),(x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1)})3.3. Educational Versions of Groebner Basis Related Algorithms

911Polynomials, Release 10.4

912

Chapter 3. Multivariate Polynomials

CHAPTERFOURRATIONAL FUNCTIONS

4.1 Fraction Field of Integral Domains
AUTHORS:• William Stein (with input from David Joyner, David Kohel, and Joe Wetherell)• Burcin Erocal• Julian Rüth (2017-06-27): embedding into the field of fractions and its section
EXAMPLES:
Quotienting is a constructor for an element of the fraction field:
sage: R.<x> = QQ[]
sage: (x^2-1)/(x+1)
x - 1
sage: parent((x^2-1)/(x+1))
Fraction Field of Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (x**Integer(2)-Integer(1))/(x+Integer(1))
x - 1>>> parent((x**Integer(2)-Integer(1))/(x+Integer(1)))
Fraction Field of Univariate Polynomial Ring in x over Rational Field

The GCD is not taken (since it doesn’t converge sometimes) in the inexact case:sage: # needs sage.rings.real_mpfr
sage: Z.<z> = CC[]
sage: I = CC.gen()sage: (1+I+z)/(z+0.1*I)(z + 1.00000000000000 + I)/(z + 0.100000000000000*I)
sage: (1+I*z)/(z+1.1)(I*z + 1.00000000000000)/(z + 1.10000000000000)>>> from sage.all import *>>> # needs sage.rings.real_mpfr>>> Z = CC[ z ]; (z,) = Z._first_ngens(1)>>> I = CC.gen()>>> (Integer(1)+I+z)/(z+RealNumber( 0.1 )*I)
(z + 1.00000000000000 + I)/(z + 0.100000000000000*I)(continues on next page)913

Polynomials, Release 10.4

(continued from previous page)>>> (Integer(1)+I*z)/(z+RealNumber( 1.1 ))(I*z + 1.00000000000000)/(z + 1.10000000000000)

sage.rings.fraction_field.FractionField(R, names=None)
Create the fraction field of the integral domain R.
INPUT:• R – an integral domain• names – ignored
EXAMPLES:
We create some example fraction fields:
sage: FractionField(IntegerRing())
Rational Field
sage: FractionField(PolynomialRing(RationalField(), x ))Fraction Field of Univariate Polynomial Ring in x over Rational Field
sage: FractionField(PolynomialRing(IntegerRing(), x ))Fraction Field of Univariate Polynomial Ring in x over Integer Ringsage: FractionField(PolynomialRing(RationalField(),2, x ))Fraction Field of Multivariate Polynomial Ring in x0, x1 over Rational Field>>> from sage.all import *>>> FractionField(IntegerRing())
Rational Field>>> FractionField(PolynomialRing(RationalField(), x ))Fraction Field of Univariate Polynomial Ring in x over Rational Field>>> FractionField(PolynomialRing(IntegerRing(), x ))Fraction Field of Univariate Polynomial Ring in x over Integer Ring>>> FractionField(PolynomialRing(RationalField(),Integer(2), x ))Fraction Field of Multivariate Polynomial Ring in x0, x1 over Rational Field

Dividing elements often implicitly creates elements of the fraction field:
sage: x = PolynomialRing(RationalField(),
sage: f = x/(x+1)
sage: g = x**3/(x+1)
sage: f/g
1/x^2
sage: g/f
x^2>>> from sage.all import *>>> x = PolynomialRing(RationalField(),>>> f = x/(x+Integer(1))>>> g = x**Integer(3)/(x+Integer(1))>>> f/g
1/x^2>>> g/fx^2x ).gen()x ).gen()

The input must be an integral domain:

914

Chapter 4. Rational Functions

Polynomials, Release 10.4

sage: Frac(Integers(4))
Traceback (most recent call last):...
TypeError: R must be an integral domain>>> from sage.all import *>>> Frac(Integers(Integer(4)))
Traceback (most recent call last):...
TypeError: R must be an integral domainclass sage.rings.fraction_field.FractionFieldEmbedding
Bases: DefaultConvertMap_unique
The embedding of an integral domain into its field of fractions.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = R.fraction_field().coerce_map_from(R); f
Coercion map:
From: Univariate Polynomial Ring in x over Rational Field
To:
Fraction Field of Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = R.fraction_field().coerce_map_from(R); f
Coercion map:
From: Univariate Polynomial Ring in x over Rational Field
To:
Fraction Field of Univariate Polynomial Ring in x over Rational Field

is_injective()
Return whether this map is injective.
EXAMPLES:
The map from an integral domain to its fraction field is always injective:
sage: R.<x> = QQ[]
sage: R.fraction_field().coerce_map_from(R).is_injective()
True>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.fraction_field().coerce_map_from(R).is_injective()
True

is_surjective()
Return whether this map is surjective.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R.fraction_field().coerce_map_from(R).is_surjective()
False

4.1. Fraction Field of Integral Domains

915

Polynomials, Release 10.4>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.fraction_field().coerce_map_from(R).is_surjective()
False

section()Return a section of this map.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R.fraction_field().coerce_map_from(R).section()
Section map:
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
To:
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.fraction_field().coerce_map_from(R).section()
Section map:
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
To:
Univariate Polynomial Ring in x over Rational Field

class sage.rings.fraction_field.FractionFieldEmbeddingSection
Bases: Section
The section of the embedding of an integral domain into its field of fractions.
EXAMPLES:
sage: R.<x> = QQ[]
sage: f = R.fraction_field().coerce_map_from(R).section(); fSection map:
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
To:
Univariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> f = R.fraction_field().coerce_map_from(R).section(); fSection map:
From: Fraction Field of Univariate Polynomial Ring in x over Rational Field
To:
Univariate Polynomial Ring in x over Rational Field

class sage.rings.fraction_field.FractionField_1poly_field(R, element_class=<class'sage.rings.fraction_field_element.FractionFieldElement_1poly_field'>)
Bases: FractionField_generic
The fraction field of a univariate polynomial ring over a field.
Many of the functions here are included for coherence with number fields.
class_number()
Here for compatibility with number fields and function fields.
EXAMPLES:

916

Chapter 4. Rational Functions

Polynomials, Release 10.4

sage: R.<t> = GF(5)[]; K = R.fraction_field()sage: K.class_number()1>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1); K = R.fraction_field()>>> K.class_number()1function_field()
Return the isomorphic function field.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: K.function_field()
Rational function field in t over Finite Field of size 5>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> K.function_field()
Rational function field in t over Finite Field of size 5

See also:
sage.rings.function_field.RationalFunctionField.field()maximal_order()Return the maximal order in this fraction field.
EXAMPLES:
sage: K = FractionField(GF(5)[ t ])sage: K.maximal_order()Univariate Polynomial Ring in t over Finite Field of size 5>>> from sage.all import *>>> K = FractionField(GF(Integer(5))[ t ])>>> K.maximal_order()Univariate Polynomial Ring in t over Finite Field of size 5

ring_of_integers()
Return the ring of integers in this fraction field.
EXAMPLES:
sage: K = FractionField(GF(5)[ t ])sage: K.ring_of_integers()
Univariate Polynomial Ring in t over Finite Field of size 5>>> from sage.all import *>>> K = FractionField(GF(Integer(5))[ t ])>>> K.ring_of_integers()
Univariate Polynomial Ring in t over Finite Field of size 5

4.1. Fraction Field of Integral Domains

917

Polynomials, Release 10.4class sage.rings.fraction_field.FractionField_generic(R, element_class=<class'sage.rings.fraction_field_element.FractionFieldElement'>,
category=Category of quotientfields)Bases: Field
The fraction field of an integral domain.
base_ring()
Return the base ring of self.
This is the base ring of the ring which this fraction field is the fraction field of.
EXAMPLES:
sage: R = Frac(ZZ[ t ])sage: R.base_ring()
Integer Ring>>> from sage.all import *>>> R = Frac(ZZ[ t ])>>> R.base_ring()
Integer Ring

characteristic()
Return the characteristic of this fraction field.
EXAMPLES:
sage: R = Frac(ZZ[ t ])sage: R.base_ring()
Integer Ringsage: R = Frac(ZZ[ t ]); R.characteristic()
0
sage: R = Frac(GF(5)[ w ]); R.characteristic()
5>>> from sage.all import *>>> R = Frac(ZZ[ t ])>>> R.base_ring()
Integer Ring>>> R = Frac(ZZ[ t ]); R.characteristic()
0>>> R = Frac(GF(Integer(5))[ w ]); R.characteristic()
5

construction()
EXAMPLES:
sage: Frac(ZZ[ x ]).construction()(FractionField, Univariate Polynomial Ring in x over Integer Ring)sage: K = Frac(GF(3)[ t ])sage: f, R = K.construction()sage: f(R)Fraction Field of Univariate Polynomial Ring in t
over Finite Field of size 3(continues on next page)

918

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)

sage: f(R) == K
True>>> from sage.all import *>>> Frac(ZZ[ x ]).construction()(FractionField, Univariate Polynomial Ring in x over Integer Ring)>>> K = Frac(GF(Integer(3))[ t ])>>> f, R = K.construction()>>> f(R)Fraction Field of Univariate Polynomial Ring in t
over Finite Field of size 3>>> f(R) == K
Truegen(i=0)
Return the i-th generator of self.
EXAMPLES:
sage: R = Frac(PolynomialRing(QQ, z ,10)); R
Fraction Field of Multivariate Polynomial Ringin z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field
sage: R.0z0
sage: R.gen(3)z3sage: R.3
z3>>> from sage.all import *>>> R = Frac(PolynomialRing(QQ, z ,Integer(10))); R
Fraction Field of Multivariate Polynomial Ringin z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field>>> R.gen(0)z0>>> R.gen(Integer(3))
z3>>> R.gen(3)z3is_exact()
Return if self is exact which is if the underlying ring is exact.
EXAMPLES:
sage: Frac(ZZ[ x ]).is_exact()
True
sage: Frac(CDF[ x ]).is_exact()˓→needs sage.rings.complex_double
False>>> from sage.all import *>>> Frac(ZZ[ x ]).is_exact()
True>>> Frac(CDF[ x ]).is_exact()#␣#␣(continues on next page)

4.1. Fraction Field of Integral Domains

919

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.complex_double
False
˓→

is_field(proof=True)
Return True, since the fraction field is a field.
EXAMPLES:
sage: Frac(ZZ).is_field()True>>> from sage.all import *>>> Frac(ZZ).is_field()True

is_finite()Tells whether this fraction field is finite.
Note: A fraction field is finite if and only if the associated integral domain is finite.
EXAMPLES:
sage: Frac(QQ[ a , b , c ]).is_finite()
False>>> from sage.all import *>>> Frac(QQ[ a , b , c ]).is_finite()
False

ngens()
This is the same as for the parent object.
EXAMPLES:
sage: R = Frac(PolynomialRing(QQ, z ,10)); R
Fraction Field of Multivariate Polynomial Ringin z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field
sage: R.ngens()
10>>> from sage.all import *>>> R = Frac(PolynomialRing(QQ, z ,Integer(10))); R
Fraction Field of Multivariate Polynomial Ringin z0, z1, z2, z3, z4, z5, z6, z7, z8, z9 over Rational Field>>> R.ngens()
10

random_element(*args, **kwds)
Return a random element in this fraction field.
The arguments are passed to the random generator of the underlying ring.
EXAMPLES:

920

Chapter 4. Rational Functions

Polynomials, Release 10.4

sage: F = ZZ[ x ].fraction_field()sage: F.random_element() # random(2*x - 8)/(-x^2 + x)>>> from sage.all import *>>> F = ZZ[ x ].fraction_field()>>> F.random_element() # random(2*x - 8)/(-x^2 + x)
sage: f = F.random_element(degree=5)
sage: f.numerator().degree() == f.denominator().degree()True
sage: f.denominator().degree() <= 5
Truesage: while f.numerator().degree() != 5:....:
f = F.random_element(degree=5)>>> from sage.all import *>>> f = F.random_element(degree=Integer(5))>>> f.numerator().degree() == f.denominator().degree()True>>> f.denominator().degree() <= Integer(5)True>>> while f.numerator().degree() != Integer(5):...
f = F.random_element(degree=Integer(5))

ring()
Return the ring that this is the fraction field of.
EXAMPLES:
sage: R = Frac(QQ[ x,y ])sage: R
Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field
sage: R.ring()
Multivariate Polynomial Ring in x, y over Rational Field>>> from sage.all import *>>> R = Frac(QQ[ x,y ])>>> R
Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field>>> R.ring()
Multivariate Polynomial Ring in x, y over Rational Field

some_elements()
Return some elements in this field.
EXAMPLES:
sage: R.<x> = QQ[]
sage: R.fraction_field().some_elements()
[0,
1,
x,
2*x,
x/(x^2 + 2*x + 1),(continues on next page)

4.1. Fraction Field of Integral Domains

921

Polynomials, Release 10.4

(continued from previous page)

1/x^2,...
(2*x^2 + 2)/(x^2 + 2*x + 1),(2*x^2 + 2)/x^3,(2*x^2 + 2)/(x^2 - 1),
2]>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> R.fraction_field().some_elements()
[0,
1,
x,
2*x,
x/(x^2 + 2*x + 1),
1/x^2,...
(2*x^2 + 2)/(x^2 + 2*x + 1),(2*x^2 + 2)/x^3,(2*x^2 + 2)/(x^2 - 1),2]

sage.rings.fraction_field.is_FractionField(x)Test whether or not x inherits from FractionField_generic.
EXAMPLES:
sage: from sage.rings.fraction_field import is_FractionField
sage: is_FractionField(Frac(ZZ[ x ]))doctest:warning...
DeprecationWarning: The function is_FractionField is deprecated;
use isinstance(..., FractionField_generic) instead.
See https://github.com/sagemath/sage/issues/38128 for details.
Truesage: is_FractionField(QQ)
False>>> from sage.all import *>>> from sage.rings.fraction_field import is_FractionField>>> is_FractionField(Frac(ZZ[ x ]))doctest:warning...
DeprecationWarning: The function is_FractionField is deprecated;
use isinstance(..., FractionField_generic) instead.
See https://github.com/sagemath/sage/issues/38128 for details.
True>>> is_FractionField(QQ)
False

922

Chapter 4. Rational Functions

Polynomials, Release 10.4

4.2 Fraction Field Elements
AUTHORS:• William Stein (input from David Joyner, David Kohel, and Joe Wetherell)• Sebastian Pancratz (2010-01-06): Rewrite of addition, multiplication and derivative to use Henrici’s algorithms[Hor1972]
class sage.rings.fraction_field_element.FractionFieldElement
Bases: FieldElement
EXAMPLES:
sage: K = FractionField(PolynomialRing(QQ, x ))sage: K
Fraction Field of Univariate Polynomial Ring in x over Rational Field
sage: loads(K.dumps()) == K
True
sage: x = K.gen()sage: f = (x^3 + x)/(17 - x^19); f(-x^3 - x)/(x^19 - 17)sage: loads(f.dumps()) == f
True>>> from sage.all import *>>> K = FractionField(PolynomialRing(QQ, x ))>>> K
Fraction Field of Univariate Polynomial Ring in x over Rational Field>>> loads(K.dumps()) == K
True>>> x = K.gen()>>> f = (x**Integer(3) + x)/(Integer(17) - x**Integer(19)); f(-x^3 - x)/(x^19 - 17)>>> loads(f.dumps()) == f
Truedenominator()
Return the denominator of self.
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: f = x/y + 1; f(x + y)/y
sage: f.denominator()y>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x/y + Integer(1); f(x + y)/y>>> f.denominator()yis_one()Return True if this element is equal to one.

4.2. Fraction Field Elements923

Polynomials, Release 10.4

EXAMPLES:
sage: F = ZZ[ x,y ].fraction_field()sage: x,y = F.gens()
sage: (x/x).is_one()True
sage: (x/y).is_one()
False>>> from sage.all import *>>> F = ZZ[ x,y ].fraction_field()>>> x,y = F.gens()>>> (x/x).is_one()True>>> (x/y).is_one()
False

is_square(root=False)
Return whether or not self is a perfect square.
If the optional argument root is True, then also returns a square root (or None, if the fraction field element
is not square).
INPUT:• root – whether or not to also return a square root (default: False)
OUTPUT:• bool – whether or not a square• object – (optional) an actual square root if found, and None otherwise.
EXAMPLES:
sage: R.<t> = QQ[]
sage: (1/t).is_square()False
sage: (1/t^6).is_square()True
sage: ((1+t)^4/t^6).is_square()True
sage: (4*(1+t)^4/t^6).is_square()True
sage: (2*(1+t)^4/t^6).is_square()False
sage: ((1+t)/t^6).is_square()False
sage: (4*(1+t)^4/t^6).is_square(root=True)(True, (2*t^2 + 4*t + 2)/t^3)
sage: (2*(1+t)^4/t^6).is_square(root=True)(False, None)sage: R.<x> = QQ[]
sage: a = 2*(x+1)^2 / (2*(x-1)^2); a(x^2 + 2*x + 1)/(x^2 - 2*x + 1)
sage: a.is_square()
True(continues on next page)924

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)

sage: (0/x).is_square()True>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> (Integer(1)/t).is_square()False>>> (Integer(1)/t**Integer(6)).is_square()True>>> ((Integer(1)+t)**Integer(4)/t**Integer(6)).is_square()True>>> (Integer(4)*(Integer(1)+t)**Integer(4)/t**Integer(6)).is_square()True>>> (Integer(2)*(Integer(1)+t)**Integer(4)/t**Integer(6)).is_square()False>>> ((Integer(1)+t)/t**Integer(6)).is_square()False>>> (Integer(4)*(Integer(1)+t)**Integer(4)/t**Integer(6)).is_square(root=True)(True, (2*t^2 + 4*t + 2)/t^3)>>> (Integer(2)*(Integer(1)+t)**Integer(4)/t**Integer(6)).is_square(root=True)(False, None)>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> a = Integer(2)*(x+Integer(1))**Integer(2) / (Integer(2)*(x˓→Integer(1))**Integer(2)); a(x^2 + 2*x + 1)/(x^2 - 2*x + 1)>>> a.is_square()True>>> (Integer(0)/x).is_square()True

is_zero()Return True if this element is equal to zero.
EXAMPLES:
sage: F = ZZ[ x,y ].fraction_field()sage: x,y = F.gens()
sage: t = F(0)/x
sage: t.is_zero()Truesage: u = 1/x - 1/x
sage: u.is_zero()Truesage: u.parent() is F
True>>> from sage.all import *>>> F = ZZ[ x,y ].fraction_field()>>> x,y = F.gens()>>> t = F(Integer(0))/x>>> t.is_zero()True>>> u = Integer(1)/x - Integer(1)/x>>> u.is_zero()(continues on next page)

4.2. Fraction Field Elements925

Polynomials, Release 10.4

(continued from previous page)True>>> u.parent() is F
True

nth_root(n)Return a n-th root of this element.
EXAMPLES:
sage: R = QQ[ t ].fraction_field()sage: t = R.gen()sage: p = (t+1)^3 / (t^2+t-1)^3
sage: p.nth_root(3)(t + 1)/(t^2 + t - 1)sage: p = (t+1) / (t-1)
sage: p.nth_root(2)Traceback (most recent call last):...
ValueError: not a 2nd power>>> from sage.all import *>>> R = QQ[ t ].fraction_field()>>> t = R.gen()>>> p = (t+Integer(1))**Integer(3) / (t**Integer(2)+t-Integer(1))**Integer(3)>>> p.nth_root(Integer(3))(t + 1)/(t^2 + t - 1)>>> p = (t+Integer(1)) / (t-Integer(1))>>> p.nth_root(Integer(2))
Traceback (most recent call last):...
ValueError: not a 2nd power

numerator()
Return the numerator of self.
EXAMPLES:
sage: R.<x,y> = ZZ[]
sage: f = x/y + 1; f(x + y)/y
sage: f.numerator()x + y>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> f = x/y + Integer(1); f(x + y)/y>>> f.numerator()x + y

reduce()Reduce this fraction.
Divides out the gcd of the numerator and denominator. If the denominator becomes a unit, it becomes 1.

926

Chapter 4. Rational Functions

Polynomials, Release 10.4

Additionally, depending on the base ring, the leading coefficients of the numerator and the denominator may
be normalized to 1.
Automatically called for exact rings, but because it may be numerically unstable for inexact rings it must be
called manually in that case.
EXAMPLES:
sage: R.<x> = RealField(10)[]˓→needs sage.rings.real_mpfr
sage: f = (x^2+2*x+1)/(x+1); f
˓→needs sage.rings.real_mpfr(x^2 + 2.0*x + 1.0)/(x + 1.0)
sage: f.reduce(); f˓→needs sage.rings.real_mpfr
x + 1.0#␣#␣#␣>>> from sage.all import *>>> R = RealField(Integer(10))[ x ]; (x,) = R._first_ngens(1)# needs sage.
˓→rings.real_mpfr>>> f = (x**Integer(2)+Integer(2)*x+Integer(1))/(x+Integer(1)); f␣˓→# needs sage.rings.real_mpfr(x^2 + 2.0*x + 1.0)/(x + 1.0)>>> f.reduce(); f#␣˓→needs sage.rings.real_mpfr
x + 1.0

specialization(D=None, phi=None)
Returns the specialization of a fraction element of a polynomial ringsubs(in_dict=None, *args, **kwds)
Substitute variables in the numerator and denominator of self.
If a dictionary is passed, the keys are mapped to generators of the parent ring. Otherwise, the arguments aretransmitted unchanged to the method subs of the numerator and the denominator.
EXAMPLES:
sage: x, y = PolynomialRing(ZZ, 2,
sage: f = x^2 + y + x^2*y^2 + 5
sage: (1/f).subs(x=5)
1/(25*y^2 + y + 30)

xy ).gens()>>> from sage.all import *>>> x, y = PolynomialRing(ZZ, Integer(2), xy ).gens()>>> f = x**Integer(2) + y + x**Integer(2)*y**Integer(2) + Integer(5)>>> (Integer(1)/f).subs(x=Integer(5))
1/(25*y^2 + y + 30)

valuation(v=None)
Return the valuation of self, assuming that the numerator and denominator have valuation functions definedon them.
EXAMPLES:
sage: x = PolynomialRing(RationalField(), x ).gen()sage: f = (x^3 + x)/(x^2 - 2*x^3)
sage: f(continues on next page)

4.2. Fraction Field Elements927

Polynomials, Release 10.4

(continued from previous page)(-1/2*x^2 - 1/2)/(x^2 - 1/2*x)
sage: f.valuation()-1
sage: f.valuation(x^2 + 1)
1>>> from sage.all import *>>> x = PolynomialRing(RationalField(), x ).gen()>>> f = (x**Integer(3) + x)/(x**Integer(2) - Integer(2)*x**Integer(3))>>> f(-1/2*x^2 - 1/2)/(x^2 - 1/2*x)>>> f.valuation()-1>>> f.valuation(x**Integer(2) + Integer(1))
1class sage.rings.fraction_field_element.FractionFieldElement_1poly_field
Bases: FractionFieldElement
A fraction field element where the parent is the fraction field of a univariate polynomial ring over a field.
Many of the functions here are included for coherence with number fields.
is_integral()
Returns whether this element is actually a polynomial.
EXAMPLES:
sage: R.<t> = QQ[]
sage: elt = (t^2 + t - 2) / (t + 2); elt # == (t + 2)*(t - 1)/(t + 2)
t - 1
sage: elt.is_integral()True
sage: elt = (t^2 - t) / (t+2); elt # == t*(t - 1)/(t + 2)
(t^2 - t)/(t + 2)
sage: elt.is_integral()False>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> elt = (t**Integer(2) + t - Integer(2)) / (t + Integer(2)); elt # == (t +␣˓→2)*(t - 1)/(t + 2)
t - 1>>> elt.is_integral()True>>> elt = (t**Integer(2) - t) / (t+Integer(2)); elt # == t*(t - 1)/(t + 2)
(t^2 - t)/(t + 2)>>> elt.is_integral()False

reduce()Pick a normalized representation of self.
In particular, for any a == b, after normalization they will have the same numerator and denominator.
EXAMPLES:
For univariate rational functions over a field, we have:
928

Chapter 4. Rational Functions

Polynomials, Release 10.4

sage: R.<x> = QQ[]
sage: (2 + 2*x) / (4*x) # indirect doctest(1/2*x + 1/2)/x>>> from sage.all import *>>> R = QQ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2) + Integer(2)*x) / (Integer(4)*x) # indirect doctest(1/2*x + 1/2)/x

Compare with:sage: R.<x> = ZZ[]
sage: (2 + 2*x) / (4*x)(x + 1)/(2*x)>>> from sage.all import *>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> (Integer(2) + Integer(2)*x) / (Integer(4)*x)(x + 1)/(2*x)

support()Returns a sorted list of primes dividing either the numerator or denominator of this element.
EXAMPLES:
sage: R.<t> = QQ[]
sage: h = (t^14 + 2*t^12 - 4*t^11 - 8*t^9 + 6*t^8 + 12*t^6 - 4*t^5....:- 8*t^3 + t^2 + 2)/(t^6 + 6*t^5 + 9*t^4 - 2*t^2 - 12*t - 18)sage: h.support()
˓→needs sage.libs.pari[t - 1, t + 3, t^2 + 2, t^2 + t + 1, t^4 - 2]

#␣>>> from sage.all import *>>> R = QQ[ t ]; (t,) = R._first_ngens(1)>>> h = (t**Integer(14) + Integer(2)*t**Integer(12) -␣˓→Integer(4)*t**Integer(11) - Integer(8)*t**Integer(9) +␣˓→Integer(6)*t**Integer(8) + Integer(12)*t**Integer(6) -␣˓→Integer(4)*t**Integer(5)...
- Integer(8)*t**Integer(3) + t**Integer(2) + Integer(2))/˓→(t**Integer(6) + Integer(6)*t**Integer(5) + Integer(9)*t**Integer(4) -␣˓→Integer(2)*t**Integer(2) - Integer(12)*t - Integer(18))>>> h.support()#␣˓→needs sage.libs.pari[t - 1, t + 3, t^2 + 2, t^2 + t + 1, t^4 - 2]sage.rings.fraction_field_element.is_FractionFieldElement(x)Return whether or not x is a FractionFieldElement.
EXAMPLES:
sage: from sage.rings.fraction_field_element import is_FractionFieldElement
sage: R.<x> = ZZ[]
sage: is_FractionFieldElement(x/2)
doctest:warning...
DeprecationWarning: The function is_FractionFieldElement is deprecated;
use isinstance(..., FractionFieldElement) instead.
(continues on next page)

4.2. Fraction Field Elements929

Polynomials, Release 10.4

(continued from previous page)

See https://github.com/sagemath/sage/issues/38128 for details.
False
sage: is_FractionFieldElement(2/x)
True
sage: is_FractionFieldElement(1/3)
False>>> from sage.all import *>>> from sage.rings.fraction_field_element import is_FractionFieldElement>>> R = ZZ[ x ]; (x,) = R._first_ngens(1)>>> is_FractionFieldElement(x/Integer(2))
doctest:warning...
DeprecationWarning: The function is_FractionFieldElement is deprecated;
use isinstance(..., FractionFieldElement) instead.
See https://github.com/sagemath/sage/issues/38128 for details.
False>>> is_FractionFieldElement(Integer(2)/x)
True>>> is_FractionFieldElement(Integer(1)/Integer(3))
False

sage.rings.fraction_field_element.make_element(parent, numerator, denominator)
Used for unpickling FractionFieldElement objects (and subclasses).
EXAMPLES:
sage: from sage.rings.fraction_field_element import make_element
sage: R = ZZ[ x,y ]sage: x,y = R.gens()
sage: F = R.fraction_field()sage: make_element(F, 1 + x, 1 + y)(x + 1)/(y + 1)>>> from sage.all import *>>> from sage.rings.fraction_field_element import make_element>>> R = ZZ[ x,y ]>>> x,y = R.gens()>>> F = R.fraction_field()>>> make_element(F, Integer(1) + x, Integer(1) + y)(x + 1)/(y + 1)

sage.rings.fraction_field_element.make_element_old(parent, cdict)Used for unpickling old FractionFieldElement pickles.
EXAMPLES:
sage: from sage.rings.fraction_field_element import make_element_old
sage: R.<x,y> = ZZ[]
sage: F = R.fraction_field()sage: make_element_old(F, { _FractionFieldElement__numerator : x + y,....:
_FractionFieldElement__denominator : x - y})(x + y)/(x - y)>>> from sage.all import *>>> from sage.rings.fraction_field_element import make_element_old(continues on next page)

930

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> F = R.fraction_field()>>> make_element_old(F, { _FractionFieldElement__numerator : x + y,...
_FractionFieldElement__denominator : x - y})(x + y)/(x - y)

4.3 Univariate rational functions over prime fields
class sage.rings.fraction_field_FpT.FpT(R, names=None)
Bases: FractionField_1poly_field
This class represents the fraction field F𝑝 (𝑇 ) for 2 < 𝑝 <√23 1 − 1.

EXAMPLES:
sage: R.<T> = GF(71)[]
sage: K = FractionField(R); K
Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 71
sage: 1-1/T(T + 70)/T
sage: parent(1-1/T) is K
True>>> from sage.all import *>>> R = GF(Integer(71))[ T ]; (T,) = R._first_ngens(1)>>> K = FractionField(R); K
Fraction Field of Univariate Polynomial Ring in T over Finite Field of size 71>>> Integer(1)-Integer(1)/T(T + 70)/T>>> parent(Integer(1)-Integer(1)/T) is K
True

INTEGER_LIMIT = 46341
iter(bound=None, start=None)
EXAMPLES:
sage: from sage.rings.fraction_field_FpT import *sage: R.<t> = FpT(GF(5)[ t ])sage: list(R.iter(2))[350:355][(t^2 + t + 1)/(t + 2),(t^2 + t + 2)/(t + 2),(t^2 + t + 4)/(t + 2),(t^2 + 2*t + 1)/(t + 2),(t^2 + 2*t + 2)/(t + 2)]>>> from sage.all import *>>> from sage.rings.fraction_field_FpT import *>>> R = FpT(GF(Integer(5))[ t ], names=( t ,)); (t,) = R._first_ngens(1)>>> list(R.iter(Integer(2)))[Integer(350):Integer(355)][(t^2 + t + 1)/(t + 2),(t^2 + t + 2)/(t + 2),(t^2 + t + 4)/(t + 2),(continues on next page)

4.3. Univariate rational functions over prime fields

931

Polynomials, Release 10.4

(continued from previous page)(t^2 + 2*t + 1)/(t + 2),(t^2 + 2*t + 2)/(t + 2)]

class sage.rings.fraction_field_FpT.FpTElement
Bases: FieldElement
An element of an FpT fraction field.
denom()
Return the denominator of this element, as an element of the polynomial ring.
EXAMPLES:
sage: K = GF(11)[ t ].fraction_field()sage: t = K.gen(0); a = (t + 1/t)^3 - 1
sage: a.denom()t^3>>> from sage.all import *>>> K = GF(Integer(11))[ t ].fraction_field()>>> t = K.gen(Integer(0)); a = (t + Integer(1)/t)**Integer(3) - Integer(1)>>> a.denom()t^3

denominator()
Return the denominator of this element, as an element of the polynomial ring.
EXAMPLES:
sage: K = GF(11)[ t ].fraction_field()sage: t = K.gen(0); a = (t + 1/t)^3 - 1
sage: a.denominator()t^3>>> from sage.all import *>>> K = GF(Integer(11))[ t ].fraction_field()>>> t = K.gen(Integer(0)); a = (t + Integer(1)/t)**Integer(3) - Integer(1)>>> a.denominator()t^3

factor()
EXAMPLES:
sage: K = Frac(GF(5)[ t ])sage: t = K.gen()sage: f = 2 * (t+1) * (t^2+t+1)^2 / (t-1)
sage: factor(f)(2) * (t + 4)^-1 * (t + 1) * (t^2 + t + 1)^2>>> from sage.all import *>>> K = Frac(GF(Integer(5))[ t ])>>> t = K.gen()>>> f = Integer(2) * (t+Integer(1)) *␣
˓→(t**Integer(2)+t+Integer(1))**Integer(2) / (t-Integer(1))>>> factor(f)(2) * (t + 4)^-1 * (t + 1) * (t^2 + t + 1)^2

932

Chapter 4. Rational Functions

Polynomials, Release 10.4

is_square()Return True if this element is the square of another element of the fraction field.
EXAMPLES:
sage: K = GF(13)[ t ].fraction_field(); t = K.gen()sage: t.is_square()False
sage: (1/t^2).is_square()True
sage: K(0).is_square()True>>> from sage.all import *>>> K = GF(Integer(13))[ t ].fraction_field(); t = K.gen()>>> t.is_square()False>>> (Integer(1)/t**Integer(2)).is_square()True>>> K(Integer(0)).is_square()True

next()
Iterate through all polynomials, returning the “next” polynomial after this one.
The strategy is as follows:• We always leave the denominator monic.
• We progress through the elements with both numerator and denominator monic, and with the denominator less than the numerator. For each such, we output all the scalar multiples of it, then all of the scalarmultiples of its inverse.
• So if the leading coefficient of the numerator is less than 𝑝 − 1, we scale the numerator to increase it by1.
• Otherwise, we consider the multiple with numerator and denominator monic.
– If the numerator is less than the denominator (lexicographically), we return the inverse of that element.
– If the numerator is greater than the denominator, we invert, and then increase the numerator (remaining monic) until we either get something relatively prime to the new denominator, or we reachthe new denominator. In this case, we increase the denominator and set the numerator to 1.
EXAMPLES:
sage: from sage.rings.fraction_field_FpT import *sage: R.<t> = FpT(GF(3)[ t ])sage: a = R(0)sage: for _ in range(30):....:a = a.next()....:
print(a)
1
2
1/t
2/t
t
2*t
1/(t + 1)(continues on next page)

4.3. Univariate rational functions over prime fields

933

Polynomials, Release 10.4

(continued from previous page)2/(t + 1)t + 1
2*t + 2t/(t + 1)
2*t/(t + 1)
(t + 1)/t(2*t + 2)/t
1/(t + 2)
2/(t + 2)t + 2
2*t + 1t/(t + 2)
2*t/(t + 2)
(t + 2)/t(2*t + 1)/t
(t + 1)/(t + 2)
(2*t + 2)/(t + 2)
(t + 2)/(t + 1)
(2*t + 1)/(t + 1)
1/t^2
2/t^2
t^2
2*t^2
>>> from sage.all import *>>> from sage.rings.fraction_field_FpT import *>>> R = FpT(GF(Integer(3))[ t ], names=( t ,)); (t,) = R._first_ngens(1)>>> a = R(Integer(0))>>> for _ in range(Integer(30)):...
a = a.next()...
print(a)
1
2
1/t
2/t
t
2*t
1/(t + 1)
2/(t + 1)t + 1
2*t + 2t/(t + 1)
2*t/(t + 1)
(t + 1)/t(2*t + 2)/t
1/(t + 2)
2/(t + 2)t + 2
2*t + 1t/(t + 2)
2*t/(t + 2)
(t + 2)/t(2*t + 1)/t
(t + 1)/(t + 2)
(2*t + 2)/(t + 2)
(t + 2)/(t + 1)
(continues on next page)934

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)(2*t + 1)/(t + 1)
1/t^2
2/t^2
t^2
2*t^2

numer()
Return the numerator of this element, as an element of the polynomial ring.
EXAMPLES:
sage: K = GF(11)[ t ].fraction_field()sage: t = K.gen(0); a = (t + 1/t)^3 - 1
sage: a.numer()t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1>>> from sage.all import *>>> K = GF(Integer(11))[ t ].fraction_field()>>> t = K.gen(Integer(0)); a = (t + Integer(1)/t)**Integer(3) - Integer(1)>>> a.numer()t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1

numerator()
Return the numerator of this element, as an element of the polynomial ring.
EXAMPLES:
sage: K = GF(11)[ t ].fraction_field()sage: t = K.gen(0); a = (t + 1/t)^3 - 1
sage: a.numerator()t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1>>> from sage.all import *>>> K = GF(Integer(11))[ t ].fraction_field()>>> t = K.gen(Integer(0)); a = (t + Integer(1)/t)**Integer(3) - Integer(1)>>> a.numerator()t^6 + 3*t^4 + 10*t^3 + 3*t^2 + 1

sqrt(extend=True, all=False)
Return the square root of this element.
INPUT:• extend – bool (default: True); if True, return a square root in an extension ring, if necessary. Otherwise, raise a ValueError if the square is not in the base ring.
• all – bool (default: False); if True, return all square roots of self, instead of just one.
EXAMPLES:
sage: from sage.rings.fraction_field_FpT import *sage: K = GF(7)[ t ].fraction_field(); t = K.gen(0)sage: p = (t + 2)^2/(3*t^3 + 1)^4
sage: p.sqrt()(3*t + 6)/(t^6 + 3*t^3 + 4)
sage: p.sqrt()^2 == p
True

4.3. Univariate rational functions over prime fields

935

Polynomials, Release 10.4>>> from sage.all import *>>> from sage.rings.fraction_field_FpT import *>>> K = GF(Integer(7))[ t ].fraction_field(); t = K.gen(Integer(0))>>> p = (t + Integer(2))**Integer(2)/(Integer(3)*t**Integer(3) +␣˓→Integer(1))**Integer(4)>>> p.sqrt()(3*t + 6)/(t^6 + 3*t^3 + 4)>>> p.sqrt()**Integer(2) == p
Truesubs(in_dict=None, *args, **kwds)
EXAMPLES:
sage: K = Frac(GF(11)[ t ])sage: t = K.gen()sage: f = (t+1)/(t-1)
sage: f.subs(t=2)
3
sage: f.subs(X=2)(t + 1)/(t + 10)>>> from sage.all import *>>> K = Frac(GF(Integer(11))[ t ])>>> t = K.gen()>>> f = (t+Integer(1))/(t-Integer(1))>>> f.subs(t=Integer(2))
3>>> f.subs(X=Integer(2))(t + 1)/(t + 10)

valuation(v)Return the valuation of self at 𝑣.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: f = (t+1)^2 * (t^2+t+1) / (t-1)^3
sage: f.valuation(t+1)
2
sage: f.valuation(t-1)-3sage: f.valuation(t)0>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> f = (t+Integer(1))**Integer(2) * (t**Integer(2)+t+Integer(1)) / (t˓→Integer(1))**Integer(3)>>> f.valuation(t+Integer(1))
2>>> f.valuation(t-Integer(1))-3>>> f.valuation(t)0class sage.rings.fraction_field_FpT.FpT_Fp_section
Bases: Section
936

Chapter 4. Rational Functions

Polynomials, Release 10.4

This class represents the section from GF(p)(t) back to GF(p)[t]EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = GF(5).convert_map_from(K); f
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5To:
Finite Field of size 5
sage: type(f)<class sage.rings.fraction_field_FpT.FpT_Fp_section >>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = GF(Integer(5)).convert_map_from(K); f
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5To:
Finite Field of size 5>>> type(f)<class sage.rings.fraction_field_FpT.FpT_Fp_section >Warning: Comparison of FpT_Fp_section objects is not currently implemented. See Issue #23469.
sage: fprime = loads(dumps(f))
sage: fprime == fFalse
sage: fprime(3) == f(3)True>>> from sage.all import *>>> fprime = loads(dumps(f))>>> fprime == f
False>>> fprime(Integer(3)) == f(Integer(3))
Trueclass sage.rings.fraction_field_FpT.FpT_Polyring_section
Bases: Section
This class represents the section from GF(p)(t) back to GF(p)[t]EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = R.convert_map_from(K); f
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5To:
Univariate Polynomial Ring in t over Finite Field of size 5(continues on next page)

4.3. Univariate rational functions over prime fields

937

Polynomials, Release 10.4

(continued from previous page)

sage: type(f)<class sage.rings.fraction_field_FpT.FpT_Polyring_section >>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = R.convert_map_from(K); f
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5To:
Univariate Polynomial Ring in t over Finite Field of size 5>>> type(f)<class sage.rings.fraction_field_FpT.FpT_Polyring_section >Warning:#23469.

Comparison of FpT_Polyring_section objects is not currently implemented. See Issue

sage: fprime = loads(dumps(f))
sage: fprime == fFalse
sage: fprime(1+t) == f(1+t)
True>>> from sage.all import *>>> fprime = loads(dumps(f))>>> fprime == f
False>>> fprime(Integer(1)+t) == f(Integer(1)+t)
Trueclass sage.rings.fraction_field_FpT.FpT_iter
Bases: object
Return a class that iterates over all elements of an FpT.
EXAMPLES:
sage: K = GF(3)[ t ].fraction_field()sage: I = K.iter(1)sage: list(I)
[0,
1,
2,
t,
t + 1,
t + 2,
2*t,
2*t + 1,
2*t + 2,
1/t,
2/t,(t + 1)/t,(t + 2)/t,(continues on next page)

938

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)(2*t + 1)/t,(2*t + 2)/t,
1/(t + 1),
2/(t + 1),
t/(t + 1),(t + 2)/(t + 1),
2*t/(t + 1),(2*t + 1)/(t + 1),
1/(t + 2),
2/(t + 2),
t/(t + 2),(t + 1)/(t + 2),
2*t/(t + 2),(2*t + 2)/(t + 2)]>>> from sage.all import *>>> K = GF(Integer(3))[ t ].fraction_field()>>> I = K.iter(Integer(1))>>> list(I)
[0,
1,
2,
t,
t + 1,
t + 2,
2*t,
2*t + 1,
2*t + 2,
1/t,
2/t,(t + 1)/t,(t + 2)/t,(2*t + 1)/t,(2*t + 2)/t,
1/(t + 1),
2/(t + 1),
t/(t + 1),(t + 2)/(t + 1),
2*t/(t + 1),(2*t + 1)/(t + 1),
1/(t + 2),
2/(t + 2),
t/(t + 2),(t + 1)/(t + 2),
2*t/(t + 2),(2*t + 2)/(t + 2)]

class sage.rings.fraction_field_FpT.Fp_FpT_coerce
Bases: RingHomomorphism
This class represents the coercion map from GF(p) to GF(p)(t)EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = K.coerce_map_from(GF(5)); f(continues on next page)

4.3. Univariate rational functions over prime fields

939

Polynomials, Release 10.4

(continued from previous page)

Ring morphism:
From: Finite Field of size 5
To:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5sage: type(f)<class sage.rings.fraction_field_FpT.Fp_FpT_coerce >>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(GF(Integer(5))); f
Ring morphism:
From: Finite Field of size 5
To:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5>>> type(f)<class sage.rings.fraction_field_FpT.Fp_FpT_coerce >section()Return the section of this inclusion: the partially defined map from GF(p)(t) back to GF(p), defined on
constant elements.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = K.coerce_map_from(GF(5))
sage: g = f.section(); gSection map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Finite Field of size 5
sage: t = K.gen()sage: g(f(1,3,reduce=False))2
sage: g(t)Traceback (most recent call last):...
ValueError: not constantsage: g(1/t)
Traceback (most recent call last):...
ValueError: not integral>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(GF(Integer(5)))>>> g = f.section(); gSection map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Finite Field of size 5>>> t = K.gen()>>> g(f(Integer(1),Integer(3),reduce=False))2(continues on next page)

940

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)>>> g(t)Traceback (most recent call last):...
ValueError: not constant>>> g(Integer(1)/t)
Traceback (most recent call last):...
ValueError: not integral

class sage.rings.fraction_field_FpT.Polyring_FpT_coerce
Bases: RingHomomorphism
This class represents the coercion map from GF(p)[t] to GF(p)(t)EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = K.coerce_map_from(R); f
Ring morphism:
From: Univariate Polynomial Ring in t over Finite Field of size 5
To:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5sage: type(f)<class sage.rings.fraction_field_FpT.Polyring_FpT_coerce >>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(R); f
Ring morphism:
From: Univariate Polynomial Ring in t over Finite Field of size 5
To:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 5>>> type(f)<class sage.rings.fraction_field_FpT.Polyring_FpT_coerce >section()Return the section of this inclusion: the partially defined map from GF(p)(t) back to GF(p)[t], definedon elements with unit denominator.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()sage: f = K.coerce_map_from(R)sage: g = f.section(); gSection map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Univariate Polynomial Ring in t over Finite Field of size 5
sage: t = K.gen()sage: g(t)tsage: g(1/t)
Traceback (most recent call last):(continues on next page)

4.3. Univariate rational functions over prime fields

941

Polynomials, Release 10.4

(continued from previous page)...
ValueError: not integral>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(R)>>> g = f.section(); gSection map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Univariate Polynomial Ring in t over Finite Field of size 5>>> t = K.gen()>>> g(t)t>>> g(Integer(1)/t)
Traceback (most recent call last):...
ValueError: not integral

class sage.rings.fraction_field_FpT.ZZ_FpT_coerce
Bases: RingHomomorphism
This class represents the coercion map from ZZ to GF(p)(t)EXAMPLES:
sage: R.<t> = GF(17)[]
sage: K = R.fraction_field()sage: f = K.coerce_map_from(ZZ); f
Ring morphism:
From: Integer RingTo:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 17
sage: type(f)<class sage.rings.fraction_field_FpT.ZZ_FpT_coerce >>>> from sage.all import *>>> R = GF(Integer(17))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(ZZ); f
Ring morphism:
From: Integer RingTo:
Fraction Field of Univariate Polynomial Ring in t over Finite Field of␣˓→size 17>>> type(f)<class sage.rings.fraction_field_FpT.ZZ_FpT_coerce >section()Return the section of this inclusion: the partially defined map from GF(p)(t) back to ZZ, defined on
constant elements.
EXAMPLES:
sage: R.<t> = GF(5)[]sage: K = R.fraction_field()(continues on next page)942

Chapter 4. Rational Functions

Polynomials, Release 10.4

(continued from previous page)

sage: f = K.coerce_map_from(ZZ)
sage: g = f.section(); gComposite map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Integer Ring
Defn:
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite␣˓→Field of size 5
To:
Finite Field of size 5
thenLifting map:
From: Finite Field of size 5
To:
Integer Ringsage: t = K.gen()sage: g(f(1,3,reduce=False))2
sage: g(t)Traceback (most recent call last):...
ValueError: not constantsage: g(1/t)
Traceback (most recent call last):...
ValueError: not integral>>> from sage.all import *>>> R = GF(Integer(5))[ t ]; (t,) = R._first_ngens(1)>>> K = R.fraction_field()>>> f = K.coerce_map_from(ZZ)>>> g = f.section(); gComposite map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite Field␣
˓→of size 5
To:
Integer Ring
Defn:
Section map:
From: Fraction Field of Univariate Polynomial Ring in t over Finite␣˓→Field of size 5
To:
Finite Field of size 5
thenLifting map:
From: Finite Field of size 5
To:
Integer Ring>>> t = K.gen()>>> g(f(Integer(1),Integer(3),reduce=False))2>>> g(t)Traceback (most recent call last):...
ValueError: not constant>>> g(Integer(1)/t)
Traceback (most recent call last):...
ValueError: not integral

sage.rings.fraction_field_FpT.unpickle_FpT_element(K, numer, denom)
Used for pickling.
4.3. Univariate rational functions over prime fields

943

Polynomials, Release 10.4

944

Chapter 4. Rational Functions

CHAPTERFIVE

LAURENT POLYNOMIALS

5.1 Ring of Laurent Polynomials (base class)±1±1
If 𝑅 is a commutative ring, then the ring of Laurent polynomials in 𝑛 variables over 𝑅 is 𝑅[𝑥±11 , 𝑥2 , . . . , 𝑥𝑛 ].

AUTHORS:• David Roe (2008-2-23): created• David Loeffler (2009-07-10): cleaned up docstrings
class sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic(R)Bases: CommutativeRing, Parent
Laurent polynomial ring (base class).
EXAMPLES:This base class inherits from CommutativeRing. Since Issue #11900, it is also initialised as such:
sage: R.<x1,x2> = LaurentPolynomialRing(QQ)
sage: R.category()
Join of Category of unique factorization domains
and Category of commutative algebras
over (number fields and quotient fields and metric spaces)
and Category of infinite sets
sage: TestSuite(R).run()>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x1 , x2 ,)); (x1, x2,) = R._first_
˓→ngens(2)>>> R.category()
Join of Category of unique factorization domains
and Category of commutative algebras
over (number fields and quotient fields and metric spaces)
and Category of infinite sets>>> TestSuite(R).run()change_ring(base_ring=None, names=None, sparse=False, order=None)
EXAMPLES:
sage: R = LaurentPolynomialRing(QQ, 2, x )sage: R.change_ring(ZZ)
Multivariate Laurent Polynomial Ring in x0, x1 over Integer Ring

945

Polynomials, Release 10.4>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, Integer(2), x )>>> R.change_ring(ZZ)
Multivariate Laurent Polynomial Ring in x0, x1 over Integer Ring

Check that the distinction between a univariate ring and a multivariate ring with one generator is preserved:
sage: P.<x> = LaurentPolynomialRing(QQ, 1)
sage: P
Multivariate Laurent Polynomial Ring in x over Rational Field
sage: K.<i> = CyclotomicField(4)˓→# needs sage.rings.number_fieldsage: P.change_ring(K)˓→# needs sage.rings.number_field
Multivariate Laurent Polynomial Ring in x over
Cyclotomic Field of order 4 and degree 2

␣␣>>> from sage.all import *>>> P = LaurentPolynomialRing(QQ, Integer(1), names=( x ,)); (x,) = P._first_
˓→ngens(1)>>> P
Multivariate Laurent Polynomial Ring in x over Rational Field>>> K = CyclotomicField(Integer(4), names=( i ,)); (i,) = K._first_ngens(1)#␣
˓→needs sage.rings.number_field>>> P.change_ring(K)␣˓→# needs sage.rings.number_field
Multivariate Laurent Polynomial Ring in x over
Cyclotomic Field of order 4 and degree 2

characteristic()
Returns the characteristic of the base ring.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x ).characteristic()
0
sage: LaurentPolynomialRing(GF(3), 2, x ).characteristic()
3>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2), x ).characteristic()
0>>> LaurentPolynomialRing(GF(Integer(3)), Integer(2), x ).characteristic()
3

completion(p=None, prec=20, extras=None)
Return the completion of self.
Currently only implemented for the ring of formal Laurent series. The prec variable controls the precisionused in the Laurent series ring. If prec is ∞, then this returns a LazyLaurentSeriesRing.
EXAMPLES:
sage: P.<x> = LaurentPolynomialRing(QQ); P
Univariate Laurent Polynomial Ring in x over Rational Field
sage: PP = P.completion(x); PP
Laurent Series Ring in x over Rational Field(continues on next page)

946

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)

sage: f = 1 - 1/x
sage: PP(f)-x^-1 + 1
sage: g = 1 / PP(f); g-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 - x^20 + O(x^21)
sage: 1 / g-x^-1 + 1 + O(x^19)
sage: # needs sage.combinat
sage: PP = P.completion(x, prec=oo); PP
Lazy Laurent Series Ring in x over Rational Field
sage: g = 1 / PP(f); g-x - x^2 - x^3 + O(x^4)
sage: 1 / g == f
True>>> from sage.all import *>>> P = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = P._first_ngens(1); P
Univariate Laurent Polynomial Ring in x over Rational Field>>> PP = P.completion(x); PP
Laurent Series Ring in x over Rational Field>>> f = Integer(1) - Integer(1)/x>>> PP(f)-x^-1 + 1>>> g = Integer(1) / PP(f); g-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 - x^20 + O(x^21)>>> Integer(1) / g-x^-1 + 1 + O(x^19)>>> # needs sage.combinat>>> PP = P.completion(x, prec=oo); PP
Lazy Laurent Series Ring in x over Rational Field>>> g = Integer(1) / PP(f); g-x - x^2 - x^3 + O(x^4)>>> Integer(1) / g == f
Trueconstruction()
Return the construction of self.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x,y ).construction()(LaurentPolynomialFunctor,
Univariate Laurent Polynomial Ring in x over Rational Field)>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2), x,y ).construction()(LaurentPolynomialFunctor,
Univariate Laurent Polynomial Ring in x over Rational Field)

fraction_field()
The fraction field is the same as the fraction field of the polynomial ring.
EXAMPLES:
5.1. Ring of Laurent Polynomials (base class)947

Polynomials, Release 10.4

sage: L.<x> = LaurentPolynomialRing(QQ)
sage: L.fraction_field()
Fraction Field of Univariate Polynomial Ring in x over Rational Field
sage: (x^-1 + 2) / (x - 1)
(2*x + 1)/(x^2 - x)>>> from sage.all import *>>> L = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = L._first_ngens(1)>>> L.fraction_field()
Fraction Field of Univariate Polynomial Ring in x over Rational Field>>> (x**-Integer(1) + Integer(2)) / (x - Integer(1))(2*x + 1)/(x^2 - x)gen(i=0)
Returns the 𝑖𝑡ℎ generator of self. If i is not specified, then the first generator will be returned.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,x0
sage: LaurentPolynomialRing(QQ, 2,x0
sage: LaurentPolynomialRing(QQ, 2,
x1x ).gen()x ).gen(0)x ).gen(1)>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),x0>>> LaurentPolynomialRing(QQ, Integer(2),x0>>> LaurentPolynomialRing(QQ, Integer(2),x1x ).gen()x ).gen(Integer(0))
x ).gen(Integer(1))

ideal(*args, **kwds)
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x ).ideal([1])
Ideal (1) of Multivariate Laurent Polynomial Ring in x0, x1 over Rational␣
˓→Field>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2), x ).ideal([Integer(1)])
Ideal (1) of Multivariate Laurent Polynomial Ring in x0, x1 over Rational␣
˓→Field

is_exact()
Return True if the base ring is exact.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x ).is_exact()
True
sage: LaurentPolynomialRing(RDF, 2, x ).is_exact()
False

948

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2), x ).is_exact()
True>>> LaurentPolynomialRing(RDF, Integer(2), x ).is_exact()
False

is_field(proof=True)
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,
Falsex ).is_field()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),False

x ).is_field()

is_finite()
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,
Falsex ).is_finite()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),False

x ).is_finite()

is_integral_domain(proof=True)
Return True if self is an integral domain.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,
Truex ).is_integral_domain()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),Truex ).is_integral_domain()

The following used to fail; see Issue #7530:
sage: L = LaurentPolynomialRing(ZZ, X )sage: L[ Y ]Univariate Polynomial Ring in Y over
Univariate Laurent Polynomial Ring in X over Integer Ring>>> from sage.all import *>>> L = LaurentPolynomialRing(ZZ, X )>>> L[ Y ]Univariate Polynomial Ring in Y over
Univariate Laurent Polynomial Ring in X over Integer Ring

is_noetherian()
Return True if self is Noetherian.
EXAMPLES:

5.1. Ring of Laurent Polynomials (base class)949

Polynomials, Release 10.4

sage: LaurentPolynomialRing(QQ, 2,
Truex ).is_noetherian()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),Truex ).is_noetherian()krull_dimension()
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,
Traceback (most recent call last):...
NotImplementedError

x ).krull_dimension()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),Traceback (most recent call last):...
NotImplementedError

x ).krull_dimension()ngens()
Return the number of generators of self.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2,
2
sage: LaurentPolynomialRing(QQ, 1,
1x ).ngens()
x ).ngens()>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),2>>> LaurentPolynomialRing(QQ, Integer(1),1x ).ngens()
x ).ngens()

polynomial_ring()
Returns the polynomial ring associated with self.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x ).polynomial_ring()
Multivariate Polynomial Ring in x0, x1 over Rational Field
sage: LaurentPolynomialRing(QQ, 1, x ).polynomial_ring()
Multivariate Polynomial Ring in x over Rational Field>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2), x ).polynomial_ring()
Multivariate Polynomial Ring in x0, x1 over Rational Field>>> LaurentPolynomialRing(QQ, Integer(1), x ).polynomial_ring()
Multivariate Polynomial Ring in x over Rational Field

random_element(min_valuation=-2, max_degree=2, *args, **kwds)
Return a random polynomial with degree at most max_degree and lowest valuation at least min_valuation.
950

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

Uses the random sampling from the base polynomial ring then divides out by a monomial to ensure correct
max_degree and min_valuation.
INPUT:• min_valuation – integer (default: -2); the minimal allowed valuation of the polynomial• max_degree – integer (default: 2); the maximal allowed degree of the polynomial• *args, **kwds – passed to the random element generator of the base polynomial ring and base ringitself
EXAMPLES:
sage: L.<x> = LaurentPolynomialRing(QQ)
sage: f = L.random_element()
sage: f.degree() <= 2
Truesage: f.valuation() >= -2
True
sage: f.parent() is L
True>>> from sage.all import *>>> L = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = L._first_ngens(1)>>> f = L.random_element()>>> f.degree() <= Integer(2)True>>> f.valuation() >= -Integer(2)True>>> f.parent() is L
True
sage: L = LaurentPolynomialRing(ZZ, 2,
sage: f = L.random_element(10, 20)
sage: f.degree() <= 20
True
sage: f.valuation() >= 10
True
sage: f.parent() is L
True

x )

>>> from sage.all import *>>> L = LaurentPolynomialRing(ZZ, Integer(2), x )>>> f = L.random_element(Integer(10), Integer(20))>>> f.degree() <= Integer(20)True>>> f.valuation() >= Integer(10)True>>> f.parent() is L
True
sage: L = LaurentPolynomialRing(GF(13), 3,
sage: f = L.random_element(-10, -1)
sage: f.degree() <= -1
True
sage: f.valuation() >= -10
True

x )

(continues on next page)

5.1. Ring of Laurent Polynomials (base class)951

Polynomials, Release 10.4

(continued from previous page)

sage: f.parent() is L
True>>> from sage.all import *>>> L = LaurentPolynomialRing(GF(Integer(13)), Integer(3),>>> f = L.random_element(-Integer(10), -Integer(1))>>> f.degree() <= -Integer(1)True>>> f.valuation() >= -Integer(10)True>>> f.parent() is L
True

x )

sage: L.<x, y> = LaurentPolynomialRing(RR)
sage: f = L.random_element()
sage: f.degree() <= 2
Truesage: f.valuation() >= -2
True
sage: f.parent() is L
True>>> from sage.all import *>>> L = LaurentPolynomialRing(RR, names=( x ,˓→ngens(2)>>> f = L.random_element()>>> f.degree() <= Integer(2)True>>> f.valuation() >= -Integer(2)True>>> f.parent() is L
True
sage: L = LaurentPolynomialRing(QQbar, 5,
sage: f = L.random_element(-1, 1)
sage: f = L.random_element(-1, 1)
sage: f.degree() <= 1
True
sage: f.valuation() >= -1
True
sage: f.parent() is L
Truey ,)); (x, y,) = L._first_

x )>>> from sage.all import *>>> L = LaurentPolynomialRing(QQbar, Integer(5), x )>>> f = L.random_element(-Integer(1), Integer(1))>>> f = L.random_element(-Integer(1), Integer(1))>>> f.degree() <= Integer(1)True>>> f.valuation() >= -Integer(1)True>>> f.parent() is L
Trueremove_var(var)952

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

EXAMPLES:
sage: R = LaurentPolynomialRing(QQ, x,y,z )sage: R.remove_var( x )Multivariate Laurent Polynomial Ring in y, z over Rational Field
sage: R.remove_var( x ).remove_var( y )Univariate Laurent Polynomial Ring in z over Rational Field>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, x,y,z )>>> R.remove_var( x )Multivariate Laurent Polynomial Ring in y, z over Rational Field>>> R.remove_var( x ).remove_var( y )Univariate Laurent Polynomial Ring in z over Rational Field

term_order()Returns the term order of self.
EXAMPLES:
sage: LaurentPolynomialRing(QQ, 2, x ).term_order()Degree reverse lexicographic term order>>> from sage.all import *>>> LaurentPolynomialRing(QQ, Integer(2),Degree reverse lexicographic term orderx ).term_order()variable_names_recursive(depth=+Infinity)
Return the list of variable names of this ring and its base rings, as if it were a single multi-variate Laurent
polynomial.
INPUT:• depth – an integer or Infinity.
OUTPUT:
A tuple of strings.
EXAMPLES:
sage: T = LaurentPolynomialRing(QQ, x )sage: S = LaurentPolynomialRing(T, y )sage: R = LaurentPolynomialRing(S, z )sage: R.variable_names_recursive()( x , y , z )sage: R.variable_names_recursive(2)( y , z )>>> from sage.all import *>>> T = LaurentPolynomialRing(QQ, x )>>> S = LaurentPolynomialRing(T, y )>>> R = LaurentPolynomialRing(S, z )>>> R.variable_names_recursive()( x , y , z )>>> R.variable_names_recursive(Integer(2))( y , z )5.1. Ring of Laurent Polynomials (base class)953

Polynomials, Release 10.4

5.2 Ring of Laurent Polynomials±1±1
If 𝑅 is a commutative ring, then the ring of Laurent polynomials in 𝑛 variables over 𝑅 is 𝑅[𝑥±11 , 𝑥2 , . . . , 𝑥𝑛 ]. We
implement it as a quotient ring𝑅[𝑥1 , 𝑦1 , 𝑥2 , 𝑦2 , . . . , 𝑥𝑛 , 𝑦𝑛 ]/(𝑥1 𝑦1 − 1, 𝑥2 𝑦2 − 1, . . . , 𝑥𝑛 𝑦𝑛 − 1).
AUTHORS:• David Roe (2008-2-23): created• David Loeffler (2009-07-10): cleaned up docstrings
sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing(base_ring,*args,**kwds)Return the globally unique univariate or multivariate Laurent polynomial ring with given properties and variablename or names.
There are four ways to call the Laurent polynomial ring constructor:
1. LaurentPolynomialRing(base_ring, name, sparse=False)
2. LaurentPolynomialRing(base_ring, names, order= degrevlex )3. LaurentPolynomialRing(base_ring, name, n, order= degrevlex )4. LaurentPolynomialRing(base_ring, n, name, order= degrevlex )The optional arguments sparse and order must be explicitly named, and the other arguments must be given
positionally.
INPUT:• base_ring – a commutative ring
• name – a string• names – a list or tuple of names, or a comma separated string• n – a positive integer• sparse – bool (default: False), whether or not elements are sparse• order – string or TermOrder, e.g.,–

degrevlex (default) – degree reverse lexicographic–lex – lexicographic–

deglex – degree lexicographic– TermOrder( deglex ,3) + TermOrder( deglex ,3) – block ordering
OUTPUT:
LaurentPolynomialRing(base_ring, name, sparse=False) returns a univariate Laurent polynomial ring; all other input formats return a multivariate Laurent polynomial ring.
UNIQUENESS and IMMUTABILITY: In Sage there is exactly one single-variate Laurent polynomial ring overeach base ring in each choice of variable and sparseness. There is also exactly one multivariate Laurent polynomial
ring over each base ring for each choice of names of variables and term order.

954

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

sage: R.<x,y> = LaurentPolynomialRing(QQ, 2); R˓→needs sage.modules
Multivariate Laurent Polynomial Ring in x, y over Rational Field
sage: f = x^2 - 2*y^-2
˓→needs sage.modules#␣#␣>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, Integer(2), names=( x , y ,)); (x, y,) = R._
˓→first_ngens(2); R# needs sage.modules
Multivariate Laurent Polynomial Ring in x, y over Rational Field>>> f = x**Integer(2) - Integer(2)*y**-Integer(2)˓→# needs sage.modules␣

You can’t just globally change the names of those variables. This is because objects all over Sage could have pointersto that polynomial ring.
sage: R._assign_names([ z , w ])˓→needs sage.modules
Traceback (most recent call last):...
ValueError: variable names cannot be changed after object creation.

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

#␣

EXAMPLES:
1. LaurentPolynomialRing(base_ring, name, sparse=False)
sage: LaurentPolynomialRing(QQ, w )Univariate Laurent Polynomial Ring in w over Rational Field>>> from sage.all import *>>> LaurentPolynomialRing(QQ, w )Univariate Laurent Polynomial Ring in w over Rational Field

Use the diamond brackets notation to make the variable ready for use after you define the ring:sage: R.<w> = LaurentPolynomialRing(QQ)
sage: (1 + w)^3
1 + 3*w + 3*w^2 + w^3>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( w ,)); (w,) = R._first_ngens(1)>>> (Integer(1) + w)**Integer(3)1 + 3*w + 3*w^2 + w^3

You must specify a name:sage: LaurentPolynomialRing(QQ)
Traceback (most recent call last):...
(continues on next page)

5.2. Ring of Laurent Polynomials

955

Polynomials, Release 10.4

(continued from previous page)

TypeError: you must specify the names of the variables
sage: R.<abc> = LaurentPolynomialRing(QQ, sparse=True); R
Univariate Laurent Polynomial Ring in abc over Rational Field
sage: R.<w> = LaurentPolynomialRing(PolynomialRing(GF(7), k )); R
Univariate Laurent Polynomial Ring in w over
Univariate Polynomial Ring in k over Finite Field of size 7>>> from sage.all import *>>> LaurentPolynomialRing(QQ)
Traceback (most recent call last):...
TypeError: you must specify the names of the variables>>> R = LaurentPolynomialRing(QQ, sparse=True, names=( abc ,)); (abc,) = R._
˓→first_ngens(1); R
Univariate Laurent Polynomial Ring in abc over Rational Field>>> R = LaurentPolynomialRing(PolynomialRing(GF(Integer(7)), k ), names=( w ,˓→)); (w,) = R._first_ngens(1); R
Univariate Laurent Polynomial Ring in w over
Univariate Polynomial Ring in k over Finite Field of size 7

Rings with different variables are different:
sage: LaurentPolynomialRing(QQ,
False>>> from sage.all import *>>> LaurentPolynomialRing(QQ,Falsex ) == LaurentPolynomialRing(QQ,x ) == LaurentPolynomialRing(QQ,

y )

y )

2. LaurentPolynomialRing(base_ring, names, order= degrevlex )sage: R = LaurentPolynomialRing(QQ, a,b,c ); R
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field
sage: S = LaurentPolynomialRing(QQ, [ a , b , c ]); S
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field
sage: T = LaurentPolynomialRing(QQ, ( a , b , c )); T
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, a,b,c ); R˓→needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field>>> S = LaurentPolynomialRing(QQ, [ a , b , c ]); S
˓→needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field#␣#␣(continues on next page)

956

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> T = LaurentPolynomialRing(QQ, ( a , b , c )); T˓→needs sage.modules
Multivariate Laurent Polynomial Ring in a, b, c over Rational Field#␣

All three rings are identical.
sage: (R is S) and (S is T)
˓→# needs sage.modules
True>>> from sage.all import *>>> (R is S) and (S is T)
˓→needs sage.modules
True

#␣

There is a unique Laurent polynomial ring with each term order:
sage: # needs sage.modules
sage: R = LaurentPolynomialRing(QQ, x,y,z , order= degrevlex ); R
Multivariate Laurent Polynomial Ring in x, y, z over Rational Field
sage: S = LaurentPolynomialRing(QQ, x,y,z , order= invlex ); S
Multivariate Laurent Polynomial Ring in x, y, z over Rational Field
sage: S is LaurentPolynomialRing(QQ, x,y,z , order= invlex )Truesage: R == S
False>>> from sage.all import *>>> # needs sage.modules>>> R = LaurentPolynomialRing(QQ, x,y,z , order= degrevlex ); R
Multivariate Laurent Polynomial Ring in x, y, z over Rational Field>>> S = LaurentPolynomialRing(QQ, x,y,z , order= invlex ); S
Multivariate Laurent Polynomial Ring in x, y, z over Rational Field>>> S is LaurentPolynomialRing(QQ, x,y,z , order= invlex )True>>> R == S
False

3. LaurentPolynomialRing(base_ring, name, n, order= degrevlex )If you specify a single name as a string and a number of variables, then variables labeled with numbers are
created.
sage: LaurentPolynomialRing(QQ, x , 10)
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
over Rational Field
sage: LaurentPolynomialRing(GF(7), y , 5)
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4
over Finite Field of size 7
sage: LaurentPolynomialRing(QQ,y , 3, sparse=True)(continues on next page)

5.2. Ring of Laurent Polynomials

957

Polynomials, Release 10.4

(continued from previous page)# needs sage.modules
Multivariate Laurent Polynomial Ring in y0, y1, y2 over Rational Field˓→>>> from sage.all import *>>> LaurentPolynomialRing(QQ, x , Integer(10))␣˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in x0, x1, x2, x3, x4, x5, x6, x7, x8, x9
over Rational Field>>> LaurentPolynomialRing(GF(Integer(7)), y , Integer(5))˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in y0, y1, y2, y3, y4
over Finite Field of size 7

␣>>> LaurentPolynomialRing(QQ, y , Integer(3), sparse=True)˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in y0, y1, y2 over Rational Field␣

By calling the inject_variables() method, all those variable names are available for interactive use:
sage: R = LaurentPolynomialRing(GF(7), 15, w ); R
˓→# needs sage.modules
Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7,
w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7
sage: R.inject_variables()˓→# needs sage.modules
Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14
sage: (w0 + 2*w8 + w13)^2
˓→# needs sage.modules
w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2>>> from sage.all import *>>> R = LaurentPolynomialRing(GF(Integer(7)), Integer(15), w ); R˓→
# needs sage.modules
Multivariate Laurent Polynomial Ring in w0, w1, w2, w3, w4, w5, w6, w7,
w8, w9, w10, w11, w12, w13, w14 over Finite Field of size 7>>> R.inject_variables()˓→needs sage.modules
Defining w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14>>> (w0 + Integer(2)*w8 + w13)**Integer(2)˓→# needs sage.modules
w0^2 + 4*w0*w8 + 4*w8^2 + 2*w0*w13 + 4*w8*w13 + w13^2

␣

#␣

␣

class sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair(R)Bases: LaurentPolynomialRing_generic
EXAMPLES:
sage: L = LaurentPolynomialRing(QQ,2, x )#␣˓→needs sage.modules
sage: type(L)#␣˓→needs sage.modules<classsage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair_with_
˓→category >sage: L == loads(dumps(L))#␣(continues on next page)

958

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)needs sage.modules
True˓→>>> from sage.all import *>>> L = LaurentPolynomialRing(QQ,Integer(2), x )␣˓→ # needs sage.modules>>> type(L)# needs␣
˓→sage.modules<classsage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair_with_
˓→category >>>> L == loads(dumps(L))# needs␣
˓→sage.modules
True

Element
alias of LaurentPolynomial_mpair
monomial(*args)
Return the monomial whose exponents are given in argument.
EXAMPLES:
sage: # needs sage.modules
sage: L = LaurentPolynomialRing(QQ,
sage: L.monomial(-3, 5)
x0^-3*x1^5sage: L.monomial(1, 1)x0*x1
sage: L.monomial(0, 0)
1
sage: L.monomial(-2, -3)
x0^-2*x1^-3

x , 2)

sage: x0, x1 = L.gens()
˓→needs sage.modules
sage: L.monomial(-1, 2) == x0^-1 * x1^2
˓→needs sage.modules
True

#␣

sage: L.monomial(1, 2, 3)
˓→needs sage.modules
Traceback (most recent call last):...
TypeError: tuple key must have same length as ngens#␣#␣>>> from sage.all import *>>> # needs sage.modules>>> L = LaurentPolynomialRing(QQ, x , Integer(2))>>> L.monomial(-Integer(3), Integer(5))
x0^-3*x1^5>>> L.monomial(Integer(1), Integer(1))
x0*x1>>> L.monomial(Integer(0), Integer(0))
1>>> L.monomial(-Integer(2), -Integer(3))(continues on next page)

5.2. Ring of Laurent Polynomials959

Polynomials, Release 10.4

(continued from previous page)x0^-2*x1^-3>>> x0, x1 = L.gens()#␣˓→needs sage.modules>>> L.monomial(-Integer(1), Integer(2)) == x0**-Integer(1) * x1**Integer(2) ␣˓→# needs sage.modules
True>>> L.monomial(Integer(1), Integer(2), Integer(3))˓→# needs sage.modules
Traceback (most recent call last):...
TypeError: tuple key must have same length as ngens

␣class sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_univariate(R)Bases: LaurentPolynomialRing_generic
EXAMPLES:
sage: L = LaurentPolynomialRing(QQ, x )sage: type(L)<class sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_
˓→univariate_with_category >sage: TestSuite(L).run()>>> from sage.all import *>>> L = LaurentPolynomialRing(QQ, x )>>> type(L)<class sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_
˓→univariate_with_category >>>> TestSuite(L).run()

Element
alias of LaurentPolynomial_univariate
sage.rings.polynomial.laurent_polynomial_ring.from_fraction_field(L, x)
Helper function to construct a Laurent polynomial from an element of its parent’s fraction field.
INPUT:• L – an instance of LaurentPolynomialRing_generic• x – an element of the fraction field of L
OUTPUT:
An instance of the element class of L. If the denominator fails to be a unit in L an error is raised.
EXAMPLES:
sage: # needs sage.modules
sage: from sage.rings.polynomial.laurent_polynomial_ring import from_fraction_
˓→field
sage: L.<x, y> = LaurentPolynomialRing(ZZ)
sage: F = L.fraction_field()sage: xi = F(~x)
sage: from_fraction_field(L, xi) == ~x
True

960

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.modules>>> from sage.rings.polynomial.laurent_polynomial_ring import from_fraction_field>>> L = LaurentPolynomialRing(ZZ, names=( x , y ,)); (x, y,) = L._first_ngens(2)>>> F = L.fraction_field()>>> xi = F(~x)>>> from_fraction_field(L, xi) == ~x
Truesage.rings.polynomial.laurent_polynomial_ring.is_LaurentPolynomialRing(R)Return True if and only if R is a Laurent polynomial ring.
EXAMPLES:
sage: from sage.rings.polynomial.laurent_polynomial_ring import is_
˓→LaurentPolynomialRing
sage: P = PolynomialRing(QQ, 2, x )sage: is_LaurentPolynomialRing(P)doctest:warning...
DeprecationWarning: is_LaurentPolynomialRing is deprecated; use isinstance(...,
sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic)␣
˓→insteadSee https://github.com/sagemath/sage/issues/35229 for details.
False
sage: R = LaurentPolynomialRing(QQ,3, x )˓→needs sage.modules
sage: is_LaurentPolynomialRing(R)˓→needs sage.modules
True

#␣
#␣

>>> from sage.all import *>>> from sage.rings.polynomial.laurent_polynomial_ring import is_
˓→LaurentPolynomialRing>>> P = PolynomialRing(QQ, Integer(2), x )>>> is_LaurentPolynomialRing(P)doctest:warning...
DeprecationWarning: is_LaurentPolynomialRing is deprecated; use isinstance(...,
sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic)␣
˓→insteadSee https://github.com/sagemath/sage/issues/35229 for details.
False>>> R = LaurentPolynomialRing(QQ,Integer(3), x )˓→# needs sage.modules>>> is_LaurentPolynomialRing(R)˓→needs sage.modules
True

5.2. Ring of Laurent Polynomials

␣
#␣

961

Polynomials, Release 10.4

5.3 Elements of Laurent polynomial rings
class sage.rings.polynomial.laurent_polynomial.LaurentPolynomial
Bases: CommutativeAlgebraElement
Base class for Laurent polynomials.
change_ring(R)Return a copy of this Laurent polynomial, with coefficients in R.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: a = x^2 + 3*x^3 + 5*x^-1
sage: a.change_ring(GF(3))
2*x^-1 + x^2>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> a = x**Integer(2) + Integer(3)*x**Integer(3) + Integer(5)*x**-Integer(1)>>> a.change_ring(GF(Integer(3)))
2*x^-1 + x^2

Check that Issue #22277 is fixed:
sage: # needs sage.modules
sage: R.<x, y> = LaurentPolynomialRing(QQ)
sage: a = 2*x^2 + 3*x^3 + 4*x^-1
sage: a.change_ring(GF(3))-x^2 + x^-1>>> from sage.all import *>>> # needs sage.modules>>> R = LaurentPolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> a = Integer(2)*x**Integer(2) + Integer(3)*x**Integer(3) + Integer(4)*x**˓→Integer(1)>>> a.change_ring(GF(Integer(3)))-x^2 + x^-1

dict()
Abstract dict method.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
sage: LaurentPolynomial.dict(x)Traceback (most recent call last):...
NotImplementedError>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial>>> LaurentPolynomial.dict(x)(continues on next page)

962

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)

Traceback (most recent call last):...
NotImplementedError

hamming_weight()
Return the hamming weight of self.
The hamming weight is number of non-zero coefficients and also known as the weight or sparsity.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: f = x^3 - 1
sage: f.hamming_weight()
2>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(3) - Integer(1)>>> f.hamming_weight()
2

map_coefficients(f, new_base_ring=None)
Apply f to the coefficients of self.
If f is a sage.categories.map.Map, then the resulting polynomial will be defined over the codomainof f. Otherwise, the resulting polynomial will be over the same ring as self. Set new_base_ring tooverride this behavior.
INPUT:• f – a callable that will be applied to the coefficients of self.
• new_base_ring (optional) – if given, the resulting polynomial will be defined over this ring.
EXAMPLES:
sage: # needs sage.rings.finite_rings
sage: k.<a> = GF(9)sage: R.<x> = LaurentPolynomialRing(k)sage: f = x*a + a
sage: f.map_coefficients(lambda a: a + 1)
(a + 1) + (a + 1)*x
sage: R.<x,y> = LaurentPolynomialRing(k, 2)
˓→needs sage.modules
sage: f = x*a + 2*x^3*y*a + a
˓→needs sage.modules
sage: f.map_coefficients(lambda a: a + 1)
˓→needs sage.modules(2*a + 1)*x^3*y + (a + 1)*x + a + 1

#␣
#␣
#␣

>>> from sage.all import *>>> # needs sage.rings.finite_rings>>> k = GF(Integer(9), names=( a ,)); (a,) = k._first_ngens(1)>>> R = LaurentPolynomialRing(k, names=( x ,)); (x,) = R._first_ngens(1)>>> f = x*a + a>>> f.map_coefficients(lambda a: a + Integer(1))(continues on next page)

5.3. Elements of Laurent polynomial rings

963

Polynomials, Release 10.4

(continued from previous page)(a + 1) + (a + 1)*x>>> R = LaurentPolynomialRing(k, Integer(2), names=( x ,˓→first_ngens(2)# needs sage.modules>>> f = x*a + Integer(2)*x**Integer(3)*y*a + a˓→# needs sage.modules>>> f.map_coefficients(lambda a: a + Integer(1))˓→# needs sage.modules(2*a + 1)*x^3*y + (a + 1)*x + a + 1y ,)); (x, y,) = R._␣␣

Examples with different base ring:sage: # needs sage.modules sage.rings.finite_rings
sage: R.<r> = GF(9); S.
 = GF(81)sage: h = Hom(R, S)[0]; hRing morphism:
From: Finite Field in r of size 3^2
To:
Finite Field in s of size 3^4
Defn: r |--> 2*s^3 + 2*s^2 + 1
sage: T.<X,Y> = LaurentPolynomialRing(R, 2)
sage: f = r*X + Y
sage: g = f.map_coefficients(h); g(2*s^3 + 2*s^2 + 1)*X + Y
sage: g.parent()
Multivariate Laurent Polynomial Ring in X, Y
over Finite Field in s of size 3^4sage: h = lambda x: x.trace()sage: g = f.map_coefficients(h); g
X - Ysage: g.parent()
Multivariate Laurent Polynomial Ring in X, Y
over Finite Field in r of size 3^2
sage: g = f.map_coefficients(h, new_base_ring=GF(3)); gX - Y
sage: g.parent()
Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3>>> from sage.all import *>>> # needs sage.modules sage.rings.finite_rings>>> R = GF(Integer(9), names=( r ,)); (r,) = R._first_ngens(1); S =␣
˓→GF(Integer(81), names=( s ,)); (s,) = S._first_ngens(1)>>> h = Hom(R, S)[Integer(0)]; h
Ring morphism:
From: Finite Field in r of size 3^2
To:
Finite Field in s of size 3^4
Defn: r |--> 2*s^3 + 2*s^2 + 1>>> T = LaurentPolynomialRing(R, Integer(2), names=( X , Y ,)); (X, Y,) = T._
˓→first_ngens(2)>>> f = r*X + Y>>> g = f.map_coefficients(h); g(2*s^3 + 2*s^2 + 1)*X + Y>>> g.parent()
Multivariate Laurent Polynomial Ring in X, Y
over Finite Field in s of size 3^4>>> h = lambda x: x.trace()>>> g = f.map_coefficients(h); g
X - Y(continues on next page)

964

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> g.parent()
Multivariate Laurent Polynomial Ring in X, Y
over Finite Field in r of size 3^2>>> g = f.map_coefficients(h, new_base_ring=GF(Integer(3))); g
X - Y>>> g.parent()
Multivariate Laurent Polynomial Ring in X, Y over Finite Field of size 3

number_of_terms()
Abstract method for number of terms
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial
sage: LaurentPolynomial.number_of_terms(x)Traceback (most recent call last):...
NotImplementedError>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> from sage.rings.polynomial.laurent_polynomial import LaurentPolynomial>>> LaurentPolynomial.number_of_terms(x)Traceback (most recent call last):...
NotImplementedError

class sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
Bases: LaurentPolynomial
A univariate Laurent polynomial in the form of 𝑡𝑛 · 𝑓 where 𝑓 is a polynomial in 𝑡.
INPUT:• parent – a Laurent polynomial ring
• f – a polynomial (or something can be coerced to one)• n – (default: 0) an integer
AUTHORS:• Tom Boothby (2011) copied this class almost verbatim from laurent_series_ring_element.pyx,
so most of the credit goes to William Stein, David Joyner, and Robert Bradshaw• Travis Scrimshaw (09-2013): Cleaned-up and added a few extra methods
coefficients()
Return the nonzero coefficients of self.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: f = -5/t^(2) + t + t^2 - 10/3*t^3sage: f.coefficients()[-5, 1, 1, -10/3]

5.3. Elements of Laurent polynomial rings

965

Polynomials, Release 10.4>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> f = -Integer(5)/t**(Integer(2)) + t + t**Integer(2) - Integer(10)/
˓→Integer(3)*t**Integer(3)>>> f.coefficients()[-5, 1, 1, -10/3]

constant_coefficient()
Return the coefficient of the constant term of self.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: f = 3*t^-2 - t^-1 + 3 + t^2
sage: f.constant_coefficient()3
sage: g = -2*t^-2 + t^-1 + 3*t
sage: g.constant_coefficient()0>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> f = Integer(3)*t**-Integer(2) - t**-Integer(1) + Integer(3) +␣˓→t**Integer(2)>>> f.constant_coefficient()3>>> g = -Integer(2)*t**-Integer(2) + t**-Integer(1) + Integer(3)*t>>> g.constant_coefficient()0

degree()Return the degree of self.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: g = x^2 - x^4sage: g.degree()4
sage: g = -10/x^5 + x^2 - x^7sage: g.degree()7>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> g = x**Integer(2) - x**Integer(4)>>> g.degree()4>>> g = -Integer(10)/x**Integer(5) + x**Integer(2) - x**Integer(7)>>> g.degree()
7

The zero polynomial is defined to have degree −∞:sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: R.zero().degree()-Infinity

966

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> R.zero().degree()-Infinity

derivative(*args)
The formal derivative of this Laurent polynomial, with respect to variables supplied in args.
Multiple variables and iteration counts may be supplied. See documentation for the global derivative()function for more details.
See also:_derivative()
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: g = 1/x^10 - x + x^2 - x^4sage: g.derivative()-10*x^-11 - 1 + 2*x - 4*x^3sage: g.derivative(x)-10*x^-11 - 1 + 2*x - 4*x^3>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> g = Integer(1)/x**Integer(10) - x + x**Integer(2) - x**Integer(4)>>> g.derivative()-10*x^-11 - 1 + 2*x - 4*x^3>>> g.derivative(x)-10*x^-11 - 1 + 2*x - 4*x^3sage: R.<t> = PolynomialRing(ZZ)
sage: S.<x> = LaurentPolynomialRing(R)sage: f = 2*t/x + (3*t^2 + 6*t)*x
sage: f.derivative()-2*t*x^-2 + (3*t^2 + 6*t)
sage: f.derivative(x)-2*t*x^-2 + (3*t^2 + 6*t)
sage: f.derivative(t)2*x^-1 + (6*t + 6)*x>>> from sage.all import *>>> R = PolynomialRing(ZZ, names=( t ,)); (t,) = R._first_ngens(1)>>> S = LaurentPolynomialRing(R, names=( x ,)); (x,) = S._first_ngens(1)>>> f = Integer(2)*t/x + (Integer(3)*t**Integer(2) + Integer(6)*t)*x>>> f.derivative()-2*t*x^-2 + (3*t^2 + 6*t)>>> f.derivative(x)-2*t*x^-2 + (3*t^2 + 6*t)>>> f.derivative(t)2*x^-1 + (6*t + 6)*x

dict()
Return a dictionary representing self.
EXAMPLES:

5.3. Elements of Laurent polynomial rings

967

Polynomials, Release 10.4

sage: R.<x,y> = ZZ[]
sage: Q.<t> = LaurentPolynomialRing(R)sage: f = (x^3 + y/t^3)^3 + t^2; fy^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2
sage: f.dict(){-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1}>>> from sage.all import *>>> R = ZZ[ x, y ]; (x, y,) = R._first_ngens(2)>>> Q = LaurentPolynomialRing(R, names=( t ,)); (t,) = Q._first_ngens(1)>>> f = (x**Integer(3) + y/t**Integer(3))**Integer(3) + t**Integer(2); fy^3*t^-9 + 3*x^3*y^2*t^-6 + 3*x^6*y*t^-3 + x^9 + t^2>>> f.dict(){-9: y^3, -6: 3*x^3*y^2, -3: 3*x^6*y, 0: x^9, 2: 1}

divides(other)
Return True if self divides other.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: (2*x**-1 + 1).divides(4*x**-2 - 1)Truesage: (2*x + 1).divides(4*x**2 + 1)
False
sage: (2*x + x**-1).divides(R(0))
True
sage: R(0).divides(2*x ** -1 + 1)
False
sage: R(0).divides(R(0))
True
sage: R.<x> = LaurentPolynomialRing(Zmod(6))
sage: p = 4*x + 3*x^-1
sage: q = 5*x^2 + x + 2*x^-2
sage: p.divides(q)False
sage: R.<x,y> = GF(2)[]sage: S.<z> = LaurentPolynomialRing(R)sage: p = (x+y+1) * z**-1 + x*y
sage: q = (y^2-x^2) * z**-2 + z + x-y
sage: p.divides(q), p.divides(p*q)˓→needs sage.libs.singular(False, True)#␣>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> (Integer(2)*x**-Integer(1) + Integer(1)).divides(Integer(4)*x**˓→Integer(2) - Integer(1))
True>>> (Integer(2)*x + Integer(1)).divides(Integer(4)*x**Integer(2) + Integer(1))
False>>> (Integer(2)*x + x**-Integer(1)).divides(R(Integer(0)))
True>>> R(Integer(0)).divides(Integer(2)*x ** -Integer(1) + Integer(1))
False>>> R(Integer(0)).divides(R(Integer(0)))(continues on next page)

968

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)True>>> R = LaurentPolynomialRing(Zmod(Integer(6)), names=( x ,)); (x,) = R._
˓→first_ngens(1)>>> p = Integer(4)*x + Integer(3)*x**-Integer(1)>>> q = Integer(5)*x**Integer(2) + x + Integer(2)*x**-Integer(2)>>> p.divides(q)False>>> R = GF(Integer(2))[ x, y ]; (x, y,) = R._first_ngens(2)>>> S = LaurentPolynomialRing(R, names=( z ,)); (z,) = S._first_ngens(1)>>> p = (x+y+Integer(1)) * z**-Integer(1) + x*y>>> q = (y**Integer(2)-x**Integer(2)) * z**-Integer(2) + z + x-y>>> p.divides(q), p.divides(p*q)˓→needs sage.libs.singular(False, True)#␣euclidean_degree()Return the degree of self as an element of an Euclidean domain.
This is the Euclidean degree of the underlying polynomial.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: (x^-5 + x^2).euclidean_degree()7
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: (x^-5 + x^2).euclidean_degree()Traceback (most recent call last):...
NotImplementedError>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> (x**-Integer(5) + x**Integer(2)).euclidean_degree()7>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> (x**-Integer(5) + x**Integer(2)).euclidean_degree()Traceback (most recent call last):...
NotImplementedError

exponents()
Return the exponents appearing in self with nonzero coefficients.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: f = -5/t^(2) + t + t^2 - 10/3*t^3sage: f.exponents()[-2, 1, 2, 3]>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)(continues on next page)

5.3. Elements of Laurent polynomial rings

969

Polynomials, Release 10.4

(continued from previous page)>>> f = -Integer(5)/t**(Integer(2)) + t + t**Integer(2) - Integer(10)/
˓→Integer(3)*t**Integer(3)>>> f.exponents()[-2, 1, 2, 3]

factor()Return a Laurent monomial (the unit part of the factorization) and a factored polynomial.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(ZZ)
sage: f = 4*t^-7 + 3*t^3 + 2*t^4 + t^-6
sage: f.factor()˓→needs sage.libs.pari(t^-7) * (4 + t + 3*t^10 + 2*t^11)#␣>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( t ,)); (t,) = R._first_ngens(1)>>> f = Integer(4)*t**-Integer(7) + Integer(3)*t**Integer(3) +␣˓→Integer(2)*t**Integer(4) + t**-Integer(6)>>> f.factor()#␣˓→needs sage.libs.pari(t^-7) * (4 + t + 3*t^10 + 2*t^11)

gcd(right)
Return the gcd of self with right where the common divisor d makes both self and right intopolynomials with the lowest possible degree.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: t.gcd(2)1sage: gcd(t^-2 + 1, t^-4 + 3*t^-1)
t^-4
sage: gcd((t^-2 + t)*(t + t^-1), (t^5 + t^8)*(1 + t^-2))
t^-3 + t^-1 + 1 + t^2>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> t.gcd(Integer(2))
1>>> gcd(t**-Integer(2) + Integer(1), t**-Integer(4) + Integer(3)*t**˓→Integer(1))
t^-4>>> gcd((t**-Integer(2) + t)*(t + t**-Integer(1)), (t**Integer(5) +␣˓→t**Integer(8))*(Integer(1) + t**-Integer(2)))
t^-3 + t^-1 + 1 + t^2

integral()
The formal integral of this Laurent series with 0 constant term.
EXAMPLES:
The integral may or may not be defined if the base ring is not a field.

970

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

sage: t = LaurentPolynomialRing(ZZ,
sage: f = 2*t^-3 + 3*t^2
sage: f.integral()-t^-2 + t^3t ).0>>> from sage.all import *>>> t = LaurentPolynomialRing(ZZ, t ).gen(0)>>> f = Integer(2)*t**-Integer(3) + Integer(3)*t**Integer(2)>>> f.integral()-t^-2 + t^3
sage: f = t^3
sage: f.integral()Traceback (most recent call last):...
ArithmeticError: coefficients of integral cannot be coerced into the base ring>>> from sage.all import *>>> f = t**Integer(3)>>> f.integral()Traceback (most recent call last):...
ArithmeticError: coefficients of integral cannot be coerced into the base ring

The integral of 1/𝑡 is log(𝑡), which is not given by a Laurent polynomial:
sage: t = LaurentPolynomialRing(ZZ, t ).0
sage: f = -1/t^3 - 31/t
sage: f.integral()Traceback (most recent call last):...
ArithmeticError: the integral of is not a Laurent polynomial, since t^-1 has␣˓→nonzero coefficient>>> from sage.all import *>>> t = LaurentPolynomialRing(ZZ, t ).gen(0)>>> f = -Integer(1)/t**Integer(3) - Integer(31)/t>>> f.integral()Traceback (most recent call last):...
ArithmeticError: the integral of is not a Laurent polynomial, since t^-1 has␣˓→nonzero coefficient

Another example with just one negative coefficient:sage: A.<t> = LaurentPolynomialRing(QQ)
sage: f = -2*t^(-4)
sage: f.integral()
2/3*t^-3sage: f.integral().derivative() == f
True>>> from sage.all import *>>> A = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = A._first_ngens(1)>>> f = -Integer(2)*t**(-Integer(4))(continues on next page)

5.3. Elements of Laurent polynomial rings

971

Polynomials, Release 10.4

(continued from previous page)>>> f.integral()
2/3*t^-3>>> f.integral().derivative() == f
Trueinverse_mod(a, m)
Invert the polynomial a with respect to m, or raise a ValueError if no such inverse exists.
The parameter m may be either a single polynomial or an ideal (for consistency with inverse_mod() inother rings).
ALGORITHM: Solve the system 𝑎𝑠 + 𝑚𝑡 = 1, returning 𝑠 as the inverse of 𝑎 mod 𝑚.
EXAMPLES:
sage: S.<t> = LaurentPolynomialRing(QQ)
sage: f = inverse_mod(t^-2 + 1, t^-3 + 1); f
1/2*t^2 - 1/2*t^3 - 1/2*t^4
sage: f * (t^-2 + 1) + (1/2*t^4 + 1/2*t^3) * (t^-3 + 1)
1>>> from sage.all import *>>> S = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = S._first_ngens(1)>>> f = inverse_mod(t**-Integer(2) + Integer(1), t**-Integer(3) + Integer(1));˓→ f
1/2*t^2 - 1/2*t^3 - 1/2*t^4>>> f * (t**-Integer(2) + Integer(1)) + (Integer(1)/Integer(2)*t**Integer(4)␣
˓→+ Integer(1)/Integer(2)*t**Integer(3)) * (t**-Integer(3) + Integer(1))
1inverse_of_unit()
Return the inverse of self if a unit.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: (t^-2).inverse_of_unit()t^2
sage: (t + 2).inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: element is not a unit>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> (t**-Integer(2)).inverse_of_unit()t^2>>> (t + Integer(2)).inverse_of_unit()
Traceback (most recent call last):...
ArithmeticError: element is not a unit

is_constant()
Return whether this Laurent polynomial is constant.
EXAMPLES:

972

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

sage: R.<x> = LaurentPolynomialRing(QQ)
sage: x.is_constant()
False
sage: R.one().is_constant()
True
sage: (x^-2).is_constant()
False
sage: (x^2).is_constant()
False
sage: (x^-2 + 2).is_constant()
False
sage: R(0).is_constant()
True
sage: R(42).is_constant()
True
sage: x.is_constant()
False
sage: (1/x).is_constant()
False>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> x.is_constant()
False>>> R.one().is_constant()True>>> (x**-Integer(2)).is_constant()
False>>> (x**Integer(2)).is_constant()
False>>> (x**-Integer(2) + Integer(2)).is_constant()
False>>> R(Integer(0)).is_constant()
True>>> R(Integer(42)).is_constant()
True>>> x.is_constant()
False>>> (Integer(1)/x).is_constant()
False

is_monomial()
Return True if self is a monomial; that is, if self is 𝑥𝑛 for some integer 𝑛.
EXAMPLES:
sage: k.<z> = LaurentPolynomialRing(QQ)
sage: z.is_monomial()
True
sage: k(1).is_monomial()
True
sage: (z+1).is_monomial()
False
sage: (z^-2909).is_monomial()
True
sage: (38*z^-2909).is_monomial()
False

5.3. Elements of Laurent polynomial rings973

Polynomials, Release 10.4>>> from sage.all import *>>> k = LaurentPolynomialRing(QQ, names=( z ,)); (z,) = k._first_ngens(1)>>> z.is_monomial()
True>>> k(Integer(1)).is_monomial()
True>>> (z+Integer(1)).is_monomial()
False>>> (z**-Integer(2909)).is_monomial()
True>>> (Integer(38)*z**-Integer(2909)).is_monomial()
False

is_square(root=False)
Return whether this Laurent polynomial is a square.
If root is set to True then return a pair made of the boolean answer together with None or a square root.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: R.one().is_square()True
sage: R(2).is_square()False
sage: t.is_square()False
sage: (t**-2).is_square()True>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> R.one().is_square()
True>>> R(Integer(2)).is_square()False>>> t.is_square()False>>> (t**-Integer(2)).is_square()
True

Usage of the root option:
sage: p = (1 + t^-1 - 2*t^3)
sage: p.is_square(root=True)(False, None)sage: (p**2).is_square(root=True)(True, -t^-1 - 1 + 2*t^3)>>> from sage.all import *>>> p = (Integer(1) + t**-Integer(1) - Integer(2)*t**Integer(3))>>> p.is_square(root=True)(False, None)(continues on next page)

974

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> (p**Integer(2)).is_square(root=True)(True, -t^-1 - 1 + 2*t^3)

The answer is dependent of the base ring:sage: # needs sage.rings.number_fieldsage: S.<u> = LaurentPolynomialRing(QQbar)
sage: (2 + 4*t + 2*t^2).is_square()False
sage: (2 + 4*u + 2*u^2).is_square()True>>> from sage.all import *>>> # needs sage.rings.number_field>>> S = LaurentPolynomialRing(QQbar, names=( u ,)); (u,) = S._first_ngens(1)>>> (Integer(2) + Integer(4)*t + Integer(2)*t**Integer(2)).is_square()False>>> (Integer(2) + Integer(4)*u + Integer(2)*u**Integer(2)).is_square()True

is_unit()
Return True if this Laurent polynomial is a unit in this ring.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: (2 + t).is_unit()
False
sage: f = 2*t
sage: f.is_unit()
True
sage: 1/f
1/2*t^-1sage: R(0).is_unit()
False
sage: R.
 = LaurentPolynomialRing(ZZ)
sage: g = 2*s
sage: g.is_unit()
False
sage: 1/g
1/2*s^-1>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> (Integer(2) + t).is_unit()
False>>> f = Integer(2)*t>>> f.is_unit()
True>>> Integer(1)/f
1/2*t^-1>>> R(Integer(0)).is_unit()
False>>> R = LaurentPolynomialRing(ZZ, names=( s ,)); (s,) = R._first_ngens(1)>>> g = Integer(2)*s>>> g.is_unit()(continues on next page)

5.3. Elements of Laurent polynomial rings

975

Polynomials, Release 10.4

(continued from previous page)

False>>> Integer(1)/g
1/2*s^-1

ALGORITHM: A Laurent polynomial is a unit if and only if its “unit part” is a unit.
is_zero()Return 1 if self is 0, else return 0.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x + x + x^2 + 3*x^4sage: f.is_zero()0sage: z = 0*f
sage: z.is_zero()1>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x + x**Integer(2) + Integer(3)*x**Integer(4)>>> f.is_zero()0>>> z = Integer(0)*f>>> z.is_zero()1monomial_reduction()
Return the decomposition as a polynomial and a power of the variable. Constructed for compatibility withthe multivariate case.
OUTPUT:
A tuple (u, t^n) where u is the underlying polynomial and n is the power of the exponent shift.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x + x^2 + 3*x^4sage: f.monomial_reduction()(3*x^5 + x^3 + 1, x^-1)>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x**Integer(2) + Integer(3)*x**Integer(4)>>> f.monomial_reduction()(3*x^5 + x^3 + 1, x^-1)

number_of_terms()
Return the number of non-zero coefficients of self.
Also called weight, hamming weight or sparsity.
EXAMPLES:

976

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: f = x^3 - 1
sage: f.number_of_terms()2
sage: R(0).number_of_terms()0
sage: f = (x+1)^100
sage: f.number_of_terms()
101>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = x**Integer(3) - Integer(1)>>> f.number_of_terms()
2>>> R(Integer(0)).number_of_terms()0>>> f = (x+Integer(1))**Integer(100)>>> f.number_of_terms()
101

The method hamming_weight() is an alias:
sage: f.hamming_weight()
101>>> from sage.all import *>>> f.hamming_weight()
101

polynomial_construction()
Return the polynomial and the shift in power used to construct the Laurent polynomial 𝑡𝑛 𝑢.
OUTPUT:
A tuple (u, n) where u is the underlying polynomial and n is the power of the exponent shift.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x + x^2 + 3*x^4sage: f.polynomial_construction()(3*x^5 + x^3 + 1, -1)>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x**Integer(2) + Integer(3)*x**Integer(4)>>> f.polynomial_construction()(3*x^5 + x^3 + 1, -1)

quo_rem(other)
Divide self by other and return a quotient q and a remainder r such that self == q * other +r.
EXAMPLES:

5.3. Elements of Laurent polynomial rings

977

Polynomials, Release 10.4

sage: R.<t> = LaurentPolynomialRing(QQ)
sage: (t^-3 - t^3).quo_rem(t^-1 - t)(t^-2 + 1 + t^2, 0)
sage: (t^-2 + 3 + t).quo_rem(t^-4)(t^2 + 3*t^4 + t^5, 0)
sage: num = t^-2 + t
sage: den = t^-2 + 1
sage: q, r = num.quo_rem(den)sage: num == q * den + r
True>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> (t**-Integer(3) - t**Integer(3)).quo_rem(t**-Integer(1) - t)(t^-2 + 1 + t^2, 0)>>> (t**-Integer(2) + Integer(3) + t).quo_rem(t**-Integer(4))(t^2 + 3*t^4 + t^5, 0)>>> num = t**-Integer(2) + t>>> den = t**-Integer(2) + Integer(1)>>> q, r = num.quo_rem(den)>>> num == q * den + r
True

residue()
Return the residue of self.
The residue is the coefficient of 𝑡− 1.
EXAMPLES:
sage: R.<t> = LaurentPolynomialRing(QQ)
sage: f = 3*t^-2 - t^-1 + 3 + t^2
sage: f.residue()-1sage: g = -2*t^-2 + 4 + 3*t
sage: g.residue()0sage: f.residue().parent()
Rational Field>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = R._first_ngens(1)>>> f = Integer(3)*t**-Integer(2) - t**-Integer(1) + Integer(3) +␣˓→t**Integer(2)>>> f.residue()-1>>> g = -Integer(2)*t**-Integer(2) + Integer(4) + Integer(3)*t>>> g.residue()0>>> f.residue().parent()
Rational Field

shift(k)Return this Laurent polynomial multiplied by the power 𝑡𝑛 . Does not change this polynomial.
EXAMPLES:
978

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

sage: R.<t> = LaurentPolynomialRing(QQ[ y ])sage: f = (t+t^-1)^4; ft^-4 + 4*t^-2 + 6 + 4*t^2 + t^4
sage: f.shift(10)t^6 + 4*t^8 + 6*t^10 + 4*t^12 + t^14
sage: f >> 10
t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6
sage: f << 4
1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ[ y ], names=( t ,)); (t,) = R._first_ngens(1)>>> f = (t+t**-Integer(1))**Integer(4); ft^-4 + 4*t^-2 + 6 + 4*t^2 + t^4>>> f.shift(Integer(10))
t^6 + 4*t^8 + 6*t^10 + 4*t^12 + t^14>>> f >> Integer(10)t^-14 + 4*t^-12 + 6*t^-10 + 4*t^-8 + t^-6>>> f << Integer(4)1 + 4*t^2 + 6*t^4 + 4*t^6 + t^8truncate(n)Return a polynomial with degree at most 𝑛 − 1 whose 𝑗-th coefficients agree with self for all 𝑗 < 𝑛.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x^12 + x^3 + x^5 + x^9sage: f.truncate(10)x^-12 + x^3 + x^5 + x^9sage: f.truncate(5)x^-12 + x^3
sage: f.truncate(-16)
0>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x**Integer(12) + x**Integer(3) + x**Integer(5) +␣˓→x**Integer(9)>>> f.truncate(Integer(10))
x^-12 + x^3 + x^5 + x^9>>> f.truncate(Integer(5))
x^-12 + x^3>>> f.truncate(-Integer(16))
0valuation(p=None)
Return the valuation of self.
The valuation of a Laurent polynomial 𝑡𝑛 𝑢 is 𝑛 plus the valuation of 𝑢.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(ZZ)
sage: f = 1/x + x^2 + 3*x^4sage: g = 1 - x + x^2 - x^4sage: f.valuation()(continues on next page)

5.3. Elements of Laurent polynomial rings

979

Polynomials, Release 10.4

(continued from previous page)-1
sage: g.valuation()0>>> from sage.all import *>>> R = LaurentPolynomialRing(ZZ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x**Integer(2) + Integer(3)*x**Integer(4)>>> g = Integer(1) - x + x**Integer(2) - x**Integer(4)>>> f.valuation()-1>>> g.valuation()0variable_name()
Return the name of variable of self as a string.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x + x^2 + 3*x^4sage: f.variable_name()x>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x**Integer(2) + Integer(3)*x**Integer(4)>>> f.variable_name()xvariables()Return the tuple of variables occurring in this Laurent polynomial.
EXAMPLES:
sage: R.<x> = LaurentPolynomialRing(QQ)
sage: f = 1/x + x^2 + 3*x^4sage: f.variables()(x,)
sage: R.one().variables()()>>> from sage.all import *>>> R = LaurentPolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> f = Integer(1)/x + x**Integer(2) + Integer(3)*x**Integer(4)>>> f.variables()(x,)>>> R.one().variables()()

xgcd(other)
Extended gcd() for univariate Laurent polynomial rings over a field.
OUTPUT:
A triple (g, p, q) such that g is the gcd() of self (= 𝑎) and other (= 𝑏), and p and q are cofactors

980

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

satisfying the Bezout identity
𝑔 = 𝑝 · 𝑎 + 𝑞 · 𝑏.
EXAMPLES:
sage: S.<t> = LaurentPolynomialRing(QQ)
sage: a = t^-2 + 1
sage: b = t^-3 + 1
sage: g, p, q = a.xgcd(b); (g, p, q)(t^-3, 1/2*t^-1 - 1/2 - 1/2*t, 1/2 + 1/2*t)
sage: g == p * a + q * b
True
sage: g == a.gcd(b)Truesage: t.xgcd(t)(t, 0, 1)
sage: t.xgcd(5)(1, 0, 1/5)>>> from sage.all import *>>> S = LaurentPolynomialRing(QQ, names=( t ,)); (t,) = S._first_ngens(1)>>> a = t**-Integer(2) + Integer(1)>>> b = t**-Integer(3) + Integer(1)>>> g, p, q = a.xgcd(b); (g, p, q)(t^-3, 1/2*t^-1 - 1/2 - 1/2*t, 1/2 + 1/2*t)>>> g == p * a + q * b
True>>> g == a.gcd(b)True>>> t.xgcd(t)(t, 0, 1)>>> t.xgcd(Integer(5))(1, 0, 1/5)

5.4 MacMahon’s Partition Analysis Omega Operator
This module implements MacMahon s Omega Operator [Mac1915], which takes a quotient of Laurent polynomials and removes all negative exponents in the corresponding power series.

5.4.1 Examples
In the following example, all negative exponents of 𝜇 are removed. The formula
Ω≥

1
1
=
(1 − 𝑥𝜇)(1 − 𝑦/𝜇)
(1 − 𝑥)(1 − 𝑥𝑦)can be calculated and verified bysage: L.<mu, x, y> = LaurentPolynomialRing(ZZ)
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1

5.4. MacMahon’s Partition Analysis Omega Operator

981

Polynomials, Release 10.4>>> from sage.all import *>>> L = LaurentPolynomialRing(ZZ, names=( mu , x , y ,)); (mu, x, y,) = L._first_
˓→ngens(3)>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1

5.4.2 Various
AUTHORS:• Daniel Krenn (2016)
ACKNOWLEDGEMENT:• Daniel Krenn is supported by the Austrian Science Fund (FWF): P 24644-N26.

5.4.3 Functions
sage.rings.polynomial.omega.MacMahonOmega(var, expression, denominator=None, op=<built-infunction ge>, Factorization_sort=False,
Factorization_simplify=True)
Return Ωop of expression with respect to var.
To be more precise, calculate
Ωop𝑛𝑑1 . . . 𝑑𝑛

for the numerator 𝑛 and the factors 𝑑1 , …, 𝑑𝑛 of the denominator, all of which are Laurent polynomials in var
and return a (partial) factorization of the result.
INPUT:• var – a variable or a representation string of a variable• expression – a Factorization of Laurent polynomials or, if denominator is specified, a Laurent
polynomial interpreted as the numerator of the expression• denominator – a Laurent polynomial or a Factorization (consisting of Laurent polynomial factors)
or a tuple/list of factors (Laurent polynomials)• op – (default: operator.ge) an operator
At the moment only operator.ge is implemented.
• Factorization_sort (default: False) and Factorization_simplify (default: True) – arepassed on to sage.structure.factorization.Factorization when creating the result
OUTPUT:
A (partial) Factorization of the result whose factors are Laurent polynomials
Note: The numerator of the result may not be factored.
REFERENCES:• [Mac1915]

982

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

• [APR2001]
EXAMPLES:
sage: L.<mu, x, y, z, w> = LaurentPolynomialRing(ZZ)
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu, 1 - z/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1 * (-x*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu])(-x*y*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z + 1)^-1 * (-y*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^2])
1 * (-x + 1)^-1 * (-x^2*y + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu])(x*y + 1) * (-x + 1)^-1 * (-x*y^2 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu^2])(-x^2*y*z - x*y^2*z + x*y*z + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-x^2*z + 1)^-1 * (-y^2*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^3])
1 * (-x + 1)^-1 * (-x^3*y + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y/mu^4])
1 * (-x + 1)^-1 * (-x^4*y + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^3, 1 - y/mu])(x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^3 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^4, 1 - y/mu])(x*y^3 + x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^4 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y/mu, 1 - z/mu])(x*y*z + x*y + x*z + 1) *(-x + 1)^-1 * (-x*y^2 + 1)^-1 * (-x*z^2 + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu^2, 1 - y*mu, 1 - z/mu])(-x*y*z^2 - x*y*z + x*z + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-x*z^2 + 1)^-1 * (-y*z + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z*mu, 1 - w/mu])(x*y*z*w^2 + x*y*z*w - x*y*w - x*z*w - y*z*w + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-z + 1)^-1 *(-x*w + 1)^-1 * (-y*w + 1)^-1 * (-z*w + 1)^-1
sage: MacMahonOmega(mu, 1, [1 - x*mu, 1 - y*mu, 1 - z/mu, 1 - w/mu])(x^2*y*z*w + x*y^2*z*w - x*y*z*w - x*y*z - x*y*w + 1) *(-x + 1)^-1 * (-y + 1)^-1 *(-x*z + 1)^-1 * (-x*w + 1)^-1 * (-y*z + 1)^-1 * (-y*w + 1)^-1
sage: MacMahonOmega(mu, mu^-2, [1 - x*mu, 1 - y/mu])x^2 * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^-1, [1 - x*mu, 1 - y/mu])x * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu, [1 - x*mu, 1 - y/mu])(-x*y + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu])(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> from sage.all import *>>> L = LaurentPolynomialRing(ZZ, names=( mu ,

x ,

y ,

z ,

w ,)); (mu, x, y,␣
(continues on next page)

5.4. MacMahon’s Partition Analysis Omega Operator

983

Polynomials, Release 10.4

(continued from previous page)z, w,) = L._first_ngens(5)˓→>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/mu,␣˓→Integer(1) - z/mu])
1 * (-x + 1)^-1 * (-x*y + 1)^-1 * (-x*z + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y*mu,␣
˓→Integer(1) - z/mu])(-x*y*z + 1) * (-x + 1)^-1 * (-y + 1)^-1 * (-x*z + 1)^-1 * (-y*z + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/
˓→mu**Integer(2)])
1 * (-x + 1)^-1 * (-x^2*y + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu**Integer(2), Integer(1) - y/˓→mu])(x*y + 1) * (-x + 1)^-1 * (-x*y^2 + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y*mu,␣
˓→Integer(1) - z/mu**Integer(2)])(-x^2*y*z - x*y^2*z + x*y*z + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-x^2*z + 1)^-1 * (-y^2*z + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/
˓→mu**Integer(3)])
1 * (-x + 1)^-1 * (-x^3*y + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y/
˓→mu**Integer(4)])
1 * (-x + 1)^-1 * (-x^4*y + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu**Integer(3), Integer(1) - y/˓→mu])(x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^3 + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu**Integer(4), Integer(1) - y/˓→mu])(x*y^3 + x*y^2 + x*y + 1) * (-x + 1)^-1 * (-x*y^4 + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu**Integer(2), Integer(1) - y/
˓→mu, Integer(1) - z/mu])(x*y*z + x*y + x*z + 1) *(-x + 1)^-1 * (-x*y^2 + 1)^-1 * (-x*z^2 + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu**Integer(2), Integer(1) -␣˓→y*mu, Integer(1) - z/mu])(-x*y*z^2 - x*y*z + x*z + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-x*z^2 + 1)^-1 * (-y*z + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y*mu,␣
˓→Integer(1) - z*mu, Integer(1) - w/mu])(x*y*z*w^2 + x*y*z*w - x*y*w - x*z*w - y*z*w + 1) *(-x + 1)^-1 * (-y + 1)^-1 * (-z + 1)^-1 *(-x*w + 1)^-1 * (-y*w + 1)^-1 * (-z*w + 1)^-1>>> MacMahonOmega(mu, Integer(1), [Integer(1) - x*mu, Integer(1) - y*mu,␣
˓→Integer(1) - z/mu, Integer(1) - w/mu])(x^2*y*z*w + x*y^2*z*w - x*y*z*w - x*y*z - x*y*w + 1) *(-x + 1)^-1 * (-y + 1)^-1 *(-x*z + 1)^-1 * (-x*w + 1)^-1 * (-y*z + 1)^-1 * (-y*w + 1)^-1>>> MacMahonOmega(mu, mu**-Integer(2), [Integer(1) - x*mu, Integer(1) - y/mu])(continues on next page)984

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)x^2 * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu**-Integer(1), [Integer(1) - x*mu, Integer(1) - y/mu])x * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu, [Integer(1) - x*mu, Integer(1) - y/mu])(-x*y + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu**Integer(2), [Integer(1) - x*mu, Integer(1) - y/mu])(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1

We demonstrate the different allowed input variants:
sage: MacMahonOmega(mu,....:Factorization([(mu, 2), (1 - x*mu, -1), (1 - y/mu, -1)]))(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2,....:
Factorization([(1 - x*mu, 1), (1 - y/mu, 1)]))(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, [1 - x*mu, 1 - y/mu])(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2, (1 - x*mu)*(1 - y/mu)) # not tested because not␣˓→fully implemented(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1
sage: MacMahonOmega(mu, mu^2 / ((1 - x*mu)*(1 - y/mu))) # not tested because not␣˓→fully implemented(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> from sage.all import *>>> MacMahonOmega(mu,...
Factorization([(mu, Integer(2)), (Integer(1) - x*mu, -Integer(1)),␣
˓→(Integer(1) - y/mu, -Integer(1))]))(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu**Integer(2),...
Factorization([(Integer(1) - x*mu, Integer(1)), (Integer(1) - y/mu,␣˓→Integer(1))]))(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu**Integer(2), [Integer(1) - x*mu, Integer(1) - y/mu])(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1>>> MacMahonOmega(mu, mu**Integer(2), (Integer(1) - x*mu)*(Integer(1) - y/mu))˓→not tested because not fully implemented(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1#␣>>> MacMahonOmega(mu, mu**Integer(2) / ((Integer(1) - x*mu)*(Integer(1) - y/mu)))␣
˓→ # not tested because not fully implemented(-x*y^2 - x*y + y^2 + y + 1) * (-x + 1)^-1 * (-x*y + 1)^-1

sage.rings.polynomial.omega.Omega_ge(exponents)
Return Ω≥ of the expression specified by the input.
To be more precise, calculateΩ≥𝜇𝑎(1 − 𝑧0 𝜇𝑒0 ) . . . (1 − 𝑧𝑛−1 𝜇𝑒𝑛−1 )5.4. MacMahon’s Partition Analysis Omega Operator

985

Polynomials, Release 10.4

and return its numerator and a factorization of its denominator. Note that 𝑧0 , …, 𝑧𝑛−1 only appear in the output,
but not in the input.
INPUT:• a – an integer• exponents – a tuple of integers
OUTPUT:
A pair representing a quotient as follows: Its first component is the numerator as a Laurent polynomial, its second
component a factorization of the denominator as a tuple of Laurent polynomials, where each Laurent polynomial
𝑧 represents a factor 1 − 𝑧.
The parents of these Laurent polynomials is always a Laurent polynomial ring in 𝑧0 , …, 𝑧𝑛−1 over Z, where 𝑛 is
the length of exponents.
EXAMPLES:
sage: from sage.rings.polynomial.omega import Omega_ge
sage: Omega_ge(0, (1, -2))
(1, (z0, z0^2*z1))
sage: Omega_ge(0, (1, -3))
(1, (z0, z0^3*z1))
sage: Omega_ge(0, (1, -4))
(1, (z0, z0^4*z1))
sage: Omega_ge(0, (2, -1))
(z0*z1 + 1, (z0, z0*z1^2))
sage: Omega_ge(0, (3, -1))
(z0*z1^2 + z0*z1 + 1, (z0, z0*z1^3))
sage: Omega_ge(0, (4, -1))
(z0*z1^3 + z0*z1^2 + z0*z1 + 1, (z0, z0*z1^4))
sage: Omega_ge(0, (1, 1, -2))(-z0^2*z1*z2 - z0*z1^2*z2 + z0*z1*z2 + 1, (z0, z1, z0^2*z2, z1^2*z2))
sage: Omega_ge(0, (2, -1, -1))
(z0*z1*z2 + z0*z1 + z0*z2 + 1, (z0, z0*z1^2, z0*z2^2))
sage: Omega_ge(0, (2, 1, -1))(-z0*z1*z2^2 - z0*z1*z2 + z0*z2 + 1, (z0, z1, z0*z2^2, z1*z2))>>> from sage.all import *>>> from sage.rings.polynomial.omega import Omega_ge>>> Omega_ge(Integer(0), (Integer(1), -Integer(2)))(1, (z0, z0^2*z1))>>> Omega_ge(Integer(0), (Integer(1), -Integer(3)))(1, (z0, z0^3*z1))>>> Omega_ge(Integer(0), (Integer(1), -Integer(4)))(1, (z0, z0^4*z1))>>> Omega_ge(Integer(0), (Integer(2), -Integer(1)))(z0*z1 + 1, (z0, z0*z1^2))>>> Omega_ge(Integer(0), (Integer(3), -Integer(1)))(z0*z1^2 + z0*z1 + 1, (z0, z0*z1^3))>>> Omega_ge(Integer(0), (Integer(4), -Integer(1)))(z0*z1^3 + z0*z1^2 + z0*z1 + 1, (z0, z0*z1^4))>>> Omega_ge(Integer(0), (Integer(1), Integer(1), -Integer(2)))(-z0^2*z1*z2 - z0*z1^2*z2 + z0*z1*z2 + 1, (z0, z1, z0^2*z2, z1^2*z2))(continues on next page)

986

Chapter 5. Laurent Polynomials

Polynomials, Release 10.4

(continued from previous page)>>> Omega_ge(Integer(0), (Integer(2), -Integer(1), -Integer(1)))(z0*z1*z2 + z0*z1 + z0*z2 + 1, (z0, z0*z1^2, z0*z2^2))>>> Omega_ge(Integer(0), (Integer(2), Integer(1), -Integer(1)))(-z0*z1*z2^2 - z0*z1*z2 + z0*z2 + 1, (z0, z1, z0*z2^2, z1*z2))
sage: Omega_ge(0, (2, -2))(-z0*z1 + 1, (z0, z0*z1, z0*z1))
sage: Omega_ge(0, (2, -3))(z0^2*z1 + 1, (z0, z0^3*z1^2))
sage: Omega_ge(0, (3, 1, -3))(-z0^3*z1^3*z2^3 + 2*z0^2*z1^3*z2^2 - z0*z1^3*z2+ z0^2*z2^2 - 2*z0*z2 + 1,
(z0, z1, z0*z2, z0*z2, z0*z2, z1^3*z2))>>> from sage.all import *>>> Omega_ge(Integer(0), (Integer(2), -Integer(2)))(-z0*z1 + 1, (z0, z0*z1, z0*z1))>>> Omega_ge(Integer(0), (Integer(2), -Integer(3)))(z0^2*z1 + 1, (z0, z0^3*z1^2))>>> Omega_ge(Integer(0), (Integer(3), Integer(1), -Integer(3)))(-z0^3*z1^3*z2^3 + 2*z0^2*z1^3*z2^2 - z0*z1^3*z2+ z0^2*z2^2 - 2*z0*z2 + 1,
(z0, z1, z0*z2, z0*z2, z0*z2, z1^3*z2))
sage: Omega_ge(0, (3, 6, -1))(-z0*z1*z2^8 - z0*z1*z2^7 - z0*z1*z2^6 - z0*z1*z2^5 - z0*z1*z2^4 +z1*z2^5 - z0*z1*z2^3 + z1*z2^4 - z0*z1*z2^2 + z1*z2^3 z0*z1*z2 + z0*z2^2 + z1*z2^2 + z0*z2 + z1*z2 + 1,
(z0, z1, z0*z2^3, z1*z2^6))>>> from sage.all import *>>> Omega_ge(Integer(0), (Integer(3), Integer(6), -Integer(1)))(-z0*z1*z2^8 - z0*z1*z2^7 - z0*z1*z2^6 - z0*z1*z2^5 - z0*z1*z2^4 +z1*z2^5 - z0*z1*z2^3 + z1*z2^4 - z0*z1*z2^2 + z1*z2^3 z0*z1*z2 + z0*z2^2 + z1*z2^2 + z0*z2 + z1*z2 + 1,
(z0, z1, z0*z2^3, z1*z2^6))sage.rings.polynomial.omega.homogeneous_symmetric_function(j, x)
Return a complete homogeneous symmetric polynomial (Wikipedia article Complete_homogeneous_symmetric_polynomial).
INPUT:• j – the degree as a nonnegative integer• x – an iterable of variables
OUTPUT:
A polynomial of the common parent of all entries of x
EXAMPLES:
sage: from sage.rings.polynomial.omega import homogeneous_symmetric_function
sage: P = PolynomialRing(ZZ, X , 3)
sage: homogeneous_symmetric_function(0, P.gens())
1(continues on next page)

5.4. MacMahon’s Partition Analysis Omega Operator

987

Polynomials, Release 10.4

(continued from previous page)

sage: homogeneous_symmetric_function(1, P.gens())
X0 + X1 + X2
sage: homogeneous_symmetric_function(2, P.gens())
X0^2 + X0*X1 + X1^2 + X0*X2 + X1*X2 + X2^2
sage: homogeneous_symmetric_function(3, P.gens())
X0^3 + X0^2*X1 + X0*X1^2 + X1^3 + X0^2*X2 +X0*X1*X2 + X1^2*X2 + X0*X2^2 + X1*X2^2 + X2^3>>> from sage.all import *>>> from sage.rings.polynomial.omega import homogeneous_symmetric_function>>> P = PolynomialRing(ZZ, X , Integer(3))>>> homogeneous_symmetric_function(Integer(0), P.gens())
1>>> homogeneous_symmetric_function(Integer(1), P.gens())
X0 + X1 + X2>>> homogeneous_symmetric_function(Integer(2), P.gens())
X0^2 + X0*X1 + X1^2 + X0*X2 + X1*X2 + X2^2>>> homogeneous_symmetric_function(Integer(3), P.gens())
X0^3 + X0^2*X1 + X0*X1^2 + X1^3 + X0^2*X2 +X0*X1*X2 + X1^2*X2 + X0*X2^2 + X1*X2^2 + X2^3

sage.rings.polynomial.omega.partition(items, predicate=<class 'bool'>)
Split items into two parts by the given predicate.
INPUT:• item – an iterator• predicate – a function
OUTPUT:
A pair of iterators; the first contains the elements not satisfying the predicate, the second the elements satisfying
the predicate.
ALGORITHM:
Source of the code: http://nedbatchelder.com/blog/201306/filter_a_list_into_two_parts.html
EXAMPLES:
sage: from sage.rings.polynomial.omega import partition
sage: E, O = partition(srange(10), is_odd)
sage: tuple(E), tuple(O)((0, 2, 4, 6, 8), (1, 3, 5, 7, 9))>>> from sage.all import *>>> from sage.rings.polynomial.omega import partition>>> E, O = partition(srange(Integer(10)), is_odd)>>> tuple(E), tuple(O)((0, 2, 4, 6, 8), (1, 3, 5, 7, 9))988

Chapter 5. Laurent Polynomials

CHAPTERSIXINFINITE POLYNOMIAL RINGS

6.1 Infinite Polynomial Rings
By Infinite Polynomial Rings, we mean polynomial rings in a countably infinite number of variables. The implementationconsists of a wrapper around the current finite polynomial rings in Sage.
AUTHORS:• Simon King <simon.king@nuigalway.ie>• Mike Hansen <mhansen@gmail.com>
An Infinite Polynomial Ring has finitely many generators 𝑥* , 𝑦* , ... and infinitely many variables of the form
𝑥0 , 𝑥1 , 𝑥2 , ..., 𝑦0 , 𝑦1 , 𝑦2 , ..., .... We refer to the natural number 𝑛 as the index of the variable 𝑥𝑛 .
INPUT:• R, the base ring. It has to be a commutative ring, and in some applications it must even be a field• names, a finite list of generator names. Generator names must be alpha-numeric.
• order (optional string). The default order is lex (lexicographic). deglex is degree lexicographic, anddegrevlex (degree reverse lexicographic) is possible but discouraged.
Each generator x produces an infinite sequence of variables x[1], x[2], ... which are printed on screen as x_1,
x_2, ... and are latex typeset as 𝑥1 , 𝑥2 . Then, the Infinite Polynomial Ring is formed by polynomials in these variables.
By default, the monomials are ordered lexicographically. Alternatively, degree (reverse) lexicographic ordering is possible
as well. However, we do not guarantee that the computation of Groebner bases will terminate in this case.
In either case, the variables of a Infinite Polynomial Ring X are ordered according to the following rule:
X.gen(i)[m] > X.gen(j)[n] if and only if i<j or (i==j and m>n)
We provide a ‘dense’ and a ‘sparse’ implementation. In the dense implementation, the Infinite Polynomial Ring carries afinite polynomial ring that comprises all variables up to the maximal index that has been used so far. This is potentiallya very big ring and may also comprise many variables that are not used.
In the sparse implementation, we try to keep the underlying finite polynomial rings small, using only those variables thatare really needed. By default, we use the dense implementation, since it usually is much faster.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(ZZ, implementation= sparse )sage: A.<alpha,beta> = InfinitePolynomialRing(QQ, order= deglex )sage: f = x[5] + 2; f
x_5 + 2
(continues on next page)989

Polynomials, Release 10.4

(continued from previous page)

sage: g = 3*y[1]; g
3*y_1>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ, implementation= sparse , names=( x , y ,)); (x, y,˓→) = X._first_ngens(2)>>> A = InfinitePolynomialRing(QQ, order= deglex , names=( alpha , beta ,)); (alpha,␣˓→beta,) = A._first_ngens(2)>>> f = x[Integer(5)] + Integer(2); f
x_5 + 2>>> g = Integer(3)*y[Integer(1)]; g
3*y_1

It has some advantages to have an underlying ring that is not univariate. Hence, we always have at least two variables:sage: g._p.parent()
Multivariate Polynomial Ring in y_1, y_0 over Integer Ringsage: f2 = alpha[5] + 2; f2
alpha_5 + 2
sage: g2 = 3*beta[1]; g2
3*beta_1
sage: A.polynomial_ring()
Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0,
beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field>>> from sage.all import *>>> g._p.parent()
Multivariate Polynomial Ring in y_1, y_0 over Integer Ring>>> f2 = alpha[Integer(5)] + Integer(2); f2
alpha_5 + 2>>> g2 = Integer(3)*beta[Integer(1)]; g2
3*beta_1>>> A.polynomial_ring()
Multivariate Polynomial Ring in alpha_5, alpha_4, alpha_3, alpha_2, alpha_1, alpha_0,
beta_5, beta_4, beta_3, beta_2, beta_1, beta_0 over Rational Field

Of course, we provide the usual polynomial arithmetic:sage: f + g
x_5 + 3*y_1 + 2
sage: p = x[10]^2*(f+g); px_10^2*x_5 + 3*x_10^2*y_1 + 2*x_10^2sage: p2 = alpha[10]^2*(f2+g2); p2
alpha_10^2*alpha_5 + 3*alpha_10^2*beta_1 + 2*alpha_10^2>>> from sage.all import *>>> f + g
x_5 + 3*y_1 + 2>>> p = x[Integer(10)]**Integer(2)*(f+g); px_10^2*x_5 + 3*x_10^2*y_1 + 2*x_10^2>>> p2 = alpha[Integer(10)]**Integer(2)*(f2+g2); p2
alpha_10^2*alpha_5 + 3*alpha_10^2*beta_1 + 2*alpha_10^2990

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

There is a permutation action on the variables, by permuting positive variable indices:sage: P = Permutation(((10,1)))
sage: p^P
x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2
sage: p2^P
alpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2>>> from sage.all import *>>> P = Permutation(((Integer(10),Integer(1))))>>> p**P
x_5*x_1^2 + 3*x_1^2*y_10 + 2*x_1^2>>> p2**Palpha_5*alpha_1^2 + 3*alpha_1^2*beta_10 + 2*alpha_1^2

Note that 𝑥𝑃
0 = 𝑥0 , since the permutations only change positive variable indices.
We also implemented ideals of Infinite Polynomial Rings. Here, it is thoroughly assumed that the ideals are set-wiseinvariant under the permutation action. We therefore refer to these ideals as Symmetric Ideals. Symmetric Ideals are
finitely generated modulo addition, multiplication by ring elements and permutation of variables. If the base ring is afield, one can compute Symmetric Groebner Bases:
sage: J = A * (alpha[1]*beta[2])sage: J.groebner_basis()
˓→needs sage.combinat sage.libs.singular[alpha_1*beta_2, alpha_2*beta_1]>>> from sage.all import *>>> J = A * (alpha[Integer(1)]*beta[Integer(2)])>>> J.groebner_basis()
˓→needs sage.combinat sage.libs.singular[alpha_1*beta_2, alpha_2*beta_1]#␣#␣For more details, see SymmetricIdeal.
Infinite Polynomial Rings can have any commutative base ring. If the base ring of an Infinite Polynomial Ring is a (classicalor infinite) Polynomial Ring, then our implementation tries to merge everything into one ring. The basic requirement is thatthe monomial orders match. In the case of two Infinite Polynomial Rings, the implementations must match. Moreover,name conflicts should be avoided. An overlap is only accepted if the order of variables can be uniquely inferred, as in thefollowing example:
sage: A.<a,b,c> = InfinitePolynomialRing(ZZ)
sage: B.<b,c,d> = InfinitePolynomialRing(A)sage: B
Infinite polynomial ring in a, b, c, d over Integer Ring>>> from sage.all import *>>> A = InfinitePolynomialRing(ZZ, names=( a , b , c ,)); (a, b, c,) = A._first_
˓→ngens(3)>>> B = InfinitePolynomialRing(A, names=( b , c , d ,)); (b, c, d,) = B._first_
˓→ngens(3)>>> B
Infinite polynomial ring in a, b, c, d over Integer Ring

This is also allowed if finite polynomial rings are involved:

6.1. Infinite Polynomial Rings

991

Polynomials, Release 10.4

sage: A.<a_3,a_1,b_1,c_2,c_0> = ZZ[]
sage: B.<b,c,d> = InfinitePolynomialRing(A, order= degrevlex )sage: B
Infinite polynomial ring in b, c, d overMultivariate Polynomial Ring in a_3, a_1 over Integer Ring>>> from sage.all import *>>> A = ZZ[ a_3, a_1, b_1, c_2, c_0 ]; (a_3, a_1, b_1, c_2, c_0,) = A._first_ngens(5)>>> B = InfinitePolynomialRing(A, order= degrevlex , names=( b , c , d ,)); (b, c,␣
˓→d,) = B._first_ngens(3)>>> B
Infinite polynomial ring in b, c, d overMultivariate Polynomial Ring in a_3, a_1 over Integer Ring

It is no problem if one generator of the Infinite Polynomial Ring is called x and one variable of the base ring is also called
x. This is since no variable of the Infinite Polynomial Ring will be called x. However, a problem arises if the underlying
classical Polynomial Ring has a variable x_1, since this can be confused with a variable of the Infinite Polynomial Ring.
In this case, an error will be raised:sage: X.<x,y_1> = ZZ[]
sage: Y.<x,z> = InfinitePolynomialRing(X)>>> from sage.all import *>>> X = ZZ[ x, y_1 ]; (x, y_1,) = X._first_ngens(2)>>> Y = InfinitePolynomialRing(X, names=( x , z ,)); (x, z,) = Y._first_ngens(2)Note that X is not merged into Y; this is since the monomial order of X is ‘degrevlex’, but of Y is ‘lex’.
sage: Y
Infinite polynomial ring in x, z overMultivariate Polynomial Ring in x, y_1 over Integer Ring>>> from sage.all import *>>> YInfinite polynomial ring in x, z overMultivariate Polynomial Ring in x, y_1 over Integer Ring

The variable x of X can still be interpreted in Y, although the first generator of Y is called x as well:sage: xx_*
sage: X( x )xsage: Y(X( x ))xsage: Y( x )x>>> from sage.all import *
>>> x
x_*
>>> X( x )x>>> Y(X( x ))x(continues on next page)992

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> Y( x )x

But there is only merging if the resulting monomial order is uniquely determined. This is not the case in the following
examples, and thus an error is raised:sage: X.<y_1,x> = ZZ[]
sage: Y.<y,z> = InfinitePolynomialRing(X)Traceback (most recent call last):...
CoercionException: Overlapping variables (( y , z ),[ y_1 ]) are incompatible
sage: Y.<z,y> = InfinitePolynomialRing(X)Traceback (most recent call last):...
CoercionException: Overlapping variables (( z , y ),[ y_1 ]) are incompatible
sage: X.<x_3,y_1,y_2> = PolynomialRing(ZZ, order= lex )sage: # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ringsage: Y.<y> = InfinitePolynomialRing(X)Traceback (most recent call last):...
CoercionException: Overlapping variables (( y ,),[ y_1 , y_2 ]) are incompatible>>> from sage.all import *>>> X = ZZ[ y_1, x ]; (y_1, x,) = X._first_ngens(2)>>> Y = InfinitePolynomialRing(X, names=( y , z ,)); (y, z,) = Y._first_ngens(2)Traceback (most recent call last):...
CoercionException: Overlapping variables (( y , z ),[ y_1 ]) are incompatible>>> Y = InfinitePolynomialRing(X, names=( z , y ,)); (z, y,) = Y._first_ngens(2)Traceback (most recent call last):...
CoercionException: Overlapping variables (( z , y ),[ y_1 ]) are incompatible>>> X = PolynomialRing(ZZ, order= lex , names=( x_3 , y_1 , y_2 ,)); (x_3, y_1, y_2,˓→) = X._first_ngens(3)>>> # y_1 and y_2 would be in opposite order in an Infinite Polynomial Ring>>> Y = InfinitePolynomialRing(X, names=( y ,)); (y,) = Y._first_ngens(1)Traceback (most recent call last):...
CoercionException: Overlapping variables (( y ,),[ y_1 , y_2 ]) are incompatible

If the type of monomial orderings (e.g., ‘degrevlex’ versus ‘lex’) or if the implementations do not match, there is no
simplified construction available:
sage: X.<x,y> = InfinitePolynomialRing(ZZ)
sage: Y.<z> = InfinitePolynomialRing(X, order= degrevlex )sage: Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ringsage: Y.<z> = InfinitePolynomialRing(X, implementation= sparse )sage: Y
Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ, names=( x , y ,)); (x, y,) = X._first_ngens(2)>>> Y = InfinitePolynomialRing(X, order= degrevlex , names=( z ,)); (z,) = Y._first_
˓→ngens(1)>>> Y(continues on next page)

6.1. Infinite Polynomial Rings

993

Polynomials, Release 10.4

(continued from previous page)

Infinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ring>>> Y = InfinitePolynomialRing(X, implementation= sparse , names=( z ,)); (z,) = Y._˓→first_ngens(1)>>> YInfinite polynomial ring in z over Infinite polynomial ring in x, y over Integer Ringclass sage.rings.polynomial.infinite_polynomial_ring.GenDictWithBasering(parent,
start)
Bases: object
A dictionary-like class that is suitable for usage in sage_eval.
This pseudo-dictionary accepts strings as index, and then walks down a chain of base rings of (infinite) polynomial
rings until it finds one ring that has the given string as variable name, which is then returned.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ)
sage: D = R.gens_dict() # indirect doctest
sage: D
GenDict of Infinite polynomial ring in a, b over Integer Ringsage: D[ a_15 ]a_15
sage: type(_)<class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense
˓→ >sage: sage_eval( 3*a_3*b_5-1/2*a_7 , D)
-1/2*a_7 + 3*a_3*b_5>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, names=( a , b ,)); (a, b,) = R._first_ngens(2)>>> D = R.gens_dict() # indirect doctest>>> D
GenDict of Infinite polynomial ring in a, b over Integer Ring>>> D[ a_15 ]a_15>>> type(_)<class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense
˓→ >>>> sage_eval( 3*a_3*b_5-1/2*a_7 , D)
-1/2*a_7 + 3*a_3*b_5

next()
Return a dictionary that can be used to interprete strings in the base ring of self.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(QQ[ t ])sage: D = R.gens_dict()
sage: D
GenDict of Infinite polynomial ring in a, b over Univariate Polynomial Ring␣˓→in t over Rational Field
sage: next(D)GenDict of Univariate Polynomial Ring in t over Rational Field
sage: sage_eval( t^2 , next(D))
t^2

994

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ[ t ], names=( a , b ,)); (a, b,) = R._
˓→first_ngens(2)>>> D = R.gens_dict()>>> D
GenDict of Infinite polynomial ring in a, b over Univariate Polynomial Ring␣˓→in t over Rational Field>>> next(D)GenDict of Univariate Polynomial Ring in t over Rational Field>>> sage_eval( t^2 , next(D))
t^2class sage.rings.polynomial.infinite_polynomial_ring.InfiniteGenDict(Gens)
Bases: object
A dictionary-like class that is suitable for usage in sage_eval.
The generators of an Infinite Polynomial Ring are not variables. Variables of an Infinite Polynomial Ring are
returned by indexing a generator. The purpose of this class is to return a variable of an Infinite Polynomial Ring,
given its string representation.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ)
sage: D = R.gens_dict() # indirect doctest
sage: D._D
[InfiniteGenDict defined by [ a , b ], { 1 : 1}]sage: D._D[0][ a_15 ]a_15
sage: type(_)<class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense
˓→ >sage: sage_eval( 3*a_3*b_5-1/2*a_7 , D._D[0])-1/2*a_7 + 3*a_3*b_5>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, names=( a , b ,)); (a, b,) = R._first_ngens(2)>>> D = R.gens_dict() # indirect doctest>>> D._D[InfiniteGenDict defined by [ a , b ], { 1 : 1}]>>> D._D[Integer(0)][ a_15 ]a_15>>> type(_)<class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense
˓→ >>>> sage_eval( 3*a_3*b_5-1/2*a_7 , D._D[Integer(0)])-1/2*a_7 + 3*a_3*b_5

class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialGen(parent,
name)Bases: SageObject
This class provides the object which is responsible for returning variables in an infinite polynomial ring (implemented in __getitem__()).
EXAMPLES:

6.1. Infinite Polynomial Rings

995

Polynomials, Release 10.4

sage: X.<x1,x2> = InfinitePolynomialRing(RR)
sage: x1
x1_*
sage: x1[5]x1_5
sage: x1 == loads(dumps(x1))
True>>> from sage.all import *>>> X = InfinitePolynomialRing(RR, names=( x1 ,˓→ngens(2)>>> x1x1_*>>> x1[Integer(5)]x1_5>>> x1 == loads(dumps(x1))
Truex2 ,)); (x1, x2,) = X._first_

classsage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRingFactory
Bases: UniqueFactory
A factory for creating infinite polynomial ring elements. It handles making sure that they are unique as well as
handling pickling. For more details, see UniqueFactory and infinite_polynomial_ring.
EXAMPLES:
sage: A.<a> = InfinitePolynomialRing(QQ)
sage: B.<b> = InfinitePolynomialRing(A)sage: B.construction()[InfPoly{[a,b], "lex", "dense"}, Rational Field]
sage: R.<a,b> = InfinitePolynomialRing(QQ)
sage: R is B
True
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: X2.<x> = InfinitePolynomialRing(QQ, implementation= sparse )sage: X is X2
False
sage: X is loads(dumps(X))
True>>> from sage.all import *>>> A = InfinitePolynomialRing(QQ, names=( a ,)); (a,) = A._first_ngens(1)>>> B = InfinitePolynomialRing(A, names=( b ,)); (b,) = B._first_ngens(1)>>> B.construction()[InfPoly{[a,b], "lex", "dense"}, Rational Field]>>> R = InfinitePolynomialRing(QQ, names=( a , b ,)); (a, b,) = R._first_ngens(2)>>> R is B
True>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> X2 = InfinitePolynomialRing(QQ, implementation= sparse , names=( x ,)); (x,)␣
˓→= X2._first_ngens(1)>>> X is X2
False(continues on next page)

996

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> X is loads(dumps(X))
Truecreate_key(R, names=('x',), order='lex', implementation='dense')
Creates a key which uniquely defines the infinite polynomial ring.
create_object(version, key)
Return the infinite polynomial ring corresponding to the key key.
class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_dense(R,names,
order)
Bases: InfinitePolynomialRing_sparse
Dense implementation of Infinite Polynomial Rings
Compared with InfinitePolynomialRing_sparse, from which this class inherits, it keeps a polynomial
ring that comprises all elements that have been created so far.
construction()
Return the construction of self.
OUTPUT:
A pair F,R, where F is a construction functor and R is a ring, so that F(R) is self.
EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(GF(5))
sage: R.construction()[InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]>>> from sage.all import *>>> R = InfinitePolynomialRing(GF(Integer(5)), names=( x ,˓→R._first_ngens(2)>>> R.construction()[InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]y ,)); (x, y,) =␣

polynomial_ring()
Return the underlying finite polynomial ring.
Note: The ring returned can change over time as more variables are used.
Since the rings are cached, we create here a ring with variable names that do not occur in other doc tests, sothat we avoid side effects.
EXAMPLES:
sage: X.<xx, yy> = InfinitePolynomialRing(ZZ)
sage: X.polynomial_ring()
Multivariate Polynomial Ring in xx_0, yy_0 over Integer Ringsage: a = yy[3]sage: X.polynomial_ring()
Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0
over Integer Ring

6.1. Infinite Polynomial Rings

997

Polynomials, Release 10.4>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ, names=( xx , yy ,)); (xx, yy,) = X._first_
˓→ngens(2)>>> X.polynomial_ring()
Multivariate Polynomial Ring in xx_0, yy_0 over Integer Ring>>> a = yy[Integer(3)]>>> X.polynomial_ring()
Multivariate Polynomial Ring in xx_3, xx_2, xx_1, xx_0, yy_3, yy_2, yy_1, yy_0
over Integer Ring

tensor_with_ring(R)Return the tensor product of self with another ring.
INPUT:• R – a ring.
OUTPUT:
An infinite polynomial ring that, mathematically, can be seen as the tensor product of self with R.
NOTE:
It is required that the underlying ring of self coerces into R. Hence, the tensor product is in fact merely an
extension of the base ring.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ, implementation= sparse )sage: R.tensor_with_ring(QQ)
Infinite polynomial ring in a, b over Rational Field
sage: R
Infinite polynomial ring in a, b over Integer Ring>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, implementation= sparse , names=( a ,˓→)); (a, b,) = R._first_ngens(2)>>> R.tensor_with_ring(QQ)
Infinite polynomial ring in a, b over Rational Field>>> R
Infinite polynomial ring in a, b over Integer Ringb ,The following tests against a bug that was fixed at Issue #10468:
sage: R.<x,y> = InfinitePolynomialRing(QQ, implementation= sparse )sage: R.tensor_with_ring(QQ) is R
True>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, implementation= sparse , names=( x ,˓→)); (x, y,) = R._first_ngens(2)>>> R.tensor_with_ring(QQ) is R
True

y ,

class sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse(R,names,
order)
Bases: CommutativeRing
998

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

Sparse implementation of Infinite Polynomial Rings.
An Infinite Polynomial Ring with generators 𝑥* , 𝑦* , ... over a field 𝐹 is a free commutative 𝐹 -algebra generated by 𝑥0 , 𝑥1 , 𝑥2 , ..., 𝑦0 , 𝑦1 , 𝑦2 , ..., ... and is equipped with a permutation action on the generators, namely𝑃𝑥𝑃
𝑛 = 𝑥𝑃 (𝑛) , 𝑦𝑛 = 𝑦𝑃 (𝑛) , ... for any permutation 𝑃 (note that variables of index zero are invariant under such
permutation).
It is known that any permutation invariant ideal in an Infinite Polynomial Ring is finitely generated modulo the
permutation action – see SymmetricIdeal for more details.
Usually, an instance of this class is created using InfinitePolynomialRing with the optional parameter
implementation= sparse . This takes care of uniqueness of parent structures. However, a direct construction is possible, in principle:
sage: X.<x,y> = InfinitePolynomialRing(QQ, implementation= sparse )sage: Y.<x,y> = InfinitePolynomialRing(QQ, implementation= sparse )sage: X is Y
True
sage: from sage.rings.polynomial.infinite_polynomial_ring import␣
˓→InfinitePolynomialRing_sparsesage: Z = InfinitePolynomialRing_sparse(QQ, [ x , y ], lex )>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, implementation= sparse , names=( x ,˓→(x, y,) = X._first_ngens(2)>>> Y = InfinitePolynomialRing(QQ, implementation= sparse , names=( x ,˓→(x, y,) = Y._first_ngens(2)>>> X is Y
True>>> from sage.rings.polynomial.infinite_polynomial_ring import␣
˓→InfinitePolynomialRing_sparse>>> Z = InfinitePolynomialRing_sparse(QQ, [ x , y ], lex )y ,));␣
y ,));␣

Nevertheless, since infinite polynomial rings are supposed to be unique parent structures, they do not evaluate equal.
sage: Z == X
False>>> from sage.all import *>>> Z == X
False

The last parameter (‘lex’ in the above example) can also be ‘deglex’ or ‘degrevlex’; this would result in an Infinite
Polynomial Ring in degree lexicographic or degree reverse lexicographic order.
See infinite_polynomial_ring for more details.
characteristic()
Return the characteristic of the base field.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(GF(25, a ))˓→needs sage.rings.finite_rings
sage: X˓→needs sage.rings.finite_rings
Infinite polynomial ring in x, y over Finite Field in a of size 5^2sage: X.characteristic()

#␣
#␣

#␣

(continues on next page)

6.1. Infinite Polynomial Rings

999

Polynomials, Release 10.4

(continued from previous page)needs sage.rings.finite_rings

˓→5>>> from sage.all import *>>> X = InfinitePolynomialRing(GF(Integer(25), a ), names=( x , y ,)); (x, y,˓→) = X._first_ngens(2)# needs sage.rings.finite_rings>>> X#␣˓→needs sage.rings.finite_rings
Infinite polynomial ring in x, y over Finite Field in a of size 5^2>>> X.characteristic()#␣˓→needs sage.rings.finite_rings
5

construction()
Return the construction of self.
OUTPUT:
A pair F,R, where F is a construction functor and R is a ring, so that F(R) is self.
EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(GF(5))
sage: R.construction()[InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]>>> from sage.all import *>>> R = InfinitePolynomialRing(GF(Integer(5)), names=( x ,˓→R._first_ngens(2)>>> R.construction()[InfPoly{[x,y], "lex", "dense"}, Finite Field of size 5]y ,)); (x, y,) =␣

gen(i=None)
Return the 𝑖𝑡ℎ ‘generator’ (see the description in ngens()) of this infinite polynomial ring.
EXAMPLES:
sage: X = InfinitePolynomialRing(QQ)
sage: x = X.gen()sage: x[1]x_1
sage: X.gen() is X.gen(0)True
sage: XX = InfinitePolynomialRing(GF(5))
sage: XX.gen(0) is XX.gen()True>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ)>>> x = X.gen()>>> x[Integer(1)]x_1>>> X.gen() is X.gen(Integer(0))
True>>> XX = InfinitePolynomialRing(GF(Integer(5)))>>> XX.gen(Integer(0)) is XX.gen()
True

1000

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

gens_dict()
Return a dictionary-like object containing the infinitely many {var_name:variable} pairs.
EXAMPLES:
sage: R = InfinitePolynomialRing(ZZ, a )sage: D = R.gens_dict()
sage: D
GenDict of Infinite polynomial ring in a over Integer Ringsage: D[ a_5 ]a_5>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, a )>>> D = R.gens_dict()>>> D
GenDict of Infinite polynomial ring in a over Integer Ring>>> D[ a_5 ]a_5

is_field(*args, **kwds)
Return False since Infinite Polynomial Rings are never fields.
Since Infinite Polynomial Rings must have at least one generator, they have infinitely many variables and thus
never are fields.
EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ)
sage: R.is_field()
False>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,˓→ngens(2)>>> R.is_field()
Falsey ,)); (x, y,) = R._first_

is_integral_domain(*args, **kwds)
An infinite polynomial ring is an integral domain if and only if the base ring is. Arguments are passed to
is_integral_domain method of base ring.
EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ)
sage: R.is_integral_domain()True>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,˓→ngens(2)>>> R.is_integral_domain()Truey ,)); (x, y,) = R._first_

is_noetherian()
Return False, since polynomial rings in infinitely many variables are never Noetherian rings.

6.1. Infinite Polynomial Rings

1001

Polynomials, Release 10.4

Since Infinite Polynomial Rings must have at least one generator, they have infinitely many variables and arethus not Noetherian, as a ring.
Note: Infinite Polynomial Rings over a field 𝐹 are Noetherian as 𝐹 (𝐺) modules, where 𝐺 is the symmetricgroup of the natural numbers. But this is not what the method is_noetherian() is answering.
key_basis()
Return the basis of self given by key polynomials.
EXAMPLES:
sage: R.<x> = InfinitePolynomialRing(GF(2))
sage: R.key_basis()
˓→needs sage.combinat sage.modules
Key polynomial basis over Finite Field of size 2#␣>>> from sage.all import *>>> R = InfinitePolynomialRing(GF(Integer(2)), names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> R.key_basis()#␣˓→needs sage.combinat sage.modules
Key polynomial basis over Finite Field of size 2

krull_dimension(*args, **kwds)
Return Infinity, since polynomial rings in infinitely many variables have infinite Krull dimension.
EXAMPLES:
sage: R.<x, y> = InfinitePolynomialRing(QQ)
sage: R.krull_dimension()+Infinity>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,˓→ngens(2)>>> R.krull_dimension()+Infinityy ,)); (x, y,) = R._first_

ngens()
Return the number of generators for this ring.
Since there are countably infinitely many variables in this polynomial ring, by ‘generators’ we mean the numberof infinite families of variables. See infinite_polynomial_ring for more details.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(ZZ)
sage: X.ngens()
1
sage: X.<x1,x2> = InfinitePolynomialRing(QQ)
sage: X.ngens()
2

1002

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ, names=( x ,)); (x,) = X._first_ngens(1)>>> X.ngens()
1>>> X = InfinitePolynomialRing(QQ, names=( x1 ,˓→ngens(2)>>> X.ngens()2x2 ,)); (x1, x2,) = X._first_

one()order()
Return Infinity, since polynomial rings have infinitely many elements.
EXAMPLES:
sage: R.<x> = InfinitePolynomialRing(GF(2))
sage: R.order()+Infinity>>> from sage.all import *>>> R = InfinitePolynomialRing(GF(Integer(2)), names=( x ,)); (x,) = R._first_
˓→ngens(1)>>> R.order()+Infinity

tensor_with_ring(R)Return the tensor product of self with another ring.
INPUT:• R – a ring.
OUTPUT:
An infinite polynomial ring that, mathematically, can be seen as the tensor product of self with R.
NOTE:
It is required that the underlying ring of self coerces into R. Hence, the tensor product is in fact merely an
extension of the base ring.
EXAMPLES:
sage: R.<a,b> = InfinitePolynomialRing(ZZ)
sage: R.tensor_with_ring(QQ)
Infinite polynomial ring in a, b over Rational Field
sage: R
Infinite polynomial ring in a, b over Integer Ring>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, names=( a , b ,)); (a, b,) = R._first_
˓→ngens(2)>>> R.tensor_with_ring(QQ)
Infinite polynomial ring in a, b over Rational Field>>> R
Infinite polynomial ring in a, b over Integer Ring

6.1. Infinite Polynomial Rings

1003

Polynomials, Release 10.4

The following tests against a bug that was fixed at Issue #10468:
sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: R.tensor_with_ring(QQ) is R
True>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,˓→ngens(2)>>> R.tensor_with_ring(QQ) is R
Truey ,)); (x, y,) = R._first_

varname_key(x)Key for comparison of variable names.
INPUT:• x – a string of the form a+ _ +str(n), where a is the name of a generator, and n is an integer
RETURN:a key used to sort the variables
THEORY:The order is defined as follows:x<y⇐⇒the string x.split( _ )[0] is later in the list of generator names ofself than y.split( _ )[0], or (x.split( _ )[0]==y.split( _ )[0] and int(x.
split( _ )[1])<int(y.split( _ )[1]))EXAMPLES:
sage: X.<alpha,beta> = InfinitePolynomialRing(ZZ)
sage: X.varname_key( alpha_1 )(0, 1)
sage: X.varname_key( beta_10 )(-1, 10)sage: X.varname_key( beta_1 )(-1, 1)
sage: X.varname_key( alpha_10 )(0, 10)sage: X.varname_key( alpha_1 )(0, 1)
sage: X.varname_key( alpha_10 )(0, 10)>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ, names=( alpha ,˓→= X._first_ngens(2)>>> X.varname_key( alpha_1 )(0, 1)>>> X.varname_key( beta_10 )(-1, 10)>>> X.varname_key( beta_1 )(-1, 1)>>> X.varname_key( alpha_10 )(0, 10)>>> X.varname_key( alpha_1 )(0, 1)

beta ,)); (alpha, beta,)␣

(continues on next page)

1004

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> X.varname_key( alpha_10 )(0, 10)6.2 Elements of Infinite Polynomial Rings
AUTHORS:• Simon King <simon.king@nuigalway.ie>• Mike Hansen <mhansen@gmail.com>
An Infinite Polynomial Ring has generators 𝑥* , 𝑦* , ..., so that the variables are of the form 𝑥0 , 𝑥1 , 𝑥2 , ..., 𝑦0 , 𝑦1 , 𝑦2 , ..., ...
(see infinite_polynomial_ring). Using the generators, we can create elements as follows:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: a = x[3]sage: b = y[4]sage: ax_3
sage: by_4
sage: c = a*b + a^3 - 2*b^4
sage: cx_3^3 + x_3*y_4 - 2*y_4^4>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_ngens(2)>>> a = x[Integer(3)]>>> b = y[Integer(4)]
>>> a
x_3
>>> b
y_4
>>> c = a*b + a**Integer(3) - Integer(2)*b**Integer(4)>>> cx_3^3 + x_3*y_4 - 2*y_4^4

Any Infinite Polynomial Ring X is equipped with a monomial ordering. We only consider monomial orderings in which:X.gen(i)[m] > X.gen(j)[n] ⇐⇒ i<j, or i==j and m>nUnder this restriction, the monomial ordering can be lexicographic (default), degree lexicographic, or degree reverse
lexicographic. Here, the ordering is lexicographic, and elements can be compared as usual:
sage: X._orderlexsage: a > b
True>>> from sage.all import *>>> X._orderlex>>> a > bTrue

6.2. Elements of Infinite Polynomial Rings

1005

Polynomials, Release 10.4

Note that, when a method is called that is not directly implemented for ‘InfinitePolynomial’, it is tried to call this method
for the underlying classical polynomial. This holds, e.g., when applying the latex function:
sage: latex(c)x_{3}^{3} + x_{3} y_{4} - 2 y_{4}^{4}>>> from sage.all import *>>> latex(c)x_{3}^{3} + x_{3} y_{4} - 2 y_{4}^{4}There is a permutation action on Infinite Polynomial Rings by permuting the indices of the variables:sage: P = Permutation(((4,5),(2,3)))
sage: c^P
x_2^3 + x_2*y_5 - 2*y_5^4>>> from sage.all import *>>> P = Permutation(((Integer(4),Integer(5)),(Integer(2),Integer(3))))>>> c**P
x_2^3 + x_2*y_5 - 2*y_5^4Note that P(0)==0, and thus variables of index zero are invariant under the permutation action. More generally, if P isany callable object that accepts non-negative integers as input and returns non-negative integers, then c^P means to apply
P to the variable indices occurring in c.
If you want to substitute variables you can use the standard polynomial methods, such as subs():sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[1] + x[1]*x[2]*x[3]sage: f.subs({x[1]: x[0]})x_3*x_2*x_0 + x_0
sage: g = x[0] + x[1] + y[0]sage: g.subs({x[0]: y[0]})x_1 + 2*y_0>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_ngens(2)>>> f = x[Integer(1)] + x[Integer(1)]*x[Integer(2)]*x[Integer(3)]>>> f.subs({x[Integer(1)]: x[Integer(0)]})x_3*x_2*x_0 + x_0>>> g = x[Integer(0)] + x[Integer(1)] + y[Integer(0)]>>> g.subs({x[Integer(0)]: y[Integer(0)]})x_1 + 2*y_0

class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial(A,p)
Bases: CommutativePolynomial
Create an element of a Polynomial Ring with a Countably Infinite Number of Variables.
Usually, an InfinitePolynomial is obtained by using the generators of an Infinite Polynomial Ring (see infinite_polynomial_ring) or by conversion.
INPUT:• A – an Infinite Polynomial Ring.
• p – a classical polynomial that can be interpreted in A.

1006

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

ASSUMPTIONS:In the dense implementation, it must be ensured that the argument p coerces into A._P by a name preserving
conversion map.
In the sparse implementation, in the direct construction of an infinite polynomial, it is not tested whether theargument p makes sense in A.
EXAMPLES:
sage: from sage.rings.polynomial.infinite_polynomial_element import␣
˓→InfinitePolynomial
sage: X.<alpha> = InfinitePolynomialRing(ZZ)
sage: P.<alpha_1,alpha_2> = ZZ[]>>> from sage.all import *>>> from sage.rings.polynomial.infinite_polynomial_element import␣
˓→InfinitePolynomial>>> X = InfinitePolynomialRing(ZZ, names=( alpha ,)); (alpha,) = X._first_ngens(1)>>> P = ZZ[ alpha_1, alpha_2 ]; (alpha_1, alpha_2,) = P._first_ngens(2)Currently, P and X._P (the underlying polynomial ring of X) both have two variables:sage: X._P
Multivariate Polynomial Ring in alpha_1, alpha_0 over Integer Ring>>> from sage.all import *>>> X._P
Multivariate Polynomial Ring in alpha_1, alpha_0 over Integer Ring

By default, a coercion from P to X._P would not be name preserving. However, this is taken care for; a namepreserving conversion is impossible, and by consequence an error is raised:sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
Traceback (most recent call last):...
TypeError: Could not find a mapping of the passed element to this ring.
>>> from sage.all import *>>> InfinitePolynomial(X, (alpha_1+alpha_2)**Integer(2))
Traceback (most recent call last):...
TypeError: Could not find a mapping of the passed element to this ring.

When extending the underlying polynomial ring, the construction of an infinite polynomial works:
sage: alpha[2]alpha_2
sage: InfinitePolynomial(X, (alpha_1+alpha_2)^2)
alpha_2^2 + 2*alpha_2*alpha_1 + alpha_1^2>>> from sage.all import *>>> alpha[Integer(2)]alpha_2>>> InfinitePolynomial(X, (alpha_1+alpha_2)**Integer(2))
alpha_2^2 + 2*alpha_2*alpha_1 + alpha_1^2

6.2. Elements of Infinite Polynomial Rings

1007

Polynomials, Release 10.4

In the sparse implementation, it is not checked whether the polynomial really belongs to the parent, and when it
does not, the results may be unexpected due to coercions:sage: Y.<alpha,beta> = InfinitePolynomialRing(GF(2), implementation= sparse )sage: a = (alpha_1+alpha_2)^2
sage: InfinitePolynomial(Y, a)alpha_0^2 + beta_0^2>>> from sage.all import *>>> Y = InfinitePolynomialRing(GF(Integer(2)), implementation= sparse , names=(
˓→ alpha ,beta ,)); (alpha, beta,) = Y._first_ngens(2)>>> a = (alpha_1+alpha_2)**Integer(2)>>> InfinitePolynomial(Y, a)alpha_0^2 + beta_0^2

However, it is checked when doing a conversion:
sage: Y(a)alpha_2^2 + alpha_1^2>>> from sage.all import *>>> Y(a)alpha_2^2 + alpha_1^2

coefficient(monomial)
Returns the coefficient of a monomial in this polynomial.
INPUT:• A monomial (element of the parent of self) or• a dictionary that describes a monomial (the keys are variables of the parent of self, the values are thecorresponding exponents)
EXAMPLES:
We can get the coefficient in front of monomials:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: a = 2*x[0]*x[1] + x[1] + x[2]sage: a.coefficient(x[0])2*x_1
sage: a.coefficient(x[1])2*x_0 + 1
sage: a.coefficient(x[2])1sage: a.coefficient(x[0]*x[1])2>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> a = Integer(2)*x[Integer(0)]*x[Integer(1)] + x[Integer(1)] + x[Integer(2)]>>> a.coefficient(x[Integer(0)])
2*x_1>>> a.coefficient(x[Integer(1)])
2*x_0 + 1>>> a.coefficient(x[Integer(2)])
1(continues on next page)

1008

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> a.coefficient(x[Integer(0)]*x[Integer(1)])
2

We can also pass in a dictionary:
sage: a.coefficient({x[0]:1, x[1]:1})
2>>> from sage.all import *>>> a.coefficient({x[Integer(0)]:Integer(1), x[Integer(1)]:Integer(1)})
2

footprint()
Leading exponents sorted by index and generator.
OUTPUT:D – a dictionary whose keys are the occurring variable indices.
D[s] is a list [i_1,...,i_n], where i_j gives the exponent of self.parent().gen(j)[s] inthe leading term of self.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = x[30]*y[1]^3*x[1]^2 + 2*x[10]*y[30]sage: sorted(p.footprint().items())[(1, [2, 3]), (30, [1, 0])]>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = x[Integer(30)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2) +␣˓→Integer(2)*x[Integer(10)]*y[Integer(30)]>>> sorted(p.footprint().items())[(1, [2, 3]), (30, [1, 0])]gcd(x)
computes the greatest common divisor
EXAMPLES:
sage: R.<x>=InfinitePolynomialRing(QQ)
sage: p1=x[0] + x[1]**2
sage: gcd(p1,p1+3)
1
sage: gcd(p1,p1)==p1
True>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> p1=x[Integer(0)] + x[Integer(1)]**Integer(2)>>> gcd(p1,p1+Integer(3))
1>>> gcd(p1,p1)==p1
True

6.2. Elements of Infinite Polynomial Rings

1009

Polynomials, Release 10.4

is_nilpotent()
Return True if self is nilpotent, i.e., some power of self is 0.
EXAMPLES:
sage: R.<x> = InfinitePolynomialRing(QQbar)#␣˓→needs sage.rings.number_fieldsage: (x[0] + x[1]).is_nilpotent()#␣˓→needs sage.rings.number_field
False
sage: R(0).is_nilpotent()#␣˓→needs sage.rings.number_fieldTrue
sage: _.<x> = InfinitePolynomialRing(Zmod(4))
sage: (2*x[0]).is_nilpotent()
True
sage: (2+x[4]*x[7]).is_nilpotent()
False
sage: _.<y> = InfinitePolynomialRing(Zmod(100))
sage: (5+2*y[0] + 10*(y[0]^2+y[1]^2)).is_nilpotent()
False
sage: (10*y[2] + 20*y[5] - 30*y[2]*y[5] + 70*(y[2]^2+y[5]^2)).is_nilpotent()True>>> from sage.all import *>>> R = InfinitePolynomialRing(QQbar, names=( x ,)); (x,) = R._first_ngens(1)˓→# needs sage.rings.number_field>>> (x[Integer(0)] + x[Integer(1)]).is_nilpotent()␣˓→# needs sage.rings.number_field
False>>> R(Integer(0)).is_nilpotent()␣˓→# needs sage.rings.number_field
True>>> _ = InfinitePolynomialRing(Zmod(Integer(4)), names=( x ,)); (x,) = _._˓→first_ngens(1)>>> (Integer(2)*x[Integer(0)]).is_nilpotent()
True>>> (Integer(2)+x[Integer(4)]*x[Integer(7)]).is_nilpotent()
False>>> _ = InfinitePolynomialRing(Zmod(Integer(100)), names=( y ,)); (y,) = _._˓→first_ngens(1)>>> (Integer(5)+Integer(2)*y[Integer(0)] +␣˓→Integer(10)*(y[Integer(0)]**Integer(2)+y[Integer(1)]**Integer(2))).is_
˓→nilpotent()
False>>> (Integer(10)*y[Integer(2)] + Integer(20)*y[Integer(5)] -␣˓→Integer(30)*y[Integer(2)]*y[Integer(5)] +␣˓→Integer(70)*(y[Integer(2)]**Integer(2)+y[Integer(5)]**Integer(2))).is_
˓→nilpotent()
True

is_unit()
Answer whether self is a unit.
EXAMPLES:
sage: R1.<x,y> = InfinitePolynomialRing(ZZ)
sage: R2.<a,b> = InfinitePolynomialRing(QQ)(continues on next page)

1010

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

sage: (1 + x[2]).is_unit()
False
sage: R1(1).is_unit()
True
sage: R1(2).is_unit()
False
sage: R2(2).is_unit()
True
sage: (1 + a[2]).is_unit()
False>>> from sage.all import *>>> R1 = InfinitePolynomialRing(ZZ, names=( x ,˓→ngens(2)>>> R2 = InfinitePolynomialRing(QQ, names=( a ,˓→ngens(2)>>> (Integer(1) + x[Integer(2)]).is_unit()
False>>> R1(Integer(1)).is_unit()
True>>> R1(Integer(2)).is_unit()
False>>> R2(Integer(2)).is_unit()True>>> (Integer(1) + a[Integer(2)]).is_unit()
Falsey ,)); (x, y,) = R1._first_b ,)); (a, b,) = R2._first_

Check that Issue #22454 is fixed:
sage: _.<x> = InfinitePolynomialRing(Zmod(4))
sage: (1 + 2*x[0]).is_unit()
True
sage: (x[0]*x[1]).is_unit()
False
sage: _.<x> = InfinitePolynomialRing(Zmod(900))
sage: (7+150*x[0] + 30*x[1] + 120*x[1]*x[100]).is_unit()
True>>> from sage.all import *>>> _ = InfinitePolynomialRing(Zmod(Integer(4)), names=( x ,)); (x,) = _._˓→first_ngens(1)>>> (Integer(1) + Integer(2)*x[Integer(0)]).is_unit()True>>> (x[Integer(0)]*x[Integer(1)]).is_unit()
False>>> _ = InfinitePolynomialRing(Zmod(Integer(900)), names=( x ,)); (x,) = _._˓→first_ngens(1)>>> (Integer(7)+Integer(150)*x[Integer(0)] + Integer(30)*x[Integer(1)] +␣˓→Integer(120)*x[Integer(1)]*x[Integer(100)]).is_unit()
True

lc()
The coefficient of the leading term of self.
EXAMPLES:

6.2. Elements of Infinite Polynomial Rings

1011

Polynomials, Release 10.4

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.lc()
3>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] +␣˓→Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)>>> p.lc()
3lm()
The leading monomial of self.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + x[10]*y[1]^3*x[1]^2
sage: p.lm()
x_10*x_1^2*y_1^3>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] +␣˓→x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)>>> p.lm()
x_10*x_1^2*y_1^3lt()
The leading term (= product of coefficient and monomial) of self.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.lt()
3*x_10*x_1^2*y_1^3>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] +␣˓→Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)>>> p.lt()
3*x_10*x_1^2*y_1^3

max_index()
Return the maximal index of a variable occurring in self, or -1 if self is scalar.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4](continues on next page)

1012

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

sage: p.max_index()
4
sage: x[0].max_index()0sage: X(10).max_index()-1>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = x[Integer(1)]**Integer(2) + y[Integer(2)]**Integer(2) +␣˓→x[Integer(1)]*x[Integer(2)]*y[Integer(3)] + x[Integer(1)]*y[Integer(4)]>>> p.max_index()
4>>> x[Integer(0)].max_index()
0>>> X(Integer(10)).max_index()-1polynomial()
Return the underlying polynomial.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(GF(7))
sage: p = x[2]*y[1] + 3*y[0]sage: px_2*y_1 + 3*y_0
sage: p.polynomial()
x_2*y_1 + 3*y_0
sage: p.polynomial().parent()
Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0
over Finite Field of size 7
sage: p.parent()
Infinite polynomial ring in x, y over Finite Field of size 7>>> from sage.all import *>>> X = InfinitePolynomialRing(GF(Integer(7)), names=( x , y ,)); (x, y,) =␣
˓→X._first_ngens(2)>>> p = x[Integer(2)]*y[Integer(1)] + Integer(3)*y[Integer(0)]>>> px_2*y_1 + 3*y_0>>> p.polynomial()
x_2*y_1 + 3*y_0>>> p.polynomial().parent()
Multivariate Polynomial Ring in x_2, x_1, x_0, y_2, y_1, y_0
over Finite Field of size 7>>> p.parent()
Infinite polynomial ring in x, y over Finite Field of size 7

reduce(I, tailreduce=False, report=None)
Symmetrical reduction of self with respect to a symmetric ideal (or list of Infinite Polynomials).
INPUT:• I – a SymmetricIdeal or a list of Infinite Polynomials.

6.2. Elements of Infinite Polynomial Rings

1013

Polynomials, Release 10.4

• tailreduce – (bool, default False) Tail reduction is performed if this parameter is True.
• report – (object, default None) If not None, some information on the progress of computation isprinted, since reduction of huge polynomials may take a long time.
OUTPUT:
Symmetrical reduction of self with respect to I, possibly with tail reduction.
THEORY:
Reducing an element 𝑝 of an Infinite Polynomial Ring 𝑋 by some other element 𝑞 means the following:
1. Let 𝑀 and 𝑁 be the leading terms of 𝑝 and 𝑞.
2. Test whether there is a permutation 𝑃 that does not does not diminish the variable indices occurring in
𝑁 and preserves their order, so that there is some term 𝑇 ∈ 𝑋 with 𝑇 𝑁 𝑃 = 𝑀 . If there is no such
permutation, return 𝑝
3. Replace 𝑝 by 𝑝 − 𝑇 𝑞 𝑃 and continue with step 1.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = y[1]^2*y[3] + y[2]*x[3]^3
sage: p.reduce([y[2]*x[1]^2])
x_3^3*y_2 + y_3*y_1^2>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = y[Integer(1)]**Integer(2)*y[Integer(3)] +␣˓→y[Integer(2)]*x[Integer(3)]**Integer(3)>>> p.reduce([y[Integer(2)]*x[Integer(1)]**Integer(2)])
x_3^3*y_2 + y_3*y_1^2

The preceding is correct: If a permutation turns y[2]*x[1]^2 into a factor of the leading monomial
y[2]*x[3]^3 of p, then it interchanges the variable indices 1 and 2; this is not allowed in a symmetric
reduction. However, reduction by y[1]*x[2]^2 works, since one can change variable index 1 into 2 and2 into 3:
sage: p.reduce([y[1]*x[2]^2])
˓→needs sage.libs.singular
y_3*y_1^2#␣>>> from sage.all import *>>> p.reduce([y[Integer(1)]*x[Integer(2)]**Integer(2)])˓→# needs sage.libs.singular
y_3*y_1^2

␣The next example shows that tail reduction is not done, unless it is explicitly advised. The input can also be a
Symmetric Ideal:
sage: I = (y[3])*X
sage: p.reduce(I)x_3^3*y_2 + y_3*y_1^2
sage: p.reduce(I, tailreduce=True)
˓→needs sage.libs.singularx_3^3*y_2

1014

#␣

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4>>> from sage.all import *>>> I = (y[Integer(3)])*X>>> p.reduce(I)x_3^3*y_2 + y_3*y_1^2>>> p.reduce(I, tailreduce=True)
˓→needs sage.libs.singularx_3^3*y_2#␣Last, we demonstrate the report option:
sage: p = x[1]^2 + y[2]^2 + x[1]*x[2]*y[3] + x[1]*y[4]sage: p.reduce(I, tailreduce=True, report=True)
˓→needs sage.libs.singular:T[2]:>>
x_1^2 + y_2^2#␣>>> from sage.all import *>>> p = x[Integer(1)]**Integer(2) + y[Integer(2)]**Integer(2) +␣˓→x[Integer(1)]*x[Integer(2)]*y[Integer(3)] + x[Integer(1)]*y[Integer(4)]>>> p.reduce(I, tailreduce=True, report=True)#␣˓→needs sage.libs.singular:T[2]:>>
x_1^2 + y_2^2

The output ‘:’ means that there was one reduction of the leading monomial. ‘T[2]’ means that a tail reduction
was performed on a polynomial with two terms. At ‘>’, one round of the reduction process is finished (there
could only be several non-trivial rounds if 𝐼 was generated by more than one polynomial).
ring()The ring which self belongs to.
This is the same as self.parent().
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(ZZ,implementation= sparse )sage: p = x[100]*y[1]^3*x[1]^2 + 2*x[10]*y[30]sage: p.ring()
Infinite polynomial ring in x, y over Integer Ring>>> from sage.all import *>>> X = InfinitePolynomialRing(ZZ,implementation= sparse , names=( x , y ,));
˓→ (x, y,) = X._first_ngens(2)>>> p = x[Integer(100)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2) +␣˓→Integer(2)*x[Integer(10)]*y[Integer(30)]>>> p.ring()
Infinite polynomial ring in x, y over Integer Ringsqueezed()
Reduce the variable indices occurring in self.
OUTPUT:
Apply a permutation to self that does not change the order of the variable indices of self but squeezes
them into the range 1,2,…
EXAMPLES:
6.2. Elements of Infinite Polynomial Rings

1015

Polynomials, Release 10.4

sage: X.<x,y> = InfinitePolynomialRing(QQ,implementation= sparse )sage: p = x[1]*y[100] + x[50]*y[1000]
sage: p.squeezed()
x_2*y_4 + x_1*y_3>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ,implementation= sparse , names=( x , y ,));
˓→ (x, y,) = X._first_ngens(2)>>> p = x[Integer(1)]*y[Integer(100)] + x[Integer(50)]*y[Integer(1000)]>>> p.squeezed()
x_2*y_4 + x_1*y_3

stretch(k)Stretch self by a given factor.
INPUT:• k – an integer.
OUTPUT:
Replace 𝑣𝑛 with 𝑣𝑛·𝑘 for all generators 𝑣* occurring in self.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: a = x[0] + x[1] + x[2]sage: a.stretch(2)x_4 + x_2 + x_0
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: a = x[0] + x[1] + y[0]*y[1]; ax_1 + x_0 + y_1*y_0
sage: a.stretch(2)x_2 + x_0 + y_2*y_0>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> a = x[Integer(0)] + x[Integer(1)] + x[Integer(2)]>>> a.stretch(Integer(2))
x_4 + x_2 + x_0>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> a = x[Integer(0)] + x[Integer(1)] + y[Integer(0)]*y[Integer(1)]; ax_1 + x_0 + y_1*y_0>>> a.stretch(Integer(2))
x_2 + x_0 + y_2*y_0

subs(fixed=None, **kwargs)
Substitute variables in self.
INPUT:• fixed – (optional) dict with {variable: value} pairs• **kwargs – named parameters
OUTPUT:

1016

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

the resulting substitution
EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[1] + x[1]*x[2]*x[3]>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> f = x[Integer(1)] + x[Integer(1)]*x[Integer(2)]*x[Integer(3)]Passing fixed={x[1]: x[0]}. Note that the keys may be given using the generators of the infinite
polynomial ring or as a string:sage: f.subs({x[1]: x[0]})x_3*x_2*x_0 + x_0
sage: f.subs({ x_1 : x[0]})x_3*x_2*x_0 + x_0>>> from sage.all import *>>> f.subs({x[Integer(1)]: x[Integer(0)]})x_3*x_2*x_0 + x_0>>> f.subs({ x_1 : x[Integer(0)]})x_3*x_2*x_0 + x_0

Passing the variables as names parameters:sage: f.subs(x_1=y[1])x_3*x_2*y_1 + y_1
sage: f.subs(x_1=y[1], x_2=2)
2*x_3*y_1 + y_1>>> from sage.all import *>>> f.subs(x_1=y[Integer(1)])
x_3*x_2*y_1 + y_1>>> f.subs(x_1=y[Integer(1)], x_2=Integer(2))
2*x_3*y_1 + y_1

The substitution returns the original polynomial if you try to substitute a variable not present:
sage: g = x[0] + x[1]sage: g.subs({y[0]: x[0]})x_1 + x_0>>> from sage.all import *>>> g = x[Integer(0)] + x[Integer(1)]>>> g.subs({y[Integer(0)]: x[Integer(0)]})x_1 + x_0

The substitution can also handle matrices:sage: # needs sage.modules
sage: M = matrix([[1,0], [0,2]])
sage: N = matrix([[0,3], [4,0]])
sage: g = x[0]^2 + 3*x[1](continues on next page)

6.2. Elements of Infinite Polynomial Rings

1017

Polynomials, Release 10.4

(continued from previous page)

sage: g.subs({ x_0 : M})[3*x_1 + 10][
0 3*x_1 + 4]
sage: g.subs({x[0]: M, x[1]: N})[ 1 9][12 4]>>> from sage.all import *>>> # needs sage.modules>>> M = matrix([[Integer(1),Integer(0)], [Integer(0),Integer(2)]])>>> N = matrix([[Integer(0),Integer(3)], [Integer(4),Integer(0)]])>>> g = x[Integer(0)]**Integer(2) + Integer(3)*x[Integer(1)]>>> g.subs({ x_0 : M})[3*x_1 + 10][
0 3*x_1 + 4]>>> g.subs({x[Integer(0)]: M, x[Integer(1)]: N})[ 1 9][12 4]

If you pass both fixed and kwargs, any conflicts will defer to fixed:
sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: f = x[0]sage: f.subs({x[0]: 1})1sage: f.subs(x_0=5)5sage: f.subs({x[0]: 1}, x_0=5)
1>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> f = x[Integer(0)]>>> f.subs({x[Integer(0)]: Integer(1)})
1>>> f.subs(x_0=Integer(5))
5>>> f.subs({x[Integer(0)]: Integer(1)}, x_0=Integer(5))
1symmetric_cancellation_order(other)
Comparison of leading terms by Symmetric Cancellation Order, <𝑠𝑐 .
INPUT:
self, other – two Infinite Polynomials
ASSUMPTION:
Both Infinite Polynomials are non-zero.
OUTPUT:(c, sigma, w), where• c = -1,0,1, or None if the leading monomial of self is smaller, equal, greater, or incomparable withrespect to other in the monomial ordering of the Infinite Polynomial Ring

1018

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

• sigma is a permutation witnessing self <𝑠𝑐 other (resp. self >𝑠𝑐 other) or is 1 if self.
lm()==other.lm()• w is 1 or is a term so that w*self.lt()^sigma == other.lt() if 𝑐 ≤ 0, and w*other.
lt()^sigma == self.lt() if 𝑐 = 1
THEORY:If the Symmetric Cancellation Order is a well-quasi-ordering then computation of Groebner bases always
terminates. This is the case, e.g., if the monomial order is lexicographic. For that reason, lexicographic orderis our default order.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]^2)(None, 1, 1)
sage: (x[2]*x[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])(-1, [2, 3, 1], y_1)
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[1])(None, 1, 1)
sage: (x[2]*x[1]*y[1]).symmetric_cancellation_order(x[2]*x[3]*y[2])(-1, [2, 3, 1], 1)>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> (x[Integer(2)]*x[Integer(1)]).symmetric_cancellation_
˓→order(x[Integer(2)]**Integer(2))(None, 1, 1)>>> (x[Integer(2)]*x[Integer(1)]).symmetric_cancellation_
˓→order(x[Integer(2)]*x[Integer(3)]*y[Integer(1)])(-1, [2, 3, 1], y_1)>>> (x[Integer(2)]*x[Integer(1)]*y[Integer(1)]).symmetric_cancellation_
˓→order(x[Integer(2)]*x[Integer(3)]*y[Integer(1)])(None, 1, 1)>>> (x[Integer(2)]*x[Integer(1)]*y[Integer(1)]).symmetric_cancellation_
˓→order(x[Integer(2)]*x[Integer(3)]*y[Integer(2)])(-1, [2, 3, 1], 1)tail()The tail of self (this is self minus its leading term).
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = 2*x[10]*y[30] + 3*x[10]*y[1]^3*x[1]^2
sage: p.tail()
2*x_10*y_30>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> p = Integer(2)*x[Integer(10)]*y[Integer(30)] +␣˓→Integer(3)*x[Integer(10)]*y[Integer(1)]**Integer(3)*x[Integer(1)]**Integer(2)>>> p.tail()
2*x_10*y_30

6.2. Elements of Infinite Polynomial Rings

1019

Polynomials, Release 10.4

variables()Return the variables occurring in self (tuple of elements of some polynomial ring).
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: p = x[1] + x[2] - 2*x[1]*x[3]sage: p.variables()(x_3, x_2, x_1)
sage: x[1].variables()(x_1,)
sage: X(1).variables()()>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> p = x[Integer(1)] + x[Integer(2)] - Integer(2)*x[Integer(1)]*x[Integer(3)]>>> p.variables()(x_3, x_2, x_1)>>> x[Integer(1)].variables()(x_1,)>>> X(Integer(1)).variables()()

class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_dense(A,p)
Bases: InfinitePolynomial
Element of a dense Polynomial Ring with a Countably Infinite Number of Variables.
INPUT:• A – an Infinite Polynomial Ring in dense implementation• p – a classical polynomial that can be interpreted in A.
Of course, one should not directly invoke this class, but rather construct elements of A in the usual way.
class sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial_sparse(A,p)
Bases: InfinitePolynomial
Element of a sparse Polynomial Ring with a Countably Infinite Number of Variables.
INPUT:• A – an Infinite Polynomial Ring in sparse implementation• p – a classical polynomial that can be interpreted in A.
Of course, one should not directly invoke this class, but rather construct elements of A in the usual way.
EXAMPLES:
sage: A.<a> = QQ[]
sage: B.<b,c> = InfinitePolynomialRing(A,implementation= sparse )sage: p = a*b[100] + 1/2*c[4]sage: pa*b_100 + 1/2*c_4
sage: p.parent()
Infinite polynomial ring in b, c(continues on next page)

1020

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

over Univariate Polynomial Ring in a over Rational Field
sage: p.polynomial().parent()
Multivariate Polynomial Ring in b_100, b_0, c_4, c_0
over Univariate Polynomial Ring in a over Rational Field>>> from sage.all import *>>> A = QQ[ a ]; (a,) = A._first_ngens(1)>>> B = InfinitePolynomialRing(A,implementation= sparse , names=( b ,˓→c,) = B._first_ngens(2)>>> p = a*b[Integer(100)] + Integer(1)/Integer(2)*c[Integer(4)]>>> pa*b_100 + 1/2*c_4>>> p.parent()
Infinite polynomial ring in b, cover Univariate Polynomial Ring in a over Rational Field>>> p.polynomial().parent()
Multivariate Polynomial Ring in b_100, b_0, c_4, c_0
over Univariate Polynomial Ring in a over Rational Fieldc ,)); (b,␣

6.3 Symmetric Ideals of Infinite Polynomial Rings
This module provides an implementation of ideals of polynomial rings in a countably infinite number of variables thatare invariant under variable permutation. Such ideals are called ‘Symmetric Ideals’ in the rest of this document. Our
implementation is based on the theory of M. Aschenbrenner and C. Hillar.
AUTHORS:• Simon King <simon.king@nuigalway.ie>
EXAMPLES:
Here, we demonstrate that working in quotient rings of Infinite Polynomial Rings works, provided that one uses symmetric
Groebner bases.
sage: R.<x> = InfinitePolynomialRing(QQ)
sage: I = R.ideal([x[1]*x[2] + x[3]])>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = R._first_ngens(1)>>> I = R.ideal([x[Integer(1)]*x[Integer(2)] + x[Integer(3)]])Note that I is not a symmetric Groebner basis:sage: # needs sage.combinat
sage: G = R * I.groebner_basis()
sage: G
Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) ofInfinite polynomial ring in x over Rational Field
sage: Q = R.quotient(G)sage: p = x[3]*x[1] + x[2]^2 + 3
sage: Q(p)-2*x_1 + 3

6.3. Symmetric Ideals of Infinite Polynomial Rings

1021

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.combinat>>> G = R * I.groebner_basis()>>> G
Symmetric Ideal (x_1^2 + x_1, x_2 - x_1) ofInfinite polynomial ring in x over Rational Field>>> Q = R.quotient(G)>>> p = x[Integer(3)]*x[Integer(1)] + x[Integer(2)]**Integer(2) + Integer(3)>>> Q(p)-2*x_1 + 3

By the second generator of G, variable 𝑥𝑛 is equal to 𝑥1 for any positive integer 𝑛. By the first generator of G, 𝑥31 is equal
to 𝑥1 in Q. Indeed, we havesage: Q(p)*x[2] == Q(p)*x[1]*x[3]*x[5]˓→needs sage.combinat
True

#␣

>>> from sage.all import *>>> Q(p)*x[Integer(2)] == Q(p)*x[Integer(1)]*x[Integer(3)]*x[Integer(5)]˓→# needs sage.combinat
True␣

class sage.rings.polynomial.symmetric_ideal.SymmetricIdeal(ring, gens, coerce=True)
Bases: Ideal_generic
Ideal in an Infinite Polynomial Ring, invariant under permutation of variable indices
THEORY:An Infinite Polynomial Ring with finitely many generators 𝑥* , 𝑦* , ... over a field 𝐹 is a free commutative 𝐹 -algebra
generated by infinitely many ‘variables’ 𝑥0 , 𝑥1 , 𝑥2 , ..., 𝑦0 , 𝑦1 , 𝑦2 , .... We refer to the natural number 𝑛 as the index
of the variable 𝑥𝑛 . See more detailed description at infinite_polynomial_ring
Infinite Polynomial Rings are equipped with a permutation action by permuting positive variable indices, i.e., 𝑥𝑃𝑛 =𝑥𝑃 (𝑛) , 𝑦𝑛𝑃 = 𝑦𝑃 (𝑛) , ... for any permutation 𝑃 . Note that the variables 𝑥0 , 𝑦0 , ... of index zero are invariant underthat action.
A Symmetric Ideal is an ideal in an infinite polynomial ring 𝑋 that is invariant under the permutation action. In
other words, if S∞ denotes the symmetric group of 1, 2, ..., then a Symmetric Ideal is a right 𝑋[S∞ ]-submoduleof 𝑋.
It is known by work of Aschenbrenner and Hillar [AB2007] that an Infinite Polynomial Ring 𝑋 with a single
generator 𝑥* is Noetherian, in the sense that any Symmetric Ideal 𝐼 ⊂ 𝑋 is finitely generated modulo addition, multiplication by elements of 𝑋, and permutation of variable indices (hence, it is a finitely generated right
𝑋[S∞ ]-module).
Moreover, if 𝑋 is equipped with a lexicographic monomial ordering with 𝑥1 < 𝑥2 < 𝑥3 ... then there is analgorithm of Buchberger type that computes a Groebner basis 𝐺 for 𝐼 that allows for computation of a uniquenormal form, that is zero precisely for the elements of 𝐼 – see [AB2008]. See groebner_basis() for moredetails.
Our implementation allows more than one generator and also provides degree lexicographic and degree reverse
lexicographic monomial orderings – we do, however, not guarantee termination of the Buchberger algorithm inthese cases.
EXAMPLES:

1022

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: I = [x[1]*y[2]*y[1] + 2*x[1]*y[2]] * X
sage: I == loads(dumps(I))
True
sage: latex(I)\left(x_{1} y_{2} y_{1} + 2 x_{1} y_{2}\right)\Bold{Q}[x_{\ast}, y_{\ast}][\˓→mathfrak{S}_{\infty}]>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_ngens(2)>>> I = [x[Integer(1)]*y[Integer(2)]*y[Integer(1)] +␣˓→Integer(2)*x[Integer(1)]*y[Integer(2)]] * X>>> I == loads(dumps(I))
True>>> latex(I)\left(x_{1} y_{2} y_{1} + 2 x_{1} y_{2}\right)\Bold{Q}[x_{\ast}, y_{\ast}][\˓→mathfrak{S}_{\infty}]

The default ordering is lexicographic. We now compute a Groebner basis:sage: J = I.groebner_basis(); J# about 3 seconds
˓→needs sage.combinat[x_1*y_2*y_1 + 2*x_1*y_2, x_2*y_2*y_1 + 2*x_2*y_1,
x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1]>>> from sage.all import *>>> J = I.groebner_basis(); J# about 3 seconds
˓→needs sage.combinat[x_1*y_2*y_1 + 2*x_1*y_2, x_2*y_2*y_1 + 2*x_2*y_1,
x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_1*y_1]#␣#␣

Note that even though the symmetric ideal can be generated by a single polynomial, its reduced symmetric Groebnerbasis comprises four elements. Ideal membership in I can now be tested by commuting symmetric reduction
modulo J:
sage: I.reduce(J)˓→needs sage.combinat
Symmetric Ideal (0) of Infinite polynomial ring in x, y over Rational Field>>> from sage.all import *>>> I.reduce(J)˓→needs sage.combinat
Symmetric Ideal (0) of Infinite polynomial ring in x, y over Rational Field#␣#␣

The Groebner basis is not point-wise invariant under permutation:
sage: # needs sage.combinat
sage: P = Permutation([2, 1])
sage: J[2]x_2*x_1*y_1^2 + 2*x_2*x_1*y_1
sage: J[2]^P
x_2*x_1*y_2^2 + 2*x_2*x_1*y_2
sage: J[2]^P in J
False

6.3. Symmetric Ideals of Infinite Polynomial Rings

1023

Polynomials, Release 10.4>>> from sage.all import *>>> # needs sage.combinat>>> P = Permutation([Integer(2), Integer(1)])>>> J[Integer(2)]x_2*x_1*y_1^2 + 2*x_2*x_1*y_1>>> J[Integer(2)]**P
x_2*x_1*y_2^2 + 2*x_2*x_1*y_2>>> J[Integer(2)]**P in J
False

However, any element of J has symmetric reduction zero even after applying a permutation. This even holds when
the permutations involve higher variable indices than the ones occurring in J:
sage: [[(p^P).reduce(J) for p in J] for P in Permutations(3)]#␣˓→needs sage.combinat[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0,␣
˓→0]]>>> from sage.all import *>>> [[(p**P).reduce(J) for p in J] for P in Permutations(Integer(3))]␣˓→# needs sage.combinat[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0,␣˓→0]]

Since I is not a Groebner basis, it is no surprise that it cannot detect ideal membership:
sage: [p.reduce(I) for p in J]#␣˓→needs sage.combinat[0, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_
˓→1*y_1]>>> from sage.all import *>>> [p.reduce(I) for p in J]#␣˓→needs sage.combinat[0, x_2*y_2*y_1 + 2*x_2*y_1, x_2*x_1*y_1^2 + 2*x_2*x_1*y_1, x_2*x_1*y_2 - x_2*x_
˓→1*y_1]

Note that we give no guarantee that the computation of a symmetric Groebner basis will terminate in any orderdifferent from lexicographic.
When multiplying Symmetric Ideals or raising them to some integer power, the permutation action is taken into
account, so that the product is indeed the product of ideals in the mathematical sense.
sage: I = X * (x[1])sage: I * I
˓→needs sage.combinat
Symmetric Ideal (x_1^2, x_2*x_1) ofInfinite polynomial ring in x, y over Rational Field
sage: I^3
˓→needs sage.combinat
Symmetric Ideal (x_1^3, x_2*x_1^2, x_2^2*x_1, x_3*x_2*x_1) ofInfinite polynomial ring in x, y over Rational Field
sage: I * I == X * (x[1]^2)
˓→needs sage.combinat
False

1024

#␣

#␣

#␣

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4>>> from sage.all import *>>> I = X * (x[Integer(1)])>>> I * I˓→needs sage.combinat
Symmetric Ideal (x_1^2, x_2*x_1) ofInfinite polynomial ring in x, y over Rational Field>>> I**Integer(3)˓→# needs sage.combinat
Symmetric Ideal (x_1^3, x_2*x_1^2, x_2^2*x_1, x_3*x_2*x_1) ofInfinite polynomial ring in x, y over Rational Field>>> I * I == X * (x[Integer(1)]**Integer(2))˓→# needs sage.combinat
False

#␣

␣

␣

groebner_basis(tailreduce=False, reduced=True, algorithm=None, report=None, use_full_group=False)
Return a symmetric Groebner basis (type Sequence) of self.
INPUT:• tailreduce – (bool, default False) If True, use tail reduction in intermediate computations• reduced – (bool, default True) If True, return the reduced normalised symmetric Groebner basis.
• algorithm – (string, default None) Determine the algorithm (see below for available algorithms).
• report – (object, default None) If not None, print information on the progress of computation.
• use_full_group – (bool, default False) If True then proceed as originally suggested by[AB2008]. Our default method should be faster; see symmetrisation() for more details.
The computation of symmetric Groebner bases also involves the computation of classical Groebner bases,
i.e., of Groebner bases for ideals in polynomial rings with finitely many variables. For these computations,
Sage provides the following ALGORITHMS:‘’
autoselect (default)‘singular:groebner’Singular’s groebner command‘singular:std’Singular’s std command‘singular:stdhilb’Singular’s stdhib command‘singular:stdfglm’Singular’s stdfglm command‘singular:slimgb’
Singular’s slimgb command‘libsingular:std’libSingular’s std command‘libsingular:slimgb’
libSingular’s slimgb command‘toy:buchberger’
Sage’s toy/educational buchberger without strategy‘toy:buchberger2’
Sage’s toy/educational buchberger with strategy
6.3. Symmetric Ideals of Infinite Polynomial Rings

1025

Polynomials, Release 10.4

‘toy:d_basis’
Sage’s toy/educational d_basis algorithm‘macaulay2:gb’
Macaulay2’s gb command (if available)‘magma:GroebnerBasis’
Magma’s Groebnerbasis command (if available)
If only a system is given - e.g. ‘magma’ - the default algorithm is chosen for that system.
Note: The Singular and libSingular versions of the respective algorithms are identical, but the former calls
an external Singular process while the later calls a C function, i.e. the calling overhead is smaller.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: I1 = X * (x[1] + x[2], x[1]*x[2])sage: I1.groebner_basis()
˓→needs sage.combinat[x_1]
sage: I2 = X * (y[1]^2*y[3] + y[1]*x[3])sage: I2.groebner_basis()
˓→needs sage.combinat[x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2]#␣#␣>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> I1 = X * (x[Integer(1)] + x[Integer(2)], x[Integer(1)]*x[Integer(2)])>>> I1.groebner_basis()#␣˓→needs sage.combinat[x_1]>>> I2 = X * (y[Integer(1)]**Integer(2)*y[Integer(3)] +␣˓→y[Integer(1)]*x[Integer(3)])>>> I2.groebner_basis()#␣˓→needs sage.combinat[x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2]

Note that a symmetric Groebner basis of a principal ideal is not necessarily formed by a single polynomial.
When using the algorithm originally suggested by Aschenbrenner and Hillar, the result is the same, but thecomputation takes much longer:
sage: I2.groebner_basis(use_full_group=True)
˓→needs sage.combinat[x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2]#␣>>> from sage.all import *>>> I2.groebner_basis(use_full_group=True)
˓→needs sage.combinat[x_1*y_2 + y_2^2*y_1, x_2*y_1 + y_2*y_1^2]#␣Last, we demonstrate how the report on the progress of computations looks like:sage: I1.groebner_basis(report=True, reduced=True)
˓→needs sage.combinat#␣(continues on next page)

1026

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

Symmetric interreduction[1/2] >
[2/2] :>
[1/2] >
[2/2] >
Symmetrise 2 polynomials at level 2
Apply permutations>>
Symmetric interreduction[1/3] >
[2/3] >
[3/3] :>-> 0
[1/2] >
[2/2] >
Symmetrisation done
Classical Groebner basis-> 2 generators
Symmetric interreduction[1/2] >
[2/2] >
Symmetrise 2 polynomials at level 3
Apply permutations
>
>
:>
::>
:>
::>
Symmetric interreduction[1/4] >
[2/4] :>-> 0
[3/4] ::>-> 0
[4/4] :>-> 0
[1/1] >
Apply permutations:>:>:>
Symmetric interreduction[1/1] >Classical Groebner basis-> 1 generators
Symmetric interreduction[1/1] >
Symmetrise 1 polynomials at level 4
Apply permutations
>
:>
:>
>
:>
:>
(continues on next page)

6.3. Symmetric Ideals of Infinite Polynomial Rings

1027

Polynomials, Release 10.4

(continued from previous page)

Symmetric interreduction[1/2] >
[2/2] :>-> 0
[1/1] >
Symmetric interreduction[1/1] >
[x_1]>>> from sage.all import *>>> I1.groebner_basis(report=True, reduced=True)
˓→needs sage.combinat
Symmetric interreduction[1/2] >
[2/2] :>
[1/2] >
[2/2] >
Symmetrise 2 polynomials at level 2
Apply permutations>>
Symmetric interreduction[1/3] >
[2/3] >
[3/3] :>-> 0
[1/2] >
[2/2] >
Symmetrisation done
Classical Groebner basis-> 2 generators
Symmetric interreduction[1/2] >
[2/2] >
Symmetrise 2 polynomials at level 3
Apply permutations
>
>
:>
::>
:>
::>
Symmetric interreduction[1/4] >
[2/4] :>-> 0
[3/4] ::>-> 0
[4/4] :>-> 0
[1/1] >
Apply permutations:>:>:>
Symmetric interreduction#␣(continues on next page)

1028

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)[1/1] >Classical Groebner basis-> 1 generators
Symmetric interreduction[1/1] >
Symmetrise 1 polynomials at level 4
Apply permutations
>
:>
:>
>
:>
:>
Symmetric interreduction[1/2] >
[2/2] :>-> 0
[1/1] >
Symmetric interreduction[1/1] >
[x_1]

The Aschenbrenner-Hillar algorithm is only guaranteed to work if the base ring is a field. So, we raise a
TypeError if this is not the case:sage: R.<x,y> = InfinitePolynomialRing(ZZ)
sage: I = R * [x[1] + x[2], y[1]]sage: I.groebner_basis()
˓→needs sage.combinat
Traceback (most recent call last):...
TypeError: The base ring (= Integer Ring) must be a field#␣>>> from sage.all import *>>> R = InfinitePolynomialRing(ZZ, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = R * [x[Integer(1)] + x[Integer(2)], y[Integer(1)]]>>> I.groebner_basis()#␣˓→needs sage.combinat
Traceback (most recent call last):...
TypeError: The base ring (= Integer Ring) must be a fieldinterreduced_basis()
A fully symmetrically reduced generating set (type Sequence) of self.
This does essentially the same as interreduction() with the option ‘tailreduce’, but it returns a Sequence rather than a SymmetricIdeal.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: I = X * (x[1] + x[2], x[1]*x[2])sage: I.interreduced_basis()
˓→needs sage.combinat[-x_1^2, x_2 + x_1]

6.3. Symmetric Ideals of Infinite Polynomial Rings

#␣

1029

Polynomials, Release 10.4>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> I = X * (x[Integer(1)] + x[Integer(2)], x[Integer(1)]*x[Integer(2)])>>> I.interreduced_basis()#␣˓→needs sage.combinat[-x_1^2, x_2 + x_1]

interreduction(tailreduce=True, sorted=False, report=None, RStrat=None)
Return symmetrically interreduced form of self.
INPUT:• tailreduce – (bool, default True) If True, the interreduction is also performed on the non-leading
monomials.
• sorted – (bool, default False) If True, it is assumed that the generators of self are already increasingly sorted.
• report – (object, default None) If not None, some information on the progress of computation isprinted• RStrat – (SymmetricReductionStrategy, default None) A reduction strategy to which thepolynomials resulting from the interreduction will be added. If RStrat already contains some polynomials, they will be used in the interreduction. The effect is to compute in a quotient ring.
OUTPUT:
A Symmetric Ideal 𝐽 (sorted list of generators) coinciding with self as an ideal, so that any generator issymmetrically reduced w.r.t. the other generators. Note that the leading coefficients of the result are notnecessarily 1.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: I = X * (x[1] + x[2], x[1]*x[2])sage: I.interreduction()
˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field#␣>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> I = X * (x[Integer(1)] + x[Integer(2)], x[Integer(1)]*x[Integer(2)])>>> I.interreduction()#␣˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field

Here, we show the report option:
sage: I.interreduction(report=True)
˓→needs sage.combinat
Symmetric interreduction[1/2] >
[2/2] :>
[1/2] >
[2/2] T[1]>>#␣(continues on next page)1030

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field>>> from sage.all import *>>> I.interreduction(report=True)
˓→needs sage.combinat
Symmetric interreduction[1/2] >
[2/2] :>
[1/2] >
[2/2] T[1]>>Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field#␣[m/n] indicates that polynomial number m is considered and the total number of polynomials underconsideration is n. ‘-> 0’ is printed if a zero reduction occurred. The rest of the report is as described insage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy.
reduce().
Last, we demonstrate the use of the optional parameter RStrat:
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: R = SymmetricReductionStrategy(X); R
Symmetric Reduction Strategy in
Infinite polynomial ring in x over Rational Field
sage: I.interreduction(RStrat=R)#␣˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field
sage: R#␣˓→needs sage.combinat
Symmetric Reduction Strategy in
Infinite polynomial ring in x over Rational Field, modulo
x_1^2,
x_2 + x_1
sage: R = SymmetricReductionStrategy(X, [x[1]^2])
sage: I.interreduction(RStrat=R)#␣˓→needs sage.combinat
Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational␣
˓→Field>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> R = SymmetricReductionStrategy(X); R
Symmetric Reduction Strategy in
Infinite polynomial ring in x over Rational Field>>> I.interreduction(RStrat=R)
˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field>>> R
˓→needs sage.combinat
Symmetric Reduction Strategy in#␣#␣(continues on next page)

6.3. Symmetric Ideals of Infinite Polynomial Rings

1031

Polynomials, Release 10.4

(continued from previous page)

Infinite polynomial ring in x over Rational Field, modulo
x_1^2,
x_2 + x_1>>> R = SymmetricReductionStrategy(X, [x[Integer(1)]**Integer(2)])>>> I.interreduction(RStrat=R)#␣˓→needs sage.combinat
Symmetric Ideal (x_2 + x_1) of Infinite polynomial ring in x over Rational␣
˓→Field

is_maximal()Answer whether self is a maximal ideal.
ASSUMPTION:
self is defined by a symmetric Groebner basis.
NOTE:
It is not checked whether self is in fact a symmetric Groebner basis. A wrong answer can result if thisassumption does not hold. A NotImplementedError is raised if the base ring is not a field, since
symmetric Groebner bases are not implemented in this setting.
EXAMPLES:
sage: R.<x,y> = InfinitePolynomialRing(QQ)
sage: I = R.ideal([x[1] + y[2], x[2] - y[1]])sage: I = R * I.groebner_basis(); I˓→needs sage.combinat
Symmetric Ideal (y_1, x_1) ofInfinite polynomial ring in x, y over Rational Field
sage: I = R.ideal([x[1] + y[2], x[2] - y[1]])˓→needs sage.combinat
sage: I.is_maximal()
˓→needs sage.combinat
False

#␣

#␣
#␣

>>> from sage.all import *>>> R = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = R._first_
˓→ngens(2)>>> I = R.ideal([x[Integer(1)] + y[Integer(2)], x[Integer(2)] -␣˓→y[Integer(1)]])>>> I = R * I.groebner_basis(); I#␣˓→needs sage.combinat
Symmetric Ideal (y_1, x_1) ofInfinite polynomial ring in x, y over Rational Field>>> I = R.ideal([x[Integer(1)] + y[Integer(2)], x[Integer(2)] -␣˓→y[Integer(1)]])# needs sage.combinat>>> I.is_maximal()#␣˓→needs sage.combinat
False

The preceding answer is wrong, since it is not the case that I is given by a symmetric Groebner basis:sage: I = R * I.groebner_basis(); I˓→needs sage.combinat
Symmetric Ideal (y_1, x_1) ofInfinite polynomial ring in x, y over Rational Field#␣(continues on next page)1032

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

sage: I.is_maximal()
˓→needs sage.combinat
True>>> from sage.all import *>>> I = R * I.groebner_basis(); I˓→needs sage.combinat
Symmetric Ideal (y_1, x_1) ofInfinite polynomial ring in x, y over Rational Field>>> I.is_maximal()
˓→needs sage.combinat
True

#␣

#␣

#␣

normalisation()
Return an ideal that coincides with self, so that all generators have leading coefficient 1.
Possibly occurring zeroes are removed from the generator list.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: I = X*(1/2*x[1] + 2/3*x[2], 0, 4/5*x[1]*x[2])sage: I.normalisation()
Symmetric Ideal (x_2 + 3/4*x_1, x_2*x_1) ofInfinite polynomial ring in x over Rational Field>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> I = X*(Integer(1)/Integer(2)*x[Integer(1)] + Integer(2)/˓→Integer(3)*x[Integer(2)], Integer(0), Integer(4)/˓→Integer(5)*x[Integer(1)]*x[Integer(2)])>>> I.normalisation()
Symmetric Ideal (x_2 + 3/4*x_1, x_2*x_1) ofInfinite polynomial ring in x over Rational Field

reduce(I, tailreduce=False)
Symmetric reduction of self by another Symmetric Ideal or list of Infinite Polynomials, or symmetric
reduction of a given Infinite Polynomial by self.
INPUT:• I – an Infinite Polynomial, or a Symmetric Ideal or a list of Infinite Polynomials.
• tailreduce – (bool, default False) If True, the non-leading terms will be reduced as well.
OUTPUT:
Symmetric reduction of self with respect to I.
THEORY:
Reduction of an element 𝑝 of an Infinite Polynomial Ring 𝑋 by some other element 𝑞 means the following:
1. Let 𝑀 and 𝑁 be the leading terms of 𝑝 and 𝑞.
2. Test whether there is a permutation 𝑃 that does not does not diminish the variable indices occurring in
𝑁 and preserves their order, so that there is some term 𝑇 ∈ 𝑋 with 𝑇 𝑁 𝑃 = 𝑀 . If there is no such
permutation, return 𝑝
3. Replace 𝑝 by 𝑝 − 𝑇 𝑞 𝑃 and continue with step 1.
6.3. Symmetric Ideals of Infinite Polynomial Rings

1033

Polynomials, Release 10.4

EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: I = X * (y[1]^2*y[3] + y[1]*x[3]^2)
sage: I.reduce([x[1]^2*y[2]])Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> I = X * (y[Integer(1)]**Integer(2)*y[Integer(3)] +␣˓→y[Integer(1)]*x[Integer(3)]**Integer(2))>>> I.reduce([x[Integer(1)]**Integer(2)*y[Integer(2)]])Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field

The preceding is correct, since any permutation that turns x[1]^2*y[2] into a factor of x[3]^2*y[2]interchanges the variable indices 1 and 2 – which is not allowed. However, reduction by x[2]^2*y[1]works, since one can change variable index 1 into 2 and 2 into 3:
sage: I.reduce([x[2]^2*y[1]])˓→needs sage.combinat
Symmetric Ideal (y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field#␣>>> from sage.all import *>>> I.reduce([x[Integer(2)]**Integer(2)*y[Integer(1)]])˓→# needs sage.combinat
Symmetric Ideal (y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field␣

The next example shows that tail reduction is not done, unless it is explicitly advised. The input can also be asymmetric ideal:
sage: J = (y[2]) * X
sage: I.reduce(J)Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field
sage: I.reduce(J, tailreduce=True)
˓→needs sage.combinat
Symmetric Ideal (x_3^2*y_1) ofInfinite polynomial ring in x, y over Rational Field>>> from sage.all import *>>> J = (y[Integer(2)]) * X>>> I.reduce(J)Symmetric Ideal (x_3^2*y_1 + y_3*y_1^2) ofInfinite polynomial ring in x, y over Rational Field>>> I.reduce(J, tailreduce=True)
˓→needs sage.combinat
Symmetric Ideal (x_3^2*y_1) ofInfinite polynomial ring in x, y over Rational Field#␣#␣squeezed()
Reduce the variable indices occurring in self.

1034

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

OUTPUT:
A Symmetric Ideal whose generators are the result of applying squeezed() to the generators of self.
NOTE:
The output describes the same Symmetric Ideal as self.
EXAMPLES:
sage: X.<x,y> = InfinitePolynomialRing(QQ, implementation= sparse )sage: I = X * (x[1000]*y[100], x[50]*y[1000])
sage: I.squeezed()
Symmetric Ideal (x_2*y_1, x_1*y_2) ofInfinite polynomial ring in x, y over Rational Field>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, implementation= sparse , names=( x ,˓→)); (x, y,) = X._first_ngens(2)>>> I = X * (x[Integer(1000)]*y[Integer(100)],␣
˓→x[Integer(50)]*y[Integer(1000)])>>> I.squeezed()
Symmetric Ideal (x_2*y_1, x_1*y_2) ofInfinite polynomial ring in x, y over Rational Fieldy ,symmetric_basis()
A symmetrised generating set (type Sequence) of self.
This does essentially the same as symmetrisation() with the option tailreduce, and it returns a
Sequence rather than a SymmetricIdeal.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: I = X * (x[1] + x[2], x[1]*x[2])sage: I.symmetric_basis()
˓→needs sage.combinat[x_1^2, x_2 + x_1]

#␣>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> I = X * (x[Integer(1)] + x[Integer(2)], x[Integer(1)]*x[Integer(2)])>>> I.symmetric_basis()#␣˓→needs sage.combinat[x_1^2, x_2 + x_1]

symmetrisation(N=None, tailreduce=False, report=None, use_full_group=False)
Apply permutations to the generators of self and interreduce.
INPUT:• N – (integer, default None) Apply permutations in 𝑆𝑦𝑚(𝑁 ). If it is not given then it will be replaced by the maximal variable index occurring in the generators of self.interreduction().
squeezed().
• tailreduce – (bool, default False) If True, perform tail reductions.
• report – (object, default None) If not None, report on the progress of computations.
• use_full_group (optional) – If True, apply all elements of 𝑆𝑦𝑚(𝑁 ) to the generators of self
(this is what [AB2008] originally suggests). The default is to apply all elementary transpositions to the
6.3. Symmetric Ideals of Infinite Polynomial Rings

1035

Polynomials, Release 10.4

generators of self.squeezed(), interreduce, and repeat until the result stabilises, which is oftenmuch faster than applying all of 𝑆𝑦𝑚(𝑁 ), and we are convinced that both methods yield the same
result.
OUTPUT:
A symmetrically interreduced symmetric ideal with respect to which any 𝑆𝑦𝑚(𝑁 )-translate of a generatorof self is symmetrically reducible, where by default N is the maximal variable index that occurs in thegenerators of self.interreduction().squeezed().
NOTE:
If I is a symmetric ideal whose generators are monomials, then I.symmetrisation() is its reduced
Groebner basis. It should be noted that without symmetrisation, monomial generators, in general, do notform a Groebner basis.
EXAMPLES:
sage: X.<x> = InfinitePolynomialRing(QQ)
sage: I = X * (x[1] + x[2], x[1]*x[2])sage: I.symmetrisation()#␣˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field
sage: I.symmetrisation(N=3)#␣
˓→needs sage.combinat
Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field
sage: I.symmetrisation(N=3, use_full_group=True)#␣˓→needs sage.combinat
Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x ,)); (x,) = X._first_ngens(1)>>> I = X * (x[Integer(1)] + x[Integer(2)], x[Integer(1)]*x[Integer(2)])>>> I.symmetrisation()#␣˓→needs sage.combinat
Symmetric Ideal (-x_1^2, x_2 + x_1) ofInfinite polynomial ring in x over Rational Field>>> I.symmetrisation(N=Integer(3))␣˓→# needs sage.combinat
Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field>>> I.symmetrisation(N=Integer(3), use_full_group=True)␣˓→# needs sage.combinat
Symmetric Ideal (-2*x_1) of Infinite polynomial ring in x over Rational Field

6.4 Symmetric Reduction of Infinite Polynomials
SymmetricReductionStrategy provides a framework for efficient symmetric reduction of Infinite Polynomials,
see infinite_polynomial_element.
AUTHORS:• Simon King <simon.king@nuigalway.ie>
THEORY:
According to M. Aschenbrenner and C. Hillar [AB2007], Symmetric Reduction of an element 𝑝 of an Infinite Polynomial
Ring 𝑋 by some other element 𝑞 means the following:

1036

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

1. Let 𝑀 and 𝑁 be the leading terms of 𝑝 and 𝑞.
2. Test whether there is a permutation 𝑃 that does not diminish the variable indices occurring in 𝑁 and preserves
their order, so that there is some term 𝑇 ∈ 𝑋 with 𝑇 𝑁 𝑃 = 𝑀 . If there is no such permutation, return 𝑝.
3. Replace 𝑝 by 𝑝 − 𝑇 𝑞 𝑃 and continue with step 1.
When reducing one polynomial 𝑝 with respect to a list 𝐿 of other polynomials, there usually is a choice of order on which
the efficiency crucially depends. Also it helps to modify the polynomials on the list in order to simplify the basic reduction
steps.
The preparation of 𝐿 may be expensive. Hence, if the same list is used many times then it is reasonable to perform the
preparation only once. This is the background of SymmetricReductionStrategy.
Our current strategy is to keep the number of terms in the polynomials as small as possible. For this, we sort 𝐿 byincreasing number of terms. If several elements of 𝐿 allow for a reduction of 𝑝, we choose the one with the smallest
number of terms. Later on, it should be possible to implement further strategies for choice.
When adding a new polynomial 𝑞 to 𝐿, we first reduce 𝑞 with respect to 𝐿. Then, we test heuristically whether it ispossible to reduce the number of terms of the elements of 𝐿 by reduction modulo 𝑞. That way, we see best chances tokeep the number of terms in intermediate reduction steps relatively small.
EXAMPLES:First, we create an infinite polynomial ring and one of its elements:
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: p = y[1]*y[3] + y[1]^2*x[3]>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_ngens(2)>>> p = y[Integer(1)]*y[Integer(3)] + y[Integer(1)]**Integer(2)*x[Integer(3)]We want to symmetrically reduce it by another polynomial. So, we put this other polynomial into a list and create a
Symmetric Reduction Strategy object:
sage: from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy
sage: S = SymmetricReductionStrategy(X, [y[2]^2*x[1]])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_1*y_2^2
sage: S.reduce(p)x_3*y_1^2 + y_3*y_1>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import SymmetricReductionStrategy>>> S = SymmetricReductionStrategy(X, [y[Integer(2)]**Integer(2)*x[Integer(1)]])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_1*y_2^2>>> S.reduce(p)x_3*y_1^2 + y_3*y_1

The preceding is correct, since any permutation that turns y[2]^2*x[1] into a factor of y[1]^2*x[3] interchanges
the variable indices 1 and 2 – which is not allowed in a symmetric reduction. However, reduction by y[1]^2*x[2]works, since one can change variable index 1 into 2 and 2 into 3. So, we add this to S:

6.4. Symmetric Reduction of Infinite Polynomials

1037

Polynomials, Release 10.4

sage: S.add_generator(y[1]^2*x[2])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_2*y_1^2,
x_1*y_2^2
sage: S.reduce(p)˓→needs sage.combinat
y_3*y_1#␣>>> from sage.all import *>>> S.add_generator(y[Integer(1)]**Integer(2)*x[Integer(2)])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_2*y_1^2,
x_1*y_2^2>>> S.reduce(p)˓→needs sage.combinat
y_3*y_1#␣The next example shows that tail reduction is not done, unless it is explicitly advised:sage: S.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1])˓→needs sage.combinat
x_3 + 2*x_2*y_1^2 + 3*x_1*y_2^2
sage: S.tailreduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1])˓→needs sage.combinat
x_3

#␣

#␣

>>> from sage.all import *>>> S.reduce(x[Integer(3)] + Integer(2)*x[Integer(2)]*y[Integer(1)]**Integer(2) +␣˓→Integer(3)*y[Integer(2)]**Integer(2)*x[Integer(1)])˓→# needs sage.combinat
x_3 + 2*x_2*y_1^2 + 3*x_1*y_2^2>>> S.tailreduce(x[Integer(3)] + Integer(2)*x[Integer(2)]*y[Integer(1)]**Integer(2) +␣˓→Integer(3)*y[Integer(2)]**Integer(2)*x[Integer(1)])#␣˓→needs sage.combinat
x_3

However, it is possible to ask for tailreduction already when the Symmetric Reduction Strategy is created:sage: S2 = SymmetricReductionStrategy(X, [y[2]^2*x[1],y[1]^2*x[2]], tailreduce=True)
sage: S2
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_2*y_1^2,
x_1*y_2^2with tailreduction
sage: S2.reduce(x[3] + 2*x[2]*y[1]^2 + 3*y[2]^2*x[1])#␣˓→needs sage.combinat
x_3>>> from sage.all import *>>> S2 = SymmetricReductionStrategy(X, [y[Integer(2)]**Integer(2)*x[Integer(1)],˓→y[Integer(1)]**Integer(2)*x[Integer(2)]], tailreduce=True)(continues on next page)

1038

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> S2Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_2*y_1^2,
x_1*y_2^2with tailreduction>>> S2.reduce(x[Integer(3)] + Integer(2)*x[Integer(2)]*y[Integer(1)]**Integer(2) +␣˓→Integer(3)*y[Integer(2)]**Integer(2)*x[Integer(1)])#␣˓→needs sage.combinat
x_3class sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy
Bases: object
A framework for efficient symmetric reduction of InfinitePolynomial, see infinite_polynomial_element.
INPUT:• Parent – an Infinite Polynomial Ring, see infinite_polynomial_element.
• L – (list, default the empty list) List of elements of Parent with respect to which will be reduced.
• good_input – (bool, default None) If this optional parameter is true, it is assumed that each element of
L is symmetrically reduced with respect to the previous elements of L.
EXAMPLES:
sage: X.<y> = InfinitePolynomialRing(QQ)
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]], good_
˓→input=True)
sage: S.reduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1])y_3 + 3*y_2^2*y_1 + 2*y_2*y_1^2
sage: S.tailreduce(y[3] + 2*y[2]*y[1]^2 + 3*y[2]^2*y[1])˓→needs sage.combinaty_3#␣>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( y ,)); (y,) = X._first_ngens(1)>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> S = SymmetricReductionStrategy(X, [y[Integer(2)]**Integer(2)*y[Integer(1)],˓→y[Integer(1)]**Integer(2)*y[Integer(2)]], good_input=True)>>> S.reduce(y[Integer(3)] + Integer(2)*y[Integer(2)]*y[Integer(1)]**Integer(2) +␣˓→Integer(3)*y[Integer(2)]**Integer(2)*y[Integer(1)])
y_3 + 3*y_2^2*y_1 + 2*y_2*y_1^2>>> S.tailreduce(y[Integer(3)] +␣˓→Integer(2)*y[Integer(2)]*y[Integer(1)]**Integer(2) +␣˓→Integer(3)*y[Integer(2)]**Integer(2)*y[Integer(1)])#␣˓→needs sage.combinat
y_3

add_generator(p, good_input=None)
Add another polynomial to self.
INPUT:

6.4. Symmetric Reduction of Infinite Polynomials1039

Polynomials, Release 10.4

• p – An element of the underlying infinite polynomial ring.
• good_input – (bool, default None) If True, it is assumed that p is reduced with respect to self.
Otherwise, this reduction will be done first (which may cost some time).
Note: Previously added polynomials may be modified. All input is prepared in view of an efficient symmetric
reduction.
EXAMPLES:
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: S = SymmetricReductionStrategy(X)sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field
sage: S.add_generator(y[3] + y[1]*(x[3]+x[1]))sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_3*y_1 + x_1*y_1 + y_3>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> S = SymmetricReductionStrategy(X)>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field>>> S.add_generator(y[Integer(3)] +␣˓→y[Integer(1)]*(x[Integer(3)]+x[Integer(1)]))>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
x_3*y_1 + x_1*y_1 + y_3

Note that the first added polynomial will be simplified when adding a suitable second polynomial:
sage: S.add_generator(x[2] + x[1])˓→needs sage.combinat
sage: S˓→needs sage.combinat
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_2 + x_1>>> from sage.all import *>>> S.add_generator(x[Integer(2)] + x[Integer(1)])˓→# needs sage.combinat>>> S
˓→needs sage.combinat
Symmetric Reduction Strategy in

#␣
#␣

␣
#␣

(continues on next page)1040

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)

Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_2 + x_1

By default, reduction is applied to any newly added polynomial. This can be avoided by specifying the optionalparameter ‘good_input’:sage: # needs sage.combinat
sage: S.add_generator(y[2] + y[1]*x[2])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_1*y_1 - y_2,
x_2 + x_1
sage: S.reduce(x[3] + x[2])-2*x_1
sage: S.add_generator(x[3] + x[2], good_input=True)
sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_3 + x_2,
x_1*y_1 - y_2,
x_2 + x_1>>> from sage.all import *>>> # needs sage.combinat>>> S.add_generator(y[Integer(2)] + y[Integer(1)]*x[Integer(2)])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_1*y_1 - y_2,
x_2 + x_1>>> S.reduce(x[Integer(3)] + x[Integer(2)])-2*x_1>>> S.add_generator(x[Integer(3)] + x[Integer(2)], good_input=True)>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3,
x_3 + x_2,
x_1*y_1 - y_2,
x_2 + x_1

In the previous example, x[3] + x[2] is added without being reduced to zero.
gens()
Return the list of Infinite Polynomials modulo which self reduces.
EXAMPLES:
sage: X.<y> = InfinitePolynomialRing(QQ)
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]])(continues on next page)

6.4. Symmetric Reduction of Infinite Polynomials

1041

Polynomials, Release 10.4

(continued from previous page)

sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1
sage: S.gens()[y_2*y_1^2, y_2^2*y_1]>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( y ,)); (y,) = X._first_ngens(1)>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> S = SymmetricReductionStrategy(X,␣˓→[y[Integer(2)]**Integer(2)*y[Integer(1)],˓→y[Integer(1)]**Integer(2)*y[Integer(2)]])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1>>> S.gens()[y_2*y_1^2, y_2^2*y_1]

reduce(p, notail=False, report=None)
Symmetric reduction of an infinite polynomial.
INPUT:• p – an element of the underlying infinite polynomial ring.
• notail – (bool, default False) If True, tail reduction is avoided (but there is no guarantee that there
will be no tail reduction at all).
• report – (object, default None) If not None, print information on the progress of the computation.
OUTPUT:
Reduction of p with respect to self.
Note: If tail reduction shall be forced, use tailreduce().
EXAMPLES:
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: S = SymmetricReductionStrategy(X, [y[3]], tailreduce=True)
sage: S.reduce(y[4]*x[1] + y[1]*x[4])x_4*y_1
sage: S.reduce(y[4]*x[1] + y[1]*x[4], notail=True)
x_4*y_1 + x_1*y_4>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_(continues on next page)1042

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)ngens(2)>>> S = SymmetricReductionStrategy(X, [y[Integer(3)]], tailreduce=True)>>> S.reduce(y[Integer(4)]*x[Integer(1)] + y[Integer(1)]*x[Integer(4)])
x_4*y_1>>> S.reduce(y[Integer(4)]*x[Integer(1)] + y[Integer(1)]*x[Integer(4)],␣
˓→notail=True)
x_4*y_1 + x_1*y_4
˓→Last, we demonstrate the report option:
sage: S = SymmetricReductionStrategy(X, [x[2] + y[1],....:x[2]*y[3] + x[1]*y[2] + y[4],....:y[3] + y[2]])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3 + y_2,
x_2 + y_1,
x_1*y_2 + y_4 - y_3*y_1
sage: S.reduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True):::>
x_1*y_1 + y_4 - y_3*y_1 - y_1>>> from sage.all import *>>> S = SymmetricReductionStrategy(X, [x[Integer(2)] + y[Integer(1)],...
x[Integer(2)]*y[Integer(3)] +␣˓→x[Integer(1)]*y[Integer(2)] + y[Integer(4)],...
y[Integer(3)] + y[Integer(2)]])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3 + y_2,
x_2 + y_1,
x_1*y_2 + y_4 - y_3*y_1>>> S.reduce(x[Integer(3)] + x[Integer(1)]*y[Integer(3)] +␣˓→x[Integer(1)]*y[Integer(1)], report=True):::>
x_1*y_1 + y_4 - y_3*y_1 - y_1

Each ‘:’ indicates that one reduction of the leading monomial was performed. Eventually, the ‘>’ indicatesthat the computation is finished.
reset()
Remove all polynomials from self.
EXAMPLES:
sage: X.<y> = InfinitePolynomialRing(QQ)
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1
sage: S.reset()(continues on next page)

6.4. Symmetric Reduction of Infinite Polynomials1043

Polynomials, Release 10.4

(continued from previous page)

sage: S
Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational␣
˓→Field>>> from sage.all import *>>> X = InfinitePolynomialRing(QQ, names=( y ,)); (y,) = X._first_ngens(1)>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> S = SymmetricReductionStrategy(X,␣˓→[y[Integer(2)]**Integer(2)*y[Integer(1)],˓→y[Integer(1)]**Integer(2)*y[Integer(2)]])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1>>> S.reset()>>> S
Symmetric Reduction Strategy in Infinite polynomial ring in y over Rational␣
˓→Field

setgens(L)Define the list of Infinite Polynomials modulo which self reduces.
INPUT:• L – a list of elements of the underlying infinite polynomial ring.
Note: It is not tested if L is a good input. That method simply assigns a copy of L to the generators of self.
EXAMPLES:
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: X.<y> = InfinitePolynomialRing(QQ)
sage: S = SymmetricReductionStrategy(X, [y[2]^2*y[1],y[1]^2*y[2]])sage: R = SymmetricReductionStrategy(X)sage: R.setgens(S.gens())
sage: R
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1
sage: R.gens() is S.gens()
False
sage: R.gens() == S.gens()True>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> X = InfinitePolynomialRing(QQ, names=( y ,)); (y,) = X._first_ngens(1)>>> S = SymmetricReductionStrategy(X,␣˓→[y[Integer(2)]**Integer(2)*y[Integer(1)],˓→y[Integer(1)]**Integer(2)*y[Integer(2)]])(continues on next page)1044

Chapter 6. Infinite Polynomial Rings

Polynomials, Release 10.4

(continued from previous page)>>> R = SymmetricReductionStrategy(X)>>> R.setgens(S.gens())>>> R
Symmetric Reduction Strategy in
Infinite polynomial ring in y over Rational Field, modulo
y_2*y_1^2,
y_2^2*y_1>>> R.gens() is S.gens()
False>>> R.gens() == S.gens()
True

tailreduce(p, report=None)
Symmetric reduction of an infinite polynomial, with forced tail reduction.
INPUT:• p – an element of the underlying infinite polynomial ring.
• report – (object, default None) If not None, print information on the progress of the computation.
OUTPUT:
Reduction (including the non-leading elements) of p with respect to self.
EXAMPLES:
sage: from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy
sage: X.<x,y> = InfinitePolynomialRing(QQ)
sage: S = SymmetricReductionStrategy(X, [y[3]])sage: S.reduce(y[4]*x[1] + y[1]*x[4])x_4*y_1 + x_1*y_4
sage: S.tailreduce(y[4]*x[1] + y[1]*x[4])˓→needs sage.combinat
x_4*y_1#␣>>> from sage.all import *>>> from sage.rings.polynomial.symmetric_reduction import␣
˓→SymmetricReductionStrategy>>> X = InfinitePolynomialRing(QQ, names=( x , y ,)); (x, y,) = X._first_
˓→ngens(2)>>> S = SymmetricReductionStrategy(X, [y[Integer(3)]])>>> S.reduce(y[Integer(4)]*x[Integer(1)] + y[Integer(1)]*x[Integer(4)])
x_4*y_1 + x_1*y_4>>> S.tailreduce(y[Integer(4)]*x[Integer(1)] + y[Integer(1)]*x[Integer(4)])˓→# needs sage.combinat
x_4*y_1

␣Last, we demonstrate the ‘report’ option:
sage: S = SymmetricReductionStrategy(X, [x[2] + y[1],....:x[2]*x[3] + x[1]*y[2] + y[4],....:y[3] + y[2]])sage: S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3 + y_2,
(continues on next page)

6.4. Symmetric Reduction of Infinite Polynomials

1045

Polynomials, Release 10.4

(continued from previous page)

x_2 + y_1,
x_1*y_2 + y_4 + y_1^2
sage: S.tailreduce(x[3] + x[1]*y[3] + x[1]*y[1], report=True)
˓→needs sage.combinat
T[3]:::>
T[3]:>
x_1*y_1 - y_2 + y_1^2 - y_1#␣>>> from sage.all import *>>> S = SymmetricReductionStrategy(X, [x[Integer(2)] + y[Integer(1)],...
x[Integer(2)]*x[Integer(3)] +␣˓→x[Integer(1)]*y[Integer(2)] + y[Integer(4)],...
y[Integer(3)] + y[Integer(2)]])>>> S
Symmetric Reduction Strategy in
Infinite polynomial ring in x, y over Rational Field, modulo
y_3 + y_2,
x_2 + y_1,
x_1*y_2 + y_4 + y_1^2>>> S.tailreduce(x[Integer(3)] + x[Integer(1)]*y[Integer(3)] +␣˓→x[Integer(1)]*y[Integer(1)], report=True)# needs sage.
˓→combinat
T[3]:::>
T[3]:>
x_1*y_1 - y_2 + y_1^2 - y_1

The protocol means the following.
• ‘T[3]’ means that we currently do tail reduction for a polynomial with three terms.
• ‘:::>’ means that there were three reductions of leading terms.
• The tail of the result of the preceding reduction still has three terms. One reduction of leading terms
was possible, and then the final result was obtained.

1046

Chapter 6. Infinite Polynomial Rings

CHAPTERSEVEN

BOOLEAN POLYNOMIALS

1047

Polynomials, Release 10.4

1048

Chapter 7. Boolean Polynomials

CHAPTEREIGHT

INDICES AND TABLES• Index• Module Index• Search Page

1049

Polynomials, Release 10.4

1050

Chapter 8. Indices and Tables

PYTHON MODULE INDEXrsage.rings.polynomial.multi_polynomial_sequence, 690
sage.rings.fraction_field, 913
sage.rings.polynomial.omega,981
sage.rings.fraction_field_element, 923
sage.rings.polynomial.padics.polynosage.rings.fraction_field_FpT, 931
mial_padic, 313
sage.rings.invariants.invariant_thesage.rings.polynomial.padics.polyory, 813
nomial_padic_capped_relasage.rings.invariants.reconstruction,
tive_dense, 319
884
sage.rings.polynomial.padics.polynosage.rings.monomials, 812
mial_padic_flat, 329
sage.rings.polynomial.complex_roots, 382
sage.rings.polynomial.pbori.pbori,??
sage.rings.polynomial.convolution, 451
sage.rings.polynomial.polydict,778
sage.rings.polynomial.cyclotomic, 452
sage.rings.polynomial.polynomial_comsage.rings.polynomial.flatten, 807
piled, 435
sage.rings.polynomial.hilbert, 805
sage.rings.polynomial.polynomial_elesage.rings.polynomial.ideal, 387
ment, 54
sage.rings.polynomial.infinite_polynosage.rings.polynomial.polynomial_elemial_element, 1005
ment_generic, 207
sage.rings.polynomial.infinite_polynosage.rings.polynomial.polynomial_fatemial_ring, 989
man, 436
sage.rings.polynomial.integer_valsage.rings.polynomial.polynomial_gf2x,
ued_polynomials, 436
223
sage.rings.polynomial.laurent_polynosage.rings.polynomial.polynomial_intemial, 962
ger_dense_flint, 234
sage.rings.polynomial.laurent_polynosage.rings.polynomial.polynomial_intemial_ring, 954
ger_dense_ntl, 248
sage.rings.polynomial.laurent_polynosage.rings.polynomial.polynomial_ring_base, 945
mial_modn_dense_ntl, 289
sage.rings.polynomial.msolve, 776
sage.rings.polynomial.polynomial_numsage.rings.polynomial.multi_polynober_field, 230
mial, 515
sage.rings.polynomial.polynomial_quosage.rings.polynomial.multi_polynotient_ring, 389
mial_element, 565
sage.rings.polynomial.polynomial_quosage.rings.polynomial.multi_polynotient_ring_element, 426
mial_ideal, 596
sage.rings.polynomial.polynomial_rasage.rings.polynomial.multi_polynotional_flint, 257
mial_ideal_libsingular, 774
sage.rings.polynomial.polynosage.rings.polynomial.multi_polynomial_real_mpfr_dense, 307
mial_libsingular, 720
sage.rings.polynomial.polynomial_ring,sage.rings.polynomial.multi_polyno15
mial_ring, 559
sage.rings.polynomial.polynosage.rings.polynomial.multi_polynomial_ring_constructor, 1
mial_ring_base, 493
1051

Polynomials, Release 10.4

sage.rings.polynomial.polynomial_ring_homomorphism, 52
sage.rings.polynomial.polynomial_singular_interface, 312
sage.rings.polynomial.polynomial_zmod_flint, 276
sage.rings.polynomial.polynomial_zz_pex, 329
sage.rings.polynomial.real_roots, 337
sage.rings.polynomial.refine_root, 386
sage.rings.polynomial.symmetric_ideal,
1021
sage.rings.polynomial.symmetric_reduction, 1036
sage.rings.polynomial.term_order, 457
sage.rings.polynomial.toy_buchberger,891
sage.rings.polynomial.toy_d_basis, 905
sage.rings.polynomial.toy_variety, 900

1052

Python Module Index

INDEX

Non-alphabetical_add_()(sage.rings.polynomial.polynomial_element.Polynomial method), 55_add_()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 234_add_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_add_()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),257_add_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 280_lmul_()(sage.rings.polynomial.polynomial_element.Polynomial method), 56_lmul_()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 235_lmul_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_lmul_()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),257_lmul_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 281_mul_()(sage.rings.polynomial.polynomial_element.Polynomial method), 57_mul_()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 235_mul_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_mul_()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),258_mul_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint

method), 282_mul_trunc_() (sage.rings.polynomial.polynomial_element.Polynomial method), 57_mul_trunc_() (sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 236_mul_trunc_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_mul_trunc_() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method),258_mul_trunc_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 283_rmul_()(sage.rings.polynomial.polynomial_element.Polynomial method), 56_rmul_()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 235_rmul_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_rmul_()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),258_rmul_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 282_sub_()(sage.rings.polynomial.polynomial_element.Polynomial method), 56_sub_()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 234_sub_()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 298_sub_()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),257_sub_()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint

1053

Polynomials, Release 10.4

method), 281

A
A_invariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 824
a_realization() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing
method), 451
abc_pd (class in sage.rings.polynomial.polynomial_compiled), 436
adams_operator()(sage.rings.polynomial.polynomial_element.Polynomial method), 58
adams_operator_on_roots() (sage.rings.polynomial.polynomial_element.Polynomial method),58
add_bigoh() (sage.rings.polynomial.polynomial_element.Polynomial method), 59
add_generator()(sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy
method), 1039
add_m_mul_q()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 731
add_pd (class in sage.rings.polynomial.polynomial_compiled), 436
algebra_generators() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ParentMethods
method),439
algebraic_dependence()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 699
AlgebraicForm (class in sage.rings.invariants.invariant_theory), 815
all_done()(sage.rings.polynomial.real_roots.ocean
method), 364
all_roots_in_interval()(sage.rings.polynomial.polynomial_element.Polynomial method),60
alpha_covariant()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 829
ambient()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 406
any_irreducible_factor() (sage.rings.polynomial.polynomial_element.Polynomial method),60
any_root()(sage.rings.polynomial.polynomial_element.Polynomial method), 63
apply_map() (sage.rings.polynomial.polydict.PolyDict
method), 789
approx_bp() (sage.rings.polynomial.real_roots.ocean
method), 3641054

args() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 515
args() (sage.rings.polynomial.polynomial_element.Polynomial method), 65
arithmetic_invariants()(sage.rings.invariants.invariant_theory.BinaryQuintic
method),829
as_float()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial_float method), 352
as_float()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer
method),355
as_QuadraticForm() (sage.rings.invariants.invariant_theory.QuadraticForm method), 855
associated_primes()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 635

B
B (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing attribute), 437
B_invariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 825
base_extend() (sage.rings.polynomial.polynomial_element.Polynomial method), 65
base_extend()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),33
base_field() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_field
method), 399
base_ring()(sage.rings.fraction_field.FractionField_generic method), 918
base_ring() (sage.rings.polynomial.polynomial_element.Polynomial method), 66
base_ring() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 406
basis(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal property), 603
basis_is_groebner()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 636
bateman_bound() (in module sage.rings.polynomial.cyclotomic), 452
bernstein_down() (in module sage.rings.polynomial.real_roots), 337
bernstein_expand() (in module sage.rings.polynomial.real_roots), 338
bernstein_polynomial()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ar method), 339
bernstein_polynomial()(sage.rings.polynomial.real_roots.bernstein_polynomial_facIndex

Polynomials, Release 10.4

tory_intlist method), 340
bernstein_polynomial()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ratlist method), 341
bernstein_polynomial_factory(classin
sage.rings.polynomial.real_roots), 338
bernstein_polynomial_factory_ar (class insage.rings.polynomial.real_roots), 339
bernstein_polynomial_factory_intlist(class in sage.rings.polynomial.real_roots), 340
bernstein_polynomial_factory_ratlist(class in sage.rings.polynomial.real_roots), 341
bernstein_up() (in module sage.rings.polynomial.real_roots), 342
beta_covariant()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 830
binary_cubic_coefficients_from_invariants() (in module sage.rings.invariants.reconstruction), 884
binary_form_from_invariants()(sage.rings.invariants.invariant_theory.InvariantTheoryFactory method), 843
binary_pd (class in sage.rings.polynomial.polynomial_compiled), 436
binary_quadratic() (sage.rings.invariants.invariant_theory.InvariantTheoryFactory
method),846
binary_quadratic_coefficients_from_invariants() (in module sage.rings.invariants.reconstruction), 885
binary_quartic()(sage.rings.invariants.invariant_theory.InvariantTheoryFactory
method),846
binary_quintic()(sage.rings.invariants.invariant_theory.InvariantTheoryFactory
method),847
binary_quintic_coefficients_from_invariants() (in module sage.rings.invariants.reconstruction), 886
BinaryQuartic (class in sage.rings.invariants.invariant_theory), 819
BinaryQuintic (class in sage.rings.invariants.invariant_theory), 824
bitsize_doctest() (in module sage.rings.polynomial.real_roots), 342
blocks() (sage.rings.polynomial.term_order.TermOrdermethod), 466
BooleanPolynomialRing_base(classin
sage.rings.polynomial.multi_polynomial_ring_base), 493
BooleanPolynomialRing_constructor()(inmodulesage.rings.polynomial.polynomial_ring_constructor), 1
bp_done()(sage.rings.polynomial.real_roots.island
Indexmethod), 360
buchberger()(inmodulesage.rings.polynomial.toy_buchberger), 896
buchberger_improved()(inmodulesage.rings.polynomial.toy_buchberger), 896

C
C_invariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 826
can_convert_to_singular()(inmodulesage.rings.polynomial.polynomial_singular_interface), 312
canonical_form()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 831
cardinality()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 407
change_ring()(sage.rings.polynomial.ideal.Ideal_1poly_field method), 387
change_ring() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 945
change_ring() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial method), 962
change_ring() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 603
change_ring()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 494
change_ring() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 515
change_ring() (sage.rings.polynomial.polynomial_element.Polynomial method), 66
change_ring()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 307
change_ring()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),34change_var()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),34change_variable_name()(sage.rings.polynomial.polynomial_element.Polynomial method),67
characteristic() (sage.rings.fraction_field.FractionField_generic method), 918
characteristic()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 999
characteristic()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 946

1055

Polynomials, Release 10.4

characteristic()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 495
characteristic()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 408
characteristic()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),34
charpoly() (sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 428
cl_maximum_root() (in module sage.rings.polynomial.real_roots), 342
cl_maximum_root_first_lambda() (in module
sage.rings.polynomial.real_roots), 343
cl_maximum_root_local_max() (in module
sage.rings.polynomial.real_roots), 343
class_group()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 408
class_number() (sage.rings.fraction_field.FractionField_1poly_field method), 916
clebsch_invariants() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 832
coeff_pd (class in sage.rings.polynomial.polynomial_compiled), 436
coefficient() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1008
coefficient() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),567
coefficient()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 731
coefficient() (sage.rings.polynomial.polydict.PolyDict method), 790
coefficient_matrix() (in module sage.rings.polynomial.toy_variety), 900
coefficient_matrix()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 701
coefficients() (sage.rings.invariants.invariant_theory.AlgebraicForm method), 816
coefficients() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method),965
coefficients() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 733
coefficients() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 517
coefficients() (sage.rings.polynomial.polydict.PolyDict method), 790
1056

coefficients()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse method), 215
coefficients()(sage.rings.polynomial.polynomial_element.Polynomial method), 67
coefficients_monomials() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 702
coefficients_monomials() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2 method), 713
coeffs() (sage.rings.invariants.invariant_theory.BinaryQuartic method), 820
coeffs() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 833
coeffs()(sage.rings.invariants.invariant_theory.QuadraticForm method), 855
coeffs()(sage.rings.invariants.invariant_theory.TernaryCubic method), 865
coeffs()(sage.rings.invariants.invariant_theory.TernaryQuadratic method), 868
coeffs_bitsize()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ar method), 340
coeffs_bitsize()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory_intlist method), 341
coeffs_bitsize()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory_ratlist method), 342
coerce_coefficients()(sage.rings.polynomial.polydict.PolyDict method), 790
combine_to_positives()(sage.rings.polynomial.polydict.ETuple method), 779
common_nonzero_positions() (sage.rings.polynomial.polydict.ETuple method), 779
CompiledPolynomialFunction(classin
sage.rings.polynomial.polynomial_compiled),
435
complete_primary_decomposition()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 640
completion() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 946
completion()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 495
completion()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),35
complex_embeddings()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuoIndex

Polynomials, Release 10.4

tientRing_field method), 399
complex_roots() (in module sage.rings.polynomial.complex_roots), 382
complex_roots()(sage.rings.polynomial.polynomial_element.Polynomial method), 68
compose_power()(sage.rings.polynomial.polynomial_element.Polynomial method), 68
compose_trunc()(sage.rings.polynomial.polynomial_element.Polynomial method), 69
composed_op() (sage.rings.polynomial.polynomial_element.Polynomial method), 70
connected_components()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 703
connection_graph()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 704
constant_coefficient()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method), 966
constant_coefficient()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 569
constant_coefficient()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 733
constant_coefficient()(sage.rings.polynomial.polynomial_element.Polynomial method),73
constant_coefficient()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense method), 198
ConstantPolynomialSection(classin
sage.rings.polynomial.polynomial_element),
54
construction() (sage.rings.fraction_field.FractionField_generic method), 918
construction() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_dense
method), 997
construction() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse
method), 1000
construction()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 947
construction() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 497
construction()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 412
construction()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),Index

36
construction()(sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain
method), 48
content() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ElementMethods method), 437
content()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 518
content()(sage.rings.polynomial.padics.polynomial_padic.Polynomial_padic method), 313
content()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 236
content()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 248
content_ideal() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 518
content_ideal()(sage.rings.polynomial.polynomial_element.Polynomial method), 73
context (class in sage.rings.polynomial.real_roots), 343
convolution() (in module sage.rings.polynomial.convolution), 452
covariant_conic()(sage.rings.invariants.invariant_theory.TernaryQuadratic method), 869
cover_ring() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 412
create_key()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRingFactory
method), 997
create_key() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRingFactory
method), 393
create_object()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRingFactory method), 997
create_object()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRingFactory method), 393
cyclotomic_coeffs() (in module sage.rings.polynomial.cyclotomic), 452
cyclotomic_part() (sage.rings.polynomial.polynomial_element.Polynomial method), 73
cyclotomic_polynomial()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 36
cyclotomic_value() (in module sage.rings.polynomial.cyclotomic), 454Dd_basis() (in module sage.rings.polynomial.toy_d_basis), 908
1057

Polynomials, Release 10.4

de_casteljau() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_float method), 352
de_casteljau() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method),355
de_casteljau_doublevec()(inmodulesage.rings.polynomial.real_roots), 344
de_casteljau_intvec()(inmodulesage.rings.polynomial.real_roots), 344
degree()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),966
degree() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 569
degree() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 734
degree()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),319
degree()(sage.rings.polynomial.polydict.PolyDict
method), 790
degree()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 215
degree()(sage.rings.polynomial.polynomial_element.Polynomial method), 74
degree()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense method), 198
degree()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense_inexact
method), 202
degree() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 226
degree()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 237
degree()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 249
degree()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 290
degree()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 295
degree()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 299
degree()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 413
degree()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),1058

259
degree()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 307
degree()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),277
degree()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),334
degree_lowest_rational_function()(inmodulesage.rings.polynomial.multi_polynomial_element), 595
degree_of_semi_regularity() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 604
degree_on_basis()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ParentMethods
method),439
degree_reduction_next_size() (in module
sage.rings.polynomial.real_roots), 345
degrees() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 571
degrees()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 736
delta() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element method), 447
delta_covariant()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 834
Delta_invariant()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method),872
Delta_invariant()(sage.rings.invariants.invariant_theory.TwoTernaryQuadratics
method),878
Delta_prime_invariant()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics
method), 872
Delta_prime_invariant()(sage.rings.invariants.invariant_theory.TwoTernaryQuadratics
method), 878
denom()(sage.rings.fraction_field_FpT.FpTElement
method), 932
denominator()(sage.rings.fraction_field_element.FractionFieldElement method), 923
denominator()(sage.rings.fraction_field_FpT.FpTElement method), 932
denominator() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 519
denominator() (sage.rings.polynomial.polynomial_element.Polynomial method), 75
Index

Polynomials, Release 10.4

denominator() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method),260
derivative()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method),967
derivative() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 520
derivative() (sage.rings.polynomial.polydict.PolyDict
method), 791
derivative() (sage.rings.polynomial.polynomial_element.Polynomial method), 77
derivative_at_minus_one()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element
method),447
derivative_i() (sage.rings.polynomial.polydict.PolyDict method), 792
dict() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial method), 962
dict() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method), 967
dict()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 572
dict()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod),737
dict() (sage.rings.polynomial.polydict.PolyDict method),792
dict()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 215
dict() (sage.rings.polynomial.polynomial_element.Polynomial method), 78
diff() (sage.rings.polynomial.polynomial_element.Polynomial method), 78
differentiate()(sage.rings.polynomial.polynomial_element.Polynomial method), 79
dimension()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 643
disc()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),320
disc()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 237
disc()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),260
discriminant() (sage.rings.invariants.invariant_theory.QuadraticForm method), 856
discriminant() (sage.rings.polynomial.multi_polynoIndex

mial.MPolynomial method), 522
discriminant()(sage.rings.polynomial.polynomial_element.Polynomial method), 80
discriminant()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 238
discriminant()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl method), 250
discriminant()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p
method), 293
discriminant()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 413
discriminant()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method), 261
dispersion() (sage.rings.polynomial.polynomial_element.Polynomial method), 82
dispersion_set()(sage.rings.polynomial.polynomial_element.Polynomial method), 83
divide_by_gcd()(sage.rings.polynomial.polydict.ETuple method), 779
divide_by_var()(sage.rings.polynomial.polydict.ETuple method), 780
divided_difference()(sage.rings.polynomial.polynomial_ring.PolynomialRing_field
method), 28
divides()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),968
divides()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 737
divides()(sage.rings.polynomial.polydict.ETuple
method), 780
divides()(sage.rings.polynomial.polynomial_element.Polynomial method), 84
done() (sage.rings.polynomial.real_roots.island method),360
dotprod()(sage.rings.polynomial.polydict.ETuple
method), 781
down_degree() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method),356
down_degree_iter()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method), 357
downscale()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method),357
dprod_imatrow_vec() (in module sage.rings.polynomial.real_roots), 346
1059

Polynomials, Release 10.4dual() (sage.rings.invariants.invariant_theory.Quadrat- esub() (sage.rings.polynomial.polydict.ETuple method),
icForm method), 857
785
dummy_pd (class in sage.rings.polynomial.polyno- ETuple (class in sage.rings.polynomial.polydict), 778
mial_compiled), 436
euclidean_degree()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
Emethod), 969
euclidean_degree()(sage.rings.polynomial.polynoeadd() (sage.rings.polynomial.polydict.ETuple method),
mial_element.Polynomial
method), 85
781
eadd_p()(sage.rings.polynomial.polydict.ETuple exponents() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),method), 782969
eadd_scaled() (sage.rings.polynomial.polydict.ETuple
exponents()(sage.rings.polynomial.multi_polynomethod), 783
mial_element.MPolynomial_polydict method),
EisensteinD() (sage.rings.invariants.invariant_the572
ory.BinaryQuartic method), 820(sage.rings.polynomial.multi_polynoEisensteinE() (sage.rings.invariants.invariant_the- exponents()
mial_libsingular.MPolynomial_libsingular
ory.BinaryQuartic method), 820
method), 738
Element(sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair
at- exponents() (sage.rings.polynomial.polydict.PolyDict
method), 792
tribute), 959(sage.rings.polynomial.polynomial_elElement(sage.rings.polynomial.laurent_polyno- exponents()
ement_generic.Polynomial_generic_sparse
mial_ring.LaurentPolynomialRing_univariate
method), 216
attribute), 960
Element (sage.rings.polynomial.multi_polynomial_lib- exponents() (sage.rings.polynomial.polynomial_element.Polynomial method), 85
singular.MPolynomialRing_libsingular attribute),
extend_variables() (sage.rings.polynomial.polyno726
mial_ring.PolynomialRing_general method), 36
Element(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericF
attribute), 401
element() (sage.rings.polynomial.multi_polynomial_el- F_covariant() (sage.rings.invariants.invariant_theement.MPolynomial_element method), 565
ory.TwoTernaryQuadratics method), 879
Element_hidden (sage.rings.polynomial.multi_polyno- factor() (sage.rings.fraction_field_FpT.FpTElement
mial_ring.MPolynomialRing_polydict attribute),
method), 932
560
factor()(sage.rings.polynomial.laurent_polynoelim_pol() (in module sage.rings.polynomial.toy_varimial.LaurentPolynomial_univariate
method),ety), 900
970
eliminate_linear_variables()factor() (sage.rings.polynomial.multi_polynomial_ele(sage.rings.polynomial.multi_polynomial_sement.MPolynomial_polydict method), 573
quence.PolynomialSequence_gf2
method), factor() (sage.rings.polynomial.multi_polynomial_lib714
singular.MPolynomial_libsingular method), 738
elimination_ideal()(sage.rings.polyno- factor()(sage.rings.polynomial.padics.polynomial.multi_polynomial_ideal.MPolynomimial_padic.Polynomial_padic method), 315
alIdeal_singular_repr method), 644
factor()(sage.rings.polynomial.polynomial_eleelimination_ideal()(sage.rings.polynoment.Polynomial method), 85
mial.multi_polynomial_ideal.NCPolynomialIdeal factor()(sage.rings.polynomial.polynomial_intemethod), 682
ger_dense_flint.Polynomial_integer_dense_flint
emax() (sage.rings.polynomial.polydict.ETuple method),
method), 238783
factor()(sage.rings.polynomial.polynomial_inteemin() (sage.rings.polynomial.polydict.ETuple method),
ger_dense_ntl.Polynomial_integer_dense_ntl
784
method), 250
emul() (sage.rings.polynomial.polydict.ETuple method), factor()(sage.rings.polynomial.polyno784
mial_zmod_flint.Polynomial_zmod_flint
escalar_div() (sage.rings.polynomial.polydict.ETuple
method), 283
method), 785
factor_mod()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polyno1060

Index

Polynomials, Release 10.4

mial_padic_capped_relative_dense
method),320
factor_mod() (sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 239
factor_mod() (sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 251
factor_mod() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method),262
factor_of_slope() (sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv
method), 208
factor_padic()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 239
factor_padic()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl method), 251
factor_padic()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method), 263
fcp()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 428
field_extension() (sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 429
field_extension() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_domain method), 395
find_roots() (sage.rings.polynomial.real_roots.ocean
method), 365
first() (sage.rings.invariants.invariant_theory.TwoAlgebraicForms method), 870
first_hilbert_series()(inmodulesage.rings.polynomial.hilbert), 805
flattening_morphism()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 497
flattening_morphism()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 37
FlatteningMorphism (class in sage.rings.polynomial.flatten), 807
footprint()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial
method),1009
form() (sage.rings.invariants.invariant_theory.AlgebraicForm method), 817
FormsBase (class in sage.rings.invariants.invariant_theory), 841
Fp_FpT_coerce(classin
sage.rings.fracIndextion_field_FpT), 939
FpT (class in sage.rings.fraction_field_FpT), 931
FpT_Fp_section(classin
sage.rings.fraction_field_FpT), 936
FpT_iter (class in sage.rings.fraction_field_FpT), 938
FpT_Polyring_section (class in sage.rings.fraction_field_FpT), 937
FpTElement (class in sage.rings.fraction_field_FpT),
932
fraction()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element method), 448
fraction_field()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 947
fraction_field()(sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_p
method), 23
fraction_field()(sage.rings.polynomial.polynomial_ring.PolynomialRing_field
method),30
FractionField() (in module sage.rings.fraction_field), 914
FractionField_1poly_field(classin
sage.rings.fraction_field), 916
FractionField_generic (class in sage.rings.fraction_field), 917
FractionFieldElement (class in sage.rings.fraction_field_element), 923
FractionFieldElement_1poly_field (class insage.rings.fraction_field_element), 928
FractionFieldEmbedding (class in sage.rings.fraction_field), 915
FractionFieldEmbeddingSection (class insage.rings.fraction_field), 916
FractionSpecializationMorphism (class insage.rings.polynomial.flatten), 810
free_resolution()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 645
from_fraction_field()(inmodulesage.rings.polynomial.laurent_polynomial_ring),
960
from_h_vector() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted method), 450
from_invariants()(sage.rings.invariants.invariant_theory.BinaryQuintic class method), 834
from_invariants()(sage.rings.invariants.invariant_theory.QuadraticForm class method), 857
from_ocean() (sage.rings.polynomial.real_roots.linear_map method), 360
from_ocean()(sage.rings.polynomial.real_roots.warp_map method), 381
1061

Polynomials, Release 10.4

from_polynomial()(sage.rings.polynomial.inte277
ger_valued_polynomials.IntegerValuedPolygcd() (sage.rings.polynomial.polynomial_zz_pex.PolynonomialRing.Bases.ParentMethods
method),mial_template method), 334
439
gen()
(sage.rings.fraction_field.FractionField_genericfunction_field() (sage.rings.fraction_field.Fracmethod), 919
tionField_1poly_field method), 917
gen() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 1000G
gen() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.Parentg_covariant() (sage.rings.invariants.invariant_theMethods method), 440
ory.BinaryQuartic method), 821
gen()(sage.rings.polynomial.laurent_polynogalois_group()(sage.rings.polynomial.polynomial_ring_base.LaurentPolynomialRing_genericmial_rational_flint.Polynomial_rational_flint
method), 948
method), 265
gen() (sage.rings.polynomial.multi_polynomial_libsingugalois_group_davenport_smith_test()
lar.MPolynomialRing_libsingular method), 726(sage.rings.polynomial.polynomial_ratio(sage.rings.polynomial.multi_polynonal_flint.Polynomial_rational_flint
method), gen()mial_ring_base.MPolynomialRing_base267
method), 498
gamma_covariant()(sage.rings.invariants.invarigen()(sage.rings.polynomial.polynomial_quoant_theory.BinaryQuintic method), 835
tient_ring.PolynomialQuotientRing_genericgcd()(sage.rings.polynomial.infinite_polynomial_elemethod), 414
ment.InfinitePolynomial method), 1009
gcd() (sage.rings.polynomial.laurent_polynomial.Lau- gen() (sage.rings.polynomial.polynomial_ring.PolynomialRing_general method), 37
rentPolynomial_univariate method), 970
gcd() (sage.rings.polynomial.multi_polynomial_libsingu- gen_index() (in module sage.rings.polynomial.polydict), 804
lar.MPolynomial_libsingular method), 743
gcd() (sage.rings.polynomial.multi_polynomial.MPolyno- GenDictWithBasering (class in sage.rings.polynomial.infinite_polynomial_ring), 994
mial method), 523
gcd()(sage.rings.polynomial.polynomial_ele- generic_pd (class in sage.rings.polynomial.polynomial_compiled), 436
ment_generic.Polynomial_generic_sparse
generic_power_trunc()(inmodulemethod), 216
sage.rings.polynomial.polynomial_element),
gcd() (sage.rings.polynomial.polynomial_element.Poly204
nomial method), 92
gcd() (sage.rings.polynomial.polynomial_gf2x.Polyno- gens() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.Parentmial_template method), 226
Methods method), 441
gcd()(sage.rings.polynomial.polynomial_integens()(sage.rings.polynomial.multi_polynoger_dense_flint.Polynomial_integer_dense_flint
mial_ideal.MPolynomialIdeal method), 606
method), 240
gcd()(sage.rings.polynomial.polynomial_inte- gens() (sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy method), 1041
ger_dense_ntl.Polynomial_integer_dense_ntl
gens_dict()(sage.rings.polynomial.infinite_polymethod), 252
nomial_ring.InfinitePolynomialRing_sparsegcd()(sage.rings.polynomial.polynomethod), 1000
mial_modn_dense_ntl.Polynomial_dense_mod_p
gens_dict()(sage.rings.polynomial.polynomethod), 294
mial_ring.PolynomialRing_general
method),gcd()(sage.rings.polynomial.polynomial_num38
ber_field.Polynomial_absolute_numgenus()(sage.rings.polynomial.multi_polynober_field_dense method), 232
mial_ideal.MPolynomialIdeal_singular_repr
gcd()(sage.rings.polynomial.polynomial_nummethod), 646
ber_field.Polynomial_relative_numget()(sage.rings.polynomial.polydict.PolyDict
method),ber_field_dense method), 233
793
gcd()
(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method), get_be_log() (sage.rings.polynomial.real_roots.context method), 344268
get_cparent()(sage.rings.polynomial.polynogcd()(sage.rings.polynomial.polynomial_gf2x.Polynomial_template
method), 227
mial_zmod_flint.Polynomial_template method),
1062

Index

Polynomials, Release 10.4

get_cparent()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),278
get_cparent()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),334
get_dc_log() (sage.rings.polynomial.real_roots.context method), 344
get_form() (sage.rings.invariants.invariant_theory.SeveralAlgebraicForms method), 861
get_msb_bit() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_float
method),353
get_msb_bit() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method),358
get_realfield_rndu() (in module sage.rings.polynomial.real_roots), 347
GF2X_BuildIrred_list()(inmodulesage.rings.polynomial.polynomial_gf2x), 223
GF2X_BuildRandomIrred_list() (in module
sage.rings.polynomial.polynomial_gf2x), 223
GF2X_BuildSparseIrred_list() (in module
sage.rings.polynomial.polynomial_gf2x), 223
global_height() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),573
global_height() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 744
global_height()(sage.rings.polynomial.polynomial_element.Polynomial method), 94
gpol() (in module sage.rings.polynomial.toy_d_basis),909
graded_free_resolution()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 649
gradient()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 746
gradient()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 524
gradient()(sage.rings.polynomial.polynomial_element.Polynomial method), 96
greater_tuple(sage.rings.polynomial.term_order.TermOrder property), 467
greater_tuple_block()(sage.rings.polynomial.term_order.TermOrder method), 467
greater_tuple_deglex()(sage.rings.polynomial.term_order.TermOrder method), 468
greater_tuple_degneglex() (sage.rings.polynomial.term_order.TermOrder method), 468
greater_tuple_degrevlex() (sage.rings.polynomial.term_order.TermOrder method), 469
Indexgreater_tuple_invlex()(sage.rings.polynomial.term_order.TermOrder method), 469
greater_tuple_lex()(sage.rings.polynomial.term_order.TermOrder method), 470
greater_tuple_matrix()(sage.rings.polynomial.term_order.TermOrder method), 470
greater_tuple_negdeglex() (sage.rings.polynomial.term_order.TermOrder method), 471
greater_tuple_negdegrevlex()(sage.rings.polynomial.term_order.TermOrdermethod), 471
greater_tuple_neglex()(sage.rings.polynomial.term_order.TermOrder method), 472
greater_tuple_negwdeglex() (sage.rings.polynomial.term_order.TermOrder method), 472
greater_tuple_negwdegrevlex()(sage.rings.polynomial.term_order.TermOrdermethod), 473
greater_tuple_wdeglex()(sage.rings.polynomial.term_order.TermOrder method), 474
greater_tuple_wdegrevlex() (sage.rings.polynomial.term_order.TermOrder method), 474
groebner_basis()(sage.rings.polynomial.ideal.Ideal_1poly_field method), 388
groebner_basis()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal
method), 607
groebner_basis()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 705
groebner_basis() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1025
groebner_basis_degrevlex()(inmodulesage.rings.polynomial.msolve), 776
groebner_cover()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal
method), 617
groebner_fan() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 618

Hh_covariant() (sage.rings.invariants.invariant_theory.BinaryQuartic method), 822
H_covariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 826
h_polynomial() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element method), 448
h_vector()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element method), 449
hamming_weight()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial
method),963
1063

Polynomials, Release 10.4

hamming_weight()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_element method), 566
hamming_weight()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 746
hamming_weight()(sage.rings.polynomial.polynomial_element.Polynomial method), 96
has_cyclotomic_factor()(sage.rings.polynomial.polynomial_element.Polynomial method),97
has_root()(sage.rings.polynomial.real_roots.island
method), 360
hensel_lift() (sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv method),209
hensel_lift() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method),
268
Hessian()(sage.rings.invariants.invariant_theory.TernaryCubic method), 862
hilbert_numerator()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 650
hilbert_poincare_series()(inmodulesage.rings.polynomial.hilbert), 806
hilbert_polynomial()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 651
hilbert_series()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 654
homogeneous_components() (sage.rings.polynomial.multi_polynomial.MPolynomial method),525
homogeneous_symmetric_function() (in module sage.rings.polynomial.omega), 987
homogenize() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 618
homogenize() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 525
homogenize() (sage.rings.polynomial.polydict.PolyDict
method), 793
homogenize() (sage.rings.polynomial.polynomial_element.Polynomial method), 98
homogenized() (sage.rings.invariants.invariant_theory.AlgebraicForm method), 817
homogenized() (sage.rings.invariants.invariant_theory.SeveralAlgebraicForms method), 861

I
i_covariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 836

1064

ideal()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 948
ideal() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method),726
ideal()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain
method), 564
ideal()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),705
Ideal_1poly_field (class in sage.rings.polynomial.ideal), 387
in_subalgebra() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 747
increase_precision()(sage.rings.polynomial.real_roots.ocean method), 365
InfiniteGenDict (class in sage.rings.polynomial.infinite_polynomial_ring), 995
InfinitePolynomial (class in sage.rings.polynomial.infinite_polynomial_element), 1006
InfinitePolynomial_dense(classin
sage.rings.polynomial.infinite_polynomial_element), 1020
InfinitePolynomial_sparse(classin
sage.rings.polynomial.infinite_polynomial_element), 1020
InfinitePolynomialGen (class in sage.rings.polynomial.infinite_polynomial_ring), 995
InfinitePolynomialRing_dense(classin
sage.rings.polynomial.infinite_polynomial_ring),
997
InfinitePolynomialRing_sparse (class insage.rings.polynomial.infinite_polynomial_ring),
998
InfinitePolynomialRingFactory (class insage.rings.polynomial.infinite_polynomial_ring),
996
inhomogeneous_quadratic_form()(sage.rings.invariants.invariant_theory.InvariantTheoryFactory method), 848
int_list()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 291
int_list()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 299
INTEGER_LIMIT (sage.rings.fraction_field_FpT.FpT attribute), 931
IntegerValuedPolynomialRing(classin
sage.rings.polynomial.integer_valued_polynomials), 436
Index

Polynomials, Release 10.4

IntegerValuedPolynomialRing.Bases (classin sage.rings.polynomial.integer_valued_polynomials), 437
IntegerValuedPolynomialRing.Bases.ElementMethods (class in sage.rings.polynomial.integer_valued_polynomials), 437
IntegerValuedPolynomialRing.Bases.ParentMethods (class in sage.rings.polynomial.integer_valued_polynomials), 439
IntegerValuedPolynomialRing.Binomial(class in sage.rings.polynomial.integer_valued_polynomials), 442
IntegerValuedPolynomialRing.Binomial.Element (class in sage.rings.polynomial.integer_valued_polynomials), 444
IntegerValuedPolynomialRing.Shifted(class in sage.rings.polynomial.integer_valued_polynomials), 445
IntegerValuedPolynomialRing.Shifted.Element(classin
sage.rings.polynomial.integer_valued_polynomials), 447
integral()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),970
integral()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),575
integral()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 748
integral()(sage.rings.polynomial.polydict.PolyDict
method), 793
integral()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 217
integral()(sage.rings.polynomial.polynomial_element.Polynomial method), 99
integral()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 307
integral_closure()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 655
integral_i() (sage.rings.polynomial.polydict.PolyDict
method), 794
inter_reduction() (in module sage.rings.polynomial.toy_buchberger), 897
interpolation() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 498
interred_libsingular()(inmodulesage.rings.polynomial.multi_polynomial_ideal_libsingular), 775
Indexinterreduced_basis()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 655
interreduced_basis() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1029
interreduction() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1030
intersection() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 657
interval_bernstein_polynomial (class insage.rings.polynomial.real_roots), 347
interval_bernstein_polynomial_float(class in sage.rings.polynomial.real_roots), 351
interval_bernstein_polynomial_integer(class in sage.rings.polynomial.real_roots), 354
interval_roots() (in module sage.rings.polynomial.complex_roots), 385
intervals_disjoint() (in module sage.rings.polynomial.complex_roots), 386
intvec_to_doublevec()(inmodulesage.rings.polynomial.real_roots), 358
invariants()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 836
invariants()(sage.rings.invariants.invariant_theory.QuadraticForm method), 858
InvariantTheoryFactory (class in sage.rings.invariants.invariant_theory), 843
inverse()(sage.rings.polynomial.flatten.FlatteningMorphism method), 808
inverse_mod() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method),972
inverse_mod() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 528
inverse_mod() (sage.rings.polynomial.polynomial_element.Polynomial method), 102
inverse_of_unit()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method), 972
inverse_of_unit()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 576
inverse_of_unit()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 749
inverse_of_unit() (sage.rings.polynomial.polynomial_element.Polynomial method), 104
inverse_series_trunc()(sage.rings.polynomial.polynomial_element.Polynomial method),104
inverse_series_trunc()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 240
1065

Polynomials, Release 10.4

inverse_series_trunc()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method), 269
inverse_series_trunc()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
method), 330
irreducible_element()(sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_finite_field method), 20
irreducible_element()(sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_p method), 24
irrelevant_ideal()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 500
is_block_order() (sage.rings.polynomial.term_order.TermOrder method), 475
is_constant() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method),972
is_constant() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),576
is_constant()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 749
is_constant() (sage.rings.polynomial.polydict.ETuple
method), 786
is_constant() (sage.rings.polynomial.polydict.PolyDict method), 794
is_constant() (sage.rings.polynomial.polynomial_element.Polynomial method), 106
is_cyclotomic()(sage.rings.polynomial.polynomial_element.Polynomial method), 106
is_cyclotomic_product()(sage.rings.polynomial.polynomial_element.Polynomial method),109
is_eisenstein() (sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),320
is_exact()(sage.rings.fraction_field.FractionField_generic method), 919
is_exact()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 948
is_exact()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 500
is_exact()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),38
is_field()(sage.rings.fraction_field.FractionField_generic method), 920
1066

is_field()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse
method), 1001
is_field()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 949
is_field()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 501
is_field()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain
method), 564
is_field() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 414
is_field()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),39
is_finite()(sage.rings.fraction_field.FractionField_generic method), 920
is_finite() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 949
is_finite() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 415
is_FractionField() (in module sage.rings.fraction_field), 922
is_FractionFieldElement()(inmodulesage.rings.fraction_field_element), 929
is_gen()(sage.rings.polynomial.polynomial_element.Polynomial method), 110
is_gen() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 227
is_gen()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 295
is_gen()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 300
is_gen()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),278
is_gen()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),334
is_generator() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),577
is_generator() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 529
is_global() (sage.rings.polynomial.term_order.TermOrder method), 475
is_groebner()(sage.rings.polynomial.multi_polyIndex

Polynomials, Release 10.4

nomial_sequence.PolynomialSequence_genericmethod), 706
is_homogeneous()(sage.rings.invariants.invariant_theory.FormsBase method), 841
is_homogeneous()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 577
is_homogeneous()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal
method), 619
is_homogeneous()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 749
is_homogeneous()(sage.rings.polynomial.multi_polynomial.MPolynomial method),529
is_homogeneous()(sage.rings.polynomial.polydict.PolyDict method), 795
is_homogeneous()(sage.rings.polynomial.polynomial_element.Polynomial method), 111
is_injective() (sage.rings.fraction_field.FractionFieldEmbedding method), 915
is_injective()(sage.rings.polynomial.polynomial_element.PolynomialBaseringInjection
method), 197
is_injective()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_coercion method), 394
is_injective()(sage.rings.polynomial.polynomial_ring_homomorphism.PolynomialRingHomomorphism_from_base method), 53
is_integral()(sage.rings.fraction_field_element.FractionFieldElement_1poly_field method),928
is_integral_domain() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 1001
is_integral_domain() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 949
is_integral_domain()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 501
is_integral_domain()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict_domain method), 564
is_integral_domain()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 416
is_integral_domain()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 39
is_irreducible()(sage.rings.polynomial.polynomial_element.Polynomial method), 111
Index

is_irreducible()(sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X method), 224
is_irreducible()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method), 269
is_irreducible()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 283
is_irreducible()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
method),330
is_LaurentPolynomialRing()(inmodulesage.rings.polynomial.laurent_polynomial_ring),
961
is_linearly_dependent()(inmodulesage.rings.polynomial.toy_variety), 901
is_local()(sage.rings.polynomial.term_order.TermOrder method), 476
is_lorentzian() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 529
is_lorentzian()(sage.rings.polynomial.polynomial_element.Polynomial method), 112
is_maximal()(sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1032
is_monic()(sage.rings.polynomial.polynomial_element.Polynomial method), 113
is_monomial() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method),973
is_monomial() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),578
is_monomial()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 750
is_monomial() (sage.rings.polynomial.polynomial_element.Polynomial method), 114
is_MPolynomial() (in module sage.rings.polynomial.multi_polynomial), 558
is_MPolynomialIdeal()(inmodulesage.rings.polynomial.multi_polynomial_ideal),689
is_MPolynomialRing() (in module sage.rings.polynomial.multi_polynomial_ring_base), 514
is_multiple_of()(sage.rings.polynomial.polydict.ETuple method), 786
is_nilpotent() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial
method),1009
is_nilpotent() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 531
is_nilpotent()(sage.rings.polynomial.polynomial_element.Polynomial method), 115
is_noetherian()(sage.rings.polynomial.in1067

Polynomials, Release 10.4

finite_polynomial_ring.InfinitePolynomialRing_sparse method), 1001
is_noetherian()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 949
is_noetherian() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 501
is_noetherian()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),39
is_one() (sage.rings.fraction_field_element.FractionFieldElement method), 923
is_one()(sage.rings.polynomial.polynomial_element.Polynomial method), 115
is_one() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 227
is_one()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 241
is_one()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),270
is_one()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),278
is_one()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),335
is_Polynomial() (in module sage.rings.polynomial.polynomial_element), 204
is_PolynomialQuotientRing()(inmodulesage.rings.polynomial.polynomial_quotient_ring), 425
is_PolynomialRing() (in module sage.rings.polynomial.polynomial_ring), 50
is_PolynomialSequence()(inmodulesage.rings.polynomial.multi_polynomial_sequence), 720
is_prime()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 658
is_primitive()(sage.rings.polynomial.polynomial_element.Polynomial method), 116
is_real_rooted()(sage.rings.polynomial.polynomial_element.Polynomial method), 119
is_sparse()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),39
is_square() (sage.rings.fraction_field_element.FractionFieldElement method), 924
is_square() (sage.rings.fraction_field_FpT.FpTElement method), 932
is_square() (sage.rings.polynomial.laurent_polyno1068

mial.LaurentPolynomial_univariate
method),974
is_square()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 532
is_square() (sage.rings.polynomial.polynomial_element.Polynomial method), 119
is_squarefree() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 751
is_squarefree()(sage.rings.polynomial.polynomial_element.Polynomial method), 120
is_surjective() (sage.rings.fraction_field.FractionFieldEmbedding method), 915
is_surjective()(sage.rings.polynomial.polynomial_element.PolynomialBaseringInjection
method), 197
is_surjective()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_coercion method), 394
is_surjective()(sage.rings.polynomial.polynomial_ring_homomorphism.PolynomialRingHomomorphism_from_base method), 53
is_symmetric() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 533
is_term() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 579
is_term()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 751
is_term()(sage.rings.polynomial.polynomial_element.Polynomial method), 123
is_term()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense method), 198
is_triangular() (in module sage.rings.polynomial.toy_variety), 902
is_unique_factorization_domain()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general method), 40
is_unit()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1010
is_unit()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),975
is_unit()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 534
is_unit()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_domain
method), 212
is_unit()(sage.rings.polynomial.polynomial_element.Polynomial method), 124
is_unit()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 431
is_univariate() (sage.rings.polynomial.multi_polyIndex

Polynomials, Release 10.4

nomial_element.MPolynomial_polydict method),580
is_univariate() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 752
is_weighted_degree_order() (sage.rings.polynomial.term_order.TermOrder method), 476
is_weil_polynomial()(sage.rings.polynomial.polynomial_element.Polynomial method),124
is_zero() (sage.rings.fraction_field_element.FractionFieldElement method), 925
is_zero()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),976
is_zero()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 752
is_zero()(sage.rings.polynomial.polynomial_element.Polynomial method), 125
is_zero()(sage.rings.polynomial.polynomial_gf2x.Polynomial_template
method),227
is_zero()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 241
is_zero()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),270
is_zero()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),278
is_zero()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),335
island (class in sage.rings.polynomial.real_roots), 358
iter() (sage.rings.fraction_field_FpT.FpT method), 931
iterator_exp_coeff()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 580
iterator_exp_coeff()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 753
iterator_exp_coeff()(sage.rings.polynomial.multi_polynomial.MPolynomial method),535

J
j_covariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 837
J_covariant() (sage.rings.invariants.invariant_theory.TernaryCubic method), 863
J_covariant() (sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method), 873
Index

J_covariant() (sage.rings.invariants.invariant_theory.TwoTernaryQuadratics method), 879
jacobian_ideal()(sage.rings.polynomial.multi_polynomial.MPolynomial method),536

K
karatsuba_threshold()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 40
kbase_libsingular() (in module sage.rings.polynomial.multi_polynomial_ideal_libsingular), 775
key_basis()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse
method), 1002
krull_dimension()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 1002
krull_dimension()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 950
krull_dimension()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 502
krull_dimension()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 417
krull_dimension()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general method),40

Llagrange_polynomial()(sage.rings.polynomial.polynomial_ring.PolynomialRing_field
method), 30
latex()(sage.rings.polynomial.polydict.PolyDict
method), 795
LaurentPolynomial (class in sage.rings.polynomial.laurent_polynomial), 962
LaurentPolynomial_univariate(classin
sage.rings.polynomial.laurent_polynomial), 965
LaurentPolynomialRing()(inmodulesage.rings.polynomial.laurent_polynomial_ring),
954
LaurentPolynomialRing_generic(classin
sage.rings.polynomial.laurent_polynomial_ring_base), 945
LaurentPolynomialRing_mpair(classin
sage.rings.polynomial.laurent_polynomial_ring),
958
LaurentPolynomialRing_univariate (class insage.rings.polynomial.laurent_polynomial_ring),
960
LC() (in module sage.rings.polynomial.toy_d_basis), 908
1069

Polynomials, Release 10.4

lc()

(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1011
lc()
(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 581
lc() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 753
lc() (sage.rings.polynomial.polynomial_element.Polynomial method), 126
LCM() (in module sage.rings.polynomial.toy_buchberger),896
lcm() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 754
lcm() (sage.rings.polynomial.polynomial_element.Polynomial method), 126lcm()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 242
lcm()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 252lcm()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),271
lcmt() (sage.rings.polynomial.polydict.PolyDict method),796
leading_coefficient()(sage.rings.polynomial.polynomial_element.Polynomial method),126
less_bits() (sage.rings.polynomial.real_roots.island
method), 360
lift()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 581
lift()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod),755
lift() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 536
lift()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),321
lift()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 431
lift()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 417
linear_map (class in sage.rings.polynomial.real_roots),
360
linear_representation()(inmodulesage.rings.polynomial.toy_variety), 903
list()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),321
list() (sage.rings.polynomial.polydict.PolyDict method),796
list()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 217
list() (sage.rings.polynomial.polynomial_element.Polynomial method), 127list() (sage.rings.polynomial.polynomial_element.Polynomial_generic_dense method), 199list() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 228list()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 242
list()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 253list()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 291
list()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 296
list()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 432
list()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),271
list()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 308
list()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),279
list() (sage.rings.polynomial.polynomial_zz_pex.Polynomial_template method), 335
list() (sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX method), 331
LM() (in module sage.rings.polynomial.toy_buchberger),896
LM() (in module sage.rings.polynomial.toy_d_basis), 908
lm()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1012
lm()
(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 582
lm() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 756lm() (sage.rings.polynomial.polynomial_element.Polynomial method), 128
local_height() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),
583

1070

Index

Polynomials, Release 10.4

local_height() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 758
local_height()(sage.rings.polynomial.polynomial_element.Polynomial method), 128
local_height_arch()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 584
local_height_arch()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 759
local_height_arch() (sage.rings.polynomial.polynomial_element.Polynomial method), 129
lshift_coeffs() (sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),322
lsign()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory method), 339
LT() (in module sage.rings.polynomial.toy_buchberger),896
lt()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1012
lt()
(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 585
lt() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 759
lt() (sage.rings.polynomial.polynomial_element.Polynomial method), 130

Mmacaulay2_str()(sage.rings.polynomial.term_order.TermOrder method), 477
macaulay_resultant()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 502
macaulay_resultant()(sage.rings.polynomial.multi_polynomial.MPolynomial method),
537
MacMahonOmega() (in module sage.rings.polynomial.omega), 982
magma_str() (sage.rings.polynomial.term_order.TermOrder method), 477
make_element()(inmodulesage.rings.fraction_field_element), 930
make_element() (in module sage.rings.polynomial.polynomial_gf2x), 229
make_element() (in module sage.rings.polynomial.polynomial_modn_dense_ntl), 302
make_element() (in module sage.rings.polynomial.polynomial_zmod_flint), 289
make_element() (in module sage.rings.polynomial.polynomial_zz_pex), 337

Index

make_element_old() (in module sage.rings.fraction_field_element), 930
make_ETuple() (in module sage.rings.polynomial.polydict), 804
make_generic_polynomial()(inmodulesage.rings.polynomial.polynomial_element),
205
make_padic_poly() (in module sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense), 329
make_PolyDict() (in module sage.rings.polynomial.polydict), 804
make_PolynomialRealDense()(inmodulesage.rings.polynomial.polynomial_real_mpfr_dense), 311
map_coefficients()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial
method),963
map_coefficients()(sage.rings.polynomial.multi_polynomial.MPolynomial method),541
map_coefficients() (sage.rings.polynomial.polynomial_element.Polynomial method), 131
matrix()(sage.rings.invariants.invariant_theory.QuadraticForm method), 858
matrix()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 432
matrix() (sage.rings.polynomial.term_order.TermOrdermethod), 478
max_abs_doublevec() (in module sage.rings.polynomial.real_roots), 361
max_bitsize_intvec_doctest() (in module
sage.rings.polynomial.real_roots), 361
max_exp()(sage.rings.polynomial.polydict.PolyDict
method), 796
max_index()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial
method),1012
maximal_degree()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method), 706
maximal_order() (sage.rings.fraction_field.FractionField_1poly_field method), 917
maximum_root_first_lambda() (in module
sage.rings.polynomial.real_roots), 361
maximum_root_local_max()(inmodulesage.rings.polynomial.real_roots), 361
min_exp()(sage.rings.polynomial.polydict.PolyDict
method), 797
min_max_delta_intvec()(inmodulesage.rings.polynomial.real_roots), 362
min_max_diff_doublevec()(inmodulesage.rings.polynomial.real_roots), 362
1071

Polynomials, Release 10.4

min_max_diff_intvec()(inmodulesage.rings.polynomial.real_roots), 362
minimal_associated_primes() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 659
minpoly()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 433
minpoly_mod()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 291
minpoly_mod()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 284
minpoly_mod()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
method),331
mk_context()(inmodulesage.rings.polynomial.real_roots), 363
mk_ibpf() (in module sage.rings.polynomial.real_roots),363
mk_ibpi() (in module sage.rings.polynomial.real_roots),
363
mod() (sage.rings.polynomial.polynomial_element.Polynomial method), 132
modular_composition()(sage.rings.polynomial.polynomial_gf2x.Polynomial_GF2X
method), 225
modulesage.rings.fraction_field, 913
sage.rings.fraction_field_element,923
sage.rings.fraction_field_FpT, 931
sage.rings.invariants.invariant_theory, 813
sage.rings.invariants.reconstruction, 884
sage.rings.monomials, 812
sage.rings.polynomial.complex_roots, 382
sage.rings.polynomial.convolution,
451
sage.rings.polynomial.cyclotomic,
452
sage.rings.polynomial.flatten, 807
sage.rings.polynomial.hilbert, 805
sage.rings.polynomial.ideal, 387
sage.rings.polynomial.infinite_polynomial_element, 1005
sage.rings.polynomial.infinite_polynomial_ring, 989
sage.rings.polynomial.integer_valued_polynomials, 436
sage.rings.polynomial.lau1072

rent_polynomial, 962
sage.rings.polynomial.laurent_polynomial_ring, 954
sage.rings.polynomial.laurent_polynomial_ring_base, 945
sage.rings.polynomial.msolve, 776
sage.rings.polynomial.multi_polynomial, 515
sage.rings.polynomial.multi_polynomial_element, 565
sage.rings.polynomial.multi_polynomial_ideal, 596
sage.rings.polynomial.multi_polynomial_ideal_libsingular, 774
sage.rings.polynomial.multi_polynomial_libsingular, 720
sage.rings.polynomial.multi_polynomial_ring, 559
sage.rings.polynomial.multi_polynomial_ring_base, 493
sage.rings.polynomial.multi_polynomial_sequence, 690
sage.rings.polynomial.omega, 981
sage.rings.polynomial.padics.polynomial_padic, 313
sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense, 319
sage.rings.polynomial.padics.polynomial_padic_flat, 329
sage.rings.polynomial.polydict, 778
sage.rings.polynomial.polynomial_compiled, 435
sage.rings.polynomial.polynomial_element, 54
sage.rings.polynomial.polynomial_element_generic, 207
sage.rings.polynomial.polynomial_fateman, 436
sage.rings.polynomial.polynomial_gf2x, 223
sage.rings.polynomial.polynomial_integer_dense_flint, 234
sage.rings.polynomial.polynomial_integer_dense_ntl, 248
sage.rings.polynomial.polynomial_modn_dense_ntl, 289
sage.rings.polynomial.polynomial_number_field, 230
sage.rings.polynomial.polynomial_quotient_ring, 389
sage.rings.polynomial.polynomial_quotient_ring_element, 426
sage.rings.polynomial.polynoIndex

Polynomials, Release 10.4

mial_rational_flint, 257
sage.rings.polynomial.polynomial_real_mpfr_dense, 307
sage.rings.polynomial.polynomial_ring, 15
sage.rings.polynomial.polynomial_ring_constructor, 1
sage.rings.polynomial.polynomial_ring_homomorphism, 52
sage.rings.polynomial.polynomial_singular_interface, 312
sage.rings.polynomial.polynomial_zmod_flint, 276
sage.rings.polynomial.polynomial_zz_pex, 329
sage.rings.polynomial.real_roots,
337
sage.rings.polynomial.refine_root,386
sage.rings.polynomial.symmetric_ideal, 1021
sage.rings.polynomial.symmetric_reduction, 1036
sage.rings.polynomial.term_order,457
sage.rings.polynomial.toy_buchberger, 891
sage.rings.polynomial.toy_d_basis,905
sage.rings.polynomial.toy_variety,
900
modulus()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 418
modulus()(sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_n
method), 21
monic()(sage.rings.polynomial.polynomial_element.Polynomial method), 133
monic()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 284
monics() (sage.rings.polynomial.polynomial_ring.PolynomialRing_general method), 41
monomial()(sage.rings.polynomial.laurent_polynomial_ring.LaurentPolynomialRing_mpair
method), 959
monomial()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 506
monomial()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),42
monomial_all_divisors()(sage.rings.polynoIndex

mial.multi_polynomial_libsingular.MPolynomialRing_libsingular method), 727
monomial_all_divisors()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method), 560
monomial_coefficient()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 586
monomial_coefficient()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 760
monomial_coefficient()(sage.rings.polynomial.polydict.PolyDict method), 797
monomial_coefficient()(sage.rings.polynomial.polynomial_element.Polynomial method),134
monomial_divides()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method), 727
monomial_divides()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method), 560
monomial_exponent() (in module sage.rings.polynomial.polydict), 804
monomial_lcm() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingularmethod), 728
monomial_lcm() (sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method),561
monomial_pairwise_prime() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method), 728
monomial_pairwise_prime()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method), 561
monomial_quotient()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method), 729
monomial_quotient()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method), 562
monomial_reduce()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method), 730
monomial_reduce()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method), 563
monomial_reduction() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method), 976
monomials() (in module sage.rings.monomials), 812
monomials()(sage.rings.invariants.invariant_theory.BinaryQuartic method), 823
1073

Polynomials, Release 10.4

monomials()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 838
monomials()(sage.rings.invariants.invariant_theory.QuadraticForm method), 859
monomials()(sage.rings.invariants.invariant_theory.TernaryCubic method), 866
monomials()(sage.rings.invariants.invariant_theory.TernaryQuadratic method), 869
monomials()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),587
monomials()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 761
monomials()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_genericmethod), 707
monomials() (sage.rings.polynomial.polynomial_element.Polynomial method), 135
monomials_of_degree()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 507
more_bits() (sage.rings.polynomial.real_roots.island
method), 360
MPolynomial(classin
sage.rings.polynomial.multi_polynomial), 515
MPolynomial_element (class in sage.rings.polynomial.multi_polynomial_element), 565
MPolynomial_libsingular(classin
sage.rings.polynomial.multi_polynomial), 558
MPolynomial_libsingular(classin
sage.rings.polynomial.multi_polynomial_libsingular), 731
MPolynomial_polydict (class in sage.rings.polynomial.multi_polynomial_element), 567
MPolynomialIdeal (class in sage.rings.polynomial.multi_polynomial_ideal), 602
MPolynomialIdeal_macaulay2_repr (class insage.rings.polynomial.multi_polynomial_ideal),
633
MPolynomialIdeal_magma_repr(classin
sage.rings.polynomial.multi_polynomial_ideal),
633
MPolynomialIdeal_quotient(classin
sage.rings.polynomial.multi_polynomial_ideal),
633
MPolynomialIdeal_singular_base_repr(class in sage.rings.polynomial.multi_polynomial_ideal), 634
MPolynomialIdeal_singular_repr (class insage.rings.polynomial.multi_polynomial_ideal),
635
MPolynomialRing_base (class in sage.rings.polynomial.multi_polynomial_ring_base), 494
1074

MPolynomialRing_libsingular(classin
sage.rings.polynomial.multi_polynomial_libsingular), 723
MPolynomialRing_macaulay2_repr (class insage.rings.polynomial.multi_polynomial_ring),
559
MPolynomialRing_polydict(classin
sage.rings.polynomial.multi_polynomial_ring),
560
MPolynomialRing_polydict_domain (class insage.rings.polynomial.multi_polynomial_ring),
564
mul_pd (class in sage.rings.polynomial.polynomial_compiled), 436
multiplication_trunc()(sage.rings.polynomial.polynomial_element.Polynomial method),136

Nn_forms() (sage.rings.invariants.invariant_theory.SeveralAlgebraicForms method), 862
name()(sage.rings.polynomial.term_order.TermOrdermethod), 478
NCPolynomialIdeal (class in sage.rings.polynomial.multi_polynomial_ideal), 680
newton_polygon()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense method), 322
newton_polygon()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv
method), 209
newton_polytope()(sage.rings.polynomial.multi_polynomial.MPolynomial method),543
newton_raphson()(sage.rings.polynomial.polynomial_element.Polynomial method), 136
newton_slopes() (sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),323
newton_slopes()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv
method), 210
newton_slopes()(sage.rings.polynomial.polynomial_element.Polynomial method), 137
next()(sage.rings.fraction_field_FpT.FpTElement
method), 933
next()(sage.rings.polynomial.infinite_polynomial_ring.GenDictWithBasering
method),994
ngens() (sage.rings.fraction_field.FractionField_genericmethod), 920
ngens()(sage.rings.polynomial.infinite_polynoIndex

Polynomials, Release 10.4

mial_ring.InfinitePolynomialRing_sparse
method), 1002
ngens()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 950
ngens() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomialRing_libsingular method),730
ngens()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 508
ngens()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 418
ngens() (sage.rings.polynomial.polynomial_ring.PolynomialRing_general method), 43
nmonomials() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_genericmethod), 707
Node (class in sage.rings.polynomial.hilbert), 805
nonzero_positions() (sage.rings.polynomial.polydict.ETuple method), 786
nonzero_values()(sage.rings.polynomial.polydict.ETuple method), 787
norm() (sage.rings.polynomial.polynomial_element.Polynomial method), 138
norm()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 434
normal_basis() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 660
normalisation()(sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1033
nparts() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),707
nth_root() (sage.rings.fraction_field_element.FractionFieldElement method), 926
nth_root()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 543
nth_root()(sage.rings.polynomial.polynomial_element.Polynomial method), 139
ntl_set_directly()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 291
ntl_set_directly()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 300
ntl_ZZ_pX()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 291
number_field()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotienIndex

tRing_generic method), 418
number_of_real_roots()(sage.rings.polynomial.polynomial_element.Polynomial method),142
number_of_roots_in_interval()(sage.rings.polynomial.polynomial_element.Polynomial method), 143
number_of_terms()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial
method),965
number_of_terms()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method), 976
number_of_terms()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_element method), 566
number_of_terms()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 761
number_of_terms()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse method), 218
number_of_terms() (sage.rings.polynomial.polynomial_element.Polynomial method), 144
numer()(sage.rings.fraction_field_FpT.FpTElement
method), 935
numerator() (sage.rings.fraction_field_element.FractionFieldElement method), 926
numerator() (sage.rings.fraction_field_FpT.FpTElement method), 935
numerator()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 762
numerator()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 544
numerator() (sage.rings.polynomial.polynomial_element.Polynomial method), 145
numerator() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method), 272
nvariables() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),588
nvariables()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 763
nvariables() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_genericmethod), 708Oocean (class in sage.rings.polynomial.real_roots), 364
Omega_ge() (in module sage.rings.polynomial.omega),
985

1075

Polynomials, Release 10.4

one() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 1003
one_basis()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ParentMethods method), 441
ord() (sage.rings.polynomial.polynomial_element.Polynomial method), 146
order()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse
method), 1003
order()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 419

P
padded_list() (sage.rings.polynomial.polynomial_element.Polynomial method), 147
parameter()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),43part()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),708
partition() (in module sage.rings.polynomial.omega),988
parts()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),709
Phi_invariant()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method),873
plot()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 620
plot()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 661
plot() (sage.rings.polynomial.polynomial_element.Polynomial method), 147
polar_conic() (sage.rings.invariants.invariant_theory.TernaryCubic method), 866
poly_repr() (sage.rings.polynomial.polydict.PolyDict
method), 797
PolyDict (class in sage.rings.polynomial.polydict), 789
polygen() (in module sage.rings.polynomial.polynomial_ring), 51
polygens() (in module sage.rings.polynomial.polynomial_ring), 52
Polynomial (class in sage.rings.polynomial.polynomial_element), 55
polynomial()(sage.rings.invariants.invariant_theory.AlgebraicForm method), 818
polynomial()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial
method),1013
1076

polynomial()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ElementMethods method), 438
polynomial() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 546
polynomial() (sage.rings.polynomial.polynomial_element.Polynomial method), 148
Polynomial_absolute_number_field_dense(class in sage.rings.polynomial.polynomial_number_field), 232
polynomial_coefficient() (sage.rings.polynomial.polydict.PolyDict method), 798
polynomial_construction()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method), 977
polynomial_default_category() (in module
sage.rings.polynomial.polynomial_ring_constructor), 12
Polynomial_dense_mod_n (class in sage.rings.polynomial.polynomial_modn_dense_ntl), 289
Polynomial_dense_mod_p (class in sage.rings.polynomial.polynomial_modn_dense_ntl), 293
Polynomial_dense_modn_ntl_ZZ(classin
sage.rings.polynomial.polynomial_modn_dense_ntl), 295
Polynomial_dense_modn_ntl_zz(classin
sage.rings.polynomial.polynomial_modn_dense_ntl), 298
Polynomial_generic_cdv (class in sage.rings.polynomial.polynomial_element_generic), 207
Polynomial_generic_cdvf(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_cdvr(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_dense(classin
sage.rings.polynomial.polynomial_element),
198
Polynomial_generic_dense_cdv(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_dense_cdvf(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_dense_cdvr(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_dense_field(classin
sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_dense_inexact (class insage.rings.polynomial.polynomial_element), 201
Polynomial_generic_domain(classin
Index

Polynomials, Release 10.4

sage.rings.polynomial.polynomial_element_generic), 212
Polynomial_generic_field(classin
sage.rings.polynomial.polynomial_element_generic), 213
Polynomial_generic_sparse(classin
sage.rings.polynomial.polynomial_element_generic), 213
Polynomial_generic_sparse_cdv(classin
sage.rings.polynomial.polynomial_element_generic), 221
Polynomial_generic_sparse_cdvf(classin
sage.rings.polynomial.polynomial_element_generic), 222
Polynomial_generic_sparse_cdvr(classin
sage.rings.polynomial.polynomial_element_generic), 222
Polynomial_generic_sparse_field(classin
sage.rings.polynomial.polynomial_element_generic), 222
Polynomial_GF2X (class in sage.rings.polynomial.polynomial_gf2x), 224
Polynomial_integer_dense_flint(classin
sage.rings.polynomial.polynomial_integer_dense_flint), 234
Polynomial_integer_dense_ntl(classin
sage.rings.polynomial.polynomial_integer_dense_ntl), 248
polynomial_is_variable()(inmodulesage.rings.polynomial.polynomial_element),
205
Polynomial_padic (class in sage.rings.polynomial.padics.polynomial_padic), 313
Polynomial_padic_capped_relative_dense(class in sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense), 319
Polynomial_padic_flat (class in sage.rings.polynomial.padics.polynomial_padic_flat), 329
Polynomial_rational_flint(classin
sage.rings.polynomial.polynomial_rational_flint), 257
Polynomial_relative_number_field_dense(class in sage.rings.polynomial.polynomial_number_field), 233
polynomial_ring()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_dense method), 997
polynomial_ring()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 950
polynomial_ring()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 420
Polynomial_singular_repr(classin
Index

sage.rings.polynomial.polynomial_singular_interface), 312
Polynomial_template (class in sage.rings.polynomial.polynomial_gf2x), 226
Polynomial_template (class in sage.rings.polynomial.polynomial_zmod_flint), 277
Polynomial_template (class in sage.rings.polynomial.polynomial_zz_pex), 333
Polynomial_zmod_flint (class in sage.rings.polynomial.polynomial_zmod_flint), 280
Polynomial_ZZ_pEX (class in sage.rings.polynomial.polynomial_zz_pex), 329
PolynomialBaseringInjection(classin
sage.rings.polynomial.polynomial_element),
195
PolynomialQuotientRing_coercion(classin
sage.rings.polynomial.polynomial_quotient_ring), 393
PolynomialQuotientRing_domain(classin
sage.rings.polynomial.polynomial_quotient_ring), 395
PolynomialQuotientRing_field(classin
sage.rings.polynomial.polynomial_quotient_ring), 398
PolynomialQuotientRing_generic(classin
sage.rings.polynomial.polynomial_quotient_ring), 399
PolynomialQuotientRingElement(classin
sage.rings.polynomial.polynomial_quotient_ring_element), 427
PolynomialQuotientRingFactory(classin
sage.rings.polynomial.polynomial_quotient_ring), 389
PolynomialRealDense (class in sage.rings.polynomial.polynomial_real_mpfr_dense), 307
PolynomialRing() (in module sage.rings.polynomial.polynomial_ring_constructor), 2
PolynomialRing_cdvf (class in sage.rings.polynomial.polynomial_ring), 18
PolynomialRing_cdvr (class in sage.rings.polynomial.polynomial_ring), 18
PolynomialRing_commutative(classin
sage.rings.polynomial.polynomial_ring), 19
PolynomialRing_dense_finite_field (classin sage.rings.polynomial.polynomial_ring), 20
PolynomialRing_dense_mod_n(classin
sage.rings.polynomial.polynomial_ring), 21
PolynomialRing_dense_mod_p(classin
sage.rings.polynomial.polynomial_ring), 23
PolynomialRing_dense_padic_field_capped_relative (class in sage.rings.polynomial.polynomial_ring), 26
PolynomialRing_dense_padic_field_generic(class in sage.rings.polynomial.polynomial_ring),
1077

Polynomials, Release 10.4

26
mial.padics.polynomial_padic_capped_relaPolynomialRing_dense_padic_ring_capped_abtive_dense.Polynomial_padic_capped_relasolute (class in sage.rings.polynomial.polynotive_dense method), 325
mial_ring), 26
precision_relative()(sage.rings.polynoPolynomialRing_dense_padic_ring_capped_relmial.padics.polynomial_padic_capped_relaative (class in sage.rings.polynomial.polynotive_dense.Polynomial_padic_capped_relamial_ring), 27
tive_dense method), 325
PolynomialRing_dense_padic_ring_fixed_mod
PrecisionError, 337(class in sage.rings.polynomial.polynomial_ring), precompute_degree_reduction_cache() (in27module sage.rings.polynomial.real_roots), 368
PolynomialRing_dense_padic_ring_generic primary_decomposition()(sage.rings.poly(class in sage.rings.polynomial.polynomial_ring),
nomial.multi_polynomial_ideal.MPolynomi27
alIdeal_singular_repr method), 662
PolynomialRing_field (class in sage.rings.polyno- primary_decomposition_complete()mial.polynomial_ring), 28(sage.rings.polynomial.multi_polynoPolynomialRing_general (class in sage.rings.polymial_ideal.MPolynomialIdeal_singular_repr
nomial.polynomial_ring), 33
method), 664
PolynomialRing_integral_domain (class in product_on_basis()(sage.rings.polynomial.intesage.rings.polynomial.polynomial_ring), 47
ger_valued_polynomials.IntegerValuedPolynoPolynomialRing_singular_repr(classinmialRing.Binomial method), 444
sage.rings.polynomial.polynomial_singular_inproduct_on_basis()(sage.rings.polynomial.inteterface), 312
ger_valued_polynomials.IntegerValuedPolynoPolynomialRingHomomorphism_from_base
mialRing.Shifted method), 450(classin
sage.rings.polynomial.polyno- pseudo_divrem()(sage.rings.polynomial.polynomial_ring_homomorphism), 53
mial_integer_dense_flint.Polynomial_intepolynomials()(sage.rings.polynomial.polynoger_dense_flint method), 243
mial_ring.PolynomialRing_general
method), pseudo_quo_rem()(sage.rings.polynomial.polyno43
mial_element.Polynomial method), 150
PolynomialSequence() (in module sage.rings.poly- pseudoinverse() (in module sage.rings.polynonomial.multi_polynomial_sequence), 696
mial.real_roots), 368
PolynomialSequence_generic(classinQ
sage.rings.polynomial.multi_polynomial_sequence), 698
quadratic_form()(sage.rings.invariants.invariPolynomialSequence_gf2 (class in sage.rings.polyant_theory.InvariantTheoryFactory
method),nomial.multi_polynomial_sequence), 713
849
PolynomialSequence_gf2e(classin QuadraticForm (class in sage.rings.invariants.invarisage.rings.polynomial.multi_polynomial_seant_theory), 854
quence), 718
quaternary_biquadratic()(sage.rings.invariPolyring_FpT_coerce (class in sage.rings.fracants.invariant_theory.InvariantTheoryFactorytion_field_FpT), 941
method), 850
pow_pd (class in sage.rings.polynomial.polynomial_com- quaternary_quadratic() (sage.rings.invariants.inpiled), 436
variant_theory.InvariantTheoryFactory method),
power_trunc() (sage.rings.polynomial.polynomial_el851
ement.Polynomial method), 148
quo_rem()(sage.rings.polynomial.laurent_polynoprec() (sage.rings.polynomial.polynomial_element.Polymial.LaurentPolynomial_univariate
method),nomial method), 150977
prec_degree()(sage.rings.polynomial.padics.poly- quo_rem() (sage.rings.polynomial.multi_polynomial_elnomial_padic_capped_relative_dense.Polynoement.MPolynomial_polydict method), 588
mial_padic_capped_relative_dense
method), quo_rem()(sage.rings.polynomial.multi_polyno324
mial_libsingular.MPolynomial_libsingularprec_degree()(sage.rings.polynomial.polynomethod), 764
mial_element.Polynomial_generic_dense_inexact quo_rem()(sage.rings.polynomial.padics.polynomethod), 203
mial_padic_capped_relative_dense.Polynoprecision_absolute()(sage.rings.polynomial_padic_capped_relative_dense
method),
1078

Index

Polynomials, Release 10.4326
quo_rem()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_field method),213
quo_rem()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 218
quo_rem()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense method), 199
quo_rem()(sage.rings.polynomial.polynomial_gf2x.Polynomial_template
method),228
quo_rem()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 243
quo_rem()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 253
quo_rem()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 292
quo_rem()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 296
quo_rem()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 300
quo_rem()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),272
quo_rem()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 308
quo_rem()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),279
quo_rem()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),335
quotient()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 667
quotient_by_principal_ideal()(sage.rings.polynomial.polynomial_ring.PolynomialRing_commutative method), 19

random_element() (sage.rings.fraction_field.FractionField_generic method), 920
random_element()(sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 950
random_element()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal
method), 622
random_element()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 508
random_element()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 420
random_element()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),45
rational_reconstruct()(sage.rings.polynomial.polynomial_element.Polynomial method),152
rational_reconstruct()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint method), 285
rational_reconstruction() (sage.rings.polynomial.polynomial_element.Polynomial method),152
rational_reconstruction() (sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 434
rational_reconstruction()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint method), 285
rational_root_bounds()(inmodulesage.rings.polynomial.real_roots), 368
real_root_intervals()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 244
real_root_intervals()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl method), 254
real_root_intervals()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method), 272
real_roots()(inmodulesage.rings.polynomial.real_roots), 369
real_roots() (sage.rings.polynomial.polynomial_eleRment.Polynomial method), 157
reciprocal_transform()(sage.rings.polynoR_invariant() (sage.rings.invariants.invariant_themial.polynomial_element.Polynomial
method),ory.BinaryQuintic method), 827
157
radical()(sage.rings.polynomial.multi_polynoreduce() (sage.rings.fraction_field_element.Fractionmial_ideal.MPolynomialIdeal_singular_repr
FieldElement method), 926
method), 667
reduce()(sage.rings.fraction_field_element.Fractionradical()(sage.rings.polynomial.polynomial_eleFieldElement_1poly_field
method), 928
ment.Polynomial method), 151
Index

1079

Polynomials, Release 10.4

reduce() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1013
reduce() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 589
reduce()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 625
reduce()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_quotient method),634
reduce()(sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal method), 683
reduce() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular method), 765
reduce() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1033
reduce()(sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy method), 1042
reduced() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),709
reduced() (sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2 method), 716
reduced_form() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 547
refine()(sage.rings.polynomial.real_roots.island
method), 360
refine_all() (sage.rings.polynomial.real_roots.ocean
method), 366
refine_recurse()(sage.rings.polynomial.real_roots.island method), 360
refine_root() (in module sage.rings.polynomial.refine_root), 386
region()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial method), 349
region()(sage.rings.polynomial.real_roots.rr_gap
method), 378
region_width() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial method), 349
relative_bounds() (in module sage.rings.polynomial.real_roots), 376
remove_var() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 952
remove_var()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 511
remove_zeros() (sage.rings.polynomial.polydict.PolyDict method), 799
repr_long()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 512
require_field (in module sage.rings.polynomial.multi_polynomial_ideal), 690
RequireField(classin
sage.rings.polyno1080

mial.multi_polynomial_ideal), 689(sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal method), 684
rescale()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),326
reset()(sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy method), 1043
reset_root_width()(sage.rings.polynomial.real_roots.island method), 360
reset_root_width()(sage.rings.polynomial.real_roots.ocean method), 366
residue()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),978
residue_class_degree()(sage.rings.polynomial.ideal.Ideal_1poly_field method), 388
residue_field()(sage.rings.polynomial.ideal.Ideal_1poly_field method), 388
residue_field()(sage.rings.polynomial.polynomial_ring.PolynomialRing_dense_mod_n
method), 22
resultant()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),591
resultant()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 766
resultant() (sage.rings.polynomial.polynomial_element.Polynomial method), 158
resultant() (sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 244
resultant()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 255
resultant()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p
method), 294
resultant() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint method), 273
resultant()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 285
resultant()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
method),332
retract()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 421
reverse()(sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),
res()

Index

Polynomials, Release 10.4

326
reverse()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 220
reverse()(sage.rings.polynomial.polynomial_element.Polynomial method), 159
reverse()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 245
reverse()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 296
reverse()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 300
reverse()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),273
reverse()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 309
reverse()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 286
reverse()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX
method),332
reverse_intvec() (in module sage.rings.polynomial.real_roots), 376
reversed()(sage.rings.polynomial.polydict.ETuple
method), 787
revert_series()(sage.rings.polynomial.polynomial_element.Polynomial method), 160
revert_series()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 245
revert_series()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method), 274
revert_series()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 287
rich_compare() (sage.rings.polynomial.polydict.PolyDict method), 800
ring() (sage.rings.fraction_field.FractionField_genericmethod), 921
ring() (sage.rings.invariants.invariant_theory.FormsBase method), 842
ring() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1015
ring()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),710
ring_of_integers()(sage.rings.fracIndextion_field.FractionField_1poly_field
method),917
root_bounds() (in module sage.rings.polynomial.real_roots), 377
root_field() (sage.rings.polynomial.padics.polynomial_padic.Polynomial_padic method), 318
root_field() (sage.rings.polynomial.polynomial_element.Polynomial method), 161
roots()(sage.rings.polynomial.polynomial_element.Polynomial method), 163
roots()(sage.rings.polynomial.real_roots.ocean
method), 367
rr_gap (class in sage.rings.polynomial.real_roots), 377
rshift_coeffs() (sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense.Polynomial_padic_capped_relative_dense
method),327

S
S (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing attribute), 445
S_class_group()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 401
S_invariant() (sage.rings.invariants.invariant_theory.TernaryCubic method), 863
S_units()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_genericmethod), 404
sage.rings.fraction_field
module, 913
sage.rings.fraction_field_element
module, 923
sage.rings.fraction_field_FpTmodule, 931
sage.rings.invariants.invariant_theory
module, 813
sage.rings.invariants.reconstruction
module, 884
sage.rings.monomials
module, 812
sage.rings.polynomial.complex_roots
module, 382
sage.rings.polynomial.convolution
module, 451
sage.rings.polynomial.cyclotomic
module, 452
sage.rings.polynomial.flatten
module, 807
sage.rings.polynomial.hilbert
module, 805
sage.rings.polynomial.ideal
module, 387

1081

Polynomials, Release 10.4

sage.rings.polynomial.infinite_polynomial_element
module, 1005
sage.rings.polynomial.infinite_polynomial_ring
module, 989
sage.rings.polynomial.integer_valued_polynomials
module, 436
sage.rings.polynomial.laurent_polynomial
module, 962
sage.rings.polynomial.laurent_polynomial_ring
module, 954
sage.rings.polynomial.laurent_polynomial_ring_base
module, 945
sage.rings.polynomial.msolve
module, 776
sage.rings.polynomial.multi_polynomial
module, 515
sage.rings.polynomial.multi_polynomial_element
module, 565
sage.rings.polynomial.multi_polynomial_ideal
module, 596
sage.rings.polynomial.multi_polynomial_ideal_libsingularmodule, 774
sage.rings.polynomial.multi_polynomial_libsingularmodule, 720
sage.rings.polynomial.multi_polynomial_ring
module, 559
sage.rings.polynomial.multi_polynomial_ring_base
module, 493
sage.rings.polynomial.multi_polynomial_sequence
module, 690
sage.rings.polynomial.omega
module, 981
sage.rings.polynomial.padics.polynomial_padic
module, 313
sage.rings.polynomial.padics.polynomial_padic_capped_relative_dense
module, 319
sage.rings.polynomial.padics.polynomial_padic_flat
1082

module, 329
sage.rings.polynomial.polydict
module, 778
sage.rings.polynomial.polynomial_compiled
module, 435
sage.rings.polynomial.polynomial_element
module, 54
sage.rings.polynomial.polynomial_element_genericmodule, 207
sage.rings.polynomial.polynomial_fateman
module, 436
sage.rings.polynomial.polynomial_gf2x
module, 223
sage.rings.polynomial.polynomial_integer_dense_flint
module, 234
sage.rings.polynomial.polynomial_integer_dense_ntl
module, 248
sage.rings.polynomial.polynomial_modn_dense_ntl
module, 289
sage.rings.polynomial.polynomial_number_field
module, 230
sage.rings.polynomial.polynomial_quotient_ring
module, 389
sage.rings.polynomial.polynomial_quotient_ring_element
module, 426
sage.rings.polynomial.polynomial_rational_flint
module, 257
sage.rings.polynomial.polynomial_real_mpfr_dense
module, 307
sage.rings.polynomial.polynomial_ring
module, 15
sage.rings.polynomial.polynomial_ring_constructor
module, 1
sage.rings.polynomial.polynomial_ring_homomorphism
module, 52
sage.rings.polynomial.polynomial_singular_interface
module, 312
sage.rings.polynomial.polynomial_zmod_flint
Index

Polynomials, Release 10.4

module, 276
sage.rings.polynomial.polynomial_zz_pex
module, 329
sage.rings.polynomial.real_roots
module, 337
sage.rings.polynomial.refine_root
module, 386
sage.rings.polynomial.symmetric_ideal
module, 1021
sage.rings.polynomial.symmetric_reduction
module, 1036
sage.rings.polynomial.term_ordermodule, 457
sage.rings.polynomial.toy_buchberger
module, 891
sage.rings.polynomial.toy_d_basis
module, 905
sage.rings.polynomial.toy_variety
module, 900
saturation() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 669
scalar_lmult() (sage.rings.polynomial.polydict.PolyDict method), 800
scalar_rmult() (sage.rings.polynomial.polydict.PolyDict method), 801
scale_intvec_var() (in module sage.rings.polynomial.real_roots), 378
scaled_coeffs()(sage.rings.invariants.invariant_theory.BinaryQuartic method), 824
scaled_coeffs()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 838
scaled_coeffs()(sage.rings.invariants.invariant_theory.QuadraticForm method), 859
scaled_coeffs()(sage.rings.invariants.invariant_theory.TernaryCubic method), 867
scaled_coeffs()(sage.rings.invariants.invariant_theory.TernaryQuadratic method), 870
second()(sage.rings.invariants.invariant_theory.TwoAlgebraicForms method), 871
section() (sage.rings.fraction_field_FpT.Fp_FpT_coerce method), 940
section()(sage.rings.fraction_field_FpT.Polyring_FpT_coerce method),941
section() (sage.rings.fraction_field_FpT.ZZ_FpT_coerce method), 942
section() (sage.rings.fraction_field.FractionFieldEmbedding method), 916
section()(sage.rings.polynomial.flatten.FlatteningMorphism method), 809
section()(sage.rings.polynomial.polynomial_eleIndex

ment.PolynomialBaseringInjection
method),197
select() (in module sage.rings.polynomial.toy_buchberger), 898
select() (in module sage.rings.polynomial.toy_d_basis),909
selmer_generators() (sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 421
selmer_group()(sage.rings.polynomial.polynomial_quotient_ring.PolynomialQuotientRing_generic method), 422
set_karatsuba_threshold() (sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 46
setgens()(sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy method), 1044
SeveralAlgebraicForms (class in sage.rings.invariants.invariant_theory), 860
shift() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ElementMethods method), 438
shift() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method), 978shift()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 220
shift()(sage.rings.polynomial.polynomial_element.Polynomial method), 181
shift()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense
method),200
shift() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 228
shift()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 292
shift()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 297
shift()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 301
shift()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 310
shift()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),279
shift() (sage.rings.polynomial.polynomial_zz_pex.Polynomial_template method), 336
shift() (sage.rings.polynomial.polynomial_zz_pex.Polynomial_ZZ_pEX method), 333
shrink_bp() (sage.rings.polynomial.real_roots.island
1083

Polynomials, Release 10.4

method), 360
singular_moreblocks()(sage.rings.polynomial.term_order.TermOrder method), 478
singular_str()(sage.rings.polynomial.term_order.TermOrder method), 479
slimgb_libsingular() (in module sage.rings.polynomial.multi_polynomial_ideal_libsingular), 776
slope_factorization()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_cdv method), 211
slope_range() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_float
method),353
slope_range() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial_integer method),358
small_roots() (in module sage.rings.polynomial.polynomial_modn_dense_ntl), 302
small_roots()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_n method), 293
small_roots()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint
method), 288
solve()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2
method),716
some_elements() (sage.rings.fraction_field.FractionField_generic method), 921
some_elements() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 513
some_elements()(sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method),47
sortkey (sage.rings.polynomial.term_order.TermOrderproperty), 483
sortkey_block()(sage.rings.polynomial.term_order.TermOrder method), 483
sortkey_deglex() (sage.rings.polynomial.term_order.TermOrder method), 484
sortkey_degneglex()(sage.rings.polynomial.term_order.TermOrder method), 484
sortkey_degrevlex()(sage.rings.polynomial.term_order.TermOrder method), 485
sortkey_invlex() (sage.rings.polynomial.term_order.TermOrder method), 485
sortkey_lex()(sage.rings.polynomial.term_order.TermOrder method), 486
sortkey_matrix() (sage.rings.polynomial.term_order.TermOrder method), 486
sortkey_negdeglex()(sage.rings.polynomial.term_order.TermOrder method), 487
sortkey_negdegrevlex()(sage.rings.polyno1084

mial.term_order.TermOrder method), 487
sortkey_neglex() (sage.rings.polynomial.term_order.TermOrder method), 488
sortkey_negwdeglex()(sage.rings.polynomial.term_order.TermOrder method), 488
sortkey_negwdegrevlex()(sage.rings.polynomial.term_order.TermOrder method), 489
sortkey_wdeglex() (sage.rings.polynomial.term_order.TermOrder method), 489
sortkey_wdegrevlex()(sage.rings.polynomial.term_order.TermOrder method), 490
sparse_iter() (sage.rings.polynomial.polydict.ETuple
method), 787
specialization()(sage.rings.fraction_field_element.FractionFieldElement method), 927
specialization()(sage.rings.polynomial.multi_polynomial.MPolynomial method),553
specialization()(sage.rings.polynomial.polynomial_element.Polynomial method), 182
SpecializationMorphism (class in sage.rings.polynomial.flatten), 810
split_for_targets() (in module sage.rings.polynomial.real_roots), 378
splitting_field() (sage.rings.polynomial.polynomial_element.Polynomial method), 183spol() (in module sage.rings.polynomial.toy_buchberger), 898
spol() (in module sage.rings.polynomial.toy_d_basis),910
sqr_pd (class in sage.rings.polynomial.polynomial_compiled), 436
sqrt()(sage.rings.fraction_field_FpT.FpTElement
method), 935
square()(sage.rings.polynomial.polynomial_element.Polynomial method), 186
squarefree_decomposition() (sage.rings.polynomial.polynomial_element.Polynomial method),186
squarefree_decomposition() (sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint method), 246
squarefree_decomposition() (sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl method), 255
squarefree_decomposition() (sage.rings.polynomial.polynomial_zmod_flint.Polynomial_zmod_flint method), 289
squeezed()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1015
squeezed()(sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1034
std()
(sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal method), 684
Index

Polynomials, Release 10.4

std_libsingular() (in module sage.rings.polynomial.multi_polynomial_ideal_libsingular), 776
stretch()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1016
sub_m_mul_q()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 768
subresultants() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),592
subresultants() (sage.rings.polynomial.multi_polynomial.MPolynomial method), 554
subresultants()(sage.rings.polynomial.polynomial_element.Polynomial method), 187
subs() (sage.rings.fraction_field_element.FractionFieldElement method), 927
subs()(sage.rings.fraction_field_FpT.FpTElement
method), 936
subs() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1016
subs()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method), 592
subs()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal method), 625
subs()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod),768
subs()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic method),711
subs() (sage.rings.polynomial.polynomial_element.Polynomial method), 188
subsample_vec_doctest()(inmodulesage.rings.polynomial.real_roots), 379
sum()(sage.rings.polynomial.multi_polynomial_ring.MPolynomialRing_polydict method),564
sum_of_coefficients() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases.ElementMethods
method),438
super_categories()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Bases method), 441
support() (sage.rings.fraction_field_element.FractionFieldElement_1poly_field method), 929
sylvester_matrix()(sage.rings.polynomial.multi_polynomial.MPolynomial method),555
sylvester_matrix() (sage.rings.polynomial.polynomial_element.Polynomial method), 188
symmetric_basis() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1035
symmetric_cancellation_order()Index(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1018
symmetric_power() (sage.rings.polynomial.polynomial_element.Polynomial method), 190
SymmetricIdeal (class in sage.rings.polynomial.symmetric_ideal), 1022
SymmetricReductionStrategy(classin
sage.rings.polynomial.symmetric_reduction),
1039
symmetrisation() (sage.rings.polynomial.symmetric_ideal.SymmetricIdeal method), 1035
syzygy()(sage.rings.invariants.invariant_theory.TernaryCubic method), 867
syzygy()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method), 876
syzygy()(sage.rings.invariants.invariant_theory.TwoTernaryQuadratics method), 881
syzygy_module() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_base_repr method), 634
syzygy_module() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 669
syzygy_module() (sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal method), 686

T
T_covariant() (sage.rings.invariants.invariant_theory.BinaryQuintic method), 828
T_covariant() (sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method), 874
T_invariant() (sage.rings.invariants.invariant_theory.TernaryCubic method), 864
T_prime_covariant() (sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method),874
tail() (sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial method), 1019
tailreduce() (sage.rings.polynomial.symmetric_reduction.SymmetricReductionStrategy
method),1045
tau_covariant()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 839
taylor_shift1_intvec()(inmodulesage.rings.polynomial.real_roots), 379
tensor_with_ring()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_dense method), 998
tensor_with_ring()(sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse method), 1003
term_lmult() (sage.rings.polynomial.polydict.PolyDict
method), 8021085

Polynomials, Release 10.4

term_order() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_genericmethod), 953
term_order()(sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 513
term_rmult() (sage.rings.polynomial.polydict.PolyDict
method), 803
TermOrder (class in sage.rings.polynomial.term_order),466
termorder_from_singular()(inmodulesage.rings.polynomial.term_order), 491
ternary_biquadratic() (sage.rings.invariants.invariant_theory.InvariantTheoryFactory method),852
ternary_cubic()(sage.rings.invariants.invariant_theory.InvariantTheoryFactory
method),853
ternary_quadratic() (sage.rings.invariants.invariant_theory.InvariantTheoryFactory
method),854
TernaryCubic (class in sage.rings.invariants.invariant_theory), 862
TernaryQuadratic (class in sage.rings.invariants.invariant_theory), 868
theta_covariant()(sage.rings.invariants.invariant_theory.BinaryQuintic method), 840
Theta_covariant()(sage.rings.invariants.invariant_theory.TernaryCubic method), 864
Theta_invariant()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics method),875
Theta_invariant()(sage.rings.invariants.invariant_theory.TwoTernaryQuadratics
method),880
Theta_prime_invariant()(sage.rings.invariants.invariant_theory.TwoQuaternaryQuadratics
method), 876
Theta_prime_invariant()(sage.rings.invariants.invariant_theory.TwoTernaryQuadratics
method), 880
to_bernstein() (in module sage.rings.polynomial.real_roots), 379
to_bernstein_warp() (in module sage.rings.polynomial.real_roots), 380
to_ocean()(sage.rings.polynomial.real_roots.linear_map method), 361
to_ocean()(sage.rings.polynomial.real_roots.warp_map method), 381
total_degree() (sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),593
total_degree() (sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingular1086

method), 770
total_degree() (sage.rings.polynomial.polydict.PolyDict method), 803
trace()(sage.rings.polynomial.polynomial_quotient_ring_element.PolynomialQuotientRingElement method), 435
trace_polynomial() (sage.rings.polynomial.polynomial_element.Polynomial method), 191
transformed() (sage.rings.invariants.invariant_theory.AlgebraicForm method), 819
transformed_basis()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 670
transvectant() (in module sage.rings.invariants.invariant_theory), 882
triangular_decomposition() (sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr method), 671
triangular_factorization()(inmodulesage.rings.polynomial.toy_variety), 904
truncate()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),979
truncate()(sage.rings.polynomial.multi_polynomial.MPolynomial method), 556
truncate()(sage.rings.polynomial.polynomial_element_generic.Polynomial_generic_sparse
method), 221
truncate()(sage.rings.polynomial.polynomial_element.Polynomial method), 192
truncate()(sage.rings.polynomial.polynomial_element.Polynomial_generic_dense
method),201
truncate()(sage.rings.polynomial.polynomial_gf2x.Polynomial_template
method),228
truncate()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_ZZ method), 297
truncate()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_modn_ntl_zz method), 301
truncate() (sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),275
truncate()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 310
truncate()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),279
truncate()(sage.rings.polynomial.polynomial_zz_pex.Polynomial_template
method),336
Index

Polynomials, Release 10.4

truncate_abs()(sage.rings.polynomial.polynomial_real_mpfr_dense.PolynomialRealDense
method), 311
try_rand_split()(sage.rings.polynomial.real_roots.interval_bernstein_polynomial
method), 349
try_split() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial method), 350
tuple_weight()(sage.rings.polynomial.term_order.TermOrder method), 490
TwoAlgebraicForms (class in sage.rings.invariants.invariant_theory), 870
TwoQuaternaryQuadratics (class in sage.rings.invariants.invariant_theory), 871
twostd()(sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal method), 688
TwoTernaryQuadratics (class in sage.rings.invariants.invariant_theory), 877

mial_ring_base), 514
unpickle_MPolynomialRing_generic_v1()(in module sage.rings.polynomial.multi_polynomial_ring_base), 514
unpickle_MPolynomialRing_libsingular()(in module sage.rings.polynomial.multi_polynomial_libsingular), 773
unpickle_PolynomialRing()(inmodulesage.rings.polynomial.polynomial_ring_constructor), 13
unweighted_degree() (sage.rings.polynomial.polydict.ETuple method), 788
unweighted_quotient_degree()(sage.rings.polynomial.polydict.ETuple method),788
update() (in module sage.rings.polynomial.toy_buchberger), 899
update() (in module sage.rings.polynomial.toy_d_basis),910
Uusign()(sage.rings.polynomial.real_roots.bernstein_polynomial_factory method), 339
umbra() (sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.EleV
ment method), 449
unary_pd (class in sage.rings.polynomial.polyno- valuation() (sage.rings.fraction_field_element.Fracmial_compiled), 436
tionFieldElement method), 927
UnflatteningMorphism (class in sage.rings.polyno- valuation() (sage.rings.fraction_field_FpT.FpTElemial.flatten), 811
ment method), 936
units()(sage.rings.polynomial.polynomial_quo- valuation() (sage.rings.polynomial.laurent_polynotient_ring.PolynomialQuotientRing_genericmial.LaurentPolynomial_univariate
method),method), 423
979
univar_pd (class in sage.rings.polynomial.polyno- valuation()(sage.rings.polynomial.padics.polynomial_compiled), 436
mial_padic_capped_relative_dense.Polynounivariate_polynomial()(sage.rings.polymial_padic_capped_relative_dense
method),nomial.multi_polynomial_element.MPolyno328
mial_polydict method), 594
valuation()(sage.rings.polynomial.polynomial_elunivariate_polynomial()(sage.rings.polynoement_generic.Polynomial_generic_sparsemial.multi_polynomial_libsingular.MPolynomethod), 221
mial_libsingular method), 771
valuation() (sage.rings.polynomial.polynomial_eleunivariate_ring()(sage.rings.polynoment.Polynomial method), 193
mial.multi_polynomial_ring_base.MPolynovaluation()(sage.rings.polynomial.polymialRing_base method), 513
nomial_modn_dense_ntl.Polynouniversal_discriminant()(inmodulemial_dense_modn_ntl_ZZ method), 297
sage.rings.polynomial.polynomial_element),
valuation()(sage.rings.polynomial.poly206
nomial_modn_dense_ntl.Polynouniverse()(sage.rings.polynomial.multi_polynomial_dense_modn_ntl_zz method), 302
mial_sequence.PolynomialSequence_genericvaluation_of_coefficient() (sage.rings.polymethod), 712
nomial.padics.polynomial_padic_capped_relunpickle_FpT_element()(inmoduleative_dense.Polynomial_padic_capped_relasage.rings.fraction_field_FpT), 943
tive_dense method), 328
unpickle_MPolynomial_libsingular()(in var_pd (class in sage.rings.polynomial.polynomial_commodule
sage.rings.polynomial.multi_polynopiled), 436
mial_libsingular), 773
variable()(sage.rings.polynomial.multi_polynounpickle_MPolynomialRing_generic()(inmial_element.MPolynomial_polydict method),modulesage.rings.polynomial.multi_polyno594
Index

1087

Polynomials, Release 10.4

variable()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 772
variable_name()(sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method), 980
variable_name()(sage.rings.polynomial.polynomial_element.Polynomial method), 193
variable_names_recursive() (sage.rings.polynomial.laurent_polynomial_ring_base.LaurentPolynomialRing_generic method), 953
variable_names_recursive() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base method), 514
variable_names_recursive() (sage.rings.polynomial.polynomial_ring.PolynomialRing_general
method), 47
variable_shift()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Binomial.Element method), 444
variable_shift()(sage.rings.polynomial.integer_valued_polynomials.IntegerValuedPolynomialRing.Shifted.Element method), 450
variables()(sage.rings.invariants.invariant_theory.FormsBase method), 842
variables()(sage.rings.polynomial.infinite_polynomial_element.InfinitePolynomial
method),1019
variables() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate
method),980
variables()(sage.rings.polynomial.multi_polynomial_element.MPolynomial_polydict method),595
variables()(sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsingularmethod), 773
variables()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_genericmethod), 712
variables() (sage.rings.polynomial.polynomial_element.Polynomial method), 194
variations() (sage.rings.polynomial.real_roots.interval_bernstein_polynomial method), 351
variety() (in module sage.rings.polynomial.msolve),778
variety()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr
method), 674
varname_key() (sage.rings.polynomial.infinite_polynomial_ring.InfinitePolynomialRing_sparse
method), 1004
vector_space_dimension()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomi1088

alIdeal_singular_repr method), 679

W
warp_map (class in sage.rings.polynomial.real_roots), 380
weighted_degree()(sage.rings.polynomial.multi_polynomial.MPolynomial method),556
weighted_degree()(sage.rings.polynomial.polydict.ETuple method), 788
weighted_quotient_degree() (sage.rings.polynomial.polydict.ETuple method), 789
weights()(sage.rings.polynomial.term_order.TermOrder method), 491
weil_polynomials() (sage.rings.polynomial.polynomial_ring.PolynomialRing_integral_domain
method), 48
weil_restriction()(sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal
method), 627
weil_restriction()(sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_gf2e method), 719
weyl_algebra() (sage.rings.polynomial.multi_polynomial_ring_base.MPolynomialRing_base
method), 514
weyl_algebra()(sage.rings.polynomial.polynomial_ring.PolynomialRing_commutative
method), 19
wordsize_rational() (in module sage.rings.polynomial.real_roots), 381X
xgcd() (sage.rings.polynomial.laurent_polynomial.LaurentPolynomial_univariate method), 980
xgcd() (sage.rings.polynomial.polynomial_element.Polynomial method), 194
xgcd() (sage.rings.polynomial.polynomial_gf2x.Polynomial_template method), 229
xgcd()(sage.rings.polynomial.polynomial_integer_dense_flint.Polynomial_integer_dense_flint
method), 247
xgcd()(sage.rings.polynomial.polynomial_integer_dense_ntl.Polynomial_integer_dense_ntl
method), 256
xgcd()(sage.rings.polynomial.polynomial_modn_dense_ntl.Polynomial_dense_mod_p
method), 294
xgcd()(sage.rings.polynomial.polynomial_rational_flint.Polynomial_rational_flint
method),276
xgcd()(sage.rings.polynomial.polynomial_zmod_flint.Polynomial_template method),
280

Index

Polynomials, Release 10.4

xgcd() (sage.rings.polynomial.polynomial_zz_pex.Polynomial_template method), 337

Z
ZZ_FpT_coerce(classtion_field_FpT), 942

Index

in

sage.rings.frac-1089