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

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

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))
from sage.rings.polynomial.polydict import ETuple
e = ETuple([-2, 1, -5, 3, 1, 0])
f = ETuple([1, -3, -3, 4, 0, 2])
e.combine_to_positives(f)
common_nonzero_positions(other, sort=False)[source]

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: 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]
from sage.rings.polynomial.polydict import ETuple
e = ETuple([1, 0, 2])
f = ETuple([0, 0, 1])
e.common_nonzero_positions(f)
e.common_nonzero_positions(f, sort=True)
divide_by_gcd(other)[source]

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

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

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
>>> 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
from sage.rings.polynomial.polydict import ETuple
ETuple([1, 1, 0, 1, 0]).divides(ETuple([2, 2, 2, 2, 2]))
ETuple([0, 3, 0, 1, 0]).divides(ETuple([2, 2, 2, 2, 2]))
ETuple([0, 3, 0, 1, 0]).divides(ETuple([0, 3, 2, 2, 2]))
ETuple([0, 0, 0, 0, 0]).divides(ETuple([2, 2, 2, 2, 2]))
ETuple({104: 18, 256: 25, 314:78}, length=400r).divides(ETuple({104: 19, 105: 20, 106: 21}, length=400r))
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))
dotprod(other)[source]

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

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

Verify that Issue #6428 has been addressed:

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 (...)   # 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
# needs sage.libs.singular
R.<y, z> = Frac(QQ['x'])[]
type(y)
y^(2^32)
eadd_p(other, pos)[source]

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])
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]
from sage.rings.polynomial.polydict import ETuple
e = ETuple([1, 0, 2])
e.eadd_p(5, 1)
e = ETuple([0]*7)
e.eadd_p(5, 4)
ETuple([0,1]).eadd_p(1, 0) == ETuple([1,1])
e = ETuple([0, 1, 0])
e.eadd_p(0, 0).nonzero_positions()
e.eadd_p(0, 1).nonzero_positions()
e.eadd_p(0, 2).nonzero_positions()
eadd_scaled(other, scalar)[source]

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)
from sage.rings.polynomial.polydict import ETuple
e = ETuple([1, 0, 2])
f = ETuple([0, 1, 1])
e.eadd_scaled(f, 3)
emax(other)[source]

Vector of maximum 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.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]
from sage.rings.polynomial.polydict import ETuple
e = ETuple([1, 0, 2])
f = ETuple([0, 1, 1])
e.emax(f)
e = ETuple((1, 2, 3, 4))
f = ETuple((4, 0, 2, 1))
f.emax(e)
e = ETuple((1, -2, -2, 4))
f = ETuple((4, 0, 0, 0))
f.emax(e)
f.emax(e).nonzero_positions()
emin(other)[source]

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

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

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):
...
ZeroDivisionError
from sage.rings.polynomial.polydict import ETuple
ETuple([1, 0, 2]).escalar_div(2)
ETuple([0, 3, 12]).escalar_div(3)
ETuple([1, 5, 2]).escalar_div(0)
esub(other)[source]

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

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

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
from sage.rings.polynomial.polydict import ETuple
ETuple([0, 0]).is_multiple_of(3)
ETuple([0, 3, 12, 0, 6]).is_multiple_of(3)
ETuple([0, 0, 2]).is_multiple_of(3)
nonzero_positions(sort=False)[source]

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

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

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

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

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
from sage.rings.polynomial.polydict import ETuple
ETuple([1, 1, 0, 2, 0]).unweighted_degree()
ETuple([-1, 1]).unweighted_degree()
unweighted_quotient_degree(other)[source]

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

Return the weighted sum of entries.

INPUT:

  • w – tuple of nonnegative 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))
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
from sage.rings.polynomial.polydict import ETuple
e = ETuple([1, 1, 0, 2, 0])
e.weighted_degree((1, 2, 3, 4, 5))
ETuple([-1, 1]).weighted_degree((1, 2))
ETuple([1, 0]).weighted_degree((1, 2, 3))
weighted_quotient_degree(other, w)[source]

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

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

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: f
PolyDict 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))
>>> f
PolyDict with representation {(1, 0): 1, (1, 1): 4}
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(1, 0): 1, (1, 1): -2})
f.apply_map(lambda x: x^2)
f
coefficient(mon)[source]

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()[source]

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]
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
sorted(f.coefficients())
coerce_coefficients(A)[source]

