Generic data structures for multivariate polynomials - Polynomials

Skip to content
Back to top
View this page
Edit this page

# 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 array

class sage.rings.polynomial.polydict.ETuple

  Bases: `object`

  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 then this 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 hash table 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

        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))

    Python

        >>> 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)

    Return an optionally sorted list of nonzero positions either in `self` or other, i.e. the only positions that need to be considered for any vector operation.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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)`.

    The entries of the result are the maximum of 0 and the difference of the corresponding entries of `self` and `other`.

  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 is zero in position `pos` and coincides with `self` in the other positions.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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 variable

  divides(other)

    Return whether `self` divides `other`, i.e., no entry of `self` exceeds that of `other`.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import ETuple
        sage: e = ETuple([1, 0, 2])
        sage: f = ETuple([0, 1, 1])
        sage: e.dotprod(f)
        2
        sage: e = ETuple([1, 1, -1])
        sage: f = ETuple([0, -2, 1])
        sage: e.dotprod(f)
        -3

    Python

        >>> 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

  eadd(other)

    Return the vector addition of `self` with `other`.

    EXAMPLES:

    Sage

        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)

    Python

        >>> 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

        sage: # needs sage.libs.singular
        sage: 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 (...)

    [Python]

        >>> 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 (...)

  eadd_p(other, pos)

    Add `other` to `self` at position `pos`.

    EXAMPLES:

    Sage

        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])
        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]

    Python

        >>> 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

        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)

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import ETuple
        sage: e = ETuple([1, 0, 2])
        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]

    Python

        >>> 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

        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)

    Python

        >>> 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)

  emul(factor)

    Scalar Vector multiplication of `self`.

    EXAMPLES:

    Sage

        sage: from sage.rings.polynomial.polydict import ETuple
        sage: e = ETuple([1, 0, 2])
        sage: e.emul(2)
        (2, 0, 4)

    Python

        >>> 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

        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

    Python

        >>> 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):
        ...
        ZeroDivisionError

  esub(other)

    Vector subtraction of `self` with `other`.

    EXAMPLES:

    Sage

        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)

    Python

        >>> 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.esub(f)
        (1, -1, 1)

  is_constant()

    Return if all exponents are zero in the tuple.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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

        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

    Python

        >>> 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 nonzero exponents in the tuple.

    INPUT:

    - `sort` – boolean (default: `False`); if `True` a sorted list is returned; if `False` an unsorted list is returned

    EXAMPLES:

    Sage

        sage: from sage.rings.polynomial.polydict import ETuple
        sage: e = ETuple([1, 0, 2])
        sage: e.nonzero_positions()
        [0, 2]

    Python

        >>> 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 nonzero values of the tuple.

    INPUT:

    - `sort` – boolean (default: `True`); if `True` the values are sorted by their indices. Otherwise the values are returned unsorted.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import ETuple
        sage: e = ETuple([1, 2, 3])
        sage: e.reversed()
        (3, 2, 1)

    Python

        >>> from sage.all import *
        >>> from sage.rings.polynomial.polydict import ETuple
        >>> e = ETuple([Integer(1), Integer(2), Integer(3)])
        >>> e.reversed()
        (3, 2, 1)

  sparse_iter()

    Iterator over the elements of `self` where the elements are returned as `(i, e)` where `i` is the position of `e` in the tuple.

    EXAMPLES:

    Sage

        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)]

    Python

        >>> 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

        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

    Python

        >>> 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 nonnegative entries of `self.esub(other)`.

  weighted_degree(w)

    Return the weighted sum of entries.

    INPUT:

    - `w` – tuple of nonnegative integers

    EXAMPLES:

    Sage

        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))
        Traceback (most recent call last):
        ...
        ValueError: w must be of the same length as the ETuple

    Python

        >>> 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 nonnegative 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 implicitly 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 the most 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

        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: f
        PolyDict with representation {(1, 0): 1, (1, 1): 4}

    Python

        >>> 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))
        >>> 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 in this polynomial.

    The coefficient is defined as follows. If f is this polynomial, then the coefficient is the sum T/mon where the sum is over terms T in f that are exactly divisible by mon.

  coefficients()

    Return the coefficients of `self`.

    EXAMPLES:

    Sage

        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]

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import PolyDict
        sage: f = PolyDict({(2, 3): 0})
        sage: f
        PolyDict 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: f
        PolyDict with representation {(2, 3): 0}

    Python

        >>> from sage.all import *
        >>> from sage.rings.polynomial.polydict import PolyDict
        >>> f = PolyDict({(Integer(2), Integer(3)): Integer(0)})
        >>> f
        PolyDict 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}

  degree(x=None)

    Return the total degree or the maximum degree in the variable `x`.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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

        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

    Python

        >>> 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),): 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

        sage: from sage.rings.polynomial.polydict import PolyDict
        sage: PolyDict({(1, 1): 1}).derivative_i(0)
        PolyDict with representation {(0, 1): 1}

    Python

        >>> 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

        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}

    Python

        >>> 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

        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)]

    Python

        >>> 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.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

        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'

    Python

        >>> 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')
        'hello'

  homogenize(var)

    Return the homogeneization of `self` by increasing the degree of the variable `var`.

    EXAMPLES:

    Sage

        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}

    Python

        >>> 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:

    Sage

        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

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import PolyDict
        sage: PolyDict({(1, 1): 1}).integral_i(0)
        PolyDict with representation {(2, 1): 1/2}

    Python

        >>> 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:

    Sage

        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

    Python

        >>> 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(w=None)

    Return whether this polynomial is homogeneous.

    EXAMPLES:

    Sage

        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

    Python

        >>> 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` – boolean (default: `True`)

    - `atomic_coefficients` – boolean (default: `True`)

    EXAMPLES:

    Sage

        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}'

    Python

        >>> 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 order

  list()

    Return a list that defines `self`.

    EXAMPLES:

    Sage

        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]]]

    Python

        >>> 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()

    Return 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

        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

    Python

        >>> 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()
        (2, 3)
        >>> PolyDict({}).max_exp() # returns None

  min_exp()

    Return 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

        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

    Python

        >>> 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 None

  monomial_coefficient(mon)

    Return the coefficient of the monomial `mon`.

    INPUT:

    - `mon` – a PolyDict with a single key

    EXAMPLES:

    Sage

        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

    Python

        >>> 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

  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` – boolean (default: `True`)

    - `atomic_coefficients` – boolean (default: `True`)

    EXAMPLES:

    Sage

        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'

    Python

        >>> 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

        sage: Integers(2)['x, y'].gens()
        (x, y)

    [Python]

        >>> from sage.all import *
        >>> Integers(Integer(2))['x, y'].gens()
        (x, y)

    We make sure that intervals are correctly represented.

    Sage

        sage: f = PolyDict({(2, 3): RIF(1/2,3/2), (1, 2): RIF(-1,1)})               # needs sage.rings.real_interval_field
        sage: f.poly_repr(['x', 'y'])                                               # needs sage.rings.real_interval_field
        '1.?*x^2*y^3 + 0.?*x*y^2'

    Python

        >>> 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` – list of degree restrictions; list elements are `None` if the variable in that position should be unrestricted

    EXAMPLES:

    Sage

        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}

    Python

        >>> 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

        sage: from sage.rings.polynomial.polydict import PolyDict
        sage: f = PolyDict({(2, 3):0})
        sage: f
        PolyDict with representation {(2, 3): 0}
        sage: f.remove_zeros()
        sage: f
        PolyDict with representation {}

    Python

        >>> from sage.all import *
        >>> from sage.rings.polynomial.polydict import PolyDict
        >>> f = PolyDict({(Integer(2), Integer(3)):Integer(0)})
        >>> f
        PolyDict 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

        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: f
        PolyDict with representation {(1, 1): O(t^1)}

    [Python]

        >>> 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.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 \(PolyDict`s using a specified term ordering ``sortkey`\).

    EXAMPLES:

    Sage

        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)
        True
        sage: p1.rich_compare(p2, op_EQ, O.sortkey)
        False
        sage: p1.rich_compare(p2, op_NE, O.sortkey)
        True
        sage: p1.rich_compare(p2, op_LT, O.sortkey)
        True

        sage: 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

    Python

        >>> 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:

    Sage

        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}

    Python

        >>> 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

        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}

    Python

        >>> 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

        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}

    Python

        >>> 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))
        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

        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}

    Python

        >>> 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

        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
        sage: PolyDict({}).degree()
        -1

    Python

        >>> 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

      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

  Python

      >>> 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({}))
      -1

sage.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

      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):
      ...
      ValueError: not a monomial

  Python

      >>> 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