28.6 Multivariate Polynomial Rings

Module: sage.rings.polynomial.multi_polynomial_ring

Multivariate Polynomial Rings

Sage implements multivariate polynomial rings through several backends. The generic implementation used the classes PolyDict and ETuple to construct a dictionary with exponent tuples as keys and coefficients as values.

Additionally, specialized and optimized implementations are provided for multivariate polynomials over $ \mathbf{Q}$ and $ \mathbf{F}_p$ . These are implemented in the classes MPolynomialRing_libsingular and MPolynomial_libsingular

Author Log:

We construct the Frobenius morphism on F$ _{5}[x,y,z]$ over $ \mathbf{F}_5$ :

sage: R, (x,y,z) = PolynomialRing(GF(5), 3, 'xyz').objgens()
sage: frob = R.hom([x^5, y^5, z^5])
sage: frob(x^2 + 2*y - z^4)
-z^20 + x^10 + 2*y^5
sage: frob((x + 2*y)^3)
x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15
sage: (x^5 + 2*y^5)^3
x^15 + x^10*y^5 + 2*x^5*y^10 - 2*y^15

We make a polynomial ring in one variable over a polynomial ring in two variables:

sage: R.<x, y> = PolynomialRing(QQ, 2)
sage: S.<t> = PowerSeriesRing(R)
sage: t*(x+y)
(x + y)*t

Class: MPolynomialRing_macaulay2_repr

class MPolynomialRing_macaulay2_repr

Functions: is_exact

Special Functions: _macaulay2_,$ \,$ _macaulay2_base_str,$ \,$ _macaulay2_set_ring

Class: MPolynomialRing_polydict

class MPolynomialRing_polydict
Multivariable polynomial ring.

sage: R = PolynomialRing(Integers(12), 'x', 5); R
Multivariate Polynomial Ring in x0, x1, x2, x3, x4 over Ring of integers
modulo 12
sage: loads(R.dumps()) == R    
True
MPolynomialRing_polydict( self, base_ring, n, names, order)

Special Functions: __call__,$ \,$ __cmp__,$ \,$ __init__,$ \,$ _monomial_order_function,$ \,$ _poly_class

__call__( self, x, [check=True])

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

We create a Macaulay2 multivariate polynomial via ideal arithmetic, then coerce it into R.

sage: R.<x,y> = PolynomialRing(QQ, 2)                        # optional
sage: I = R.ideal([x^3 + y, y])                              # optional
sage: S = I._macaulay2_()                                    # optional
sage: T = S*S*S                                              # optional
sage: U = T.gens().entries().flatten()                       # optional
sage: f = U[2]; f                                            # optional
x^6*y+2*x^3*y^2+y^3
sage: R(repr(f))                                             # optional
x^6*y + 2*x^3*y^2 + y^3

Some other subtle coercions. We create polynomial rings in 2 variables over the rationals, integers, and a finite field.

sage: R.<x,y> = QQ[]
sage: S.<x,y> = ZZ[]
sage: T.<x,y> = GF(7)[]

We coerce from the integer to the rationals, and back:

sage: f = R(S.0^2 - 4*S.1^3); f
-4*y^3 + x^2
sage: parent(f)
Multivariate Polynomial Ring in x, y over Rational Field
sage: parent(S(f))
Multivariate Polynomial Ring in x, y over Integer Ring

We coerce from the finite field.

sage: f = R(T.0^2 - 4*T.1^3); f
3*y^3 + x^2
sage: parent(f)
Multivariate Polynomial Ring in x, y over Rational Field

We dump and load a the polynomial ring S:

sage: S2 = loads(dumps(S))
sage: S2 == S
True

Coerce works and gets the right parent.

sage: parent(S2._coerce_(S.0)) is S2
True

Coercion to reduce modulo a prime between rings with different variable names:

sage: R.<x,y> = PolynomialRing(QQ,2)
sage: S.<a,b> = PolynomialRing(GF(7),2)
sage: f = x^2 + 2/3*y^3
sage: S(f)
3*b^3 + a^2

Coercion from symbolic variables:

sage: x,y,z = var('x,y,z')
sage: R = QQ[x,y,z]
sage: type(x)
<class 'sage.calculus.calculus.SymbolicVariable'>
sage: type(R(x))
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsi
ngular'>
sage: f = R(x^3 + y^3 - z^3); f
x^3 + y^3 - z^3
sage: type(f)
<type 'sage.rings.polynomial.multi_polynomial_libsingular.MPolynomial_libsi
ngular'>
sage: parent(f)
Multivariate Polynomial Ring in x, y, z over Rational Field

A more complicated symbolic and computational mix. Behind the scenes Singular and Maxima are doing the real work.

sage: R = QQ[x,y,z]
sage: f = (x^3 + y^3 - z^3)^10; f
(-z^3 + y^3 + x^3)^10
sage: g = R(f); parent(g)
Multivariate Polynomial Ring in x, y, z over Rational Field
sage: (f - g).expand()
0

It intellegently handles coercion from polynomial rings in a subset of the variables too.

sage: R = GF(5)['x,y,z']
sage: S = ZZ['y']
sage: R(7*S.0)
2*y
sage: T = ZZ['x,z']
sage: R(2*T.0 + 6*T.1 + T.0*T.1^2)
x*z^2 + 2*x + z