Coerce the coefficients in the parent A.

EXAMPLES:

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}
>>> 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}
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 0})
f
f.coerce_coefficients(QQ)
f
degree(x=None)[source]

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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.degree()
f.degree(PolyDict({(1, 0): 1}))
f.degree(PolyDict({(0, 1): 1}))
derivative(x)[source]

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),): 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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.derivative(PolyDict({(1, 0): 1}))
f.derivative(PolyDict({(0, 1): 1}))
PolyDict({(-1,): 1}).derivative(PolyDict({(1,): 1}))
PolyDict({(-2,): 1}).derivative(PolyDict({(1,): 1}))
PolyDict({}).derivative(PolyDict({(1, 1): 1}))
derivative_i(i)[source]

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}
from sage.rings.polynomial.polydict import PolyDict
PolyDict({(1, 1): 1}).derivative_i(0)
dict()[source]

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}
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.dict()
exponents()[source]

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), Integer(2)): Integer(3), (Integer(2), Integer(1)): Integer(4)})
>>> sorted(f.exponents())
[(1, 2), (2, 1), (2, 3)]
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
sorted(f.exponents())
get(e, default=None)[source]

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')
'hello'
from sage.rings.polynomial.polydict import PolyDict, ETuple
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.get(ETuple([1,2]))
f.get(ETuple([1,1]), 'hello')
homogenize(var)[source]

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}
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(0, 0): 1, (2, 1): 3, (1, 1): 5})
f.homogenize(0)
f.homogenize(1)
PolyDict({(0, 1): 1, (1, 1): -1}).homogenize(0)
integral(x)[source]

Return the integral 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.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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.integral(PolyDict({(1, 0): 1}))
f.integral(PolyDict({(0, 1): 1}))
PolyDict({(-1,): 1}).integral(PolyDict({(1,): 1}))
PolyDict({(-2,): 1}).integral(PolyDict({(1,): 1}))
PolyDict({}).integral(PolyDict({(1, 1): 1}))
integral_i(i)[source]

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}
from sage.rings.polynomial.polydict import PolyDict
PolyDict({(1, 1): 1}).integral_i(0)
is_constant()[source]

Return whether this polynomial is constant.

EXAMPLES:

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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.is_constant()
g = PolyDict({(0, 0): 2})
g.is_constant()
h = PolyDict({})
h.is_constant()
is_homogeneous(w=None)[source]

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
from sage.rings.polynomial.polydict import PolyDict
PolyDict({}).is_homogeneous()
PolyDict({(1, 2): 1, (0, 3): -2}).is_homogeneous()
PolyDict({(1, 0): 1, (1, 2): 3}).is_homogeneous()
latex(vars, atomic_exponents=True, atomic_coefficients=True, sortkey=None)[source]

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: 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}'
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.latex(['a', 'WW'])
lcmt(greater_etuple)[source]

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()[source]

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]]]
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
sorted(f.list())
max_exp()[source]

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: 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()
(2, 3)
>>> PolyDict({}).max_exp() # returns None
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.max_exp()
PolyDict({}).max_exp() # returns None
min_exp()[source]

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: 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 None
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.min_exp()
PolyDict({}).min_exp() # returns None
monomial_coefficient(mon)[source]

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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
f.monomial_coefficient(PolyDict({(2,1):1}).dict())
poly_repr(vars, atomic_exponents=True, atomic_coefficients=True, sortkey=None)[source]

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: 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'
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
f.poly_repr(['a', 'WW'])

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)
Integers(2)['x, y'].gens()

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_field
sage: 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'
f = PolyDict({(2, 3): RIF(1/2,3/2), (1, 2): RIF(-1,1)})               # needs sage.rings.real_interval_field
f.poly_repr(['x', 'y'])                                               # needs sage.rings.real_interval_field
polynomial_coefficient(degrees)[source]

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: 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}
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.polynomial_coefficient([2, None])
f = PolyDict({(0, 3): 2, (0, 2): 3, (2, 1): 4})
f.polynomial_coefficient([0, None])
remove_zeros(zero_test=None)[source]

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

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: f
PolyDict 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.zero()})
>>> f.remove_zeros(lambda s: s.is_zero() and s.prec() is Infinity)
>>> f
PolyDict with representation {(1, 1): O(t^1)}
R.<t> = PowerSeriesRing(QQ)
f = PolyDict({(1, 1): O(t), (1, 0): R.zero()})
f.remove_zeros(lambda s: s.is_zero() and s.prec() is Infinity)
f
rich_compare(other, op, sortkey=None)[source]

