# Polynomials Module¶

## Introduction¶

This tutorial tries to give an overview of the functionality concerning polynomials within SymPy. All code examples assume:

```>>> from sympy import *
>>> x, y, z = symbols('xyz')
```

## Basic functionality¶

These functions provide different algorithms dealing with polynomials in the form of SymPy expression, like symbols, sums etc.

### Division¶

The function div() provides division of polynomials with remainder. That is, for polynomials f and g, it computes q and r, such that f == g*q + r and degree(r) < q. For polynomials in one variables with coefficients in a field, say, the rational numbers, q and r are uniquely defined this way.

```>>> from sympy import pprint
>>> import sys
>>> sys.displayhook = pprint
>>> f = 5*x**2 + 10*x + 3
>>> g = 2*x + 2
>>> q, r = div(f, g, x, y)
>>> q
5*x
5/2 + ---
2
>>> r
-2
>>> (q*g + r).expand()
2
3 + 10*x + 5*x
```

As you can see, q has a non-integer coefficient. If you want to do division only in the ring of polynomials with integer coefficients you can specify an additional parameter.

```>>> q, r = div(f, g, coeff='int')
>>> q
0
>>> r
13 + 5*x**2 + 15*x
```

But be warned, that this ring is no longer euclidean and that the degree of the remainder doesn’t need to be smaller than that of f. Since 2 doesn’t divide 5, 2*x doesn’t divide 5*x**2, even if the degree is smaller. But:

```>>> g = 5*x + 1
>>> q, r = div(f, g, x, coeff='int')
>>> q
x
>>> r
13 + 14*x
>>> (q*g + r).expand()
13 + 5*x**2 + 15*x
```

This also works for polynomials with multiple variables.

```>>> f = x*y + y*z
>>> g = 3*x + 3*z
>>> q, r = div(f, g, x, y)
>>> q
y
-
3
>>> r
0
```

In the last examples, all of the three variables x, y and z are assumed to be variables of the polynomials. But if you have some unrelated constant as coefficient, you can specify the variables explicitly:

```>>> a, b, c = symbols('abc')
>>> f = a*x**2 + b*x + c
>>> g = 3*x + 2
>>> q, r = div(f, g, x)
>>> q
2*a   b   a*x
- --- + - + ---
9    3    3
>>> r
2*b   4*a
c - --- + ---
3     9
```

Another option is division by multiple polynomials at the same time. In general, the output is not unique and depends on the order of the divisors and the given monomial order (if specified).

```>>> f = x*y + y*z + z*x
>>> g1 = x + 1
>>> g2 = 2*y + 1
>>> q, r = div(f, [g1, g2], x, y, z)
>>> q
z
[y + z, -1/2 + -]
2
>>> r
3*z
1/2 - ---
2
>>> (q*g1 + q*g2 + r).expand()
x*y + x*z + y*z

>>> q, r = div(f, [g2, g1], x, y, z)
>>> q
x   z
[- + -, -1/2 + z]
2   2
>>> r
3*z
1/2 - ---
2
>>> (q*g2 + q*g1 + r).expand()
x*y + x*z + y*z
```

### GCD and LCM¶

With division, there is also the computation of the greatest common divisor and the least common multiple.

When the polynomials have integer coefficients, the contents’ gcd is also considered.

```>>> f = 12*(x + 1)*x
>>> g = 16*x**2
>>> gcd(f, g, x)
4*x
```

It also works with multiple variables. In this case, the variables are ordered alphabetically, be default, which has influence on the leading coefficient.

```>>> f = x*y/2 + y**2
>>> g = 3*x + 6*y
>>> gcd(f, g, x, y)
x + 2*y
>>> gcd(f, g, y, x)
x
y + -
2
```

The lcm is connected with the gcd and one can be computed using the other.

```>>> f = x*y**2 + x**2*y
>>> g = x**2*y**2
>>> gcd(f, g, x, y)
x*y
>>> lcm(f, g, x, y)
3  2    2  3
x *y  + x *y
>>> (f*g).expand()
4  3    3  4
x *y  + x *y
>>> (gcd(f, g, x, y)*lcm(f, g, x, y)).expand()
4  3    3  4
x *y  + x *y
```

### Square-free factorization¶

