Ideals in multivariate polynomial rings - Polynomials

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

# Ideals in multivariate polynomial rings

Sage has a powerful system to compute with multivariate polynomial rings. Most algorithms dealing with these ideals are centered on the computation of Groebner bases. Sage mainly uses Singular to implement this functionality. Singular is widely regarded as the best open-source system for Groebner basis calculation in multivariate polynomial rings over fields.

EXAMPLES:

We compute a Groebner basis for some given ideal. The type returned by the `groebner_basis` method is `PolynomialSequence`, i.e., it is not a `MPolynomialIdeal`:

Sage

    sage: x,y,z = QQ['x,y,z'].gens()
    sage: I = ideal(x^5 + y^4 + z^3 - 1,  x^3 + y^3 + z^2 - 1)
    sage: B = I.groebner_basis()
    sage: type(B)
    <class 'sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic'>

Python

    >>> from sage.all import *
    >>> x,y,z = QQ['x,y,z'].gens()
    >>> I = ideal(x**Integer(5) + y**Integer(4) + z**Integer(3) - Integer(1),  x**Integer(3) + y**Integer(3) + z**Integer(2) - Integer(1))
    >>> B = I.groebner_basis()
    >>> type(B)
    <class 'sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic'>

Groebner bases can be used to solve the ideal membership problem:

Sage

    sage: f,g,h = B
    sage: (2*x*f + g).reduce(B)
    0

    sage: (2*x*f + g) in I
    True

    sage: (2*x*f + 2*z*h + y^3).reduce(B)
    y^3

    sage: (2*x*f + 2*z*h + y^3) in I
    False

[Python]

    >>> from sage.all import *
    >>> f,g,h = B
    >>> (Integer(2)*x*f + g).reduce(B)
    0

    >>> (Integer(2)*x*f + g) in I
    True

    >>> (Integer(2)*x*f + Integer(2)*z*h + y**Integer(3)).reduce(B)
    y^3

    >>> (Integer(2)*x*f + Integer(2)*z*h + y**Integer(3)) in I
    False

We compute a Groebner basis for Cyclic 6, which is a standard benchmark and test ideal.

Sage

    sage: R.<x,y,z,t,u,v> = QQ['x,y,z,t,u,v']
    sage: I = sage.rings.ideal.Cyclic(R,6)
    sage: B = I.groebner_basis()
    sage: len(B)
    45

Python

    >>> from sage.all import *
    >>> R = QQ['x,y,z,t,u,v']; (x, y, z, t, u, v,) = R._first_ngens(6)
    >>> I = sage.rings.ideal.Cyclic(R,Integer(6))
    >>> B = I.groebner_basis()
    >>> len(B)
    45

We compute in a quotient of a polynomial ring over \(\ZZ/17\ZZ\):

Sage

    sage: R.<x,y> = ZZ[]
    sage: S.<a,b> = R.quotient((x^2 + y^2, 17))
    sage: S
    Quotient of Multivariate Polynomial Ring in x, y over Integer Ring
    by the ideal (x^2 + y^2, 17)

    sage: a^2 + b^2 == 0
    True
    sage: a^3 - b^2
    -a*b^2 - b^2

[Python]

    >>> from sage.all import *
    >>> R = ZZ['x, y']; (x, y,) = R._first_ngens(2)
    >>> S = R.quotient((x**Integer(2) + y**Integer(2), Integer(17)), names=('a', 'b',)); (a, b,) = S._first_ngens(2)
    >>> S
    Quotient of Multivariate Polynomial Ring in x, y over Integer Ring
    by the ideal (x^2 + y^2, 17)

    >>> a**Integer(2) + b**Integer(2) == Integer(0)
    True
    >>> a**Integer(3) - b**Integer(2)
    -a*b^2 - b^2

Note that the result of a computation is not necessarily reduced:

Sage

    sage: (a+b)^17
    a*b^16 + b^17
    sage: S(17) == 0
    True

Python

    >>> from sage.all import *
    >>> (a+b)**Integer(17)
    a*b^16 + b^17
    >>> S(Integer(17)) == Integer(0)
    True

Or we can work with \(\ZZ/17\ZZ\) directly:

Sage

    sage: R.<x,y> = Zmod(17)[]
    sage: S.<a,b> = R.quotient((x^2 + y^2,))
    sage: S
    Quotient of Multivariate Polynomial Ring in x, y over Ring of
    integers modulo 17 by the ideal (x^2 + y^2)

    sage: a^2 + b^2 == 0
    True
    sage: a^3 - b^2 == -a*b^2 - b^2 == 16*a*b^2 + 16*b^2
    True
    sage: (a+b)^17
    a*b^16 + b^17
    sage: S(17) == 0
    True

[Python]

    >>> from sage.all import *
    >>> R = Zmod(Integer(17))['x, y']; (x, y,) = R._first_ngens(2)
    >>> S = R.quotient((x**Integer(2) + y**Integer(2),), names=('a', 'b',)); (a, b,) = S._first_ngens(2)
    >>> S
    Quotient of Multivariate Polynomial Ring in x, y over Ring of
    integers modulo 17 by the ideal (x^2 + y^2)

    >>> a**Integer(2) + b**Integer(2) == Integer(0)
    True
    >>> a**Integer(3) - b**Integer(2) == -a*b**Integer(2) - b**Integer(2) == Integer(16)*a*b**Integer(2) + Integer(16)*b**Integer(2)
    True
    >>> (a+b)**Integer(17)
    a*b^16 + b^17
    >>> S(Integer(17)) == Integer(0)
    True

Working with a polynomial ring over \(\ZZ\):

Sage

    sage: R.<x,y,z,w> = ZZ[]
    sage: I = ideal(x^2 + y^2 - z^2 - w^2, x-y)
    sage: J = I^2
    sage: J.groebner_basis()
    [4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4,
     2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2,
     x^2 - 2*x*y + y^2]

    sage: y^2 - 2*x*y + x^2 in J
    True
    sage: 0 in J
    True

Python

    >>> from sage.all import *
    >>> R = ZZ['x, y, z, w']; (x, y, z, w,) = R._first_ngens(4)
    >>> I = ideal(x**Integer(2) + y**Integer(2) - z**Integer(2) - w**Integer(2), x-y)
    >>> J = I**Integer(2)
    >>> J.groebner_basis()
    [4*y^4 - 4*y^2*z^2 + z^4 - 4*y^2*w^2 + 2*z^2*w^2 + w^4,
     2*x*y^2 - 2*y^3 - x*z^2 + y*z^2 - x*w^2 + y*w^2,
     x^2 - 2*x*y + y^2]

    >>> y**Integer(2) - Integer(2)*x*y + x**Integer(2) in J
    True
    >>> Integer(0) in J
    True

We do a Groebner basis computation over a number field:

Sage

    sage: K.<zeta> = CyclotomicField(3)
    sage: R.<x,y,z> = K[]; R
    Multivariate Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2

    sage: i = ideal(x - zeta*y + 1, x^3 - zeta*y^3); i
    Ideal (x + (-zeta)*y + 1, x^3 + (-zeta)*y^3) of Multivariate
    Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2

    sage: i.groebner_basis()
    [y^3 + (2*zeta + 1)*y^2 + (zeta - 1)*y + (-1/3*zeta - 2/3), x + (-zeta)*y + 1]

    sage: S = R.quotient(i); S
    Quotient of Multivariate Polynomial Ring in x, y, z over
    Cyclotomic Field of order 3 and degree 2 by the ideal (x +
    (-zeta)*y + 1, x^3 + (-zeta)*y^3)

    sage: S.0  - zeta*S.1
    -1
    sage: S.0^3 - zeta*S.1^3
    0

[Python]

    >>> from sage.all import *
    >>> K = CyclotomicField(Integer(3), names=('zeta',)); (zeta,) = K._first_ngens(1)
    >>> R = K['x, y, z']; (x, y, z,) = R._first_ngens(3); R
    Multivariate Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2

    >>> i = ideal(x - zeta*y + Integer(1), x**Integer(3) - zeta*y**Integer(3)); i
    Ideal (x + (-zeta)*y + 1, x^3 + (-zeta)*y^3) of Multivariate
    Polynomial Ring in x, y, z over Cyclotomic Field of order 3 and degree 2

    >>> i.groebner_basis()
    [y^3 + (2*zeta + 1)*y^2 + (zeta - 1)*y + (-1/3*zeta - 2/3), x + (-zeta)*y + 1]

    >>> S = R.quotient(i); S
    Quotient of Multivariate Polynomial Ring in x, y, z over
    Cyclotomic Field of order 3 and degree 2 by the ideal (x +
    (-zeta)*y + 1, x^3 + (-zeta)*y^3)

    >>> S.gen(0)  - zeta*S.gen(1)
    -1
    >>> S.gen(0)**Integer(3) - zeta*S.gen(1)**Integer(3)
    0

Two examples from the Mathematica documentation (done in Sage):

> We compute a Groebner basis:

> Sage

>     sage: R.<x,y> = PolynomialRing(QQ, order='lex')
>     sage: ideal(x^2 - 2*y^2, x*y - 3).groebner_basis()
>     [x - 2/3*y^3, y^4 - 9/2]

> Python