Compare two \(PolyDict`s using a specified term ordering ``sortkey`\).

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)
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
>>> 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
from sage.rings.polynomial.polydict import PolyDict
from sage.structure.richcmp import op_EQ, op_NE, op_LT
p1 = PolyDict({(0,): 1})
p2 = PolyDict({(0,): 2})
O = TermOrder()
p1.rich_compare(PolyDict({(0,): 1}), op_EQ, O.sortkey)
p1.rich_compare(p2, op_EQ, O.sortkey)
p1.rich_compare(p2, op_NE, O.sortkey)
p1.rich_compare(p2, op_LT, O.sortkey)
p3 = PolyDict({(3, 2, 4): 1, (3, 2, 5): 2})
p4 = PolyDict({(3, 2, 4): 1, (3, 2, 3): 2})
p3.rich_compare(p4, op_LT, O.sortkey)
scalar_lmult(s)[source]

Return the left 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_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}
from sage.rings.polynomial.polydict import PolyDict
x, y = FreeMonoid(2, 'x, y').gens()  # a strange object to live in a polydict, but non-commutative!   # needs sage.combinat
f = PolyDict({(2,3):x})                                               # needs sage.combinat
f.scalar_lmult(y)                                                     # needs sage.combinat
f = PolyDict({(2,3):2, (1,2):3, (2,1):4})
f.scalar_lmult(-2)
f.scalar_lmult(RIF(-1,1))                                             # needs sage.rings.real_interval_field
scalar_rmult(s)[source]

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}
>>> 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}
from sage.rings.polynomial.polydict import PolyDict
x, y = FreeMonoid(2, 'x, y').gens()  # a strange object to live in a polydict, but non-commutative!   # needs sage.combinat
f = PolyDict({(2, 3): x})                                             # needs sage.combinat
f.scalar_rmult(y)                                                     # needs sage.combinat
f = PolyDict({(2,3):2, (1, 2): 3, (2, 1): 4})
f.scalar_rmult(-2)
f.scalar_rmult(RIF(-1,1))                                             # needs sage.rings.real_interval_field
term_lmult(exponent, s)[source]

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))
PolyDict with representation {(2, 4): -6, (3, 3): -8, (3, 5): -4}
from sage.rings.polynomial.polydict import ETuple, PolyDict
x, y = FreeMonoid(2, 'x, y').gens()  # a strange object to live in a polydict, but non-commutative!   # needs sage.combinat
f = PolyDict({(2, 3): x})                                             # needs sage.combinat
f.term_lmult(ETuple((1, 2)), y)                                       # needs sage.combinat
f = PolyDict({(2,3): 2, (1,2): 3, (2,1): 4})
f.term_lmult(ETuple((1, 2)), -2)
term_rmult(exponent, s)[source]

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}
from sage.rings.polynomial.polydict import ETuple, PolyDict
x, y = FreeMonoid(2, 'x, y').gens()  # a strange object to live in a polydict, but non-commutative!   # needs sage.combinat
f = PolyDict({(2, 3): x})                                             # needs sage.combinat
f.term_rmult(ETuple((1, 2)), y)                                       # needs sage.combinat
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.term_rmult(ETuple((1, 2)), -2)
total_degree(w=None)[source]

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
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
from sage.rings.polynomial.polydict import PolyDict
f = PolyDict({(2, 3): 2, (1, 2): 3, (2, 1): 4})
f.total_degree()
f.total_degree((3, 1))
PolyDict({}).degree()
sage.rings.polynomial.polydict.gen_index(x)[source]

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({}))
-1
from sage.rings.polynomial.polydict import PolyDict, gen_index
gen_index(PolyDict({(1, 0): 1}))
gen_index(PolyDict({(0, 1): 1}))
gen_index(PolyDict({}))
sage.rings.polynomial.polydict.make_ETuple(data, length)[source]

Ensure support for pickled data from older sage versions.

sage.rings.polynomial.polydict.make_PolyDict(data)[source]

Ensure support for pickled data from older sage versions.

sage.rings.polynomial.polydict.monomial_exponent(p)[source]

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