The square-free factorization of a univariate polynomial is the product of all factors (not irreducible) of degree 1, 2 ...

```>>> sqf((x + 2)*(x*(x + 1))**2, x)
2
[2 + x, x + x ]
```

### Factorization¶

This function provides factorization of univariate and multivariate polynomials with rational coefficients.

```>>> factor(Rational(1,2)*x**4 + Rational(5,12)*x**3 - Rational(1,3)*x**2)
2
-x *(1 - 2*x)*(4 + 3*x)
-----------------------
12

>>> factor(x**2 + 4*x*y + 4*y**2)
2
(x + 2*y)
```

### Groebner bases¶

Buchberger’s algorithm is implemented, supporting various monomial orders.

```>>> groebner([x**2 + 1, y**4*x + x**3], x, y, order='lex')
2        4
[1 + x , -1 + y ]

>>> groebner([x**2 + 1, y**4*x + x**3, x*y*z**3], x, y, z, order='grevlex')
4   3       2
[-1 + y , z , 1 + x ]
```

### Solving Equations¶

We have (incomplete) methods to find the complex or even symbolic roots of polynomials and to solve some systems of polynomial equations.

```>>> from sympy import roots, solve_poly_system
>>> solve(x**3 + 2*x + 3, x)
____                ____
I*\/ 11             I*\/ 11
[1/2 - --------, -1, 1/2 + --------]
2                   2

>>> p = Symbol('p')
>>> q = Symbol('q')
>>> sorted(solve(x**2 + p*x + q, x))
___________           ___________
/         2           /         2
p   \/  -4*q + p      p   \/  -4*q + p
[- - + --------------, - - - --------------]
2         2           2         2

>>> solve_poly_system([y - x, x - 5], x, y)
[(5, 5)]

>>> solve_poly_system([y**2 - x**3 + 1, y*x], x, y)
___                  ___
I*\/ 3               I*\/ 3
[(0, -I), (1, 0), (-1/2 - -------, 0), (-1/2 + -------, 0), (0, I)]
2                    2
```

### Poly¶

class sympy.polys.Poly

Represents polynomials with symbolic coefficients.

Polynomials are internally represented as two lists containing coefficients and monomials (tuples of exponents), respectively. Stored are only terms with non-zero coefficients, so generally all polynomials are considered sparse. However, algorithms will detect dense polynomials and use the appropriate method to solve them in the most efficient way.

The most common way to initialize a polynomial instance is to provide a valid expression together with a set of ordered symbols and, additionally, monomial ordering:

Poly(expression, x_1, x_2, ..., x_n, order=’grlex’)

If the given expression is not a polynomial with respect to the given variables, an exception is raised. Alternatively you can use Basic.as_poly to avoid exception handling.

By default ordering of monomials can be omitted. In this case graded lexicographic order will be used. Anyway, remember that ‘order’ is a keyword argument.

Currently, four standard orderings are supported:

 lex -> lexicographic order  grlex -> graded lex order  grevlex -> reversed grlex order  1-el -> first elimination order

Polynomials can also be constructed explicitly by passing a collection of coefficients and monomials in as an expression. Interpretation of the collection depends on the collection’s type according to the following semantics:

 expression is a LIST
1. [(c_1, M_1), (c_2, M_2), ..., (c_n, M_n)]
2. [(c_1, m_1), (c_2, m_2), ..., (c_n, m_n)]
3. [ c_1, c_2, ..., c_n ]
```>>> from sympy import Poly, S
>>> from sympy.abc import a, x, y
>>> # a) M is a tuple (m_1, m_2, ..., m_3)
>>> Poly([(4, (2,2)), (3, (1,2))], x, y)
Poly(4*x**2*y**2 + 3*x*y**2, x, y)
>>> # b) m_i are integers
>>> Poly([(1, 2), (a, 0)], x)
Poly(x**2 + a, x)
>>> # c) only coefficients
>>> Poly([1, 0, a], x)
Poly(x**2 + a, x)
```
 expression is a TUPLE:

((c_1, c2, ..., c_n), (M_1, M_2, ..., M_n))

```>>> Poly( ((S(1), S(2)), ((3,), (4,))), x)
Poly(x**3 + 2*x**4, x)
```
 expression is a DICTIONARY:

{ M_1 : c_1, M_2 : c_2, ..., M_n : c_n }

```>>> Poly( {(1, 2): S(3), (4, 5): S(6)} ,x ,y)
Poly(6*x**4*y**5 + 3*x*y**2, x, y)
```

These initialization methods are not just conveniences for creating polynomials. They are designed for different tasks and the resulting polynomials have specific properties:

 All coefficients and monomials are validated before
polynomial instance is created. Monomials are sorted with respect to the given order.

 No validity checking, no sorting, just a raw copy.

 No validity checking, but monomials are sorted with
respect to the given order.

For interactive usage choose  as it’s safe and relatively fast.

CAUTION: Use  or  internally for time critical algorithms, when you know that coefficients and monomials will be valid sympy expressions. Use them with caution! If the coefficients are integers instead of sympy integers (e.g. 1 instead of S(1)) the polynomial will be created but you may run into problems if you try to print the polynomial. If the monomials are not given as tuples of integers you will have problems.

Implemented methods:

U –> handles uniformly int | long and Basic coefficients
(other methods need to be overridden in IntegerPoly)

P –> a property (with appropriate decorator)

• –> otherwise

 Representation conversion:

[1.1] [–] as_basic –> converts to a valid sympy expression [1.2] [U-] as_dict –> returns { M_1 : c_1, ..., M_1 : c_1 } [1.3] [U-] as_uv_dict –> returns dict with integer keys

 Polynomial internals:

[2.1] [UP] coeffs –> list of coefficients [2.2] [UP] monoms –> list of monomials [2.3] [UP] symbols –> an ordered list of symbols [2.4] [UP] order –> the ordering of monomials [2.5] [UP] stamp –> frozen set of polynomial’s variables [2.6] [UP] domain –> coefficient domain, see  for details [2.7] [UP] args –> required for printing and hashing [2.8] [UP] flags –> dict of keyword arguments to Poly

 General characteristics:

[3.1] [UP] norm –> computes oo-norm of coefficients [3.2] [UP] length –> counts the total number of terms [3.3] [UP] degree –> returns degree of the leading monomial [3.4] [UP] total_degree –> returns true total degree of a polynomial

 Items generators:

[4.1] [U-] iter_coeffs –> iterate over coefficients [4.2] [U-] iter_monoms –> iterate over monomials [4.3] [U-] iter_terms –> iterate over terms

[4.4] [U-] iter_all_coeffs –> iterate over all coefficients [4.5] [U-] iter_all_monoms –> iterate over all monomials [4.6] [U-] iter_all_terms –> iterate over all terms

 Leading and trailing items:

[5.1] [UP] lead_coeff or LC –> returns the leading coefficient [5.2] [UP] lead_monom or LM –> returns the leading monomial [5.3] [UP] lead_term or LT –> returns the leading term

[5.4] [UP] tail_coeff or TC –> returns the trailing coefficient [5.5] [UP] tail_monom or TM –> returns the trailing monomial [5.6] [UP] tail_term or TT –> returns the trailing term

 Arithmetic operators:

[6.1] [U-] __abs__ –> for all i, abs(c_i) [6.2] [U-] __neg__ –> polynomial negation [6.3] [U-] __add__ –> polynomial addition [6.4] [U-] __sub__ –> polynomial subtraction [6.5] [–] __mul__ –> polynomial multiplication [6.6] [U-] __pow__ –> polynomial exponentiation [6.7] [U-] __div__ –> polynomial quotient [6.8] [U-] __mod__ –> polynomial remainder [6.9] [U-] __divmod__ –> both ‘div’ and ‘mod’ [6.10] [U-] __truediv__ –> the same as ‘div’

 Polynomial properties:

[7.1] [UP] is_zero –> only one term c_0 == 0 [7.2] [UP] is_one –> only one term c_0 == 1 [7.3] [-P] is_number –> only numeric constant term [7.4] [UP] is_constant –> only arbitrary constant term [7.5] [UP] is_monomial –> number of terms == 1 [7.6] [UP] is_univariate –> number of variables == 1 [7.7] [UP] is_multivariate –> number of variables > 1 [7.8] [UP] is_homogeneous –> has constant term [7.9] [UP] is_inhomogeneous –> no constant term [7.10] [UP] is_sparse –> filled with less than 90% of terms [7.11] [UP] is_dense –> filled with more than 90% of terms [7.12] [UP] is_monic –> returns True if leading coeff is one [7.13] [UP] is_primitive –> returns True if content is one [7.14] [UP] is_squarefree –> no factors of multiplicity >= 2 [7.15] [UP] is_linear –> all monomials of degree <= 1

 Coefficients properties:

[8.1] [UP] has_integer_coeffs –> for all i, c_i in Z [8.2] [UP] has_rational_coeffs –> for all i, c_i in Q [8.3] [UP] has_radical_coeffs –> for all i, c_i in R [8.4] [UP] has_complex_coeffs –> for all i, c_i in C [8.5] [UP] has_symbolic_coeffs –> otherwise

 Special functionality:

[9.1] [–] as_monic –> divides all coefficients by LC [9.2] [–] as_integer –> returns polynomial with integer coeffs

[9.3] [-P] content –> returns GCD of polynomial coefficients [9.4] [–] as_primitive –> returns content and primitive part

[9.5] [U-] as_squarefree –> returns square-free part of a polynomial

[9.6] [U-] as_reduced –> extract GCD of polynomial monomials

[9.7] [–] map_coeffs –> applies a function to all coefficients [9.8] [U-] coeff –> returns coefficient of the given monomial

[9.9] [U-] unify_with –> returns polys with a common set of symbols

[9.10] [U-] diff –> efficient polynomial differentiation [9.11] [U-] integrate –> efficient polynomial integration

[9.12] [U-] invert –> computes multiplicative inverse in K[t]

 Operations on terms:

[10.1] [U-] add_term –> add a term to a polynomial [10.2] [U-] sub_term –> subtract a term from a polynomial

[10.3] [–] mul_term –> multiply a polynomial with a term [10.4] [–] div_term –> divide a polynomial by a term

[10.5] [U-] remove_lead_term –> remove leading term (up to order) [10.6] [U-] remove_last_term –> remove last term (up to order)

 Substitution and evaluation:

[11.1] [U-] __call__ –> evaluates poly at the given point [11.2] [U-] evaluate –> evaluates poly for specific vars [11.3] [–] _eval_subs –> efficiently substitute variables

 Comparison functions:

[12.1] [U-] __eq__ –> P1 == P, up to order of monomials [12.2] [U-] __ne__ –> P1 != P, up to order of monomials [12.3] [U-] __nonzero__ –> check if zero polynomial

 String representation functions:

[13.1] [U-] repr –> returns representation of ‘self’ [13.3] [U-] str –> returns pretty representation

 Other (derived from Basic) functionality:

[14.1] [U-] _eval_is_polynomial –> checks if poly is a poly

For general information on polynomials and algorithms, refer to:

 D. E. Knuth, The Art of Computer Programming: Seminumerical
Algorithms, v.2, Addison-Wesley Professional, 1997
 J. von zur Gathen, J. Gerhard, Modern Computer Algebra,
Second Edition, Cambridge University Press, 2003
 K. Geddes, S. R. Czapor, G. Labahn, Algorithms for
Computer Algebra, Springer, 1992
 D. Bini, V. Y.Pan, Polynomial and Matrix Computations:
Volume 1: Fundamental Algorithms, Birkhauser Boston, 1994
 R. T. Moenck, Practical Fast Polynomial Multiplication,
Proceedings of the third ACM symposium on Symbolic and algebraic computation, ACM Press, Yorktown Heights, New York, USA, 1976, pp. 136-148
 M. Bronstein, Symbolic Integration I: Transcendental
Functions, Second Edition, Springer-Verlag, 2005

Efficiently add a single term to ‘self’.

The list of monomials is sorted at initialization time, this motivates usage of binary search algorithm to find an index of an existing monomial or a suitable place for a new one. This gives O(lg(n)) complexity, where ‘n’ is the initial number of terms, superior to naive approach.

For more information on the implemented algorithm refer to:

 D. E. Knuth, The Art of Computer Programming: Sorting
and Searching, v.1, Addison-Wesley Professional, 1998
as_basic()

Converts polynomial to a valid sympy expression.

Takes list representation of a polynomial and constructs expression using symbols used during creation of a given polynomial. If you wish to have different symbols in the resulting expressions, use subs() first.