>     >>> from sage.all import *
>     >>> R = PolynomialRing(QQ, order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
>     >>> ideal(x**Integer(2) - Integer(2)*y**Integer(2), x*y - Integer(3)).groebner_basis()
>     [x - 2/3*y^3, y^4 - 9/2]

> We show that three polynomials have no common root:

> Sage

>     sage: R.<x,y> = QQ[]
>     sage: ideal(x+y, x^2 - 1, y^2 - 2*x).groebner_basis()
>     [1]

> [Python]

>     >>> from sage.all import *
>     >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
>     >>> ideal(x+y, x**Integer(2) - Integer(1), y**Integer(2) - Integer(2)*x).groebner_basis()
>     [1]

The next example shows how we can use Groebner bases over \(\ZZ\) to find the primes modulo which a system of equations has a solution, when the system has no solutions over the rationals.

> We first form a certain ideal \(I\) in \(\ZZ[x, y, z]\), and note that the Groebner basis of \(I\) over \(\QQ\) contains 1, so there are no solutions over \(\QQ\) or an algebraic closure of it (this is not surprising as there are 4 equations in 3 unknowns).

> Sage

>     sage: P.<x,y,z> = PolynomialRing(ZZ,order='lex')
>     sage: I = ideal(-y^2 - 3*y + z^2 + 3, -2*y*z + z^2 + 2*z + 1,
>     ....:           x*z + y*z + z^2, -3*x*y + 2*y*z + 6*z^2)
>     sage: I.change_ring(P.change_ring(QQ)).groebner_basis()
>     [1]

> Python

>     >>> from sage.all import *
>     >>> P = PolynomialRing(ZZ,order='lex', names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
>     >>> I = ideal(-y**Integer(2) - Integer(3)*y + z**Integer(2) + Integer(3), -Integer(2)*y*z + z**Integer(2) + Integer(2)*z + Integer(1),
>     ...           x*z + y*z + z**Integer(2), -Integer(3)*x*y + Integer(2)*y*z + Integer(6)*z**Integer(2))
>     >>> I.change_ring(P.change_ring(QQ)).groebner_basis()
>     [1]

> However, when we compute the Groebner basis of \(I\) (defined over \(\ZZ\)), we note that there is a certain integer in the ideal which is not 1.

> Sage

>     sage: I.groebner_basis()
>     [x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ...,
>      2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]

> [Python]

>     >>> from sage.all import *
>     >>> I.groebner_basis()
>     [x + y + 57119*z + 4, y^2 + 3*y + 17220, y*z + ...,
>      2*y + 158864, z^2 + 17223, 2*z + 41856, 164878]

> Now for each prime \(p\) dividing this integer 164878, the Groebner basis of \(I\) modulo \(p\) will be non-trivial and will thus give a solution of the original system modulo \(p\).

> Sage

>     sage: factor(164878)
>     2 * 7 * 11777

>     sage: I.change_ring(P.change_ring(GF(2))).groebner_basis()                      # needs sage.rings.finite_rings
>     [x + y + z, y^2 + y, y*z + y, z^2 + 1]
>     sage: I.change_ring(P.change_ring(GF(7))).groebner_basis()                      # needs sage.rings.finite_rings
>     [x - 1, y + 3, z - 2]
>     sage: I.change_ring(P.change_ring(GF(11777))).groebner_basis()                  # needs sage.rings.finite_rings
>     [x + 5633, y - 3007, z - 2626]

> Python

>     >>> from sage.all import *
>     >>> factor(Integer(164878))
>     2 * 7 * 11777

>     >>> I.change_ring(P.change_ring(GF(Integer(2)))).groebner_basis()                      # needs sage.rings.finite_rings
>     [x + y + z, y^2 + y, y*z + y, z^2 + 1]
>     >>> I.change_ring(P.change_ring(GF(Integer(7)))).groebner_basis()                      # needs sage.rings.finite_rings
>     [x - 1, y + 3, z - 2]
>     >>> I.change_ring(P.change_ring(GF(Integer(11777)))).groebner_basis()                  # needs sage.rings.finite_rings
>     [x + 5633, y - 3007, z - 2626]

> The Groebner basis modulo any product of the prime factors is also non-trivial:

> Sage

>     sage: I.change_ring(P.change_ring(IntegerModRing(2 * 7))).groebner_basis()
>     [x + ..., y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10]

> [Python]

>     >>> from sage.all import *
>     >>> I.change_ring(P.change_ring(IntegerModRing(Integer(2) * Integer(7)))).groebner_basis()
>     [x + ..., y^2 + 3*y, y*z + 7*y + 6, 2*y + 6, z^2 + 3, 2*z + 10]

> Modulo any other prime the Groebner basis is trivial so there are no other solutions. For example:

> Sage

>     sage: I.change_ring(P.change_ring(GF(3))).groebner_basis()                      # needs sage.rings.finite_rings
>     [1]

> Python

>     >>> from sage.all import *
>     >>> I.change_ring(P.change_ring(GF(Integer(3)))).groebner_basis()                      # needs sage.rings.finite_rings
>     [1]

Note

Sage distinguishes between lists or sequences of polynomials and ideals. Thus an ideal is not identified with a particular set of generators. For sequences of multivariate polynomials see `sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic`.

AUTHORS:

- William Stein: initial version

- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some Singular features

- Martin Albrecht (2007,2008): refactoring, many Singular related functions, added plot()

- Martin Albrecht (2009): added Groebner basis over rings functionality from Singular 3.1

- John Perry (2012): bug fixing equality & containment of ideals

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal(ring, gens, coerce=True)

  Bases: `MPolynomialIdeal_singular_repr`, `MPolynomialIdeal_macaulay2_repr`, `MPolynomialIdeal_magma_repr`, `Ideal_generic`

  Create an ideal in a multivariate polynomial ring.

  INPUT:

  - `ring` – the ring the ideal is defined in

  - `gens` – list of generators for the ideal

  - `coerce` – whether to coerce elements to the ring `ring`

  EXAMPLES:

  Sage

      sage: R.<x,y> = PolynomialRing(IntegerRing(), 2, order='lex')
      sage: R.ideal([x, y])
      Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring
      sage: R.<x0,x1> = GF(3)[]
      sage: R.ideal([x0^2, x1^3])
      Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3

  Python

      >>> from sage.all import *
      >>> R = PolynomialRing(IntegerRing(), Integer(2), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
      >>> R.ideal([x, y])
      Ideal (x, y) of Multivariate Polynomial Ring in x, y over Integer Ring
      >>> R = GF(Integer(3))['x0, x1']; (x0, x1,) = R._first_ngens(2)
      >>> R.ideal([x0**Integer(2), x1**Integer(3)])
      Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3

  property basis

    Shortcut to `gens()`.

    EXAMPLES:

    Sage

        sage: P.<x,y> = PolynomialRing(QQ,2)
        sage: I = Ideal([x, y + 1])
        sage: I.basis
        [x, y + 1]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ,Integer(2), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
        >>> I = Ideal([x, y + Integer(1)])
        >>> I.basis
        [x, y + 1]

  change_ring(P)

    Return the ideal `I` in `P` spanned by the generators \(g_1, ..., g_n\) of `self` as returned by `self.gens()`.

    INPUT:

    - `P` – a multivariate polynomial ring

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ,3,order='lex')
        sage: I = sage.rings.ideal.Cyclic(P)
        sage: I
        Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
        Multivariate Polynomial Ring in x, y, z over Rational Field

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ,Integer(3),order='lex', names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = sage.rings.ideal.Cyclic(P)
        >>> I
        Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
        Multivariate Polynomial Ring in x, y, z over Rational Field

    Sage

        sage: I.groebner_basis()
        [x + y + z, y^2 + y*z + z^2, z^3 - 1]

    [Python]

        >>> from sage.all import *
        >>> I.groebner_basis()
        [x + y + z, y^2 + y*z + z^2, z^3 - 1]

    Sage

        sage: Q.<x,y,z> = P.change_ring(order='degrevlex'); Q
        Multivariate Polynomial Ring in x, y, z over Rational Field
        sage: Q.term_order()
        Degree reverse lexicographic term order

    Python

        >>> from sage.all import *
        >>> Q = P.change_ring(order='degrevlex', names=('x', 'y', 'z',)); (x, y, z,) = Q._first_ngens(3); Q
        Multivariate Polynomial Ring in x, y, z over Rational Field
        >>> Q.term_order()
        Degree reverse lexicographic term order

    Sage

        sage: J = I.change_ring(Q); J
        Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
        Multivariate Polynomial Ring in x, y, z over Rational Field

    [Python]

        >>> from sage.all import *
        >>> J = I.change_ring(Q); J
        Ideal (x + y + z, x*y + x*z + y*z, x*y*z - 1) of
        Multivariate Polynomial Ring in x, y, z over Rational Field

    Sage

        sage: J.groebner_basis()
        [z^3 - 1, y^2 + y*z + z^2, x + y + z]

    Python

        >>> from sage.all import *
        >>> J.groebner_basis()
        [z^3 - 1, y^2 + y*z + z^2, x + y + z]

  degree_of_semi_regularity()

    Return the degree of semi-regularity of this ideal under the assumption that it is semi-regular.

    Let \(\{f_1, ... , f_m\} \subset K[x_1 , ... , x_n]\) be homogeneous polynomials of degrees \(d_1,... ,d_m\) respectively. This sequence is semi-regular if:

    > - \(\{f_1, ... , f_m\} \neq K[x_1 , ... , x_n]\)

    > - for all \(1 \leq i \leq m\) and \(g \in K[x_1,\dots,x_n]\): \(deg(g \cdot pi ) < D\) and \(g \cdot f_i \in <f_1 , \dots , f_{i-1}>\) implies that \(g \in <f_1, ..., f_{i-1}>\) where \(D\) is the degree of regularity.

    This notion can be extended to affine polynomials by considering their homogeneous components of highest degree.

    The degree of regularity of a semi-regular sequence \(f_1, ...,f_m\) of respective degrees \(d_1,...,d_m\) is given by the index of the first nonpositive coefficient of:

    > \(\sum c_k z^k = \frac{\prod (1 - z^{d_i})}{(1-z)^n}\)

    EXAMPLES:

    We consider a homogeneous example:

    Sage

        sage: n = 8
        sage: K = GF(127)
        sage: P = PolynomialRing(K, n, 'x')
        sage: s = [K.random_element() for _ in range(n)]
        sage: L = []
        sage: for i in range(2 * n):
        ....:     f = P.random_element(degree=2, terms=binomial(n, 2))
        ....:     f -= f(*s)
        ....:     L.append(f.homogenize())
        sage: I = Ideal(L)
        sage: I.degree_of_semi_regularity()
        4

    Python

        >>> from sage.all import *
        >>> n = Integer(8)
        >>> K = GF(Integer(127))
        >>> P = PolynomialRing(K, n, 'x')
        >>> s = [K.random_element() for _ in range(n)]
        >>> L = []
        >>> for i in range(Integer(2) * n):
        ...     f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))
        ...     f -= f(*s)
        ...     L.append(f.homogenize())
        >>> I = Ideal(L)
        >>> I.degree_of_semi_regularity()
        4

    From this, we expect a Groebner basis computation to reach at most degree 4. For homogeneous systems this is equivalent to the largest degree in the Groebner basis:

    Sage

        sage: max(f.degree() for f in I.groebner_basis())
        4

    [Python]

        >>> from sage.all import *
        >>> max(f.degree() for f in I.groebner_basis())
        4

    We increase the number of polynomials and observe a decrease of the degree of regularity:

    Sage

        sage: for i in range(2 * n):
        ....:     f = P.random_element(degree=2, terms=binomial(n, 2))
        ....:     f -= f(*s)
        ....:     L.append(f.homogenize())
        sage: I = Ideal(L)
        sage: I.degree_of_semi_regularity()
        3

        sage: max(f.degree() for f in I.groebner_basis())
        3

    Python

        >>> from sage.all import *
        >>> for i in range(Integer(2) * n):
        ...     f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))
        ...     f -= f(*s)
        ...     L.append(f.homogenize())
        >>> I = Ideal(L)
        >>> I.degree_of_semi_regularity()
        3

        >>> max(f.degree() for f in I.groebner_basis())
        3

    The degree of regularity approaches 2 for quadratic systems as the number of polynomials approaches \(n^2\):

    Sage

        sage: for i in range((n-4) * n):
        ....:     f = P.random_element(degree=2, terms=binomial(n, 2))
        ....:     f -= f(*s)
        ....:     L.append(f.homogenize())
        sage: I = Ideal(L)
        sage: I.degree_of_semi_regularity()
        2

        sage: max(f.degree() for f in I.groebner_basis())
        2

    [Python]

        >>> from sage.all import *
        >>> for i in range((n-Integer(4)) * n):
        ...     f = P.random_element(degree=Integer(2), terms=binomial(n, Integer(2)))
        ...     f -= f(*s)
        ...     L.append(f.homogenize())
        >>> I = Ideal(L)
        >>> I.degree_of_semi_regularity()
        2

        >>> max(f.degree() for f in I.groebner_basis())
        2

    Note

    It is unknown whether semi-regular sequences exist. However, it is expected that random systems are semi-regular sequences. For more details about semi-regular sequences see [BFS2004].

  gens()

    Return a set of generators / a basis of this ideal.

    This is usually the set of generators provided during object creation.

    EXAMPLES:

    Sage

        sage: P.<x,y> = PolynomialRing(QQ,2)
        sage: I = Ideal([x, y + 1]); I
        Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field
        sage: I.gens()
        [x, y + 1]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ,Integer(2), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
        >>> I = Ideal([x, y + Integer(1)]); I
        Ideal (x, y + 1) of Multivariate Polynomial Ring in x, y over Rational Field
        >>> I.gens()
        [x, y + 1]

  groebner_basis(algorithm='', deg_bound=None, mult_bound=None, prot=False, *args, **kwds)

    Return the reduced Groebner basis of this ideal.

    A Groebner basis \(g_1,...,g_n\) for an ideal \(I\) is a generating set such that \(<LM(g_i)> = LM(I)\), i.e., the leading monomial ideal of \(I\) is spanned by the leading terms of \(g_1,...,g_n\). Groebner bases are the key concept in computational ideal theory in multivariate polynomial rings which allows a variety of problems to be solved.

    Additionally, a reduced Groebner basis \(G\) is a unique representation for the ideal \(<G>\) with respect to the chosen monomial ordering.

    INPUT:

    - `algorithm` – determines the algorithm to use, see below for available algorithms

    - `deg_bound` – only compute to degree `deg_bound`, that is, ignore all S-polynomials of higher degree. (default: `None`)

    - `mult_bound` – the computation is stopped if the ideal is zero-dimensional in a ring with local ordering and its multiplicity is lower than `mult_bound`. Singular only. (default: `None`)

    - `prot` – if set to `True` the computation protocol of the underlying implementation is printed. If an algorithm from the `singular:` or `magma:` family is used, `prot` may also be `sage` in which case the output is parsed and printed in a common format where the amount of information printed can be controlled via calls to `set_verbose()`.

    - `*args` – additional parameters passed to the respective implementations

    - `**kwds` – additional keyword parameters passed to the respective implementations

    ALGORITHMS:

    `''`

      autoselect (default)

    `'singular:groebner'`

      Singular’s `groebner` command

    `'singular:std'`

      Singular’s `std` command

    `'singular:stdhilb'`

      Singular’s `stdhib` command

    `'singular:stdfglm'`

      Singular’s `stdfglm` command

    `'singular:slimgb'`

      Singular’s `slimgb` command

    `'libsingular:groebner'`

      libSingular’s `groebner` command

    `'libsingular:std'`

      libSingular’s `std` command

    `'libsingular:slimgb'`

      libSingular’s `slimgb` command

    `'libsingular:stdhilb'`

      libSingular’s `stdhib` command

    `'libsingular:stdfglm'`

      libSingular’s `stdfglm` command

    `'toy:buchberger'`

      Sage’s toy/educational buchberger without Buchberger criteria

    `'toy:buchberger2'`

      Sage’s toy/educational buchberger with Buchberger criteria

    `'toy:d_basis'`

      Sage’s toy/educational algorithm for computation over PIDs

    `'macaulay2:gb'`

      Macaulay2’s `gb` command (if available)

    `'macaulay2:f4'`

      Macaulay2’s `GroebnerBasis` command with the strategy “F4” (if available)

    `'macaulay2:mgb'`

      Macaulay2’s `GroebnerBasis` command with the strategy “MGB” (if available)

    `'msolve'`

      optional package msolve (degrevlex order)

    `'magma:GroebnerBasis'`

      Magma’s `Groebnerbasis` command (if available)

    `'ginv:TQ'`, `'ginv:TQBlockHigh'`, `'ginv:TQBlockLow'` and `'ginv:TQDegree'`

      One of GINV’s implementations (if available)

    `'giac:gbasis'`

      Giac’s `gbasis` command (if available)

    If only a system is given - e.g. `'magma'` - the default algorithm is chosen for that system.

    Note

    The Singular and libSingular versions of the respective algorithms are identical, but the former calls an external Singular process while the latter calls a C function, and thus the calling overhead is smaller. However, the libSingular interface does not support pretty printing of computation protocols.

    EXAMPLES:

    Consider Katsura-3 over \(\QQ\) with lexicographical term ordering. We compute the reduced Groebner basis using every available implementation and check their equality.

    Sage

        sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis()
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ,Integer(3), order='lex', names=('a', 'b', 'c',)); (a, b, c,) = P._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis()
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('libsingular:groebner')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    [Python]

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('libsingular:groebner')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('libsingular:std')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Python

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('libsingular:std')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('libsingular:stdhilb')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    [Python]

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('libsingular:stdhilb')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('libsingular:stdfglm')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Python

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('libsingular:stdfglm')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('libsingular:slimgb')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    [Python]

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('libsingular:slimgb')
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Although Giac does support lexicographical ordering, we use degree reverse lexicographical ordering here, in order to test against Issue #21884:

    Sage

        sage: # needs sage.libs.giac
        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: J = I.change_ring(P.change_ring(order='degrevlex'))
        sage: gb = J.groebner_basis('giac')  # random
        sage: gb
        [c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1]
        sage: J.groebner_basis.set_cache(gb)
        sage: ideal(J.transformed_basis()).change_ring(P).interreduced_basis()  # testing issue #21884
        ...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Python

        >>> from sage.all import *
        >>> # needs sage.libs.giac
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> J = I.change_ring(P.change_ring(order='degrevlex'))
        >>> gb = J.groebner_basis('giac')  # random
        >>> gb
        [c^3 - 79/210*c^2 + 1/30*b + 1/70*c, b^2 - 3/5*c^2 - 1/5*b + 1/5*c, b*c + 6/5*c^2 - 1/10*b - 2/5*c, a + 2*b + 2*c - 1]
        >>> J.groebner_basis.set_cache(gb)
        >>> ideal(J.transformed_basis()).change_ring(P).interreduced_basis()  # testing issue #21884
        ...[a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Giac’s gbasis over \(\QQ\) can benefit from a probabilistic lifting and multi threaded operations:

    Sage

        sage: # needs sage.libs.giac
        sage: A9 = PolynomialRing(QQ, 9, 'x')
        sage: I9 = sage.rings.ideal.Katsura(A9)
        sage: print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=1e-7)  # long time (3s)
        possible output...
        Polynomial Sequence with 143 Polynomials in 9 Variables

    [Python]

        >>> from sage.all import *
        >>> # needs sage.libs.giac
        >>> A9 = PolynomialRing(QQ, Integer(9), 'x')
        >>> I9 = sage.rings.ideal.Katsura(A9)
        >>> print("possible output from giac", flush=True); I9.groebner_basis("giac", proba_epsilon=RealNumber('1e-7'))  # long time (3s)
        possible output...
        Polynomial Sequence with 143 Polynomials in 9 Variables

    The list of available Giac options is provided at `sage.libs.giac.groebner_basis()`.

    Note that `toy:buchberger` does not return the reduced Groebner basis,

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: gb = I.groebner_basis('toy:buchberger')
        sage: gb.is_groebner()
        True
        sage: gb == gb.reduced()
        False

    Python

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> gb = I.groebner_basis('toy:buchberger')
        >>> gb.is_groebner()
        True
        >>> gb == gb.reduced()
        False

    but that `toy:buchberger2` does.

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: gb = I.groebner_basis('toy:buchberger2'); gb
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
        sage: gb == gb.reduced()
        True

    [Python]

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> gb = I.groebner_basis('toy:buchberger2'); gb
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1, b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]
        >>> gb == gb.reduced()
        True

    Here we use Macaulay2 with three different strategies over a finite field.

    Sage

        sage: # optional - macaulay2
        sage: R.<a,b,c> = PolynomialRing(GF(101), 3)
        sage: I = sage.rings.ideal.Katsura(R,3)  # regenerate to prevent caching
        sage: I.groebner_basis('macaulay2:gb')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]
        sage: I = sage.rings.ideal.Katsura(R,3)  # regenerate to prevent caching
        sage: I.groebner_basis('macaulay2:f4')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]
        sage: I = sage.rings.ideal.Katsura(R,3)  # regenerate to prevent caching
        sage: I.groebner_basis('macaulay2:mgb')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]

    Python

        >>> from sage.all import *
        >>> # optional - macaulay2
        >>> R = PolynomialRing(GF(Integer(101)), Integer(3), names=('a', 'b', 'c',)); (a, b, c,) = R._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(R,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('macaulay2:gb')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]
        >>> I = sage.rings.ideal.Katsura(R,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('macaulay2:f4')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]
        >>> I = sage.rings.ideal.Katsura(R,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('macaulay2:mgb')
        [c^3 + 28*c^2 - 37*b + 13*c, b^2 - 41*c^2 + 20*b - 20*c,
         b*c - 19*c^2 + 10*b + 40*c, a + 2*b + 2*c - 1]

    Over prime fields of small characteristic, we can also use the optional package msolve:

    Sage

        sage: R.<a,b,c> = PolynomialRing(GF(101), 3)
        sage: I = sage.rings.ideal.Katsura(R,3)  # regenerate to prevent caching
        sage: I.groebner_basis('msolve')                    # optional - msolve
        [a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,
         b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(101)), Integer(3), names=('a', 'b', 'c',)); (a, b, c,) = R._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(R,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('msolve')                    # optional - msolve
        [a + 2*b + 2*c - 1, b*c - 19*c^2 + 10*b + 40*c,
         b^2 - 41*c^2 + 20*b - 20*c, c^3 + 28*c^2 - 37*b + 13*c]

    Sage

        sage: I = sage.rings.ideal.Katsura(P,3)  # regenerate to prevent caching
        sage: I.groebner_basis('magma:GroebnerBasis')       # optional - magma
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1,
         b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Python

        >>> from sage.all import *
        >>> I = sage.rings.ideal.Katsura(P,Integer(3))  # regenerate to prevent caching
        >>> I.groebner_basis('magma:GroebnerBasis')       # optional - magma
        [a - 60*c^3 + 158/7*c^2 + 8/7*c - 1,
         b + 30*c^3 - 79/7*c^2 + 3/7*c, c^4 - 10/21*c^3 + 1/84*c^2 + 1/84*c]

    Singular and libSingular can compute Groebner basis with degree restrictions.

    Sage

        sage: R.<x,y> = QQ[]
        sage: I = R*[x^3 + y^2, x^2*y + 1]
        sage: I.groebner_basis(algorithm='singular')
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        sage: I.groebner_basis(algorithm='singular', deg_bound=2)
        [x^3 + y^2, x^2*y + 1]
        sage: I.groebner_basis()
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        sage: I.groebner_basis(deg_bound=2)
        [x^3 + y^2, x^2*y + 1]

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
        >>> I = R*[x**Integer(3) + y**Integer(2), x**Integer(2)*y + Integer(1)]
        >>> I.groebner_basis(algorithm='singular')
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        >>> I.groebner_basis(algorithm='singular', deg_bound=Integer(2))
        [x^3 + y^2, x^2*y + 1]
        >>> I.groebner_basis()
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        >>> I.groebner_basis(deg_bound=Integer(2))
        [x^3 + y^2, x^2*y + 1]

    A protocol is printed, if the verbosity level is at least 2, or if the argument `prot` is provided. Historically, the protocol did not appear during doctests, so, we skip the examples with protocol output.

    Sage

        sage: from sage.misc.verbose import set_verbose
        sage: set_verbose(2)
        sage: I = R*[x^3+y^2,x^2*y+1]
        sage: I.groebner_basis()  # not tested
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        sage: I.groebner_basis(prot=False)
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        sage: set_verbose(0)
        sage: I.groebner_basis(prot=True)  # not tested
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]

    Python

        >>> from sage.all import *
        >>> from sage.misc.verbose import set_verbose
        >>> set_verbose(Integer(2))
        >>> I = R*[x**Integer(3)+y**Integer(2),x**Integer(2)*y+Integer(1)]
        >>> I.groebner_basis()  # not tested
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        >>> I.groebner_basis(prot=False)
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]
        >>> set_verbose(Integer(0))
        >>> I.groebner_basis(prot=True)  # not tested
        std in (QQ),(x,y),(dp(2),C)
        [...:2]3ss4s6
        (S:2)--
        product criterion:1 chain criterion:0
        [x^3 + y^2, x^2*y + 1, y^3 - x]

    The list of available options is provided at `LibSingularOptions`.

    Note that Groebner bases over \(\ZZ\) can also be computed.

    Sage

        sage: P.<a,b,c> = PolynomialRing(ZZ,3)
        sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
        sage: I.groebner_basis()
        [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
         2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2,
         42*c^3 + b^2 + 2*b*c - 14*c^2 + b,
         2*b^2 + 6*b*c + 6*c^2 - b - 2*c,
         10*b*c + 12*c^2 - b - 4*c,
         a + 2*b + 2*c - 1]

    [Python]

        >>> from sage.all import *
        >>> P = PolynomialRing(ZZ,Integer(3), names=('a', 'b', 'c',)); (a, b, c,) = P._first_ngens(3)
        >>> I = P * (a + Integer(2)*b + Integer(2)*c - Integer(1), a**Integer(2) - a + Integer(2)*b**Integer(2) + Integer(2)*c**Integer(2), Integer(2)*a*b + Integer(2)*b*c - b)
        >>> I.groebner_basis()
        [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
         2*b*c^2 - 6*c^3 - b^2 - b*c + 2*c^2,
         42*c^3 + b^2 + 2*b*c - 14*c^2 + b,
         2*b^2 + 6*b*c + 6*c^2 - b - 2*c,
         10*b*c + 12*c^2 - b - 4*c,
         a + 2*b + 2*c - 1]

    Sage

        sage: I.groebner_basis('macaulay2')                 # optional - macaulay2
        [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
         2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c,
         42*c^3 + b^2 + 2*b*c - 14*c^2 + b,
         2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c,
         a + 2*b + 2*c - 1]

    Python

        >>> from sage.all import *
        >>> I.groebner_basis('macaulay2')                 # optional - macaulay2
        [b^3 + b*c^2 + 12*c^3 + b^2 + b*c - 4*c^2,
         2*b*c^2 - 6*c^3 + b^2 + 5*b*c + 8*c^2 - b - 2*c,
         42*c^3 + b^2 + 2*b*c - 14*c^2 + b,
         2*b^2 - 4*b*c - 6*c^2 + 2*c, 10*b*c + 12*c^2 - b - 4*c,
         a + 2*b + 2*c - 1]

    Groebner bases over \(\ZZ/n\ZZ\) are also supported:

    Sage

        sage: P.<a,b,c> = PolynomialRing(Zmod(1000), 3)
        sage: I = P * (a + 2*b + 2*c - 1, a^2 - a + 2*b^2 + 2*c^2, 2*a*b + 2*b*c - b)
        sage: I.groebner_basis()
        [b*c^2 + 732*b*c + 808*b,
         2*c^3 + 884*b*c + 666*c^2 + 320*b,
         b^2 + 438*b*c + 281*b,
         5*b*c + 156*c^2 + 112*b + 948*c,
         50*c^2 + 600*b + 650*c,
         a + 2*b + 2*c + 999,
         125*b]

    [Python]

        >>> from sage.all import *
        >>> P = PolynomialRing(Zmod(Integer(1000)), Integer(3), names=('a', 'b', 'c',)); (a, b, c,) = P._first_ngens(3)
        >>> I = P * (a + Integer(2)*b + Integer(2)*c - Integer(1), a**Integer(2) - a + Integer(2)*b**Integer(2) + Integer(2)*c**Integer(2), Integer(2)*a*b + Integer(2)*b*c - b)
        >>> I.groebner_basis()
        [b*c^2 + 732*b*c + 808*b,
         2*c^3 + 884*b*c + 666*c^2 + 320*b,
         b^2 + 438*b*c + 281*b,
         5*b*c + 156*c^2 + 112*b + 948*c,
         50*c^2 + 600*b + 650*c,
         a + 2*b + 2*c + 999,
         125*b]

    Sage

        sage: R.<x,y,z> = PolynomialRing(Zmod(2233497349584))
        sage: I = R.ideal([z*(x-3*y), 3^2*x^2-y*z, z^2+y^2])
        sage: I.groebner_basis()
        [2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 + 2233497349583*y*z, y^2 + z^2, x*z + 2233497349581*y*z, 248166372176*y*z]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(Zmod(Integer(2233497349584)), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal([z*(x-Integer(3)*y), Integer(3)**Integer(2)*x**Integer(2)-y*z, z**Integer(2)+y**Integer(2)])
        >>> I.groebner_basis()
        [2*z^4, y*z^2 + 81*z^3, 248166372176*z^3, 9*x^2 + 2233497349583*y*z, y^2 + z^2, x*z + 2233497349581*y*z, 248166372176*y*z]

    Sage also supports local orderings:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ, 3, order='negdegrevlex')
        sage: I = P * (  x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 )
        sage: I.groebner_basis()
        [x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6]

    [Python]

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, Integer(3), order='negdegrevlex', names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = P * (  x*y*z + z**Integer(5), Integer(2)*x**Integer(2) + y**Integer(3) + z**Integer(7), Integer(3)*z**Integer(5) + y**Integer(5) )
        >>> I.groebner_basis()
        [x^2 + 1/2*y^3, x*y*z + z^5, y^5 + 3*z^5, y^4*z - 2*x*z^5, z^6]

    We can represent every element in the ideal as a combination of the generators using the `lift()` method:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ, 3)
        sage: I = P * ( x*y*z + z^5, 2*x^2 + y^3 + z^7, 3*z^5 + y^5 )
        sage: J = Ideal(I.groebner_basis())
        sage: f = sum(P.random_element(terms=2)*f for f in I.gens())
        sage: f                        # random
        1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 + 3/2*x^2*y*z + 95*x*y*z^2
        sage: f.lift(I.gens())         # random
        [2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0]
        sage: l = f.lift(J.gens()); l  # random
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/4*y*z^3 + 2*x + 95*z]
        sage: sum(map(mul, zip(l,J.gens()))) == f
        True

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = P * ( x*y*z + z**Integer(5), Integer(2)*x**Integer(2) + y**Integer(3) + z**Integer(7), Integer(3)*z**Integer(5) + y**Integer(5) )
        >>> J = Ideal(I.groebner_basis())
        >>> f = sum(P.random_element(terms=Integer(2))*f for f in I.gens())
        >>> f                        # random
        1/2*y^2*z^7 - 1/4*y*z^8 + 2*x*z^5 + 95*z^6 + 1/2*y^5 - 1/4*y^4*z + x^2*y^2 + 3/2*x^2*y*z + 95*x*y*z^2
        >>> f.lift(I.gens())         # random
        [2*x + 95*z, 1/2*y^2 - 1/4*y*z, 0]
        >>> l = f.lift(J.gens()); l  # random
        [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1/2*y^2 + 1/4*y*z, 1/2*y^2*z^2 - 1/4*y*z^3 + 2*x + 95*z]
        >>> sum(map(mul, zip(l,J.gens()))) == f
        True

    Groebner bases over fraction fields of polynomial rings are also supported:

    Sage

        sage: P.<t> = QQ[]
        sage: F = Frac(P)
        sage: R.<X,Y,Z> = F[]
        sage: I = Ideal([f + P.random_element() for f in sage.rings.ideal.Katsura(R).gens()])
        sage: I.groebner_basis().ideal() == I
        True

    [Python]

        >>> from sage.all import *
        >>> P = QQ['t']; (t,) = P._first_ngens(1)
        >>> F = Frac(P)
        >>> R = F['X, Y, Z']; (X, Y, Z,) = R._first_ngens(3)
        >>> I = Ideal([f + P.random_element() for f in sage.rings.ideal.Katsura(R).gens()])
        >>> I.groebner_basis().ideal() == I
        True

    In cases where a characteristic cannot be determined, we use a toy implementation of Buchberger’s algorithm (see Issue #6581):

    Sage

        sage: R.<a,b> = QQ[]; I = R.ideal(a^2+b^2-1)
        sage: Q = QuotientRing(R,I); K = Frac(Q)
        sage: R2.<x,y> = K[]; J = R2.ideal([(a^2+b^2)*x + y, x+y])
        sage: J.groebner_basis()
        verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
        [x + y]

    Python

        >>> from sage.all import *
        >>> R = QQ['a, b']; (a, b,) = R._first_ngens(2); I = R.ideal(a**Integer(2)+b**Integer(2)-Integer(1))
        >>> Q = QuotientRing(R,I); K = Frac(Q)
        >>> R2 = K['x, y']; (x, y,) = R2._first_ngens(2); J = R2.ideal([(a**Integer(2)+b**Integer(2))*x + y, x+y])
        >>> J.groebner_basis()
        verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
        [x + y]

    ALGORITHM:

    Uses Singular, one of the other systems listed above (if available), or a toy implementation.

  groebner_cover()

    Compute the Gröbner cover of the ideal, over a field with parameters.

    The Groebner cover is a partition of the space of parameters, such that the Groebner basis in each part is given by the same expression.

    EXAMPLES:

    Sage

        sage: F = PolynomialRing(QQ,'a').fraction_field()
        sage: F.inject_variables()
        Defining a
        sage: R.<x,y,z> = F[]
        sage: I = R.ideal([-x+3*y+z-5,2*x+a*z+4,4*x-3*z-1/a])
        sage: I.groebner_cover()
        {Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             0
           and Y is defined by:
             2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1),
                           (12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x + 11],
         Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             ...
           and Y is defined by:
             1: [1],
         Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             ...
           and Y is defined by:
             1: [1]}

    Python

        >>> from sage.all import *
        >>> F = PolynomialRing(QQ,'a').fraction_field()
        >>> F.inject_variables()
        Defining a
        >>> R = F['x, y, z']; (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal([-x+Integer(3)*y+z-Integer(5),Integer(2)*x+a*z+Integer(4),Integer(4)*x-Integer(3)*z-Integer(1)/a])
        >>> I.groebner_cover()
        {Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             0
           and Y is defined by:
             2*a^2 + 3*a: [(2*a^2 + 3*a)*z + (8*a + 1),
                           (12*a^2 + 18*a)*y + (-20*a^2 - 35*a - 2), (4*a + 6)*x + 11],
         Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             ...
           and Y is defined by:
             1: [1],
         Quasi-affine subscheme X - Y of Affine Space of dimension 1 over Rational Field,
           where X is defined by:
             ...
           and Y is defined by:
             1: [1]}

  groebner_fan(is_groebner_basis=False, symmetry=None, verbose=False)

    Return the Groebner fan of this ideal.

    The base ring must be \(\QQ\) or a finite field \(\GF{p}\) of with \(p \leq 32749\).

    EXAMPLES:

    Sage

        sage: P.<x,y> = PolynomialRing(QQ)
        sage: i = ideal(x^2 - y^2 + 1)
        sage: g = i.groebner_fan()
        sage: g.reduced_groebner_bases()
        [[x^2 - y^2 + 1], [-x^2 + y^2 - 1]]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = P._first_ngens(2)
        >>> i = ideal(x**Integer(2) - y**Integer(2) + Integer(1))
        >>> g = i.groebner_fan()
        >>> g.reduced_groebner_bases()
        [[x^2 - y^2 + 1], [-x^2 + y^2 - 1]]

    INPUT:

    - `is_groebner_basis` – boolean (default: `False`); if `True`, then `I.gens()` must be a Groebner basis with respect to the standard degree lexicographic term order

    - `symmetry` – (default: `None`) if not `None`, describes symmetries of the ideal

    - `verbose` – (default: `False`) if `True`, printout useful info during computations

  homogenize(var='h')

    Return homogeneous ideal spanned by the homogeneous polynomials generated by homogenizing the generators of this ideal.

    INPUT:

    - `h` – variable name or variable in cover ring (default: `'h'`)

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(GF(2))
        sage: I = Ideal([x^2*y + z + 1, x + y^2 + 1]); I
        Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate
        Polynomial Ring in x, y, z over Finite Field of size 2

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(GF(Integer(2)), names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = Ideal([x**Integer(2)*y + z + Integer(1), x + y**Integer(2) + Integer(1)]); I
        Ideal (x^2*y + z + 1, y^2 + x + 1) of Multivariate
        Polynomial Ring in x, y, z over Finite Field of size 2

    Sage

        sage: I.homogenize()
        Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) of
        Multivariate Polynomial Ring in x, y, z, h over Finite
        Field of size 2

    [Python]

        >>> from sage.all import *
        >>> I.homogenize()
        Ideal (x^2*y + z*h^2 + h^3, y^2 + x*h + h^2) of
        Multivariate Polynomial Ring in x, y, z, h over Finite
        Field of size 2

    Sage

        sage: I.homogenize(y)
        Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate
        Polynomial Ring in x, y, z over Finite Field of size 2

    Python

        >>> from sage.all import *
        >>> I.homogenize(y)
        Ideal (x^2*y + y^3 + y^2*z, x*y) of Multivariate
        Polynomial Ring in x, y, z over Finite Field of size 2

    Sage

        sage: I = Ideal([x^2*y + z^3 + y^2*x, x + y^2 + 1])
        sage: I.homogenize()
        Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) of
        Multivariate Polynomial Ring in x, y, z, h over Finite
        Field of size 2

    [Python]

        >>> from sage.all import *
        >>> I = Ideal([x**Integer(2)*y + z**Integer(3) + y**Integer(2)*x, x + y**Integer(2) + Integer(1)])
        >>> I.homogenize()
        Ideal (x^2*y + x*y^2 + z^3, y^2 + x*h + h^2) of
        Multivariate Polynomial Ring in x, y, z, h over Finite
        Field of size 2

  is_homogeneous()

    Return `True` if this ideal is spanned by homogeneous polynomials, i.e., if it is a homogeneous ideal.

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ,3)
        sage: I = sage.rings.ideal.Katsura(P)
        sage: I
        Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y +
        2*y*z - y) of Multivariate Polynomial Ring in x, y, z over
        Rational Field

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ,Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(P)
        >>> I
        Ideal (x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y +
        2*y*z - y) of Multivariate Polynomial Ring in x, y, z over
        Rational Field

    Sage

        sage: I.is_homogeneous()
        False

    [Python]

        >>> from sage.all import *
        >>> I.is_homogeneous()
        False

    Sage

        sage: J = I.homogenize()
        sage: J
        Ideal (x + 2*y + 2*z - h, x^2 + 2*y^2 + 2*z^2 - x*h, 2*x*y
        + 2*y*z - y*h) of Multivariate Polynomial Ring in x, y, z,
        h over Rational Field

    Python

        >>> from sage.all import *
        >>> J = I.homogenize()
        >>> J
        Ideal (x + 2*y + 2*z - h, x^2 + 2*y^2 + 2*z^2 - x*h, 2*x*y
        + 2*y*z - y*h) of Multivariate Polynomial Ring in x, y, z,
        h over Rational Field

    Sage

        sage: J.is_homogeneous()
        True

    [Python]

        >>> from sage.all import *
        >>> J.is_homogeneous()
        True

  plot(*args, **kwds)

    Plot the real zero locus of this principal ideal.

    INPUT:

    - `self` – a principal ideal in 2 variables

    - `*args` – (optional) tuples `(variable, minimum, maximum)` for plotting dimensions

    - `**kwds` – optional keyword arguments passed on to `implicit_plot`

    EXAMPLES:

    Implicit plotting in 2-d:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ, 2)
        sage: I = R.ideal([y^3 - x^2])
        sage: I.plot()  # cusp, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal([y**Integer(3) - x**Integer(2)])
        >>> I.plot()  # cusp, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: I = R.ideal([y^2 - x^2 - 1])
        sage: I.plot((x,-3, 3), (y, -2, 2))  # hyperbola, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    [Python]

        >>> from sage.all import *
        >>> I = R.ideal([y**Integer(2) - x**Integer(2) - Integer(1)])
        >>> I.plot((x,-Integer(3), Integer(3)), (y, -Integer(2), Integer(2)))  # hyperbola, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: I = R.ideal([y^2 + x^2*(1/4) - 1])
        sage: I.plot()   # ellipse, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Python

        >>> from sage.all import *
        >>> I = R.ideal([y**Integer(2) + x**Integer(2)*(Integer(1)/Integer(4)) - Integer(1)])
        >>> I.plot()   # ellipse, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
        sage: I.plot()  # elliptic curve, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    [Python]

        >>> from sage.all import *
        >>> I = R.ideal([y**Integer(2)-(x**Integer(2)-Integer(1))*(x-Integer(2))])
        >>> I.plot()  # elliptic curve, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: f = ((x+3)^3 + 2*(x+3)^2 - y^2)*(x^3 - y^2)*((x-3)^3-2*(x-3)^2-y^2)
        sage: I = R.ideal(f)
        sage: I.plot()  # the Singular logo, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Python

        >>> from sage.all import *
        >>> f = ((x+Integer(3))**Integer(3) + Integer(2)*(x+Integer(3))**Integer(2) - y**Integer(2))*(x**Integer(3) - y**Integer(2))*((x-Integer(3))**Integer(3)-Integer(2)*(x-Integer(3))**Integer(2)-y**Integer(2))
        >>> I = R.ideal(f)
        >>> I.plot()  # the Singular logo, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: R.<x,y> = PolynomialRing(QQ, 2)
        sage: I = R.ideal([x - 1])
        sage: I.plot((y, -2, 2))  # vertical line, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal([x - Integer(1)])
        >>> I.plot((y, -Integer(2), Integer(2)))  # vertical line, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Sage

        sage: I = R.ideal([-x^2*y + 1])
        sage: I.plot()  # blow up, needs sage.plot
        Graphics object consisting of 1 graphics primitive

    Python

        >>> from sage.all import *
        >>> I = R.ideal([-x**Integer(2)*y + Integer(1)])
        >>> I.plot()  # blow up, needs sage.plot
        Graphics object consisting of 1 graphics primitive

  random_element(degree, compute_gb=False, *args, **kwds)

    Return a random element in this ideal as \(r = \sum h_i·f_i\).

    INPUT:

    - `compute_gb` – if `True` then a Gröbner basis is computed first and \(f_i\) are the elements in the Gröbner basis. Otherwise whatever basis is returned by `self.gens()` is used.

    - `*args` and `**kwds` are passed to `R.random_element()` with `R = self.ring()`.

    EXAMPLES:

    We compute a uniformly random element up to the provided degree.

    Sage

        sage: P.<x,y,z> = GF(127)[]
        sage: I = sage.rings.ideal.Katsura(P)
        sage: f = I.random_element(degree=4, compute_gb=True, terms=infinity)
        sage: f.degree() <= 4
        True
        sage: len(list(f)) <= 35
        True

    Python

        >>> from sage.all import *
        >>> P = GF(Integer(127))['x, y, z']; (x, y, z,) = P._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(P)
        >>> f = I.random_element(degree=Integer(4), compute_gb=True, terms=infinity)
        >>> f.degree() <= Integer(4)
        True
        >>> len(list(f)) <= Integer(35)
        True

    Note that sampling uniformly at random from the ideal at some large enough degree is equivalent to computing a Gröbner basis. We give an example showing how to compute a Gröbner basis if we can sample uniformly at random from an ideal:

    Sage

        sage: n = 3; d = 4
        sage: P = PolynomialRing(GF(127), n, 'x')
        sage: I = sage.rings.ideal.Cyclic(P)

    [Python]

        >>> from sage.all import *
        >>> n = Integer(3); d = Integer(4)
        >>> P = PolynomialRing(GF(Integer(127)), n, 'x')
        >>> I = sage.rings.ideal.Cyclic(P)

    1. We sample \(n^d\) uniformly random elements in the ideal:

       Sage

           sage: F = Sequence(I.random_element(degree=d, compute_gb=True,
           ....:                               terms=infinity)
           ....:              for _ in range(n^d))

       Python

           >>> from sage.all import *
           >>> F = Sequence(I.random_element(degree=d, compute_gb=True,
           ...                               terms=infinity)
           ...              for _ in range(n**d))

    2. We linearize and compute the echelon form:

       Sage

           sage: A, v = F.coefficients_monomials()
           sage: A.echelonize()

       Python

           >>> from sage.all import *
           >>> A, v = F.coefficients_monomials()
           >>> A.echelonize()

    3. The result is the desired Gröbner basis:

       Sage

           sage: G = Sequence((A * v).list())
           sage: G.is_groebner()
           True
           sage: Ideal(G) == I
           True

       Python

           >>> from sage.all import *
           >>> G = Sequence((A * v).list())
           >>> G.is_groebner()
           True
           >>> Ideal(G) == I
           True

    We return some element in the ideal with no guarantee on the distribution:

    Sage

        sage: P = PolynomialRing(GF(127), 10, 'x')
        sage: I = sage.rings.ideal.Katsura(P)
        sage: f = I.random_element(degree=3)
        sage: f  # random
        -25*x0^2*x1 + 14*x1^3 + 57*x0*x1*x2 + ... + 19*x7*x9 + 40*x8*x9 + 49*x1
        sage: f.degree()
        3

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(GF(Integer(127)), Integer(10), 'x')
        >>> I = sage.rings.ideal.Katsura(P)
        >>> f = I.random_element(degree=Integer(3))
        >>> f  # random
        -25*x0^2*x1 + 14*x1^3 + 57*x0*x1*x2 + ... + 19*x7*x9 + 40*x8*x9 + 49*x1
        >>> f.degree()
        3

    We show that the default method does not sample uniformly at random from the ideal:

    Sage

        sage: P.<x,y,z> = GF(127)[]
        sage: G = Sequence([x + 7, y - 2, z + 110])
        sage: I = Ideal([sum(P.random_element() * g for g in G)
        ....:            for _ in range(4)])
        sage: all(I.random_element(degree=1) == 0 for _ in range(100))
        True

    [Python]

        >>> from sage.all import *
        >>> P = GF(Integer(127))['x, y, z']; (x, y, z,) = P._first_ngens(3)
        >>> G = Sequence([x + Integer(7), y - Integer(2), z + Integer(110)])
        >>> I = Ideal([sum(P.random_element() * g for g in G)
        ...            for _ in range(Integer(4))])
        >>> all(I.random_element(degree=Integer(1)) == Integer(0) for _ in range(Integer(100)))
        True

    If `degree` equals the degree of the generators, a random linear combination of the generators is returned:

    Sage

        sage: P.<x,y> = QQ[]
        sage: I = P.ideal([x^2,y^2])
        sage: set_random_seed(5)
        sage: I.random_element(degree=2)
        -2*x^2 + 2*y^2

    Python

        >>> from sage.all import *
        >>> P = QQ['x, y']; (x, y,) = P._first_ngens(2)
        >>> I = P.ideal([x**Integer(2),y**Integer(2)])
        >>> set_random_seed(Integer(5))
        >>> I.random_element(degree=Integer(2))
        -2*x^2 + 2*y^2

  reduce(f)

    Reduce an element modulo the reduced Groebner basis for this ideal. This returns 0 if and only if the element is in this ideal. In any case, this reduction is unique up to monomial orders.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ, 2)
        sage: I = (x^3 + y, y) * R
        sage: I.reduce(y)
        0
        sage: I.reduce(x^3)
        0
        sage: I.reduce(x - y)
        x

        sage: I = (y^2 - (x^3 + x)) * R
        sage: I.reduce(x^3)
        y^2 - x
        sage: I.reduce(x^6)
        y^4 - 2*x*y^2 + x^2
        sage: (y^2 - x)^2
        y^4 - 2*x*y^2 + x^2

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = (x**Integer(3) + y, y) * R
        >>> I.reduce(y)
        0
        >>> I.reduce(x**Integer(3))
        0
        >>> I.reduce(x - y)
        x

        >>> I = (y**Integer(2) - (x**Integer(3) + x)) * R
        >>> I.reduce(x**Integer(3))
        y^2 - x
        >>> I.reduce(x**Integer(6))
        y^4 - 2*x*y^2 + x^2
        >>> (y**Integer(2) - x)**Integer(2)
        y^4 - 2*x*y^2 + x^2

    Note

    Requires computation of a Groebner basis, which can be a very expensive operation.

  subs(in_dict=None, **kwds)

    Substitute variables.

    This method substitutes some variables in the polynomials that generate the ideal with given values. Variables that are not specified in the input remain unchanged.

    INPUT:

    - `in_dict` – (optional) dictionary of inputs

    - `**kwds` – named parameters

    OUTPUT:

    A new ideal with modified generators. If possible, in the same polynomial ring. Raises a `TypeError` if no common polynomial ring of the substituted generators can be found.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(ZZ, 2, 'xy')
        sage: I = R.ideal(x^5 + y^5, x^2 + y + x^2*y^2 + 5); I
        Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring
        sage: I.subs(x=y)
        Ideal (2*y^5, y^4 + y^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring
        sage: I.subs({x: y})    # same substitution but with dictionary
        Ideal (2*y^5, y^4 + y^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(ZZ, Integer(2), 'xy', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal(x**Integer(5) + y**Integer(5), x**Integer(2) + y + x**Integer(2)*y**Integer(2) + Integer(5)); I
        Ideal (x^5 + y^5, x^2*y^2 + x^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring
        >>> I.subs(x=y)
        Ideal (2*y^5, y^4 + y^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring
        >>> I.subs({x: y})    # same substitution but with dictionary
        Ideal (2*y^5, y^4 + y^2 + y + 5)
         of Multivariate Polynomial Ring in x, y over Integer Ring

    The new ideal can be in a different ring:

    Sage

        sage: R.<a,b> = PolynomialRing(QQ, 2)
        sage: S.<x,y> = PolynomialRing(QQ, 2)
        sage: I = R.ideal(a^2 + b^2 + a - b + 2); I
        Ideal (a^2 + b^2 + a - b + 2)
         of Multivariate Polynomial Ring in a, b over Rational Field
        sage: I.subs(a=x, b=y)
        Ideal (x^2 + y^2 + x - y + 2)
         of Multivariate Polynomial Ring in x, y over Rational Field

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('a', 'b',)); (a, b,) = R._first_ngens(2)
        >>> S = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = S._first_ngens(2)
        >>> I = R.ideal(a**Integer(2) + b**Integer(2) + a - b + Integer(2)); I
        Ideal (a^2 + b^2 + a - b + 2)
         of Multivariate Polynomial Ring in a, b over Rational Field
        >>> I.subs(a=x, b=y)
        Ideal (x^2 + y^2 + x - y + 2)
         of Multivariate Polynomial Ring in x, y over Rational Field

    The resulting ring need not be a multivariate polynomial ring:

    Sage

        sage: T.<t> = PolynomialRing(QQ)
        sage: I.subs(a=t, b=t)
        Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational Field
        sage: var("z")                                                              # needs sage.symbolic
        z
        sage: I.subs(a=z, b=z)                                                      # needs sage.symbolic
        Principal ideal (2*z^2 + 2) of Symbolic Ring

    Python

        >>> from sage.all import *
        >>> T = PolynomialRing(QQ, names=('t',)); (t,) = T._first_ngens(1)
        >>> I.subs(a=t, b=t)
        Principal ideal (t^2 + 1) of Univariate Polynomial Ring in t over Rational Field
        >>> var("z")                                                              # needs sage.symbolic
        z
        >>> I.subs(a=z, b=z)                                                      # needs sage.symbolic
        Principal ideal (2*z^2 + 2) of Symbolic Ring

    Variables that are not substituted remain unchanged:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ, 2)
        sage: I = R.ideal(x^2 + y^2 + x - y + 2); I
        Ideal (x^2 + y^2 + x - y + 2)
         of Multivariate Polynomial Ring in x, y over Rational Field
        sage: I.subs(x=1)
        Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational Field

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal(x**Integer(2) + y**Integer(2) + x - y + Integer(2)); I
        Ideal (x^2 + y^2 + x - y + 2)
         of Multivariate Polynomial Ring in x, y over Rational Field
        >>> I.subs(x=Integer(1))
        Ideal (y^2 - y + 4) of Multivariate Polynomial Ring in x, y over Rational Field

  weil_restriction()

    Compute the Weil restriction of this ideal over some extension field. If the field is a finite field, then this computes the Weil restriction to the prime subfield.

    A Weil restriction of scalars - denoted \(Res_{L/k}\) - is a functor which, for any finite extension of fields \(L/k\) and any algebraic variety \(X\) over \(L\), produces another corresponding variety \(Res_{L/k}(X)\), defined over \(k\). It is useful for reducing questions about varieties over large fields to questions about more complicated varieties over smaller fields.

    This function does not compute this Weil restriction directly but computes on generating sets of polynomial ideals:

    Let \(d\) be the degree of the field extension \(L/k\), let \(a\) a generator of \(L/k\) and \(p\) the minimal polynomial of \(L/k\). Denote this ideal by \(I\).

    Specifically, this function first maps each variable \(x\) to its representation over \(k\): \(\sum_{i=0}^{d-1} a^i x_i\). Then each generator of \(I\) is evaluated over these representations and reduced modulo the minimal polynomial \(p\). The result is interpreted as a univariate polynomial in \(a\) and its coefficients are the new generators of the returned ideal.

    If the input and the output ideals are radical, this is equivalent to the statement about algebraic varieties above.

    OUTPUT: `MPolynomialIdeal`

    EXAMPLES:

    Sage

        sage: k.<a> = GF(2^2)
        sage: P.<x,y> = PolynomialRing(k, 2)
        sage: I = Ideal([x*y + 1, a*x + 1])
        sage: I.variety()
        [{y: a, x: a + 1}]
        sage: J = I.weil_restriction()
        sage: J
        Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1) of
         Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
        sage: J += sage.rings.ideal.FieldIdeal(J.ring())  # ensure radical ideal
        sage: J.variety()
        [{y1: 1, y0: 0, x1: 1, x0: 1}]
        sage: J.weil_restriction()  # returns J
        Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1,
         x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate
         Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2

        sage: k.<a> = GF(3^5)
        sage: P.<x,y,z> = PolynomialRing(k)
        sage: I = sage.rings.ideal.Katsura(P)
        sage: I.dimension()
        0
        sage: I.variety()
         [{z: 0, y: 0, x: 1}]
        sage: J = I.weil_restriction(); J
        Ideal (x0 - y0 - z0 - 1,
               x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4,
               x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 - x0,
               -x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3
                    + y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 - x1,
               x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2
                     - y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 - x2,
               -x1*x2 - x0*x3 - x3*x4 - x4^2
                    + y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 - x3,
               x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2
                             + y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 - x4,
               -x0*y0 + x4*y1 + x3*y2 + x2*y3
                                  + x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 - y0,
               -x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3
                                  - x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2
                                          + y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 - y1,
               -x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4
                  - y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 - y2,
               -x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4
                          - y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 - y3,
               -x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4
                                  - y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4)
         of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4,
         z0, z1, z2, z3, z4 over Finite Field of size 3
        sage: J += sage.rings.ideal.FieldIdeal(J.ring())  # ensure radical ideal
        sage: J.variety()
        [{z4: 0,
          z3: 0,
          z2: 0,
          z1: 0,
          z0: 0,
          y4: 0,
          y3: 0,
          y2: 0,
          y1: 0,
          y0: 0,
          x4: 0,
          x3: 0,
          x2: 0,
          x1: 0,
          x0: 1}]

    Python

        >>> from sage.all import *
        >>> k = GF(Integer(2)**Integer(2), names=('a',)); (a,) = k._first_ngens(1)
        >>> P = PolynomialRing(k, Integer(2), names=('x', 'y',)); (x, y,) = P._first_ngens(2)
        >>> I = Ideal([x*y + Integer(1), a*x + Integer(1)])
        >>> I.variety()
        [{y: a, x: a + 1}]
        >>> J = I.weil_restriction()
        >>> J
        Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1) of
         Multivariate Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2
        >>> J += sage.rings.ideal.FieldIdeal(J.ring())  # ensure radical ideal
        >>> J.variety()
        [{y1: 1, y0: 0, x1: 1, x0: 1}]
        >>> J.weil_restriction()  # returns J
        Ideal (x0*y0 + x1*y1 + 1, x1*y0 + x0*y1 + x1*y1, x1 + 1, x0 + x1,
         x0^2 + x0, x1^2 + x1, y0^2 + y0, y1^2 + y1) of Multivariate
         Polynomial Ring in x0, x1, y0, y1 over Finite Field of size 2

        >>> k = GF(Integer(3)**Integer(5), names=('a',)); (a,) = k._first_ngens(1)
        >>> P = PolynomialRing(k, names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = sage.rings.ideal.Katsura(P)
        >>> I.dimension()
        0
        >>> I.variety()
         [{z: 0, y: 0, x: 1}]
        >>> J = I.weil_restriction(); J
        Ideal (x0 - y0 - z0 - 1,
               x1 - y1 - z1, x2 - y2 - z2, x3 - y3 - z3, x4 - y4 - z4,
               x0^2 + x2*x3 + x1*x4 - y0^2 - y2*y3 - y1*y4 - z0^2 - z2*z3 - z1*z4 - x0,
               -x0*x1 - x2*x3 - x3^2 - x1*x4 + x2*x4 + y0*y1 + y2*y3
                    + y3^2 + y1*y4 - y2*y4 + z0*z1 + z2*z3 + z3^2 + z1*z4 - z2*z4 - x1,
               x1^2 - x0*x2 + x3^2 - x2*x4 + x3*x4 - y1^2 + y0*y2
                     - y3^2 + y2*y4 - y3*y4 - z1^2 + z0*z2 - z3^2 + z2*z4 - z3*z4 - x2,
               -x1*x2 - x0*x3 - x3*x4 - x4^2
                    + y1*y2 + y0*y3 + y3*y4 + y4^2 + z1*z2 + z0*z3 + z3*z4 + z4^2 - x3,
               x2^2 - x1*x3 - x0*x4 + x4^2 - y2^2
                             + y1*y3 + y0*y4 - y4^2 - z2^2 + z1*z3 + z0*z4 - z4^2 - x4,
               -x0*y0 + x4*y1 + x3*y2 + x2*y3
                                  + x1*y4 - y0*z0 + y4*z1 + y3*z2 + y2*z3 + y1*z4 - y0,
               -x1*y0 - x0*y1 - x4*y1 - x3*y2 + x4*y2 - x2*y3 + x3*y3
                                  - x1*y4 + x2*y4 - y1*z0 - y0*z1 - y4*z1 - y3*z2
                                          + y4*z2 - y2*z3 + y3*z3 - y1*z4 + y2*z4 - y1,
               -x2*y0 - x1*y1 - x0*y2 - x4*y2 - x3*y3 + x4*y3 - x2*y4 + x3*y4
                  - y2*z0 - y1*z1 - y0*z2 - y4*z2 - y3*z3 + y4*z3 - y2*z4 + y3*z4 - y2,
               -x3*y0 - x2*y1 - x1*y2 - x0*y3 - x4*y3 - x3*y4 + x4*y4
                          - y3*z0 - y2*z1 - y1*z2 - y0*z3 - y4*z3 - y3*z4 + y4*z4 - y3,
               -x4*y0 - x3*y1 - x2*y2 - x1*y3 - x0*y4 - x4*y4
                                  - y4*z0 - y3*z1 - y2*z2 - y1*z3 - y0*z4 - y4*z4 - y4)
         of Multivariate Polynomial Ring in x0, x1, x2, x3, x4, y0, y1, y2, y3, y4,
         z0, z1, z2, z3, z4 over Finite Field of size 3
        >>> J += sage.rings.ideal.FieldIdeal(J.ring())  # ensure radical ideal
        >>> J.variety()
        [{z4: 0,
          z3: 0,
          z2: 0,
          z1: 0,
          z0: 0,
          y4: 0,
          y3: 0,
          y2: 0,
          y1: 0,
          y0: 0,
          x4: 0,
          x3: 0,
          x2: 0,
          x1: 0,
          x0: 1}]

    Weil restrictions are often used to study elliptic curves over extension fields so we give a simple example involving those:

    Sage

        sage: K.<a> = QuadraticField(1/3)                                           # needs sage.rings.number_field
        sage: E = EllipticCurve(K, [1,2,3,4,5])                                     # needs sage.rings.number_field

    [Python]

        >>> from sage.all import *
        >>> K = QuadraticField(Integer(1)/Integer(3), names=('a',)); (a,) = K._first_ngens(1)# needs sage.rings.number_field
        >>> E = EllipticCurve(K, [Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)])                                     # needs sage.rings.number_field

    We pick a point on `E`:

    Sage

        sage: p = E.lift_x(1); p                                                    # needs sage.rings.number_field
        (1 : -6 : 1)

        sage: I = E.defining_ideal(); I                                             # needs sage.rings.number_field
        Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3)
         of Multivariate Polynomial Ring in x, y, z
          over Number Field in a with defining polynomial x^2 - 1/3
           with a = 0.5773502691896258?

    Python

        >>> from sage.all import *
        >>> p = E.lift_x(Integer(1)); p                                                    # needs sage.rings.number_field
        (1 : -6 : 1)

        >>> I = E.defining_ideal(); I                                             # needs sage.rings.number_field
        Ideal (-x^3 - 2*x^2*z + x*y*z + y^2*z - 4*x*z^2 + 3*y*z^2 - 5*z^3)
         of Multivariate Polynomial Ring in x, y, z
          over Number Field in a with defining polynomial x^2 - 1/3
           with a = 0.5773502691896258?

    Of course, the point `p` is a root of all generators of `I`:

    Sage

        sage: I.subs(x=1, y=2, z=1)                                                 # needs sage.rings.number_field
        Ideal (0) of Multivariate Polynomial Ring in x, y, z
         over Number Field in a with defining polynomial x^2 - 1/3
          with a = 0.5773502691896258?

    [Python]

        >>> from sage.all import *
        >>> I.subs(x=Integer(1), y=Integer(2), z=Integer(1))                                                 # needs sage.rings.number_field
        Ideal (0) of Multivariate Polynomial Ring in x, y, z
         over Number Field in a with defining polynomial x^2 - 1/3
          with a = 0.5773502691896258?

    `I` is also radical:

    Sage

        sage: I.radical() == I                                                      # needs sage.rings.number_field
        True

    Python

        >>> from sage.all import *
        >>> I.radical() == I                                                      # needs sage.rings.number_field
        True

    So we compute its Weil restriction:

    Sage

        sage: J = I.weil_restriction(); J                                           # needs sage.rings.number_field
        Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0
                 + 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3
                 - 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1
                 - 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2,
               -3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0
                 + 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1 - 2/3*x1^2*z1
                 + x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1
                 + 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3)
        of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field

    [Python]

        >>> from sage.all import *
        >>> J = I.weil_restriction(); J                                           # needs sage.rings.number_field
        Ideal (-x0^3 - x0*x1^2 - 2*x0^2*z0 - 2/3*x1^2*z0 + x0*y0*z0 + y0^2*z0
                 + 1/3*x1*y1*z0 + 1/3*y1^2*z0 - 4*x0*z0^2 + 3*y0*z0^2 - 5*z0^3
                 - 4/3*x0*x1*z1 + 1/3*x1*y0*z1 + 1/3*x0*y1*z1 + 2/3*y0*y1*z1
                 - 8/3*x1*z0*z1 + 2*y1*z0*z1 - 4/3*x0*z1^2 + y0*z1^2 - 5*z0*z1^2,
               -3*x0^2*x1 - 1/3*x1^3 - 4*x0*x1*z0 + x1*y0*z0 + x0*y1*z0
                 + 2*y0*y1*z0 - 4*x1*z0^2 + 3*y1*z0^2 - 2*x0^2*z1 - 2/3*x1^2*z1
                 + x0*y0*z1 + y0^2*z1 + 1/3*x1*y1*z1 + 1/3*y1^2*z1 - 8*x0*z0*z1
                 + 6*y0*z0*z1 - 15*z0^2*z1 - 4/3*x1*z1^2 + y1*z1^2 - 5/3*z1^3)
        of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1 over Rational Field

    We can check that the point `p` is still a root of all generators of `J`:

    Sage

        sage: J.subs(x0=1, y0=2, z0=1, x1=0, y1=0, z1=0)                            # needs sage.rings.number_field
        Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1
         over Rational Field

    Python

        >>> from sage.all import *
        >>> J.subs(x0=Integer(1), y0=Integer(2), z0=Integer(1), x1=Integer(0), y1=Integer(0), z1=Integer(0))                            # needs sage.rings.number_field
        Ideal (0, 0) of Multivariate Polynomial Ring in x0, x1, y0, y1, z0, z1
         over Rational Field

    Example for relative number fields:

    Sage

        sage: R.<x> = QQ[]
        sage: K.<w> = NumberField(x^5 - 2)
        sage: R.<x> = K[]
        sage: L.<v> = K.extension(x^2 + 1)
        sage: S.<x,y> = L[]
        sage: I = S.ideal([y^2 - x^3 - 1])
        sage: I.weil_restriction()
        Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of
         Multivariate Polynomial Ring in x0, x1, y0, y1
          over Number Field in w with defining polynomial x^5 - 2

    [Python]

        >>> from sage.all import *
        >>> R = QQ['x']; (x,) = R._first_ngens(1)
        >>> K = NumberField(x**Integer(5) - Integer(2), names=('w',)); (w,) = K._first_ngens(1)
        >>> R = K['x']; (x,) = R._first_ngens(1)
        >>> L = K.extension(x**Integer(2) + Integer(1), names=('v',)); (v,) = L._first_ngens(1)
        >>> S = L['x, y']; (x, y,) = S._first_ngens(2)
        >>> I = S.ideal([y**Integer(2) - x**Integer(3) - Integer(1)])
        >>> I.weil_restriction()
        Ideal (-x0^3 + 3*x0*x1^2 + y0^2 - y1^2 - 1, -3*x0^2*x1 + x1^3 + 2*y0*y1) of
         Multivariate Polynomial Ring in x0, x1, y0, y1
          over Number Field in w with defining polynomial x^5 - 2

    Note

    Based on a Singular implementation by Michael Brickenstein

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_macaulay2_repr

  Bases: `object`

  An ideal in a multivariate polynomial ring, which has an underlying Macaulay2 ring associated to it.

  EXAMPLES:

  Sage

      sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
      sage: I = ideal(x*y-z^2, y^2-w^2)
      sage: I
      Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring

  Python

      >>> from sage.all import *
      >>> R = PolynomialRing(ZZ, Integer(4), names=('x', 'y', 'z', 'w',)); (x, y, z, w,) = R._first_ngens(4)
      >>> I = ideal(x*y-z**Integer(2), y**Integer(2)-w**Integer(2))
      >>> I
      Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_magma_repr

  Bases: `object`

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_quotient(ring, gens, coerce=True)

  Bases: `QuotientRingIdeal_generic`, `MPolynomialIdeal`

  An ideal in a quotient of a multivariate polynomial ring.

  EXAMPLES:

  Sage

      sage: Q.<x,y,z,w> = QQ['x,y,z,w'].quotient(['x*y-z^2', 'y^2-w^2'])
      sage: I = ideal(x + y^2 + z - 1)
      sage: I
      Ideal (w^2 + x + z - 1) of Quotient
       of Multivariate Polynomial Ring in x, y, z, w over Rational Field
       by the ideal (x*y - z^2, y^2 - w^2)

  Python

      >>> from sage.all import *
      >>> Q = QQ['x,y,z,w'].quotient(['x*y-z^2', 'y^2-w^2'], names=('x', 'y', 'z', 'w',)); (x, y, z, w,) = Q._first_ngens(4)
      >>> I = ideal(x + y**Integer(2) + z - Integer(1))
      >>> I
      Ideal (w^2 + x + z - 1) of Quotient
       of Multivariate Polynomial Ring in x, y, z, w over Rational Field
       by the ideal (x*y - z^2, y^2 - w^2)

  reduce(f)

    Reduce an element modulo a Gröbner basis for this ideal. This returns 0 if and only if the element is in this ideal. In any case, this reduction is unique up to monomial orders.

    EXAMPLES:

    Sage

        sage: R.<T,U,V,W,X,Y,Z> = PolynomialRing(QQ, order='lex')
        sage: I = R.ideal([T^2 + U^2 - 1, V^2 + W^2 - 1, X^2 + Y^2 + Z^2 - 1])
        sage: Q.<t,u,v,w,x,y,z> = R.quotient(I)
        sage: J = Q.ideal([u*v - x, u*w - y, t - z])
        sage: J.reduce(t^2 - z^2)
        0
        sage: J.reduce(u^2)
        -z^2 + 1
        sage: t^2 - z^2 in J
        True
        sage: u^2 in J
        False

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, order='lex', names=('T', 'U', 'V', 'W', 'X', 'Y', 'Z',)); (T, U, V, W, X, Y, Z,) = R._first_ngens(7)
        >>> I = R.ideal([T**Integer(2) + U**Integer(2) - Integer(1), V**Integer(2) + W**Integer(2) - Integer(1), X**Integer(2) + Y**Integer(2) + Z**Integer(2) - Integer(1)])
        >>> Q = R.quotient(I, names=('t', 'u', 'v', 'w', 'x', 'y', 'z',)); (t, u, v, w, x, y, z,) = Q._first_ngens(7)
        >>> J = Q.ideal([u*v - x, u*w - y, t - z])
        >>> J.reduce(t**Integer(2) - z**Integer(2))
        0
        >>> J.reduce(u**Integer(2))
        -z^2 + 1
        >>> t**Integer(2) - z**Integer(2) in J
        True
        >>> u**Integer(2) in J
        False

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_base_repr

  Bases: `object`

  syzygy_module()

    Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ)
        sage: f = 2*x^2 + y
        sage: g = y
        sage: h = 2*f + g
        sage: I = Ideal([f,g,h])
        sage: M = I.syzygy_module(); M
        [       -2        -1         1]
        [       -y 2*x^2 + y         0]
        sage: G = vector(I.gens())
        sage: M*G
        (0, 0)

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> f = Integer(2)*x**Integer(2) + y
        >>> g = y
        >>> h = Integer(2)*f + g
        >>> I = Ideal([f,g,h])
        >>> M = I.syzygy_module(); M
        [       -2        -1         1]
        [       -y 2*x^2 + y         0]
        >>> G = vector(I.gens())
        >>> M*G
        (0, 0)

    ALGORITHM: Uses Singular’s syz command