sage: R = QQ['t,x,y,z']
sage: S.<x> = ZZ['x']
sage: T.<z> = S['z']
sage: T
Univariate Polynomial Ring in z over Univariate Polynomial Ring in x over
Integer Ring
sage: f = (x+3*z+5)^2; f
9*z^2 + (6*x + 30)*z + x^2 + 10*x + 25
sage: R(f)
x^2 + 6*x*z + 9*z^2 + 10*x + 30*z + 25

<Merge Conflict> Arithmetic with a constant from a base ring:

sage: R.<u,v> = QQ[]
sage: S.<x,y> = R[]
sage: u^3*x^2 + v*y
u^3*x^2 + v*y

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

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

Second, the multivariate case:

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

Conversion from strings:

sage: R.<x,y> = QQ[]
sage: R('x+(1/2)*y^2')
1/2*y^2 + x
sage: S.<u,v> = ZZ[]
sage: S('u^2 + u*v + v^2')
u^2 + u*v + v^2

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

sage: R.<x,y> = QQ[]
sage: S.<u,v> = R[]
sage: T.<a,b> = QQ[]
sage: S(a + b)
u + v

Class: MPolynomialRing_polydict_domain

class MPolynomialRing_polydict_domain
MPolynomialRing_polydict_domain( self, base_ring, n, names, order)

Functions: ideal,$ \,$ is_field,$ \,$ is_integral_domain,$ \,$ monomial_all_divisors,$ \,$ monomial_divides,$ \,$ monomial_lcm,$ \,$ monomial_pairwise_prime,$ \,$ monomial_quotient,$ \,$ monomial_reduce

ideal( self)

Create an ideal in this polynomial ring.

monomial_all_divisors( self, t)

Return a list of all monomials that divide t, coefficients are ignored.

Input:

t
- a monomial

Output: a list of monomials

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_all_divisors(x^2*z^3)
[x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3]

ALGORITHM: addwithcarry idea by Toon Segers

monomial_divides( self, a, b)

Return False if a does not divide b and True otherwise.

Input:

a
- monomial
b
- monomial

sage: P.<x,y,z>=MPolynomialRing(ZZ,3, order='degrevlex')
sage: P.monomial_divides(x*y*z, x^3*y^2*z^4)
True
sage: P.monomial_divides(x^3*y^2*z^4, x*y*z)
False

TESTS:

sage: P.<x,y,z>=MPolynomialRing(ZZ,3, order='degrevlex')
sage: P.monomial_divides(P(1), P(0))
True
sage: P.monomial_divides(P(1), x)
True

monomial_lcm( self, f, g)

LCM for monomials. Coefficients are ignored.

Input:

f
- monomial
g
- monomial

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_lcm(3/2*x*y,x)
x*y

TESTS:

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: R.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_lcm(x*y,R.gen())
x*y

sage: P.monomial_lcm(P(3/2),P(2/3))
1

sage: P.monomial_lcm(x,P(1))
x

monomial_pairwise_prime( self, h, g)

Return True if h and g are pairwise prime. Both are treated as monomials.

Input:

h
- monomial
g
- monomial

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_pairwise_prime(x^2*z^3, y^4)
True

sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3)
False

TESTS:

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: Q.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_pairwise_prime(x^2*z^3, Q('y^4'))
True

sage: P.monomial_pairwise_prime(1/2*x^3*y^2, Q(0))
True

sage: P.monomial_pairwise_prime(P(1/2),x)
False

monomial_quotient( self, f, g, [coeff=False])

Return f/g, where both f and g are treated as monomials. Coefficients are ignored by default.

Input:

f
- monomial
g
- monomial
coeff
- divide coefficents as well (default: False)

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ, 3, order='degrevlex')
sage: P.monomial_quotient(3/2*x*y,x)
y

sage: P.monomial_quotient(3/2*x*y,2*x,coeff=True)
3/4*y

TESTS:

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: R.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: P.monomial_quotient(x*y,x)
y

sage: P.monomial_quotient(x*y,R.gen())
y

sage: P.monomial_quotient(P(0),P(1))
0

sage: P.monomial_quotient(P(1),P(0))
Traceback (most recent call last):
...
ZeroDivisionError

sage: P.monomial_quotient(P(3/2),P(2/3), coeff=True)
9/4

sage: P.monomial_quotient(x,y) # Note the wrong result
x*y^-1

sage: P.monomial_quotient(x,P(1))
x

NOTE: Assumes that the head term of f is a multiple of the head term of g and return the multiplicant m. If this rule is violated, funny things may happen.

monomial_reduce( self, f, G)

Try to find a g in G where g.lm() divides f. If found (g,flt) is returned, (0,0) otherwise, where flt is f/g.lm().

It is assumed that G is iterable and contains ONLY elements in self.

Input:

f
- monomial
G
- list/set of mpolynomials

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: f = x*y^2
sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, P(1/2)  ]
sage: P.monomial_reduce(f,G)
(y, 1/4*x*y + 2/7)

TESTS:

sage: from sage.rings.polynomial.multi_polynomial_ring import MPolynomialRing_polydict_domain
sage: P.<x,y,z>=MPolynomialRing_polydict_domain(QQ,3, order='degrevlex')
sage: f = x*y^2
sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, P(1/2)  ]

sage: P.monomial_reduce(P(0),G)
(0, 0)

sage: P.monomial_reduce(f,[P(0)])
(0, 0)

Special Functions: __init__

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