Note that the result is always returned in expanded form.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> p = Poly(x**2+3, x)
>>> p.as_basic()
3 + x**2
```
as_dict()

Convert list representation to dictionary representation.

Due to hashing of immutable expressions in Python, we can not store a dictionary directly in a polynomial instance. Also it would be inconvenient in case of ordering of monomials (unnecessary sorting).

This method creates dictionary efficiently, so it can be used in several algorithms which perform best when dicts are being used, e.g. addition, multiplication etc.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> p = Poly(x**2+3, x)
>>> p.as_dict()
{(0,): 3, (2,): 1}
```
as_integer()

Makes all coefficients integers if possible.

Given a polynomial with rational coefficients, returns a tuple consisting of a common denominator of those coefficients and an integer polynomial. Otherwise an exception is being raised.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly(3*x**2 + x, x).as_integer()
(1, Poly(3*x**2 + x, x))
```
```>>> Poly(3*x**2 + x/2, x).as_integer()
(2, Poly(6*x**2 + x, x))
```
as_monic()

Returns a monic polynomial.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly(x**2 + 4, x).as_monic()
Poly(x**2 + 4, x)
```
```>>> Poly(2*x**2 + 4, x).as_monic()
Poly(x**2 + 2, x)
```
```>>> Poly(y*x**2 + y**2 + y, x).as_monic()
Poly(x**2 + 1 + y, x)
```
as_primitive()

Returns content and primitive part of a polynomial.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> p = Poly(4*x**2 + 2*x, x)
>>> p.as_primitive()
(2, Poly(2*x**2 + x, x))
```
as_reduced()

Remove GCD of monomials from ‘self’.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly(x**3 + x, x).as_reduced()
((1,), Poly(x**2 + 1, x))
```
```>>> Poly(x**3*y+x**2*y**2, x, y).as_reduced()
((2, 1), Poly(x + y, x, y))
```
as_squarefree()

Returns square-free part of a polynomial.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly((x-1)**2, x).as_squarefree()
Poly(x - 1, x)
```
as_uv_dict()

Return dictionary representation with integer keys.

In case of univariate polynomials it is inefficient to to handle exponents as singleton tuples, as an example see multiplication algorithm. This method will return dictionary representation with all tuples converted to explicit integers.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> p = Poly(x**2+3, x)
>>> p.as_uv_dict()
{0: 3, 2: 1}
```
static cancel(f, *symbols)

Cancel common factors in a fractional expression.

Given a quotient of polynomials, cancel common factors from the numerator and the denominator. The result is formed in an expanded form, even if there was no cancellation.

To improve the speed of calculations a list of symbols can be specified. This can be particularly useful in univariate case with additional parameters, to avoid Groebner basis computations.

The input fraction can be given as a single expression or as a tuple consisting of the numerator and denominator.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly.cancel((x**2-y**2)/(x-y), x, y)
x + y
```
```>>> Poly.cancel((x**2-y**2, x-y), x, y)
x + y
```
coeff(*monom)

Returns coefficient of a particular monomial.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> p = Poly(3*x**2*y + 4*x*y**2 + 1, x, y)
```
```>>> p.coeff(2, 1)
3
>>> p.coeff(1, 2)
4
>>> p.coeff(1, 1)
0
```

If len(monom) == 0 then returns coeff of the constant term:

```>>> p.coeff(0, 0)
1
>>> p.coeff()
1
```
content

Returns integer GCD of all the coefficients.

```>>> from sympy import Poly
>>> from sympy.abc import x, y, z
```
```>>> p = Poly(2*x + 5*x*y, x, y)
>>> p.content
1
```
```>>> p = Poly(2*x + 4*x*y, x, y)
>>> p.content
2
```
```>>> p = Poly(2*x + z*x*y, x, y)
>>> p.content
1
```
degree
Returns degree of the leading term.
diff(*symbols)

Efficiently differentiate polynomials.

Differentiate a polynomial with respect to a set of symbols. If a symbol is polynomial’s variable, then monomial differentiation is performed and coefficients updated with integer factors. In other case each of the coefficients is differentiated.

Additionally, for each of the symbols you can specify a single positive integer which will indicate the number of times to perform differentiation using this symbol.