class sage.rings.polynomial.multi_polynomial_ideal.MPolynomialIdeal_singular_repr

  Bases: `MPolynomialIdeal_singular_base_repr`

  An ideal in a multivariate polynomial ring, which has an underlying Singular ring associated to it.

  associated_primes(algorithm='sy')

    Return a list of the associated primes of primary ideals of which the intersection is \(I\) = `self`.

    An ideal \(Q\) is called primary if it is a proper ideal of the ring \(R\) and if whenever \(ab \in Q\) and \(a \not\in Q\) then \(b^n \in Q\) for some \(n \in \ZZ\).

    If \(Q\) is a primary ideal of the ring \(R\), then the radical ideal \(P\) of \(Q\), i.e. \(P = \{a \in R, a^n \in Q\}\) for some \(n \in \ZZ\), is called the associated prime of \(Q\).

    If \(I\) is a proper ideal of the ring \(R\) then there exists a decomposition in primary ideals \(Q_i\) such that

    - their intersection is \(I\)

    - none of the \(Q_i\) contains the intersection of the rest, and

    - the associated prime ideals of \(Q_i\) are pairwise different.

    This method returns the associated primes of the \(Q_i\).

    INPUT:

    - `algorithm` – string; one of

      - `'sy'` – (default) use the Shimoyama-Yokoyama algorithm

      - `'gtz'` – use the Gianni-Trager-Zacharias algorithm

    OUTPUT: list of associated primes

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
        sage: p = z^2 + 1; q = z^3 + 2
        sage: I = (p*q^2, y - z^2) * R
        sage: pd = I.associated_primes(); sorted(pd, key=str)
        [Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(3), order='lex', names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)
        >>> I = (p*q**Integer(2), y - z**Integer(2)) * R
        >>> pd = I.associated_primes(); sorted(pd, key=str)
        [Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field]

    ALGORITHM:

    Uses Singular.

    REFERENCES:

    - Thomas Becker and Volker Weispfenning. Groebner Bases - A Computational Approach To Commutative Algebra. Springer, New York 1993.

  basis_is_groebner(singular=None)

    Return `True` if the generators of this ideal (`self.gens()`) form a Groebner basis.

    Let \(I\) be the set of generators of this ideal. The check is performed by trying to lift \(Syz(LM(I))\) to \(Syz(I)\) as \(I\) forms a Groebner basis if and only if for every element \(S\) in \(Syz(LM(I))\):

    \[S * G = \sum_{i=0}^{m} h_ig_i ---->_G 0.\]

    ALGORITHM:

    Uses Singular.

    EXAMPLES:

    Sage

        sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127), 10)
        sage: I = sage.rings.ideal.Cyclic(R, 4)
        sage: I.basis_is_groebner()
        False
        sage: I2 = Ideal(I.groebner_basis())
        sage: I2.basis_is_groebner()
        True

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(127)), Integer(10), names=('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',)); (a, b, c, d, e, f, g, h, i, j,) = R._first_ngens(10)
        >>> I = sage.rings.ideal.Cyclic(R, Integer(4))
        >>> I.basis_is_groebner()
        False
        >>> I2 = Ideal(I.groebner_basis())
        >>> I2.basis_is_groebner()
        True

    A more complicated example:

    Sage

        sage: R.<U6,U5,U4,U3,U2, u6,u5,u4,u3,u2, h> = PolynomialRing(GF(7583))      # needs sage.rings.finite_rings
        sage: l = [u6 + u5 + u4 + u3 + u2 - 3791*h,                                 # needs sage.rings.finite_rings
        ....:      U6 + U5 + U4 + U3 + U2 - 3791*h,
        ....:      U2*u2 - h^2, U3*u3 - h^2, U4*u4 - h^2,
        ....:      U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - 3791*U5*h
        ....:        - 3791*U4*h - 3791*U3*h - 3791*U2*h - 2842*h^2,
        ....:      U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - 3791*u5*h
        ....:        - 3791*u4*h - 3791*u3*h - 3791*u2*h - 2842*h^2,
        ....:      U5*u5 - h^2, U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3^2*u2 - 3791*U5*U3*h
        ....:        - 3791*U4*U3*h - 3791*U3^2*h - 3791*U5*U2*h- 3791*U4*U2*h + U3*U2*h
        ....:        - 3791*U2^2*h - 3791*U4*u3*h - 3791*U4*u2*h - 3791*U3*u2*h
        ....:        - 2843*U5*h^2 + 1897*U4*h^2 - 946*U3*h^2 - 947*U2*h^2 + 2370*h^3,
        ....:      U3*u5*u4 + U2*u5*u4 + U3*u4^2 + U2*u4^2 + U2*u4*u3 - 3791*u5*u4*h
        ....:        - 3791*u4^2*h - 3791*u4*u3*h - 3791*u4*u2*h + u5*h^2 - 2842*u4*h^2,
        ....:      U2*u5*u4*u3 + U2*u4^2*u3 + U2*u4*u3^2 - 3791*u5*u4*u3*h
        ....:        - 3791*u4^2*u3*h - 3791*u4*u3^2*h - 3791*u4*u3*u2*h + u5*u4*h^2
        ....:        + u4^2*h^2 + u5*u3*h^2 - 2842*u4*u3*h^2,
        ....:      U5^2*U4*u3 + U5*U4^2*u3 + U5^2*U4*u2 + U5*U4^2*u2 + U5^2*U3*u2
        ....:        + 2*U5*U4*U3*u2 + U5*U3^2*u2 - 3791*U5^2*U4*h - 3791*U5*U4^2*h
        ....:        - 3791*U5^2*U3*h + U5*U4*U3*h - 3791*U5*U3^2*h - 3791*U5^2*U2*h
        ....:        + U5*U4*U2*h+ U5*U3*U2*h - 3791*U5*U2^2*h - 3791*U5*U3*u2*h
        ....:        - 2842*U5^2*h^2 + 1897*U5*U4*h^2 - U4^2*h^2 - 947*U5*U3*h^2
        ....:        - U4*U3*h^2 - 948*U5*U2*h^2 - U4*U2*h^2 - 1422*U5*h^3 + 3791*U4*h^3,
        ....:      u5*u4*u3*u2*h + u4^2*u3*u2*h + u4*u3^2*u2*h + u4*u3*u2^2*h
        ....:        + 2*u5*u4*u3*h^2 + 2*u4^2*u3*h^2 + 2*u4*u3^2*h^2 + 2*u5*u4*u2*h^2
        ....:        + 2*u4^2*u2*h^2 + 2*u5*u3*u2*h^2 + 1899*u4*u3*u2*h^2,
        ....:      U5^2*U4*U3*u2 + U5*U4^2*U3*u2 + U5*U4*U3^2*u2 - 3791*U5^2*U4*U3*h
        ....:        - 3791*U5*U4^2*U3*h - 3791*U5*U4*U3^2*h - 3791*U5*U4*U3*U2*h
        ....:        + 3791*U5*U4*U3*u2*h + U5^2*U4*h^2 + U5*U4^2*h^2 + U5^2*U3*h^2
        ....:        - U4^2*U3*h^2 - U5*U3^2*h^2 - U4*U3^2*h^2 - U5*U4*U2*h^2 - U5*U3*U2*h^2
        ....:        - U4*U3*U2*h^2 + 3791*U5*U4*h^3 + 3791*U5*U3*h^3 + 3791*U4*U3*h^3,
        ....:      u4^2*u3*u2*h^2 + 1515*u5*u3^2*u2*h^2 + u4*u3^2*u2*h^2
        ....:        + 1515*u5*u4*u2^2*h^2 + 1515*u5*u3*u2^2*h^2 + u4*u3*u2^2*h^2
        ....:        + 1521*u5*u4*u3*h^3 - 3028*u4^2*u3*h^3 - 3028*u4*u3^2*h^3
        ....:        + 1521*u5*u4*u2*h^3 - 3028*u4^2*u2*h^3 + 1521*u5*u3*u2*h^3
        ....:        + 3420*u4*u3*u2*h^3,
        ....:      U5^2*U4*U3*U2*h + U5*U4^2*U3*U2*h + U5*U4*U3^2*U2*h + U5*U4*U3*U2^2*h
        ....:        + 2*U5^2*U4*U3*h^2 + 2*U5*U4^2*U3*h^2 + 2*U5*U4*U3^2*h^2
        ....:        + 2*U5^2*U4*U2*h^2 + 2*U5*U4^2*U2*h^2 + 2*U5^2*U3*U2*h^2
        ....:        - 2*U4^2*U3*U2*h^2 - 2*U5*U3^2*U2*h^2 - 2*U4*U3^2*U2*h^2
        ....:        - 2*U5*U4*U2^2*h^2 - 2*U5*U3*U2^2*h^2 - 2*U4*U3*U2^2*h^2
        ....:        - U5*U4*U3*h^3 - U5*U4*U2*h^3 - U5*U3*U2*h^3 - U4*U3*U2*h^3]

        sage: Ideal(l).basis_is_groebner()                                          # needs sage.rings.finite_rings
        False
        sage: gb = Ideal(l).groebner_basis()                                        # needs sage.rings.finite_rings
        sage: Ideal(gb).basis_is_groebner()                                         # needs sage.rings.finite_rings
        True

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(7583)), names=('U6', 'U5', 'U4', 'U3', 'U2', 'u6', 'u5', 'u4', 'u3', 'u2', 'h',)); (U6, U5, U4, U3, U2, u6, u5, u4, u3, u2, h,) = R._first_ngens(11)# needs sage.rings.finite_rings
        >>> l = [u6 + u5 + u4 + u3 + u2 - Integer(3791)*h,                                 # needs sage.rings.finite_rings
        ...      U6 + U5 + U4 + U3 + U2 - Integer(3791)*h,
        ...      U2*u2 - h**Integer(2), U3*u3 - h**Integer(2), U4*u4 - h**Integer(2),
        ...      U5*u4 + U5*u3 + U4*u3 + U5*u2 + U4*u2 + U3*u2 - Integer(3791)*U5*h
        ...        - Integer(3791)*U4*h - Integer(3791)*U3*h - Integer(3791)*U2*h - Integer(2842)*h**Integer(2),
        ...      U4*u5 + U3*u5 + U2*u5 + U3*u4 + U2*u4 + U2*u3 - Integer(3791)*u5*h
        ...        - Integer(3791)*u4*h - Integer(3791)*u3*h - Integer(3791)*u2*h - Integer(2842)*h**Integer(2),
        ...      U5*u5 - h**Integer(2), U4*U2*u3 + U5*U3*u2 + U4*U3*u2 + U3**Integer(2)*u2 - Integer(3791)*U5*U3*h
        ...        - Integer(3791)*U4*U3*h - Integer(3791)*U3**Integer(2)*h - Integer(3791)*U5*U2*h- Integer(3791)*U4*U2*h + U3*U2*h
        ...        - Integer(3791)*U2**Integer(2)*h - Integer(3791)*U4*u3*h - Integer(3791)*U4*u2*h - Integer(3791)*U3*u2*h
        ...        - Integer(2843)*U5*h**Integer(2) + Integer(1897)*U4*h**Integer(2) - Integer(946)*U3*h**Integer(2) - Integer(947)*U2*h**Integer(2) + Integer(2370)*h**Integer(3),
        ...      U3*u5*u4 + U2*u5*u4 + U3*u4**Integer(2) + U2*u4**Integer(2) + U2*u4*u3 - Integer(3791)*u5*u4*h
        ...        - Integer(3791)*u4**Integer(2)*h - Integer(3791)*u4*u3*h - Integer(3791)*u4*u2*h + u5*h**Integer(2) - Integer(2842)*u4*h**Integer(2),
        ...      U2*u5*u4*u3 + U2*u4**Integer(2)*u3 + U2*u4*u3**Integer(2) - Integer(3791)*u5*u4*u3*h
        ...        - Integer(3791)*u4**Integer(2)*u3*h - Integer(3791)*u4*u3**Integer(2)*h - Integer(3791)*u4*u3*u2*h + u5*u4*h**Integer(2)
        ...        + u4**Integer(2)*h**Integer(2) + u5*u3*h**Integer(2) - Integer(2842)*u4*u3*h**Integer(2),
        ...      U5**Integer(2)*U4*u3 + U5*U4**Integer(2)*u3 + U5**Integer(2)*U4*u2 + U5*U4**Integer(2)*u2 + U5**Integer(2)*U3*u2
        ...        + Integer(2)*U5*U4*U3*u2 + U5*U3**Integer(2)*u2 - Integer(3791)*U5**Integer(2)*U4*h - Integer(3791)*U5*U4**Integer(2)*h
        ...        - Integer(3791)*U5**Integer(2)*U3*h + U5*U4*U3*h - Integer(3791)*U5*U3**Integer(2)*h - Integer(3791)*U5**Integer(2)*U2*h
        ...        + U5*U4*U2*h+ U5*U3*U2*h - Integer(3791)*U5*U2**Integer(2)*h - Integer(3791)*U5*U3*u2*h
        ...        - Integer(2842)*U5**Integer(2)*h**Integer(2) + Integer(1897)*U5*U4*h**Integer(2) - U4**Integer(2)*h**Integer(2) - Integer(947)*U5*U3*h**Integer(2)
        ...        - U4*U3*h**Integer(2) - Integer(948)*U5*U2*h**Integer(2) - U4*U2*h**Integer(2) - Integer(1422)*U5*h**Integer(3) + Integer(3791)*U4*h**Integer(3),
        ...      u5*u4*u3*u2*h + u4**Integer(2)*u3*u2*h + u4*u3**Integer(2)*u2*h + u4*u3*u2**Integer(2)*h
        ...        + Integer(2)*u5*u4*u3*h**Integer(2) + Integer(2)*u4**Integer(2)*u3*h**Integer(2) + Integer(2)*u4*u3**Integer(2)*h**Integer(2) + Integer(2)*u5*u4*u2*h**Integer(2)
        ...        + Integer(2)*u4**Integer(2)*u2*h**Integer(2) + Integer(2)*u5*u3*u2*h**Integer(2) + Integer(1899)*u4*u3*u2*h**Integer(2),
        ...      U5**Integer(2)*U4*U3*u2 + U5*U4**Integer(2)*U3*u2 + U5*U4*U3**Integer(2)*u2 - Integer(3791)*U5**Integer(2)*U4*U3*h
        ...        - Integer(3791)*U5*U4**Integer(2)*U3*h - Integer(3791)*U5*U4*U3**Integer(2)*h - Integer(3791)*U5*U4*U3*U2*h
        ...        + Integer(3791)*U5*U4*U3*u2*h + U5**Integer(2)*U4*h**Integer(2) + U5*U4**Integer(2)*h**Integer(2) + U5**Integer(2)*U3*h**Integer(2)
        ...        - U4**Integer(2)*U3*h**Integer(2) - U5*U3**Integer(2)*h**Integer(2) - U4*U3**Integer(2)*h**Integer(2) - U5*U4*U2*h**Integer(2) - U5*U3*U2*h**Integer(2)
        ...        - U4*U3*U2*h**Integer(2) + Integer(3791)*U5*U4*h**Integer(3) + Integer(3791)*U5*U3*h**Integer(3) + Integer(3791)*U4*U3*h**Integer(3),
        ...      u4**Integer(2)*u3*u2*h**Integer(2) + Integer(1515)*u5*u3**Integer(2)*u2*h**Integer(2) + u4*u3**Integer(2)*u2*h**Integer(2)
        ...        + Integer(1515)*u5*u4*u2**Integer(2)*h**Integer(2) + Integer(1515)*u5*u3*u2**Integer(2)*h**Integer(2) + u4*u3*u2**Integer(2)*h**Integer(2)
        ...        + Integer(1521)*u5*u4*u3*h**Integer(3) - Integer(3028)*u4**Integer(2)*u3*h**Integer(3) - Integer(3028)*u4*u3**Integer(2)*h**Integer(3)
        ...        + Integer(1521)*u5*u4*u2*h**Integer(3) - Integer(3028)*u4**Integer(2)*u2*h**Integer(3) + Integer(1521)*u5*u3*u2*h**Integer(3)
        ...        + Integer(3420)*u4*u3*u2*h**Integer(3),
        ...      U5**Integer(2)*U4*U3*U2*h + U5*U4**Integer(2)*U3*U2*h + U5*U4*U3**Integer(2)*U2*h + U5*U4*U3*U2**Integer(2)*h
        ...        + Integer(2)*U5**Integer(2)*U4*U3*h**Integer(2) + Integer(2)*U5*U4**Integer(2)*U3*h**Integer(2) + Integer(2)*U5*U4*U3**Integer(2)*h**Integer(2)
        ...        + Integer(2)*U5**Integer(2)*U4*U2*h**Integer(2) + Integer(2)*U5*U4**Integer(2)*U2*h**Integer(2) + Integer(2)*U5**Integer(2)*U3*U2*h**Integer(2)
        ...        - Integer(2)*U4**Integer(2)*U3*U2*h**Integer(2) - Integer(2)*U5*U3**Integer(2)*U2*h**Integer(2) - Integer(2)*U4*U3**Integer(2)*U2*h**Integer(2)
        ...        - Integer(2)*U5*U4*U2**Integer(2)*h**Integer(2) - Integer(2)*U5*U3*U2**Integer(2)*h**Integer(2) - Integer(2)*U4*U3*U2**Integer(2)*h**Integer(2)
        ...        - U5*U4*U3*h**Integer(3) - U5*U4*U2*h**Integer(3) - U5*U3*U2*h**Integer(3) - U4*U3*U2*h**Integer(3)]

        >>> Ideal(l).basis_is_groebner()                                          # needs sage.rings.finite_rings
        False
        >>> gb = Ideal(l).groebner_basis()                                        # needs sage.rings.finite_rings
        >>> Ideal(gb).basis_is_groebner()                                         # needs sage.rings.finite_rings
        True

    Note

    From the Singular Manual for the reduce function we use in this method: ‘The result may have no meaning if the second argument (`self`) is not a standard basis’. I (malb) believe this refers to the mathematical fact that the results may have no meaning if `self` is no standard basis, i.e., Singular doesn’t ‘add’ any additional ‘nonsense’ to the result. So we may actually use reduce to determine if `self` is a Groebner basis.

  complete_primary_decomposition()

    A decorator that creates a cached version of an instance method of a class.

    Note

    For proper behavior, the method must be a pure function (no side effects). Arguments to the method must be hashable or transformed into something hashable using `key` or they must define `sage.structure.sage_object.SageObject._cache_key()`.

    EXAMPLES:

    Sage

        sage: class Foo():
        ....:     @cached_method
        ....:     def f(self, t, x=2):
        ....:         print('computing')
        ....:         return t**x
        sage: a = Foo()

    Python

        >>> from sage.all import *
        >>> class Foo():
        ...     @cached_method
        ...     def f(self, t, x=Integer(2)):
        ...         print('computing')
        ...         return t**x
        >>> a = Foo()

    The example shows that the actual computation takes place only once, and that the result is identical for equivalent input:

    Sage

        sage: res = a.f(3, 2); res
        computing
        9
        sage: a.f(t = 3, x = 2) is res
        True
        sage: a.f(3) is res
        True

    [Python]

        >>> from sage.all import *
        >>> res = a.f(Integer(3), Integer(2)); res
        computing
        9
        >>> a.f(t = Integer(3), x = Integer(2)) is res
        True
        >>> a.f(Integer(3)) is res
        True

    Note, however, that accessing the attribute directly will call `__get__()`, and returns a `CachedMethodCaller` or `CachedMethodCallerNoArgs`.

    Sage

        sage: P.<a,b,c,d> = QQ[]
        sage: I = P*[a,b]
        sage: type(I.__class__.gens)
        <class 'sage.misc.cachefunc.CachedMethodCallerNoArgs'>
        sage: type(I.__class__.__dict__["gens"])
        <class 'sage.misc.cachefunc.CachedMethod'>

    Python

        >>> from sage.all import *
        >>> P = QQ['a, b, c, d']; (a, b, c, d,) = P._first_ngens(4)
        >>> I = P*[a,b]
        >>> type(I.__class__.gens)
        <class 'sage.misc.cachefunc.CachedMethodCallerNoArgs'>
        >>> type(I.__class__.__dict__["gens"])
        <class 'sage.misc.cachefunc.CachedMethod'>

    The parameter `key` can be used to pass a function which creates a custom cache key for inputs. In the following example, this parameter is used to ignore the `algorithm` keyword for caching:

    Sage

        sage: class A():
        ....:     def _f_normalize(self, x, algorithm): return x
        ....:     @cached_method(key=_f_normalize)
        ....:     def f(self, x, algorithm='default'): return x
        sage: a = A()
        sage: a.f(1, algorithm='default') is a.f(1) is a.f(1, algorithm='algorithm')
        True

    [Python]

        >>> from sage.all import *
        >>> class A():
        ...     def _f_normalize(self, x, algorithm): return x
        ...     @cached_method(key=_f_normalize)
        ...     def f(self, x, algorithm='default'): return x
        >>> a = A()
        >>> a.f(Integer(1), algorithm='default') is a.f(Integer(1)) is a.f(Integer(1), algorithm='algorithm')
        True

    The parameter `do_pickle` can be used to enable pickling of the cache. Usually the cache is not stored when pickling:

    Sage

        sage: class A():
        ....:     @cached_method
        ....:     def f(self, x): return None
        sage: import __main__
        sage: __main__.A = A
        sage: a = A()
        sage: a.f(1)
        sage: len(a.f.cache)
        1
        sage: b = loads(dumps(a))
        sage: len(b.f.cache)
        0

    Python

        >>> from sage.all import *
        >>> class A():
        ...     @cached_method
        ...     def f(self, x): return None
        >>> import __main__
        >>> __main__.A = A
        >>> a = A()
        >>> a.f(Integer(1))
        >>> len(a.f.cache)
        1
        >>> b = loads(dumps(a))
        >>> len(b.f.cache)
        0

    When `do_pickle` is set, the pickle contains the contents of the cache:

    Sage

        sage: class A():
        ....:     @cached_method(do_pickle=True)
        ....:     def f(self, x): return None
        sage: __main__.A = A
        sage: a = A()
        sage: a.f(1)
        sage: len(a.f.cache)
        1
        sage: b = loads(dumps(a))
        sage: len(b.f.cache)
        1

    [Python]

        >>> from sage.all import *
        >>> class A():
        ...     @cached_method(do_pickle=True)
        ...     def f(self, x): return None
        >>> __main__.A = A
        >>> a = A()
        >>> a.f(Integer(1))
        >>> len(a.f.cache)
        1
        >>> b = loads(dumps(a))
        >>> len(b.f.cache)
        1

    Cached methods cannot be copied like usual methods, see Issue #12603. Copying them can lead to very surprising results:

    Sage

        sage: class A:
        ....:     @cached_method
        ....:     def f(self):
        ....:         return 1
        sage: class B:
        ....:     g=A.f
        ....:     def f(self):
        ....:         return 2

        sage: b=B()
        sage: b.f()
        2
        sage: b.g()
        1
        sage: b.f()
        1

    Python

        >>> from sage.all import *
        >>> class A:
        ...     @cached_method
        ...     def f(self):
        ...         return Integer(1)
        >>> class B:
        ...     g=A.f
        ...     def f(self):
        ...         return Integer(2)

        >>> b=B()
        >>> b.f()
        2
        >>> b.g()
        1
        >>> b.f()
        1

  dimension(singular=None)

    The dimension of the ring modulo this ideal.

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(GF(32003), order='degrevlex')              # needs sage.rings.finite_rings
        sage: I = ideal(x^2 - y, x^3)                                               # needs sage.rings.finite_rings
        sage: I.dimension()                                                         # needs sage.rings.finite_rings
        1

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(GF(Integer(32003)), order='degrevlex', names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.finite_rings
        >>> I = ideal(x**Integer(2) - y, x**Integer(3))                                               # needs sage.rings.finite_rings
        >>> I.dimension()                                                         # needs sage.rings.finite_rings
        1

    If the ideal is the total ring, the dimension is \(-1\) by convention.

    ALGORITHM:

    For principal ideals, Theorem 3.5.1 of [Ger2008] is used. Otherwise Singular is used, unless the characteristic is too large. This requires computation of a Groebner basis, which can be very expensive.

    For polynomials over a finite field of order too large for Singular, this falls back on a toy implementation of Buchberger to compute the Groebner basis, then uses the algorithm described in Chapter 9, Section 1 of Cox, Little, and O’Shea’s “Ideals, Varieties, and Algorithms”.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(GF(2147483659^2), order='lex')
        sage: I = R.ideal([x*y, x*y + 1])
        sage: I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        -1
        sage: I=ideal([x*(x*y+1), y*(x*y+1)])
        sage: I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        1
        sage: I = R.ideal([x^3*y, x*y^2])
        sage: I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        1
        sage: R.<x,y> = PolynomialRing(GF(2147483659^2), order='lex')
        sage: I = R.ideal(0)
        sage: I.dimension()
        2

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(2147483659)**Integer(2)), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal([x*y, x*y + Integer(1)])
        >>> I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        -1
        >>> I=ideal([x*(x*y+Integer(1)), y*(x*y+Integer(1))])
        >>> I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        1
        >>> I = R.ideal([x**Integer(3)*y, x*y**Integer(2)])
        >>> I.dimension()
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        1
        >>> R = PolynomialRing(GF(Integer(2147483659)**Integer(2)), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal(Integer(0))
        >>> I.dimension()
        2

  elimination_ideal(variables, algorithm=None, *args, **kwds)

    Return the elimination ideal of this ideal with respect to the variables given in `variables`.

    INPUT:

    - `variables` – list or tuple of variables in `self.ring()`

    - `algorithm` – determines the algorithm to use, see below for available algorithms

    ALGORITHMS:

    - `'libsingular:eliminate'` – libSingular’s `eliminate` command (default)

    - `'giac:eliminate'` – Giac’s `eliminate` command (if available)

    If only a system is given - e.g. ‘giac’ - the default algorithm is chosen for that system.

    EXAMPLES:

    Sage

        sage: R.<x,y,t,s,z> = PolynomialRing(QQ,5)
        sage: I = R * [x - t, y - t^2, z - t^3, s - x + y^3]
        sage: J = I.elimination_ideal([t, s]); J
        Ideal (y^2 - x*z, x*y - z, x^2 - y)
         of Multivariate Polynomial Ring in x, y, t, s, z over Rational Field

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ,Integer(5), names=('x', 'y', 't', 's', 'z',)); (x, y, t, s, z,) = R._first_ngens(5)
        >>> I = R * [x - t, y - t**Integer(2), z - t**Integer(3), s - x + y**Integer(3)]
        >>> J = I.elimination_ideal([t, s]); J
        Ideal (y^2 - x*z, x*y - z, x^2 - y)
         of Multivariate Polynomial Ring in x, y, t, s, z over Rational Field

    You can use Giac to compute the elimination ideal:

    Sage

        sage: # needs sage.libs.giac
        sage: print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm='giac') == J
        possible output...
        True

    [Python]

        >>> from sage.all import *
        >>> # needs sage.libs.giac
        >>> print("possible output from giac", flush=True); I.elimination_ideal([t, s], algorithm='giac') == J
        possible output...
        True

    The list of available Giac options is provided at `sage.libs.giac.groebner_basis()`.

    ALGORITHM:

    Uses Singular, or Giac (if available).

    Note

    Requires computation of a Groebner basis, which can be a very expensive operation.

  free_resolution(*args, **kwds)

    Return a free resolution of `self`.

    For input options, see `FreeResolution`.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ)
        sage: f = 2*x^2 + y
        sage: g = y
        sage: h = 2*f + g
        sage: I = R.ideal([f,g,h])
        sage: res = I.free_resolution()
        sage: res
        S^1 <-- S^2 <-- S^1 <-- 0
        sage: ascii_art(res.chain_complex())
                                    [-x^2]
                    [  y x^2]       [   y]
         0 <-- C_0 <---------- C_1 <------- C_2 <-- 0

        sage: q = ZZ['q'].fraction_field().gen()
        sage: R.<x,y,z> = q.parent()[]
        sage: I = R.ideal([x^2+y^2+z^2, x*y*z^4])
        sage: I.free_resolution()
        Traceback (most recent call last):
        ...
        NotImplementedError: the ring must be a polynomial ring using Singular

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> f = Integer(2)*x**Integer(2) + y
        >>> g = y
        >>> h = Integer(2)*f + g
        >>> I = R.ideal([f,g,h])
        >>> res = I.free_resolution()
        >>> res
        S^1 <-- S^2 <-- S^1 <-- 0
        >>> ascii_art(res.chain_complex())
                                    [-x^2]
                    [  y x^2]       [   y]
         0 <-- C_0 <---------- C_1 <------- C_2 <-- 0

        >>> q = ZZ['q'].fraction_field().gen()
        >>> R = q.parent()['x, y, z']; (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal([x**Integer(2)+y**Integer(2)+z**Integer(2), x*y*z**Integer(4)])
        >>> I.free_resolution()
        Traceback (most recent call last):
        ...
        NotImplementedError: the ring must be a polynomial ring using Singular

  genus()

    A decorator that creates a cached version of an instance method of a class.

    Note

    For proper behavior, the method must be a pure function (no side effects). Arguments to the method must be hashable or transformed into something hashable using `key` or they must define `sage.structure.sage_object.SageObject._cache_key()`.

    EXAMPLES:

    Sage

        sage: class Foo():
        ....:     @cached_method
        ....:     def f(self, t, x=2):
        ....:         print('computing')
        ....:         return t**x
        sage: a = Foo()

    Python

        >>> from sage.all import *
        >>> class Foo():
        ...     @cached_method
        ...     def f(self, t, x=Integer(2)):
        ...         print('computing')
        ...         return t**x
        >>> a = Foo()

    The example shows that the actual computation takes place only once, and that the result is identical for equivalent input:

    Sage

        sage: res = a.f(3, 2); res
        computing
        9
        sage: a.f(t = 3, x = 2) is res
        True
        sage: a.f(3) is res
        True

    [Python]

        >>> from sage.all import *
        >>> res = a.f(Integer(3), Integer(2)); res
        computing
        9
        >>> a.f(t = Integer(3), x = Integer(2)) is res
        True
        >>> a.f(Integer(3)) is res
        True

    Note, however, that accessing the attribute directly will call `__get__()`, and returns a `CachedMethodCaller` or `CachedMethodCallerNoArgs`.

    Sage

        sage: P.<a,b,c,d> = QQ[]
        sage: I = P*[a,b]
        sage: type(I.__class__.gens)
        <class 'sage.misc.cachefunc.CachedMethodCallerNoArgs'>
        sage: type(I.__class__.__dict__["gens"])
        <class 'sage.misc.cachefunc.CachedMethod'>

    Python

        >>> from sage.all import *
        >>> P = QQ['a, b, c, d']; (a, b, c, d,) = P._first_ngens(4)
        >>> I = P*[a,b]
        >>> type(I.__class__.gens)
        <class 'sage.misc.cachefunc.CachedMethodCallerNoArgs'>
        >>> type(I.__class__.__dict__["gens"])
        <class 'sage.misc.cachefunc.CachedMethod'>

    The parameter `key` can be used to pass a function which creates a custom cache key for inputs. In the following example, this parameter is used to ignore the `algorithm` keyword for caching:

    Sage

        sage: class A():
        ....:     def _f_normalize(self, x, algorithm): return x
        ....:     @cached_method(key=_f_normalize)
        ....:     def f(self, x, algorithm='default'): return x
        sage: a = A()
        sage: a.f(1, algorithm='default') is a.f(1) is a.f(1, algorithm='algorithm')
        True

    [Python]

        >>> from sage.all import *
        >>> class A():
        ...     def _f_normalize(self, x, algorithm): return x
        ...     @cached_method(key=_f_normalize)
        ...     def f(self, x, algorithm='default'): return x
        >>> a = A()
        >>> a.f(Integer(1), algorithm='default') is a.f(Integer(1)) is a.f(Integer(1), algorithm='algorithm')
        True

    The parameter `do_pickle` can be used to enable pickling of the cache. Usually the cache is not stored when pickling:

    Sage

        sage: class A():
        ....:     @cached_method
        ....:     def f(self, x): return None
        sage: import __main__
        sage: __main__.A = A
        sage: a = A()
        sage: a.f(1)
        sage: len(a.f.cache)
        1
        sage: b = loads(dumps(a))
        sage: len(b.f.cache)
        0

    Python

        >>> from sage.all import *
        >>> class A():
        ...     @cached_method
        ...     def f(self, x): return None
        >>> import __main__
        >>> __main__.A = A
        >>> a = A()
        >>> a.f(Integer(1))
        >>> len(a.f.cache)
        1
        >>> b = loads(dumps(a))
        >>> len(b.f.cache)
        0

    When `do_pickle` is set, the pickle contains the contents of the cache:

    Sage

        sage: class A():
        ....:     @cached_method(do_pickle=True)
        ....:     def f(self, x): return None
        sage: __main__.A = A
        sage: a = A()
        sage: a.f(1)
        sage: len(a.f.cache)
        1
        sage: b = loads(dumps(a))
        sage: len(b.f.cache)
        1

    [Python]

        >>> from sage.all import *
        >>> class A():
        ...     @cached_method(do_pickle=True)
        ...     def f(self, x): return None
        >>> __main__.A = A
        >>> a = A()
        >>> a.f(Integer(1))
        >>> len(a.f.cache)
        1
        >>> b = loads(dumps(a))
        >>> len(b.f.cache)
        1

    Cached methods cannot be copied like usual methods, see Issue #12603. Copying them can lead to very surprising results:

    Sage

        sage: class A:
        ....:     @cached_method
        ....:     def f(self):
        ....:         return 1
        sage: class B:
        ....:     g=A.f
        ....:     def f(self):
        ....:         return 2

        sage: b=B()
        sage: b.f()
        2
        sage: b.g()
        1
        sage: b.f()
        1

    Python

        >>> from sage.all import *
        >>> class A:
        ...     @cached_method
        ...     def f(self):
        ...         return Integer(1)
        >>> class B:
        ...     g=A.f
        ...     def f(self):
        ...         return Integer(2)

        >>> b=B()
        >>> b.f()
        2
        >>> b.g()
        1
        >>> b.f()
        1

  graded_free_resolution(*args, **kwds)

    Return a graded free resolution of `self`.

    For input options, see `GradedFreeResolution`.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ)
        sage: f = 2*x^2 + y^2
        sage: g = y^2
        sage: h = 2*f + g
        sage: I = R.ideal([f,g,h])
        sage: I.graded_free_resolution(shifts=[1])
        S(-1) <-- S(-3)⊕S(-3) <-- S(-5) <-- 0

        sage: f = 2*x^2 + y
        sage: g = y
        sage: h = 2*f + g
        sage: I = R.ideal([f,g,h])
        sage: I.graded_free_resolution(degrees=[1,2])
        S(0) <-- S(-2)⊕S(-2) <-- S(-4) <-- 0

        sage: q = ZZ['q'].fraction_field().gen()
        sage: R.<x,y,z> = q.parent()[]
        sage: I = R.ideal([x^2+y^2+z^2, x*y*z^4])
        sage: I.graded_free_resolution()
        Traceback (most recent call last):
        ...
        NotImplementedError: the ring must be a polynomial ring using Singular

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> f = Integer(2)*x**Integer(2) + y**Integer(2)
        >>> g = y**Integer(2)
        >>> h = Integer(2)*f + g
        >>> I = R.ideal([f,g,h])
        >>> I.graded_free_resolution(shifts=[Integer(1)])
        S(-1) <-- S(-3)⊕S(-3) <-- S(-5) <-- 0

        >>> f = Integer(2)*x**Integer(2) + y
        >>> g = y
        >>> h = Integer(2)*f + g
        >>> I = R.ideal([f,g,h])
        >>> I.graded_free_resolution(degrees=[Integer(1),Integer(2)])
        S(0) <-- S(-2)⊕S(-2) <-- S(-4) <-- 0

        >>> q = ZZ['q'].fraction_field().gen()
        >>> R = q.parent()['x, y, z']; (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal([x**Integer(2)+y**Integer(2)+z**Integer(2), x*y*z**Integer(4)])
        >>> I.graded_free_resolution()
        Traceback (most recent call last):
        ...
        NotImplementedError: the ring must be a polynomial ring using Singular

  hilbert_numerator(grading=None, algorithm='sage')

    Return the Hilbert numerator of this ideal.

    INPUT:

    - `grading` – (optional) a list or tuple of integers

    - `algorithm` – (default: `'sage'`) must be either `'sage'` or `'singular'`

    Let \(I\) (which is `self`) be a homogeneous ideal and \(R = \bigoplus_d R_d\) (which is `self.ring()`) be a graded commutative algebra over a field \(K\). Then the Hilbert function is defined as \(H(d) = \dim_K R_d\) and the Hilbert series of \(I\) is defined as the formal power series \(HS(t) = \sum_{d=0}^{\infty} H(d) t^d\).

    This power series can be expressed as \(HS(t) = Q(t) / (1-t)^n\) where \(Q(t)\) is a polynomial over \(\ZZ\) and \(n\) the number of variables in \(R\). This method returns \(Q(t)\), the numerator; hence the name, `hilbert_numerator`. An optional `grading` can be given, in which case the graded (or weighted) Hilbert numerator is given.

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ)
        sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
        sage: I.hilbert_numerator()                                                 # needs sage.libs.flint
        -t^5 + 1
        sage: R.<a,b> = PolynomialRing(QQ)
        sage: J = R.ideal([a^2*b, a*b^2])
        sage: J.hilbert_numerator()                                                 # needs sage.libs.flint
        t^4 - 2*t^3 + 1
        sage: J.hilbert_numerator(grading=(10,3))                                   # needs sage.libs.flint
        t^26 - t^23 - t^16 + 1

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = Ideal([x**Integer(3)*y**Integer(2) + Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) + z**Integer(5)])
        >>> I.hilbert_numerator()                                                 # needs sage.libs.flint
        -t^5 + 1
        >>> R = PolynomialRing(QQ, names=('a', 'b',)); (a, b,) = R._first_ngens(2)
        >>> J = R.ideal([a**Integer(2)*b, a*b**Integer(2)])
        >>> J.hilbert_numerator()                                                 # needs sage.libs.flint
        t^4 - 2*t^3 + 1
        >>> J.hilbert_numerator(grading=(Integer(10),Integer(3)))                                   # needs sage.libs.flint
        t^26 - t^23 - t^16 + 1

  hilbert_polynomial(algorithm='sage')

    Return the Hilbert polynomial of this ideal.

    INPUT:

    - `algorithm` – (default: `'sage'`) must be either `'sage'` or `'singular'`

    Let \(I\) (which is `self`) be a homogeneous ideal and \(R = \bigoplus_d R_d\) (which is `self.ring()`) be a graded commutative algebra over a field \(K\). The Hilbert polynomial is the unique polynomial \(HP(t)\) with rational coefficients such that \(HP(d) = \dim_K R_d\) for all but finitely many positive integers \(d\).

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ)
        sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
        sage: I.hilbert_polynomial()                                                # needs sage.libs.flint
        5*t - 5

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = Ideal([x**Integer(3)*y**Integer(2) + Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) + z**Integer(5)])
        >>> I.hilbert_polynomial()                                                # needs sage.libs.flint
        5*t - 5

    Of course, the Hilbert polynomial of a zero-dimensional ideal is zero:

    Sage

        sage: J0 = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5,
        ....:             y^3 - 2*x*z^2 + x*y, x^4 + x*y - y*z^2])
        sage: J = P*[m.lm() for m in J0.groebner_basis()]
        sage: J.dimension()
        0
        sage: J.hilbert_polynomial()                                                # needs sage.libs.flint
        0

    [Python]

        >>> from sage.all import *
        >>> J0 = Ideal([x**Integer(3)*y**Integer(2) + Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) + z**Integer(5),
        ...             y**Integer(3) - Integer(2)*x*z**Integer(2) + x*y, x**Integer(4) + x*y - y*z**Integer(2)])
        >>> J = P*[m.lm() for m in J0.groebner_basis()]
        >>> J.dimension()
        0
        >>> J.hilbert_polynomial()                                                # needs sage.libs.flint
        0

    It is possible to request a computation using the Singular library:

    Sage

        sage: I.hilbert_polynomial(algorithm='singular') == I.hilbert_polynomial()  # needs sage.libs.flint
        True
        sage: J.hilbert_polynomial(algorithm='singular') == J.hilbert_polynomial()  # needs sage.libs.flint
        True

    Python

        >>> from sage.all import *
        >>> I.hilbert_polynomial(algorithm='singular') == I.hilbert_polynomial()  # needs sage.libs.flint
        True
        >>> J.hilbert_polynomial(algorithm='singular') == J.hilbert_polynomial()  # needs sage.libs.flint
        True

    Here is a bigger examples:

    Sage

        sage: n = 4; m = 11; P = PolynomialRing(QQ, n * m, "x"); x = P.gens()
        sage: M = Matrix(n, x)
        sage: Minors = P.ideal(M.minors(2))
        sage: hp = Minors.hilbert_polynomial(); hp                                  # needs sage.libs.flint
        1/21772800*t^13 + 61/21772800*t^12 + 1661/21772800*t^11
         + 26681/21772800*t^10 + 93841/7257600*t^9 + 685421/7257600*t^8
         + 1524809/3110400*t^7 + 39780323/21772800*t^6 + 6638071/1360800*t^5
         + 12509761/1360800*t^4 + 2689031/226800*t^3 + 1494509/151200*t^2
         + 12001/2520*t + 1

    [Python]

        >>> from sage.all import *
        >>> n = Integer(4); m = Integer(11); P = PolynomialRing(QQ, n * m, "x"); x = P.gens()
        >>> M = Matrix(n, x)
        >>> Minors = P.ideal(M.minors(Integer(2)))
        >>> hp = Minors.hilbert_polynomial(); hp                                  # needs sage.libs.flint
        1/21772800*t^13 + 61/21772800*t^12 + 1661/21772800*t^11
         + 26681/21772800*t^10 + 93841/7257600*t^9 + 685421/7257600*t^8
         + 1524809/3110400*t^7 + 39780323/21772800*t^6 + 6638071/1360800*t^5
         + 12509761/1360800*t^4 + 2689031/226800*t^3 + 1494509/151200*t^2
         + 12001/2520*t + 1

    Because Singular uses 32-bit integers, the above example would fail with Singular. We don’t test it here, as it has a side-effect on other tests that is not understood yet (see Issue #26300):

    Sage

        sage: Minors.hilbert_polynomial(algorithm='singular')       # not tested
        Traceback (most recent call last):
        ...
        RuntimeError: error in Singular function call 'hilbPoly':
        int overflow in hilb 1
        error occurred in or before poly.lib::hilbPoly line 58: `   intvec v=hilb(I,2);`
        expected intvec-expression. type 'help intvec;'

    Python

        >>> from sage.all import *
        >>> Minors.hilbert_polynomial(algorithm='singular')       # not tested
        Traceback (most recent call last):
        ...
        RuntimeError: error in Singular function call 'hilbPoly':
        int overflow in hilb 1
        error occurred in or before poly.lib::hilbPoly line 58: `   intvec v=hilb(I,2);`
        expected intvec-expression. type 'help intvec;'

    Note that in this example, the Hilbert polynomial gives the coefficients of the Hilbert-Poincaré series in all degrees:

    Sage

        sage: P = PowerSeriesRing(QQ, 't', default_prec=50)
        sage: hs = Minors.hilbert_series()                                          # needs sage.libs.flint
        sage: list(P(hs.numerator()) / P(hs.denominator())) == [hp(t=k)             # needs sage.libs.flint
        ....:                                                   for k in range(50)]
        True

    [Python]

        >>> from sage.all import *
        >>> P = PowerSeriesRing(QQ, 't', default_prec=Integer(50))
        >>> hs = Minors.hilbert_series()                                          # needs sage.libs.flint
        >>> list(P(hs.numerator()) / P(hs.denominator())) == [hp(t=k)             # needs sage.libs.flint
        ...                                                   for k in range(Integer(50))]
        True

  hilbert_series(grading=None, algorithm='sage')

    Return the Hilbert series of this ideal.

    INPUT:

    - `grading` – (optional) a list or tuple of integers

    - `algorithm` – (default: `'sage'`) must be either `'sage'` or `'singular'`

    Let \(I\) (which is `self`) be a homogeneous ideal and \(R = \bigoplus_d R_d\) (which is `self.ring()`) be a graded commutative algebra over a field \(K\). Then the Hilbert function is defined as \(H(d) = \dim_K R_d\) and the Hilbert series of \(I\) is defined as the formal power series \(HS(t) = \sum_{d=0}^{\infty} H(d) t^d\).

    This power series can be expressed as \(HS(t) = Q(t) / (1-t)^n\) where \(Q(t)\) is a polynomial over \(\ZZ\) and \(n\) the number of variables in \(R\). This method returns \(Q(t) / (1-t)^n\), normalised so that the leading monomial of the numerator is positive.

    An optional `grading` can be given, in which case the graded (or weighted) Hilbert series is given.

    EXAMPLES:

    Sage

        sage: P.<x,y,z> = PolynomialRing(QQ)
        sage: I = Ideal([x^3*y^2 + 3*x^2*y^2*z + y^3*z^2 + z^5])
        sage: I.hilbert_series()                                                    # needs sage.libs.flint
        (t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1)
        sage: R.<a,b> = PolynomialRing(QQ)
        sage: J = R.ideal([a^2*b, a*b^2])
        sage: J.hilbert_series()                                                    # needs sage.libs.flint
        (t^3 - t^2 - t - 1)/(t - 1)
        sage: J.hilbert_series(grading=(10,3))                                      # needs sage.libs.flint
        (t^25 + t^24 + t^23 - t^15 - t^14 - t^13 - t^12 - t^11
         - t^10 - t^9 - t^8 - t^7 - t^6 - t^5 - t^4 - t^3 - t^2
         - t - 1)/(t^12 + t^11 + t^10 - t^2 - t - 1)

        sage: K = R.ideal([a^2*b^3, a*b^4 + a^3*b^2])
        sage: K.hilbert_series(grading=[1,2])                                       # needs sage.libs.flint
        (t^11 + t^8 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^2 - 1)
        sage: K.hilbert_series(grading=[2,1])                                       # needs sage.libs.flint
        (2*t^7 - t^6 - t^4 - t^2 - 1)/(t - 1)

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)
        >>> I = Ideal([x**Integer(3)*y**Integer(2) + Integer(3)*x**Integer(2)*y**Integer(2)*z + y**Integer(3)*z**Integer(2) + z**Integer(5)])
        >>> I.hilbert_series()                                                    # needs sage.libs.flint
        (t^4 + t^3 + t^2 + t + 1)/(t^2 - 2*t + 1)
        >>> R = PolynomialRing(QQ, names=('a', 'b',)); (a, b,) = R._first_ngens(2)
        >>> J = R.ideal([a**Integer(2)*b, a*b**Integer(2)])
        >>> J.hilbert_series()                                                    # needs sage.libs.flint
        (t^3 - t^2 - t - 1)/(t - 1)
        >>> J.hilbert_series(grading=(Integer(10),Integer(3)))                                      # needs sage.libs.flint
        (t^25 + t^24 + t^23 - t^15 - t^14 - t^13 - t^12 - t^11
         - t^10 - t^9 - t^8 - t^7 - t^6 - t^5 - t^4 - t^3 - t^2
         - t - 1)/(t^12 + t^11 + t^10 - t^2 - t - 1)

        >>> K = R.ideal([a**Integer(2)*b**Integer(3), a*b**Integer(4) + a**Integer(3)*b**Integer(2)])
        >>> K.hilbert_series(grading=[Integer(1),Integer(2)])                                       # needs sage.libs.flint
        (t^11 + t^8 - t^6 - t^5 - t^4 - t^3 - t^2 - t - 1)/(t^2 - 1)
        >>> K.hilbert_series(grading=[Integer(2),Integer(1)])                                       # needs sage.libs.flint
        (2*t^7 - t^6 - t^4 - t^2 - 1)/(t - 1)

    This also works for `NCPolynomialRing_plural`:

    Sage

        sage: M = matroids.CompleteGraphic(4)
        sage: OS = M.orlik_solomon_algebra(QQ)
        sage: A = OS.as_gca()
        sage: I = A.defining_ideal()
        sage: HS = I.hilbert_series(); HS
        6*t^3 + 11*t^2 + 6*t + 1
        sage: HS.factor()
        (t + 1) * (2*t + 1) * (3*t + 1)

    [Python]

        >>> from sage.all import *
        >>> M = matroids.CompleteGraphic(Integer(4))
        >>> OS = M.orlik_solomon_algebra(QQ)
        >>> A = OS.as_gca()
        >>> I = A.defining_ideal()
        >>> HS = I.hilbert_series(); HS
        6*t^3 + 11*t^2 + 6*t + 1
        >>> HS.factor()
        (t + 1) * (2*t + 1) * (3*t + 1)

  integral_closure(p=0, r=True, singular=None)

    Let \(I\) = `self`.

    Return the integral closure of \(I, ..., I^p\), where \(sI\) is an ideal in the polynomial ring \(R=k[x(1),...x(n)]\). If \(p\) is not given, or \(p=0\), compute the closure of all powers up to the maximum degree in \(t\) occurring in the closure of \(R[It]\) (so this is the last power whose closure is not just the sum/product of the smaller). If \(r\) is given and `r is True`, `I.integral_closure()` starts with a check whether \(I\) is already a radical ideal.

    INPUT:

    - `p` – powers of \(I\) (default: 0)

    - `r` – check whether `self` is a radical ideal first (default: `True`)

    EXAMPLES:

    Sage

        sage: R.<x,y> = QQ[]
        sage: I = ideal([x^2, x*y^4, y^5])
        sage: I.integral_closure()
        [x^2, x*y^4, y^5, x*y^3]

    Python

        >>> from sage.all import *
        >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2)
        >>> I = ideal([x**Integer(2), x*y**Integer(4), y**Integer(5)])
        >>> I.integral_closure()
        [x^2, x*y^4, y^5, x*y^3]

    ALGORITHM:

    Uses libSINGULAR.

  interreduced_basis()

    If this ideal is spanned by \((f_1, ..., f_n)\), return \((g_1, ..., g_s)\) such that:

    - \((f_1,...,f_n) = (g_1,...,g_s)\)

    - \(LT(g_i) \neq LT(g_j)\) for all \(i \neq j\)

    - \(LT(g_i)\) does not divide \(m\) for all monomials \(m\) of \(\{g_1,...,g_{i-1},g_{i+1},...,g_s\}\)

    - \(LC(g_i) = 1\) for all \(i\) if the coefficient ring is a field.

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ)
        sage: I = Ideal([z*x + y^3, z + y^3, z + x*y])
        sage: I.interreduced_basis()
        [y^3 + z, x*y + z, x*z - z]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = Ideal([z*x + y**Integer(3), z + y**Integer(3), z + x*y])
        >>> I.interreduced_basis()
        [y^3 + z, x*y + z, x*z - z]

    Note that tail reduction for local orderings is not well-defined:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ,order='negdegrevlex')
        sage: I = Ideal([z*x + y^3, z + y^3, z + x*y])
        sage: I.interreduced_basis()
        [z + x*y, x*y - y^3, x^2*y - y^3]

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ,order='negdegrevlex', names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = Ideal([z*x + y**Integer(3), z + y**Integer(3), z + x*y])
        >>> I.interreduced_basis()
        [z + x*y, x*y - y^3, x^2*y - y^3]

    A fixed error with nonstandard base fields:

    Sage

        sage: R.<t> = QQ['t']
        sage: K.<x,y> = R.fraction_field()['x,y']
        sage: I = t*x * K
        sage: I.interreduced_basis()
        [x]

    Python

        >>> from sage.all import *
        >>> R = QQ['t']; (t,) = R._first_ngens(1)
        >>> K = R.fraction_field()['x,y']; (x, y,) = K._first_ngens(2)
        >>> I = t*x * K
        >>> I.interreduced_basis()
        [x]

    The interreduced basis of 0 is 0:

    Sage

        sage: P.<x,y,z> = GF(2)[]
        sage: Ideal(P(0)).interreduced_basis()
        [0]

    [Python]

        >>> from sage.all import *
        >>> P = GF(Integer(2))['x, y, z']; (x, y, z,) = P._first_ngens(3)
        >>> Ideal(P(Integer(0))).interreduced_basis()
        [0]

    ALGORITHM:

    Uses Singular’s `interred` command or `sage.rings.polynomial.toy_buchberger.inter_reduction()` if conversion to Singular fails.

  intersection(*others)

    Return the intersection of the arguments with this ideal.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ, 2, order='lex')
        sage: I = x*R
        sage: J = y*R
        sage: I.intersection(J)
        Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = x*R
        >>> J = y*R
        >>> I.intersection(J)
        Ideal (x*y) of Multivariate Polynomial Ring in x, y over Rational Field

    The following simple example illustrates that the product need not equal the intersection.

    Sage

        sage: I = (x^2, y) * R
        sage: J = (y^2, x) * R
        sage: K = I.intersection(J); K
        Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational Field
        sage: IJ = I*J; IJ
        Ideal (x^2*y^2, x^3, y^3, x*y)
         of Multivariate Polynomial Ring in x, y over Rational Field
        sage: IJ == K
        False

    [Python]

        >>> from sage.all import *
        >>> I = (x**Integer(2), y) * R
        >>> J = (y**Integer(2), x) * R
        >>> K = I.intersection(J); K
        Ideal (y^2, x*y, x^2) of Multivariate Polynomial Ring in x, y over Rational Field
        >>> IJ = I*J; IJ
        Ideal (x^2*y^2, x^3, y^3, x*y)
         of Multivariate Polynomial Ring in x, y over Rational Field
        >>> IJ == K
        False

    Intersection of several ideals:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
        sage: I1 = x * R
        sage: I2 = y * R
        sage: I3 = (x, y) * R
        sage: I4 = (x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z) * R
        sage: I1.intersection(I2, I3, I4).groebner_basis()
        [x^2*y + x*y*z^4, x*y^2 - x*y*z^3, x*y*z^20 - x*y*z^3]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(3), order='lex', names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I1 = x * R
        >>> I2 = y * R
        >>> I3 = (x, y) * R
        >>> I4 = (x**Integer(2) + x*y*z, y**Integer(2) - z**Integer(3)*y, z**Integer(3) + y**Integer(5)*x*z) * R
        >>> I1.intersection(I2, I3, I4).groebner_basis()
        [x^2*y + x*y*z^4, x*y^2 - x*y*z^3, x*y*z^20 - x*y*z^3]

    The ideals must share the same ring:

    Sage

        sage: R2.<x,y> = PolynomialRing(QQ, 2, order='lex')
        sage: R3.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
        sage: I2 = x*R2
        sage: I3 = x*R3
        sage: I2.intersection(I3)
        Traceback (most recent call last):
        ...
        TypeError: Intersection is only available for ideals of the same ring.

    [Python]

        >>> from sage.all import *
        >>> R2 = PolynomialRing(QQ, Integer(2), order='lex', names=('x', 'y',)); (x, y,) = R2._first_ngens(2)
        >>> R3 = PolynomialRing(QQ, Integer(3), order='lex', names=('x', 'y', 'z',)); (x, y, z,) = R3._first_ngens(3)
        >>> I2 = x*R2
        >>> I3 = x*R3
        >>> I2.intersection(I3)
        Traceback (most recent call last):
        ...
        TypeError: Intersection is only available for ideals of the same ring.

  is_prime(**kwds)

    Return `True` if this ideal is prime.

    INPUT:

    - keyword arguments are passed on to `complete_primary_decomposition()`; in this way you can specify the algorithm to use.

    EXAMPLES:

    Sage

        sage: R.<x, y> = PolynomialRing(QQ, 2)
        sage: I = (x^2 - y^2 - 1) * R
        sage: I.is_prime()
        True
        sage: (I^2).is_prime()
        False

        sage: J = (x^2 - y^2) * R
        sage: J.is_prime()
        False
        sage: (J^3).is_prime()
        False

        sage: (I * J).is_prime()
        False

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(2), names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = (x**Integer(2) - y**Integer(2) - Integer(1)) * R
        >>> I.is_prime()
        True
        >>> (I**Integer(2)).is_prime()
        False

        >>> J = (x**Integer(2) - y**Integer(2)) * R
        >>> J.is_prime()
        False
        >>> (J**Integer(3)).is_prime()
        False

        >>> (I * J).is_prime()
        False

    The following is Issue #5982. Note that the quotient ring is not recognized as being a field at this time, so the fraction field is not the quotient ring itself:

    Sage

        sage: Q = R.quotient(I); Q
        Quotient of Multivariate Polynomial Ring in x, y over Rational Field
         by the ideal (x^2 - y^2 - 1)
        sage: Q.fraction_field()
        Fraction Field of
         Quotient of Multivariate Polynomial Ring in x, y over Rational Field
          by the ideal (x^2 - y^2 - 1)

    [Python]

        >>> from sage.all import *
        >>> Q = R.quotient(I); Q
        Quotient of Multivariate Polynomial Ring in x, y over Rational Field
         by the ideal (x^2 - y^2 - 1)
        >>> Q.fraction_field()
        Fraction Field of
         Quotient of Multivariate Polynomial Ring in x, y over Rational Field
          by the ideal (x^2 - y^2 - 1)

  minimal_associated_primes()

    OUTPUT: list of prime ideals

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ, 3, 'xyz')
        sage: p = z^2 + 1; q = z^3 + 2
        sage: I = (p*q^2, y - z^2) * R
        sage: sorted(I.minimal_associated_primes(), key=str)
        [Ideal (z^2 + 1, -z^2 + y)
          of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^3 + 2, -z^2 + y)
          of Multivariate Polynomial Ring in x, y, z over Rational Field]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(3), 'xyz', names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)
        >>> I = (p*q**Integer(2), y - z**Integer(2)) * R
        >>> sorted(I.minimal_associated_primes(), key=str)
        [Ideal (z^2 + 1, -z^2 + y)
          of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^3 + 2, -z^2 + y)
          of Multivariate Polynomial Ring in x, y, z over Rational Field]

    ALGORITHM:

    Uses Singular.

  normal_basis(degree=None, algorithm='libsingular', singular=None)

    Return a vector space basis of the quotient ring of this ideal.

    INPUT:

    - `degree` – integer (default: `None`)

    - `algorithm` – string (default: `'libsingular'`); if not the default, this will use the `kbase()` or `weightKB()` command from Singular

    - `singular` – the singular interpreter to use when `algorithm` is not `'libsingular'` (default: the default instance)

    OUTPUT:

    Monomials in the basis. If `degree` is given, only the monomials of the given degree are returned.

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ)
        sage: I = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5, x*z - 1)
        sage: I.normal_basis()
        [y*z^2, z^2, y*z, z, x*y, y, x, 1]
        sage: I.normal_basis(algorithm='singular')
        [y*z^2, z^2, y*z, z, x*y, y, x, 1]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal(x**Integer(2) + y**Integer(2) + z**Integer(2) - Integer(4), x**Integer(2) + Integer(2)*y**Integer(2) - Integer(5), x*z - Integer(1))
        >>> I.normal_basis()
        [y*z^2, z^2, y*z, z, x*y, y, x, 1]
        >>> I.normal_basis(algorithm='singular')
        [y*z^2, z^2, y*z, z, x*y, y, x, 1]

    The result can be restricted to monomials of a chosen degree, which is particularly useful when the quotient ring is not finite-dimensional as a vector space.

    Sage

        sage: J = R.ideal(x^2 + y^2 + z^2 - 4, x^2 + 2*y^2 - 5)
        sage: J.dimension()
        1
        sage: [J.normal_basis(d) for d in (0..3)]
        [[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]
        sage: [J.normal_basis(d, algorithm='singular') for d in (0..3)]
        [[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]

    [Python]

        >>> from sage.all import *
        >>> J = R.ideal(x**Integer(2) + y**Integer(2) + z**Integer(2) - Integer(4), x**Integer(2) + Integer(2)*y**Integer(2) - Integer(5))
        >>> J.dimension()
        1
        >>> [J.normal_basis(d) for d in (ellipsis_iter(Integer(0),Ellipsis,Integer(3)))]
        [[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]
        >>> [J.normal_basis(d, algorithm='singular') for d in (ellipsis_iter(Integer(0),Ellipsis,Integer(3)))]
        [[1], [z, y, x], [z^2, y*z, x*z, x*y], [z^3, y*z^2, x*z^2, x*y*z]]

    In case of a polynomial ring with a weighted term order, the degree of the monomials is taken with respect to the weights.

    Sage

        sage: T = TermOrder('wdegrevlex', (1, 2, 3))
        sage: R.<x,y,z> = PolynomialRing(QQ, order=T)
        sage: B = R.ideal(x*y^2 + x^5, z*y + x^3*y).normal_basis(9); B
        [x^2*y^2*z, x^3*z^2, x*y*z^2, z^3]
        sage: all(f.degree() == 9 for f in B)
        True

    Python

        >>> from sage.all import *
        >>> T = TermOrder('wdegrevlex', (Integer(1), Integer(2), Integer(3)))
        >>> R = PolynomialRing(QQ, order=T, names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> B = R.ideal(x*y**Integer(2) + x**Integer(5), z*y + x**Integer(3)*y).normal_basis(Integer(9)); B
        [x^2*y^2*z, x^3*z^2, x*y*z^2, z^3]
        >>> all(f.degree() == Integer(9) for f in B)
        True

  primary_decomposition(algorithm='sy')

    Return a list of primary ideals such that their intersection is `self`.

    An ideal \(Q\) is called primary if it is a proper ideal of the ring \(R\), and if whenever \(ab \in Q\) and \(a \not\in Q\), then \(b^n \in Q\) for some \(n \in \ZZ\).

    If \(Q\) is a primary ideal of the ring \(R\), then the radical ideal \(P\) of \(Q\) (i.e., the ideal consisting of all \(a \in R\) with \(a^n \in Q\) for some \(n \in \ZZ\)), is called the associated prime of \(Q\).

    If \(I\) is a proper ideal of a Noetherian ring \(R\), then there exists a finite collection of primary ideals \(Q_i\) such that the following hold:

    - the intersection of the \(Q_i\) is \(I\);

    - none of the \(Q_i\) contains the intersection of the others;

    - the associated prime ideals of the \(Q_i\) are pairwise distinct.

    INPUT:

    - `algorithm` – string; one of

      - `'sy'` – (default) use the Shimoyama-Yokoyama algorithm

      - `'gtz'` – use the Gianni-Trager-Zacharias algorithm

    OUTPUT:

    - a list of primary ideals \(Q_i\) forming a primary decomposition of `self`.

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ, 3, order='lex')
        sage: p = z^2 + 1; q = z^3 + 2
        sage: I = (p*q^2, y - z^2) * R
        sage: pd = I.primary_decomposition(); sorted(pd, key=str)
        [Ideal (z^2 + 1, y + 1)
          of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^6 + 4*z^3 + 4, y - z^2)
          of Multivariate Polynomial Ring in x, y, z over Rational Field]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(3), order='lex', names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)
        >>> I = (p*q**Integer(2), y - z**Integer(2)) * R
        >>> pd = I.primary_decomposition(); sorted(pd, key=str)
        [Ideal (z^2 + 1, y + 1)
          of Multivariate Polynomial Ring in x, y, z over Rational Field,
         Ideal (z^6 + 4*z^3 + 4, y - z^2)
          of Multivariate Polynomial Ring in x, y, z over Rational Field]

    Sage

        sage: from functools import reduce
        sage: reduce(lambda Qi, Qj: Qi.intersection(Qj), pd) == I
        True

    [Python]

        >>> from sage.all import *
        >>> from functools import reduce
        >>> reduce(lambda Qi, Qj: Qi.intersection(Qj), pd) == I
        True

    ALGORITHM:

    Uses Singular.

    REFERENCES:

    - Thomas Becker and Volker Weispfenning. Groebner Bases - A Computational Approach To Commutative Algebra. Springer, New York 1993.

  primary_decomposition_complete()

    alias of `complete_primary_decomposition()`.

  quotient(J)

    Given ideals \(I\) = `self` and \(J\) in the same polynomial ring \(P\), return the ideal quotient of \(I\) by \(J\) consisting of the polynomials \(a\) of \(P\) such that \(\{aJ \subset I\}\).

    This is also referred to as the colon ideal (\(I\):\(J\)).

    INPUT:

    - `J` – multivariate polynomial ideal

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(GF(181), 3)
        sage: I = Ideal([x^2 + x*y*z, y^2 - z^3*y, z^3 + y^5*x*z])
        sage: J = Ideal([x])
        sage: Q = I.quotient(J)
        sage: y*z + x in I
        False
        sage: x in J
        True
        sage: x * (y*z + x) in I
        True

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(181)), Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = Ideal([x**Integer(2) + x*y*z, y**Integer(2) - z**Integer(3)*y, z**Integer(3) + y**Integer(5)*x*z])
        >>> J = Ideal([x])
        >>> Q = I.quotient(J)
        >>> y*z + x in I
        False
        >>> x in J
        True
        >>> x * (y*z + x) in I
        True

  radical()

    The radical of this ideal.

    EXAMPLES:

    This is an obviously not radical ideal:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ, 3)
        sage: I = (x^2, y^3, (x*z)^4 + y^3 + 10*x^2) * R
        sage: I.radical()
        Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = (x**Integer(2), y**Integer(3), (x*z)**Integer(4) + y**Integer(3) + Integer(10)*x**Integer(2)) * R
        >>> I.radical()
        Ideal (y, x) of Multivariate Polynomial Ring in x, y, z over Rational Field

    That the radical is correct is clear from the Groebner basis.

    Sage

        sage: I.groebner_basis()
        [y^3, x^2]

    [Python]

        >>> from sage.all import *
        >>> I.groebner_basis()
        [y^3, x^2]

    This is the example from the Singular manual:

    Sage

        sage: p = z^2 + 1; q = z^3 + 2
        sage: I = (p*q^2, y - z^2) * R
        sage: I.radical()
        Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
         of Multivariate Polynomial Ring in x, y, z over Rational Field

    Python

        >>> from sage.all import *
        >>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)
        >>> I = (p*q**Integer(2), y - z**Integer(2)) * R
        >>> I.radical()
        Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
         of Multivariate Polynomial Ring in x, y, z over Rational Field

    Note

    From the Singular manual: A combination of the algorithms of Krick/Logar and Kemper is used. Works also in positive characteristic (Kempers algorithm).

    Sage

        sage: R.<x,y,z> = PolynomialRing(GF(37), 3)
        sage: p = z^2 + 1; q = z^3 + 2
        sage: I = (p*q^2, y - z^2) * R
        sage: I.radical()
        Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
         of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(37)), Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> p = z**Integer(2) + Integer(1); q = z**Integer(3) + Integer(2)
        >>> I = (p*q**Integer(2), y - z**Integer(2)) * R
        >>> I.radical()
        Ideal (z^2 - y, y^2*z + y*z + 2*y + 2)
         of Multivariate Polynomial Ring in x, y, z over Finite Field of size 37

  saturation(other)

    Return the saturation (and saturation exponent) of the ideal `self` with respect to the ideal `other`.

    INPUT:

    - `other` – another ideal in the same ring

    OUTPUT: a pair (ideal, integer)

    EXAMPLES:

    Sage

        sage: R.<x, y, z> = QQ[]
        sage: I = R.ideal(x^5*z^3, x*y*z, y*z^4)
        sage: J = R.ideal(z)
        sage: I.saturation(J)
        (Ideal (y, x^5) of Multivariate Polynomial Ring in x, y, z over Rational Field, 4)

    Python

        >>> from sage.all import *
        >>> R = QQ['x, y, z']; (x, y, z,) = R._first_ngens(3)
        >>> I = R.ideal(x**Integer(5)*z**Integer(3), x*y*z, y*z**Integer(4))
        >>> J = R.ideal(z)
        >>> I.saturation(J)
        (Ideal (y, x^5) of Multivariate Polynomial Ring in x, y, z over Rational Field, 4)

  syzygy_module()

    Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal.

    EXAMPLES:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ)
        sage: f = 2*x^2 + y
        sage: g = y
        sage: h = 2*f + g
        sage: I = Ideal([f,g,h])
        sage: M = I.syzygy_module(); M
        [       -2        -1         1]
        [       -y 2*x^2 + y         0]
        sage: G = vector(I.gens())
        sage: M*G
        (0, 0)

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> f = Integer(2)*x**Integer(2) + y
        >>> g = y
        >>> h = Integer(2)*f + g
        >>> I = Ideal([f,g,h])
        >>> M = I.syzygy_module(); M
        [       -2        -1         1]
        [       -y 2*x^2 + y         0]
        >>> G = vector(I.gens())
        >>> M*G
        (0, 0)

    ALGORITHM:

    Uses Singular’s syz command.

  transformed_basis(algorithm='gwalk', other_ring=None, singular=None)

    Return a lex or `other_ring` Groebner Basis for this ideal.

    INPUT:

    - `algorithm` – see below for options

    - `other_ring` – only valid for `algorithm='fglm'`; if provided, conversion will be performed to this ring. Otherwise a lex Groebner basis will be returned.

    ALGORITHMS:

    - `'fglm'` – FGLM algorithm. The input ideal must be given with a reduced Groebner Basis of a zero-dimensional ideal

    - `'gwalk'` – Groebner Walk algorithm (default)

    - `'awalk1'` – ‘first alternative’ algorithm

    - `'awalk2'` – ‘second alternative’ algorithm

    - `'twalk'` – Tran algorithm

    - `'fwalk'` – Fractal Walk algorithm

    EXAMPLES:

    Sage

        sage: R.<x,y,z> = PolynomialRing(QQ,3)
        sage: I = Ideal([y^3+x^2,x^2*y+x^2, x^3-x^2, z^4-x^2-y])
        sage: I = Ideal(I.groebner_basis())
        sage: S.<z,x,y> = PolynomialRing(QQ,3,order='lex')
        sage: J = Ideal(I.transformed_basis('fglm',S))
        sage: J
        Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3)
         of Multivariate Polynomial Ring in z, x, y over Rational Field

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ,Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = R._first_ngens(3)
        >>> I = Ideal([y**Integer(3)+x**Integer(2),x**Integer(2)*y+x**Integer(2), x**Integer(3)-x**Integer(2), z**Integer(4)-x**Integer(2)-y])
        >>> I = Ideal(I.groebner_basis())
        >>> S = PolynomialRing(QQ,Integer(3),order='lex', names=('z', 'x', 'y',)); (z, x, y,) = S._first_ngens(3)
        >>> J = Ideal(I.transformed_basis('fglm',S))
        >>> J
        Ideal (z^4 + y^3 - y, x^2 + y^3, x*y^3 - y^3, y^4 + y^3)
         of Multivariate Polynomial Ring in z, x, y over Rational Field

    Sage

        sage: R.<z,y,x> = PolynomialRing(GF(32003), 3, order='lex')                 # needs sage.rings.finite_rings
        sage: I = Ideal([y^3 + x*y*z + y^2*z + x*z^3, 3 + x*y + x^2*y + y^2*z])     # needs sage.rings.finite_rings
        sage: I.transformed_basis('gwalk')                                          # needs sage.rings.finite_rings
        [z*y^2 + y*x^2 + y*x + 3,
         z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3
           - 8297*y^6*x^2 - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2
           + 3556*y^5*x + 3556*y^4*x^3 + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x
           - 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - 1185*y^2*x^6 - 8297*y^2*x^5
           - 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 + x^5 + 2*x^4 + x^3,
         y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7
           - 3*y^3*x^6 - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3
           - 27*y*x^3 - 27*y*x^2 - 27*x]

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(32003)), Integer(3), order='lex', names=('z', 'y', 'x',)); (z, y, x,) = R._first_ngens(3)# needs sage.rings.finite_rings
        >>> I = Ideal([y**Integer(3) + x*y*z + y**Integer(2)*z + x*z**Integer(3), Integer(3) + x*y + x**Integer(2)*y + y**Integer(2)*z])     # needs sage.rings.finite_rings
        >>> I.transformed_basis('gwalk')                                          # needs sage.rings.finite_rings
        [z*y^2 + y*x^2 + y*x + 3,
         z*x + 8297*y^8*x^2 + 8297*y^8*x + 3556*y^7 - 8297*y^6*x^4 + 15409*y^6*x^3
           - 8297*y^6*x^2 - 8297*y^5*x^5 + 15409*y^5*x^4 - 8297*y^5*x^3 + 3556*y^5*x^2
           + 3556*y^5*x + 3556*y^4*x^3 + 3556*y^4*x^2 - 10668*y^4 - 10668*y^3*x
           - 8297*y^2*x^9 - 1185*y^2*x^8 + 14224*y^2*x^7 - 1185*y^2*x^6 - 8297*y^2*x^5
           - 14223*y*x^7 - 10666*y*x^6 - 10666*y*x^5 - 14223*y*x^4 + x^5 + 2*x^4 + x^3,
         y^9 - y^7*x^2 - y^7*x - y^6*x^3 - y^6*x^2 - 3*y^6 - 3*y^5*x - y^3*x^7
           - 3*y^3*x^6 - 3*y^3*x^5 - y^3*x^4 - 9*y^2*x^5 - 18*y^2*x^4 - 9*y^2*x^3
           - 27*y*x^3 - 27*y*x^2 - 27*x]

    ALGORITHM:

    Uses Singular.

  triangular_decomposition(algorithm=None, singular=None)

    Decompose zero-dimensional ideal `self` into triangular sets.

    This requires that the given basis is reduced w.r.t. to the lexicographical monomial ordering. If the basis of `self` does not have this property, the required Groebner basis is computed implicitly.

    INPUT:

    - `algorithm` – string or `None` (default: `None`)

    ALGORITHMS:

    - `'singular:triangL'` – decomposition of `self` into triangular systems (Lazard)

    - `'singular:triangLfak'` – decomposition of `self` into triangular systems plus factorization

    - `'singular:triangM'` – decomposition of `self` into triangular systems (Moeller)

    OUTPUT: list \(T\) of lists \(t\) such that the variety of `self` is the union of the varieties of \(t\) in \(L\) and each \(t\) is in triangular form

    EXAMPLES:

    Sage

        sage: P.<e,d,c,b,a> = PolynomialRing(QQ, 5, order='lex')
        sage: I = sage.rings.ideal.Cyclic(P)
        sage: GB = Ideal(I.groebner_basis('libsingular:stdfglm'))
        sage: GB.triangular_decomposition('singular:triangLfak')
        [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3, e + b^3 + b^2 + b + 1) of Multivariate
          Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1,
                -11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a - 24,
                11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2,
                -11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2,
                e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a,
                e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, -d + a^3,
                -e + a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a,
                e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1,
                c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, -d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2,
                -e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, -11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a - 24,
                11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, -11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2)
               of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field]

        sage: R.<x1,x2> = PolynomialRing(QQ, 2, order='lex')
        sage: f1 = 1/2*((x1^2 + 2*x1 - 4)*x2^2 + 2*(x1^2 + x1)*x2 + x1^2)
        sage: f2 = 1/2*((x1^2 + 2*x1 + 1)*x2^2 + 2*(x1^2 + x1)*x2 - 4*x1^2)
        sage: I = Ideal(f1,f2)
        sage: I.triangular_decomposition()
        [Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field...
         Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5)
          of Multivariate Polynomial Ring in x1, x2 over Rational Field]

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(QQ, Integer(5), order='lex', names=('e', 'd', 'c', 'b', 'a',)); (e, d, c, b, a,) = P._first_ngens(5)
        >>> I = sage.rings.ideal.Cyclic(P)
        >>> GB = Ideal(I.groebner_basis('libsingular:stdfglm'))
        >>> GB.triangular_decomposition('singular:triangLfak')
        [Ideal (a - 1, b - 1, c - 1, d^2 + 3*d + 1, e + d + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b - 1, c^2 + 3*c + 1, d + c + 3, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b^2 + 3*b + 1, c + b + 3, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a - 1, b^4 + b^3 + b^2 + b + 1, -c + b^2, -d + b^3, e + b^3 + b^2 + b + 1) of Multivariate
          Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^2 + 3*a + 1, b - 1, c - 1, d - 1, e + a + 3) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^2 + 3*a + 1, b + a + 3, c - 1, d - 1, e - 1) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 - 4*a^3 + 6*a^2 + a + 1,
                -11*b^2 + 6*b*a^3 - 26*b*a^2 + 41*b*a - 4*b - 8*a^3 + 31*a^2 - 40*a - 24,
                11*c + 3*a^3 - 13*a^2 + 26*a - 2, 11*d + 3*a^3 - 13*a^2 + 26*a - 2,
                -11*e - 11*b + 6*a^3 - 26*a^2 + 41*a - 4) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c - a, d^2 + 3*d*a + a^2,
                e + d + 3*a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - a, c^2 + 3*c*a + a^2, d + c + 3*a,
                e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b - 1, c + a^3 + a^2 + a + 1, -d + a^3,
                -e + a^2) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b^2 + 3*b*a + a^2, c + b + 3*a, d - a,
                e - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + a^2 + a + 1, b^3 + b^2*a + b^2 + b*a^2 + b*a + b + a^3 + a^2 + a + 1,
                c + b^2*a^3 + b^2*a^2 + b^2*a + b^2, -d + b^2*a^2 + b^2*a + b^2 + b*a^2 + b*a + a^2,
                -e + b^2*a^3 - b*a^2 - b*a - b - a^2 - a) of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field,
         Ideal (a^4 + a^3 + 6*a^2 - 4*a + 1, -11*b^2 + 6*b*a^3 + 10*b*a^2 + 39*b*a + 2*b + 16*a^3 + 23*a^2 + 104*a - 24,
                11*c + 3*a^3 + 5*a^2 + 25*a + 1, 11*d + 3*a^3 + 5*a^2 + 25*a + 1, -11*e - 11*b + 6*a^3 + 10*a^2 + 39*a + 2)
               of Multivariate Polynomial Ring in e, d, c, b, a over Rational Field]

        >>> R = PolynomialRing(QQ, Integer(2), order='lex', names=('x1', 'x2',)); (x1, x2,) = R._first_ngens(2)
        >>> f1 = Integer(1)/Integer(2)*((x1**Integer(2) + Integer(2)*x1 - Integer(4))*x2**Integer(2) + Integer(2)*(x1**Integer(2) + x1)*x2 + x1**Integer(2))
        >>> f2 = Integer(1)/Integer(2)*((x1**Integer(2) + Integer(2)*x1 + Integer(1))*x2**Integer(2) + Integer(2)*(x1**Integer(2) + x1)*x2 - Integer(4)*x1**Integer(2))
        >>> I = Ideal(f1,f2)
        >>> I.triangular_decomposition()
        [Ideal (x2, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field...
         Ideal (x2^4 + 4*x2^3 - 6*x2^2 - 20*x2 + 5, 8*x1 - x2^3 + x2^2 + 13*x2 - 5)
          of Multivariate Polynomial Ring in x1, x2 over Rational Field]

  variety(ring=None)

    Return the variety of this ideal.

    Given a zero-dimensional ideal \(I\) (= `self`) of a polynomial ring \(P\) whose order is lexicographic, return the variety of \(I\) as a list of dictionaries with `(variable, value)` pairs. By default, the variety of the ideal over its coefficient field \(K\) is returned; `ring` can be specified to find the variety over a different ring.

    These dictionaries have cardinality equal to the number of variables in \(P\) and represent assignments of values to these variables such that all polynomials in \(I\) vanish.

    If `ring` is specified, then a triangular decomposition of `self` is found over the original coefficient field \(K\); then the triangular systems are solved using root-finding over `ring`. This is particularly useful when \(K\) is `QQ` (to allow fast symbolic computation of the triangular decomposition) and `ring` is `RR`, `AA`, `CC`, or `QQbar` (to compute the whole real or complex variety of the ideal).

    Note that with `ring=RR` or `CC`, computation is done numerically and potentially inaccurately; in particular, the number of points in the real variety may be miscomputed. With `ring=AA` or `QQbar`, computation is done exactly (which may be much slower, of course).

    INPUT:

    - `ring` – return roots in the `ring` instead of the base ring of this ideal (default: `None`)

    - `algorithm` – algorithm or implementation to use; see below for supported values

    - `proof` – return a provably correct result (default: `True`)

    EXAMPLES:

    Sage

        sage: K.<w> = GF(27)  # this example is from the MAGMA handbook
        sage: P.<x, y> = PolynomialRing(K, 2, order='lex')
        sage: I = Ideal([x^8 + y + 2, y^6 + x*y^5 + x^2])
        sage: I = Ideal(I.groebner_basis()); I
        Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - y^37 - y^36
                 + y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + y^28 + y^27 + y^26
                 + y^25 - y^23 + y^22 + y^21 - y^19 - y^18 - y^16 + y^15 + y^13
                 + y^12 - y^10 + y^9 + y^8 + y^7 - y^6 + y^4 + y^3 + y^2 + y - 1,
               y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28
                 - y^25 + y^24 + y^2 + y + 1)
        of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3
        sage: V = I.variety();
        sage: sorted(V, key=str)
        [{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}]
        sage: [f.subs(v)                      # check that all polynomials vanish
        ....:  for f in I.gens() for v in V]
        [0, 0, 0, 0, 0, 0]
        sage: [I.subs(v).is_zero() for v in V]  # same test, but nicer syntax
        [True, True, True]

    Python

        >>> from sage.all import *
        >>> K = GF(Integer(27), names=('w',)); (w,) = K._first_ngens(1)# this example is from the MAGMA handbook
        >>> P = PolynomialRing(K, Integer(2), order='lex', names=('x', 'y',)); (x, y,) = P._first_ngens(2)
        >>> I = Ideal([x**Integer(8) + y + Integer(2), y**Integer(6) + x*y**Integer(5) + x**Integer(2)])
        >>> I = Ideal(I.groebner_basis()); I
        Ideal (x - y^47 - y^45 + y^44 - y^43 + y^41 - y^39 - y^38 - y^37 - y^36
                 + y^35 - y^34 - y^33 + y^32 - y^31 + y^30 + y^28 + y^27 + y^26
                 + y^25 - y^23 + y^22 + y^21 - y^19 - y^18 - y^16 + y^15 + y^13
                 + y^12 - y^10 + y^9 + y^8 + y^7 - y^6 + y^4 + y^3 + y^2 + y - 1,
               y^48 + y^41 - y^40 + y^37 - y^36 - y^33 + y^32 - y^29 + y^28
                 - y^25 + y^24 + y^2 + y + 1)
        of Multivariate Polynomial Ring in x, y over Finite Field in w of size 3^3
        >>> V = I.variety();
        >>> sorted(V, key=str)
        [{y: w^2 + 2*w, x: 2*w + 2}, {y: w^2 + 2, x: 2*w}, {y: w^2 + w, x: 2*w + 1}]
        >>> [f.subs(v)                      # check that all polynomials vanish
        ...  for f in I.gens() for v in V]
        [0, 0, 0, 0, 0, 0]
        >>> [I.subs(v).is_zero() for v in V]  # same test, but nicer syntax
        [True, True, True]

    However, we only account for solutions in the ground field and not in the algebraic closure:

    Sage

        sage: I.vector_space_dimension()                                            # needs sage.rings.finite_rings
        48

    [Python]

        >>> from sage.all import *
        >>> I.vector_space_dimension()                                            # needs sage.rings.finite_rings
        48

    Here we compute the points of intersection of a hyperbola and a circle, in several fields:

    Sage

        sage: K.<x, y> = PolynomialRing(QQ, 2, order='lex')
        sage: I = Ideal([x*y - 1, (x-2)^2 + (y-1)^2 - 1])
        sage: I = Ideal(I.groebner_basis()); I
        Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1)
         of Multivariate Polynomial Ring in x, y over Rational Field

    Python

        >>> from sage.all import *
        >>> K = PolynomialRing(QQ, Integer(2), order='lex', names=('x', 'y',)); (x, y,) = K._first_ngens(2)
        >>> I = Ideal([x*y - Integer(1), (x-Integer(2))**Integer(2) + (y-Integer(1))**Integer(2) - Integer(1)])
        >>> I = Ideal(I.groebner_basis()); I
        Ideal (x + y^3 - 2*y^2 + 4*y - 4, y^4 - 2*y^3 + 4*y^2 - 4*y + 1)
         of Multivariate Polynomial Ring in x, y over Rational Field

    These two curves have one rational intersection:

    Sage

        sage: I.variety()
        [{y: 1, x: 1}]

    [Python]

        >>> from sage.all import *
        >>> I.variety()
        [{y: 1, x: 1}]

    There are two real intersections:

    Sage

        sage: sorted(I.variety(ring=RR), key=str)
        [{y: 0.361103080528647, x: 2.76929235423863},
         {y: 1.00000000000000, x: 1.00000000000000}]
        sage: I.variety(ring=AA)                                                    # needs sage.rings.number_field
        [{y: 1, x: 1},
         {y: 0.3611030805286474?, x: 2.769292354238632?}]

    Python

        >>> from sage.all import *
        >>> sorted(I.variety(ring=RR), key=str)
        [{y: 0.361103080528647, x: 2.76929235423863},
         {y: 1.00000000000000, x: 1.00000000000000}]
        >>> I.variety(ring=AA)                                                    # needs sage.rings.number_field
        [{y: 1, x: 1},
         {y: 0.3611030805286474?, x: 2.769292354238632?}]

    and a total of four intersections:

    Sage

        sage: sorted(I.variety(ring=CC), key=str)
        [{y: 0.31944845973567... + 1.6331702409152...*I,
          x: 0.11535382288068... - 0.58974280502220...*I},
         {y: 0.31944845973567... - 1.6331702409152...*I,
          x: 0.11535382288068... + 0.58974280502220...*I},
         {y: 0.36110308052864..., x: 2.7692923542386...},
         {y: 1.00000000000000, x: 1.00000000000000}]
        sage: sorted(I.variety(ring=QQbar), key=str)                                # needs sage.rings.number_field
        [{y: 0.3194484597356763? + 1.633170240915238?*I,
          x: 0.11535382288068429? - 0.5897428050222055?*I},
         {y: 0.3194484597356763? - 1.633170240915238?*I,
          x: 0.11535382288068429? + 0.5897428050222055?*I},
         {y: 0.3611030805286474?, x: 2.769292354238632?},
         {y: 1, x: 1}]

    [Python]

        >>> from sage.all import *
        >>> sorted(I.variety(ring=CC), key=str)
        [{y: 0.31944845973567... + 1.6331702409152...*I,
          x: 0.11535382288068... - 0.58974280502220...*I},
         {y: 0.31944845973567... - 1.6331702409152...*I,
          x: 0.11535382288068... + 0.58974280502220...*I},
         {y: 0.36110308052864..., x: 2.7692923542386...},
         {y: 1.00000000000000, x: 1.00000000000000}]
        >>> sorted(I.variety(ring=QQbar), key=str)                                # needs sage.rings.number_field
        [{y: 0.3194484597356763? + 1.633170240915238?*I,
          x: 0.11535382288068429? - 0.5897428050222055?*I},
         {y: 0.3194484597356763? - 1.633170240915238?*I,
          x: 0.11535382288068429? + 0.5897428050222055?*I},
         {y: 0.3611030805286474?, x: 2.769292354238632?},
         {y: 1, x: 1}]

    We can also use the optional package msolve to compute the variety. See `msolve` for more information.

    Sage

        sage: I.variety(RBF, algorithm='msolve', proof=False)   # optional - msolve
        [{y: [0.361103080528647 +/- 4.53e-16], x: [2.76929235423863 +/- 2.08e-15]},
         {y: 1.000000000000000, x: 1.000000000000000}]

    Python

        >>> from sage.all import *
        >>> I.variety(RBF, algorithm='msolve', proof=False)   # optional - msolve
        [{y: [0.361103080528647 +/- 4.53e-16], x: [2.76929235423863 +/- 2.08e-15]},
         {y: 1.000000000000000, x: 1.000000000000000}]

    Computation over floating point numbers may compute only a partial solution, or even none at all. Notice that x values are missing from the following variety:

    Sage

        sage: R.<x,y> = CC[]
        sage: I = ideal([x^2+y^2-1,x*y-1])
        sage: sorted(I.variety(), key=str)
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
        [{y: -0.86602540378443... + 0.500000000000000*I},
         {y: -0.86602540378443... - 0.500000000000000*I},
         {y: 0.86602540378443... + 0.500000000000000*I},
         {y: 0.86602540378443... - 0.500000000000000*I}]

    [Python]

        >>> from sage.all import *
        >>> R = CC['x, y']; (x, y,) = R._first_ngens(2)
        >>> I = ideal([x**Integer(2)+y**Integer(2)-Integer(1),x*y-Integer(1)])
        >>> sorted(I.variety(), key=str)
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: computations in the complex field are inexact; variety may be computed partially or incorrectly.
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
        [{y: -0.86602540378443... + 0.500000000000000*I},
         {y: -0.86602540378443... - 0.500000000000000*I},
         {y: 0.86602540378443... + 0.500000000000000*I},
         {y: 0.86602540378443... - 0.500000000000000*I}]

    This is due to precision error, which causes the computation of an intermediate Groebner basis to fail.

    If the ground field’s characteristic is too large for Singular, we resort to a toy implementation:

    Sage

        sage: R.<x,y> = PolynomialRing(GF(2147483659^3), order='lex')
        sage: I = ideal([x^3 - 2*y^2, 3*x + y^4])
        sage: I.variety()
        verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
        [{y: 0, x: 0}]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(2147483659)**Integer(3)), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = ideal([x**Integer(3) - Integer(2)*y**Integer(2), Integer(3)*x + y**Integer(4)])
        >>> I.variety()
        verbose 0 (...: multi_polynomial_ideal.py, groebner_basis) Warning: falling back to very slow toy implementation.
        verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
        verbose 0 (...: multi_polynomial_ideal.py, variety) Warning: falling back to very slow toy implementation.
        [{y: 0, x: 0}]

    The dictionary expressing the variety will be indexed by generators of the polynomial ring after changing to the target field. But the mapping will also accept generators of the original ring, or even generator names as strings, when provided as keys:

    Sage

        sage: K.<x,y> = QQ[]
        sage: I = ideal([x^2 + 2*y - 5, x + y + 3])
        sage: v = I.variety(AA)[0]; v[x], v[y]
        (4.464101615137755?, -7.464101615137755?)
        sage: list(v)[0].parent()
        Multivariate Polynomial Ring in x, y over Algebraic Real Field
        sage: v[x]
        4.464101615137755?
        sage: v["y"]
        -7.464101615137755?

    [Python]

        >>> from sage.all import *
        >>> K = QQ['x, y']; (x, y,) = K._first_ngens(2)
        >>> I = ideal([x**Integer(2) + Integer(2)*y - Integer(5), x + y + Integer(3)])
        >>> v = I.variety(AA)[Integer(0)]; v[x], v[y]
        (4.464101615137755?, -7.464101615137755?)
        >>> list(v)[Integer(0)].parent()
        Multivariate Polynomial Ring in x, y over Algebraic Real Field
        >>> v[x]
        4.464101615137755?
        >>> v["y"]
        -7.464101615137755?

    `msolve` also works over finite fields:

    Sage

        sage: R.<x, y> = PolynomialRing(GF(536870909), 2, order='lex')              # needs sage.rings.finite_rings
        sage: I = Ideal([x^2 - 1, y^2 - 1])                                         # needs sage.rings.finite_rings
        sage: sorted(I.variety(algorithm='msolve',          # optional - msolve, needs sage.rings.finite_rings
        ....:                  proof=False),
        ....:        key=lambda d: str(sorted(d.items())))
        [{y: 1, x: 1},
         {y: 1, x: 536870908},
         {y: 536870908, x: 1},
         {y: 536870908, x: 536870908}]

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(536870909)), Integer(2), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)# needs sage.rings.finite_rings
        >>> I = Ideal([x**Integer(2) - Integer(1), y**Integer(2) - Integer(1)])                                         # needs sage.rings.finite_rings
        >>> sorted(I.variety(algorithm='msolve',          # optional - msolve, needs sage.rings.finite_rings
        ...                  proof=False),
        ...        key=lambda d: str(sorted(d.items())))
        [{y: 1, x: 1},
         {y: 1, x: 536870908},
         {y: 536870908, x: 1},
         {y: 536870908, x: 536870908}]

    but may fail in small characteristic, especially with ideals of high degree with respect to the characteristic:

    Sage

        sage: R.<x, y> = PolynomialRing(GF(3), 2, order='lex')
        sage: I = Ideal([x^2 - 1, y^2 - 1])
        sage: I.variety(algorithm='msolve', proof=False)    # optional - msolve
        Traceback (most recent call last):
        ...
        NotImplementedError: characteristic 3 too small

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(GF(Integer(3)), Integer(2), order='lex', names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = Ideal([x**Integer(2) - Integer(1), y**Integer(2) - Integer(1)])
        >>> I.variety(algorithm='msolve', proof=False)    # optional - msolve
        Traceback (most recent call last):
        ...
        NotImplementedError: characteristic 3 too small

    ALGORITHM:

    - With `algorithm` = `'triangular_decomposition'` (default), uses triangular decomposition, via Singular if possible, falling back on a toy implementation otherwise.

    - With `algorithm` = `'msolve'`, uses the optional package msolve. Note that msolve uses heuristics and therefore requires setting the `proof` flag to `False`. See `msolve` for more information.

  vector_space_dimension()

    Return the vector space dimension of the ring modulo this ideal. If the ideal is not zero-dimensional, a `TypeError` is raised.

    ALGORITHM:

    Uses Singular.

    EXAMPLES:

    Sage

        sage: R.<u,v> = PolynomialRing(QQ)
        sage: g = u^4 + v^4 + u^3 + v^3
        sage: I = ideal(g) + ideal(g.gradient())
        sage: I.dimension()
        0
        sage: I.vector_space_dimension()
        4

    Python

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('u', 'v',)); (u, v,) = R._first_ngens(2)
        >>> g = u**Integer(4) + v**Integer(4) + u**Integer(3) + v**Integer(3)
        >>> I = ideal(g) + ideal(g.gradient())
        >>> I.dimension()
        0
        >>> I.vector_space_dimension()
        4

    When the ideal is not zero-dimensional, we return infinity:

    Sage

        sage: R.<x,y> = PolynomialRing(QQ)
        sage: I = R.ideal(x)
        sage: I.dimension()
        1
        sage: I.vector_space_dimension()
        +Infinity

    [Python]

        >>> from sage.all import *
        >>> R = PolynomialRing(QQ, names=('x', 'y',)); (x, y,) = R._first_ngens(2)
        >>> I = R.ideal(x)
        >>> I.dimension()
        1
        >>> I.vector_space_dimension()
        +Infinity

    Due to integer overflow, the result is correct only modulo `2^32`, see Issue #8586:

    Sage

        sage: P.<x,y,z> = PolynomialRing(GF(32003), 3)                              # needs sage.rings.finite_rings
        sage: sage.rings.ideal.FieldIdeal(P).vector_space_dimension()       # known bug, needs sage.rings.finite_rings
        32777216864027

    Python

        >>> from sage.all import *
        >>> P = PolynomialRing(GF(Integer(32003)), Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = P._first_ngens(3)# needs sage.rings.finite_rings
        >>> sage.rings.ideal.FieldIdeal(P).vector_space_dimension()       # known bug, needs sage.rings.finite_rings
        32777216864027

class sage.rings.polynomial.multi_polynomial_ideal.NCPolynomialIdeal(ring, gens, coerce=True, side='left')

  Bases: `MPolynomialIdeal_singular_repr`, `Ideal_nc`

  Create a non-commutative polynomial ideal.

  INPUT:

  - `ring` – the g-algebra to which this ideal belongs

  - `gens` – the generators of this ideal

  - `coerce` – boolean (default: `True`); generators are coerced into the ring before creating the ideal

  - `side` – (optional) string; either `'left'` (default) or `'twosided'`. Defines whether this ideal is left or two-sided.

  EXAMPLES:

  Sage

      sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
      sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
      sage: H.inject_variables()
      Defining x, y, z
      sage: I = H.ideal([y^2, x^2, z^2 - H.one()],             # indirect doctest
      ....:             coerce=False)
      sage: I  # random
      Left Ideal (y^2, x^2, z^2 - 1) of
       Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
       nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
      sage: sorted(I.gens(), key=str)
      [x^2, y^2, z^2 - 1]
      sage: H.ideal([y^2, x^2, z^2 - H.one()], side='twosided')  # random
      Twosided Ideal (y^2, x^2, z^2 - 1) of
       Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
       nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
      sage: sorted(H.ideal([y^2, x^2, z^2 - H.one()], side='twosided').gens(),
      ....:        key=str)
      [x^2, y^2, z^2 - 1]
      sage: H.ideal([y^2, x^2, z^2 - H.one()], side='right')
      Traceback (most recent call last):
      ...
      ValueError: Only left and two-sided ideals are allowed.

  Python

      >>> from sage.all import *
      >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
      >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
      >>> H.inject_variables()
      Defining x, y, z
      >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],             # indirect doctest
      ...             coerce=False)
      >>> I  # random
      Left Ideal (y^2, x^2, z^2 - 1) of
       Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
       nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
      >>> sorted(I.gens(), key=str)
      [x^2, y^2, z^2 - 1]
      >>> H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side='twosided')  # random
      Twosided Ideal (y^2, x^2, z^2 - 1) of
       Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
       nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
      >>> sorted(H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side='twosided').gens(),
      ...        key=str)
      [x^2, y^2, z^2 - 1]
      >>> H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], side='right')
      Traceback (most recent call last):
      ...
      ValueError: Only left and two-sided ideals are allowed.

  elimination_ideal(variables)

    Return the elimination ideal of this ideal with respect to the variables given in `variables`.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
        sage: I.elimination_ideal([x, z])
        Left Ideal (y^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}
        sage: J = I.twostd(); J
        Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}
        sage: J.elimination_ideal([x, z])
        Twosided Ideal (y^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], coerce=False)
        >>> I.elimination_ideal([x, z])
        Left Ideal (y^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}
        >>> J = I.twostd(); J
        Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}
        >>> J.elimination_ideal([x, z])
        Twosided Ideal (y^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {...}

    ALGORITHM: Uses Singular’s `eliminate` command

  groebner_basis()

    Compute a Gröbner basis of the ideal.

    The Gröbner basis is two-sided if and only if the ideal is two-sided.

    OUTPUT:

    `PolynomialSequence()`

    ALGORITHM:

    Uses the `std()` method.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
        sage: I.groebner_basis()
        [z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2]

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], coerce=False)
        >>> I.groebner_basis()
        [z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2]

  is_homogeneous()

    Return `True` if this ideal is spanned by homogeneous polynomials, i.e., if it is a homogeneous ideal.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
        sage: I.is_homogeneous()
        False
        sage: J = H.ideal([y^2, x^2, z^2 - x*y], coerce=False)
        sage: J.is_homogeneous()
        True

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], coerce=False)
        >>> I.is_homogeneous()
        False
        >>> J = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - x*y], coerce=False)
        >>> J.is_homogeneous()
        True

  reduce(p)

    Reduce an element modulo a Groebner basis for this ideal.

    It returns 0 if and only if the element is in this ideal. In any case, this reduction is unique up to monomial orders.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H.<x,y,z> = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()],
        ....:             coerce=False, side='twosided')
        sage: Q = H.quotient(I); Q  #random
        Quotient of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
         by the ideal (y^2, x^2, z^2 - 1)
        sage: Q.2^2 == Q.one()   # indirect doctest
        True

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y}, names=('x', 'y', 'z',)); (x, y, z,) = H._first_ngens(3)
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()],
        ...             coerce=False, side='twosided')
        >>> Q = H.quotient(I); Q  #random
        Quotient of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
         by the ideal (y^2, x^2, z^2 - 1)
        >>> Q.gen(2)**Integer(2) == Q.one()   # indirect doctest
        True

    Here, we see that the relation that we just found in the quotient is actually a consequence of the given relations:

    Sage

        sage: H.2^2 - H.one() in I.std().gens()                                     # needs sage.combinat sage.modules
        True

    [Python]

        >>> from sage.all import *
        >>> H.gen(2)**Integer(2) - H.one() in I.std().gens()                                     # needs sage.combinat sage.modules
        True

    Here is the corresponding direct test:

    Sage

        sage: I.reduce(z^2)                                                         # needs sage.combinat sage.modules
        1

    Python

        >>> from sage.all import *
        >>> I.reduce(z**Integer(2))                                                         # needs sage.combinat sage.modules
        1

  res(length)

    Compute the resolution up to a given length of the ideal.

    NOTE:

    Only left syzygies can be computed. So, even if the ideal is two-sided, then the resolution is only one-sided. In that case, a warning is printed.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False)
        sage: I.res(3)
        <Resolution>

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2)-H.one()], coerce=False)
        >>> I.res(Integer(3))
        <Resolution>

  std()

    Compute a GB of the ideal. It is two-sided if and only if the ideal is two-sided.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
        sage: I.std()  #random
        Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        sage: sorted(I.std().gens(), key=str)
        [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], coerce=False)
        >>> I.std()  #random
        Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        >>> sorted(I.std().gens(), key=str)
        [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

    If the ideal is a left ideal, then `std()` returns a left Groebner basis. But if it is a two-sided ideal, then the output of `std()` and `twostd()` coincide:

    Sage

        sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])
        sage: JL  #random
        Left Ideal (x^3, y^3, z^3 - 4*z) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        sage: sorted(JL.gens(), key=str)
        [x^3, y^3, z^3 - 4*z]
        sage: JL.std()  # random
        Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z,
                    x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        sage: sorted(JL.std().gens(), key=str)
        [2*x*y*z - z^2 - 2*z, x*z^2 + 2*x*z, x^3, y*z^2 - 2*y*z, y^3, z^3 - 4*z]
        sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')
        sage: JT  #random
        Twosided Ideal (x^3, y^3, z^3 - 4*z) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        sage: sorted(JT.gens(), key=str)
        [x^3, y^3, z^3 - 4*z]
        sage: JT.std()  #random
        Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z,
                        y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2,
                        y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        sage: sorted(JT.std().gens(), key=str)
        [2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x,
         x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z]
        sage: JT.std() == JL.twostd()
        True

    [Python]

        >>> from sage.all import *
        >>> JL = H.ideal([x**Integer(3), y**Integer(3), z**Integer(3) - Integer(4)*z])
        >>> JL  #random
        Left Ideal (x^3, y^3, z^3 - 4*z) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        >>> sorted(JL.gens(), key=str)
        [x^3, y^3, z^3 - 4*z]
        >>> JL.std()  # random
        Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z,
                    x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        >>> sorted(JL.std().gens(), key=str)
        [2*x*y*z - z^2 - 2*z, x*z^2 + 2*x*z, x^3, y*z^2 - 2*y*z, y^3, z^3 - 4*z]
        >>> JT = H.ideal([x**Integer(3), y**Integer(3), z**Integer(3) - Integer(4)*z], side='twosided')
        >>> JT  #random
        Twosided Ideal (x^3, y^3, z^3 - 4*z) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        >>> sorted(JT.gens(), key=str)
        [x^3, y^3, z^3 - 4*z]
        >>> JT.std()  #random
        Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z,
                        y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2,
                        y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field,
         nc-relations: {z*x: x*z + 2*x, z*y: y*z - 2*y, y*x: x*y - z}
        >>> sorted(JT.std().gens(), key=str)
        [2*x*y*z - z^2 - 2*z, x*y^2 - y*z, x*z^2 + 2*x*z, x^2*y - x*z - 2*x,
         x^2*z + 2*x^2, x^3, y*z^2 - 2*y*z, y^2*z - 2*y^2, y^3, z^3 - 4*z]
        >>> JT.std() == JL.twostd()
        True

    ALGORITHM: Uses Singular’s `std` command

  syzygy_module()

    Compute the first syzygy (i.e., the module of relations of the given generators) of the ideal.

    NOTE:

    Only left syzygies can be computed. So, even if the ideal is two-sided, then the syzygies are only one-sided. In that case, a warning is printed.

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2-H.one()], coerce=False)
        sage: G = vector(I.gens()); G
        d...: UserWarning: You are constructing a free module
        over a noncommutative ring. Sage does not have a concept
        of left/right and both sided modules, so be careful.
        It's also not guaranteed that all multiplications are
        done from the right side.
        d...: UserWarning: You are constructing a free module
        over a noncommutative ring. Sage does not have a concept
        of left/right and both sided modules, so be careful.
        It's also not guaranteed that all multiplications are
        done from the right side.
        (y^2, x^2, z^2 - 1)
        sage: M = I.syzygy_module(); M
        [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2]
        [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2]
        [                                                              x^2*z^2 + 8*x^2*z + 15*x^2                                                              -y^2*z^2 + 8*y^2*z - 15*y^2                                                                   -4*x*y*z + 2*z^2 + 2*z]
        [                 x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 - 282*x*z - 360*x                                                              -y^3*z^2 + 7*y^3*z - 12*y^3                                                                                  6*y*z^2]
        [                                                              x^3*z^2 + 7*x^3*z + 12*x^3                 -x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 + 52*y*z^2 - 224*y*z + 320*y                                                                                 -6*x*z^2]
        [  x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 + 312*z + 288                                                                           -y^4*z + 4*y^4                                                                                        0]
        [                                                  2*x^3*y*z + 8*x^3*y + 9*x^2*z + 27*x^2                                   -2*x*y^3*z + 8*x*y^3 - 12*y^2*z^2 + 99*y^2*z - 195*y^2                                                                -36*x*y*z + 24*z^2 + 18*z]
        [                                                                           x^4*z + 4*x^4    -x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 - 64*x*y + 66*z^2 - 240*z + 288                                                                                        0]
        [x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 - 1656*x*z - 2052*x                                      -x*y^4*z + 4*x*y^4 - 8*y^3*z^2 + 62*y^3*z - 114*y^3                                                                        48*y*z^2 - 36*y*z]

        sage: M*G                                                                   # needs sage.combinat sage.modules
        (0, 0, 0, 0, 0, 0, 0, 0, 0)

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2)-H.one()], coerce=False)
        >>> G = vector(I.gens()); G
        d...: UserWarning: You are constructing a free module
        over a noncommutative ring. Sage does not have a concept
        of left/right and both sided modules, so be careful.
        It's also not guaranteed that all multiplications are
        done from the right side.
        d...: UserWarning: You are constructing a free module
        over a noncommutative ring. Sage does not have a concept
        of left/right and both sided modules, so be careful.
        It's also not guaranteed that all multiplications are
        done from the right side.
        (y^2, x^2, z^2 - 1)
        >>> M = I.syzygy_module(); M
        [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2]
        [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2]
        [                                                              x^2*z^2 + 8*x^2*z + 15*x^2                                                              -y^2*z^2 + 8*y^2*z - 15*y^2                                                                   -4*x*y*z + 2*z^2 + 2*z]
        [                 x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 - 282*x*z - 360*x                                                              -y^3*z^2 + 7*y^3*z - 12*y^3                                                                                  6*y*z^2]
        [                                                              x^3*z^2 + 7*x^3*z + 12*x^3                 -x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 + 52*y*z^2 - 224*y*z + 320*y                                                                                 -6*x*z^2]
        [  x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 + 312*z + 288                                                                           -y^4*z + 4*y^4                                                                                        0]
        [                                                  2*x^3*y*z + 8*x^3*y + 9*x^2*z + 27*x^2                                   -2*x*y^3*z + 8*x*y^3 - 12*y^2*z^2 + 99*y^2*z - 195*y^2                                                                -36*x*y*z + 24*z^2 + 18*z]
        [                                                                           x^4*z + 4*x^4    -x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 - 64*x*y + 66*z^2 - 240*z + 288                                                                                        0]
        [x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 - 1656*x*z - 2052*x                                      -x*y^4*z + 4*x*y^4 - 8*y^3*z^2 + 62*y^3*z - 114*y^3                                                                        48*y*z^2 - 36*y*z]

        >>> M*G                                                                   # needs sage.combinat sage.modules
        (0, 0, 0, 0, 0, 0, 0, 0, 0)

    ALGORITHM: Uses Singular’s `syz` command

  twostd()

    Compute a two-sided GB of the ideal (even if it is a left ideal).

    EXAMPLES:

    Sage

        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
        sage: H = A.g_algebra({y*x: x*y-z, z*x: x*z+2*x, z*y: y*z-2*y})
        sage: H.inject_variables()
        Defining x, y, z
        sage: I = H.ideal([y^2, x^2, z^2 - H.one()], coerce=False)
        sage: I.twostd()  #random
        Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
        sage: sorted(I.twostd().gens(), key=str)
        [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

    Python

        >>> from sage.all import *
        >>> A = FreeAlgebra(QQ, Integer(3), names=('x', 'y', 'z',)); (x, y, z,) = A._first_ngens(3)
        >>> H = A.g_algebra({y*x: x*y-z, z*x: x*z+Integer(2)*x, z*y: y*z-Integer(2)*y})
        >>> H.inject_variables()
        Defining x, y, z
        >>> I = H.ideal([y**Integer(2), x**Integer(2), z**Integer(2) - H.one()], coerce=False)
        >>> I.twostd()  #random
        Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of
         Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
        >>> sorted(I.twostd().gens(), key=str)
        [2*x*y - z - 1, x*z + x, x^2, y*z - y, y^2, z^2 - 1]

    ALGORITHM: Uses Singular’s `twostd` command

class sage.rings.polynomial.multi_polynomial_ideal.RequireField(f)

  Bases: `MethodDecorator`

  Decorator which throws an exception if a computation over a coefficient ring which is not a field is attempted.

  Note

  This decorator is used automatically internally so the user does not need to use it manually.

sage.rings.polynomial.multi_polynomial_ideal.require_field

  alias of `RequireField`