```>>> from sympy import Poly
>>> from sympy.abc import x, y, z
```
```>>> p = Poly(x**2*y + z**2, x, y)
```
```>>> p.diff(x)
Poly(2*x*y, x, y)
```
```>>> p.diff(x, 2)
Poly(2*y, x, y)
```
```>>> p.diff(x, 2, y)
Poly(2, x, y)
```
```>>> p.diff(z)
Poly(2*z, x, y)
```
div_term(coeff, monom=None)
Efficiently divide ‘self’ by a single term.
evaluate(pattern)
Evaluates polynomial for a given set of symbols.
integrate(*symbols)

Efficiently integrate polynomials.

Integrate a polynomial with respect a set of symbols. If a symbol is polynomial’s variable, then monomial integration is performed and coefficients updated with integer factors. In other case each of the coefficients is integrated.

Additionally, for each of the symbols you can specify a single positive integer which will indicate the number of times to perform integration using this symbol.

```>>> from sympy import Poly
>>> from sympy.abc import x, y, z
```
```>>> p = Poly(x**2*y + z**2, x, y)
```
```>>> p.integrate(x)
Poly(1/3*x**3*y + z**2*x, x, y)
```
```>>> p.integrate(x, 2)
Poly(1/12*x**4*y + z**2/2*x**2, x, y)
```
```>>> p.integrate(x, 2, y)
Poly(1/24*x**4*y**2 + z**2/2*x**2*y, x, y)
```
```>>> p.integrate(z)
Poly(z*x**2*y + z**3/3, x, y)
```
invert(modulus)
Compute multiplicative inverse in K[x].
is_dense

Returns True if ‘self’ is dense.

Let ‘self’ be a polynomial in M variables of a total degree N and having L terms (with non-zero coefficients). Let K be the number of monomials in M variables of degree at most N. Then ‘self’ is considered dense if it’s at least 90% filled.

The total number of monomials is given by (M + N)! / (M! N!), where the factorials are estimated using improved Stirling’s approximation:

n! = sqrt((2 n + 1/3) pi) n**n exp(-n)

For more information on this subject refer to:

http://mathworld.wolfram.com/StirlingsApproximation.html
is_squarefree

Returns True if ‘self’ has no factors of multiplicity >= 2.

```>>> from sympy import Poly
>>> from sympy.abc import x, y
```
```>>> Poly(x-1, x).is_squarefree
True
```
```>>> Poly((x-1)**2, x).is_squarefree
False
```
kill_last_term()
Removes last term from ‘self’.
Removes leading term from ‘self’.
map_coeffs(f, *args, **kwargs)

Apply a function to all the coefficients.

```>>> from sympy import Poly, expand
>>> from sympy.abc import x, y, u, v
```
```>>> p = Poly(x**2 + 2*x*y, x, y)
>>> q = p.map_coeffs(lambda c: 2*c)
```
```>>> q.as_basic()
4*x*y + 2*x**2
```
```>>> p = Poly(u*x**2 + v*x*y, x, y)
>>> q = p.map_coeffs(expand, complex=True)
```
```>>> q.as_basic()
x**2*(I*im(u) + re(u)) + x*y*(I*im(v) + re(v))
```
mul_term(coeff, monom=None)
Efficiently multiply ‘self’ with a single term.
norm
Computes oo-norm of polynomial’s coefficients.
sub_term(coeff, monom)

Efficiently subtract a single term from ‘self’.

The list of monomials is sorted at initialization time, this motivates usage of binary search algorithm to find an index of an existing monomial or a suitable place for a new one. This gives O(lg(n)) complexity, where ‘n’ is the initial number of terms, superior to naive approach.

For more information on the implemented algorithm refer to:

 D. E. Knuth, The Art of Computer Programming: Sorting
and Searching, v.2, Addison-Wesley Professional, 1998
total_degree
Returns true total degree of a polynomial.
unify_with(other)

Unify ‘self’ with a polynomial or a set of polynomials.

This method will return polynomials of the same type, dominated by ‘self’, with a common set of symbols (which is a union of all symbols from all polynomials) and with common monomial ordering.

You can pass a polynomial or an expression to this method, or a list or a tuple of polynomials or expressions. If any of the inputs would be an expression then it will be converted to a polynomial.