/sage/rings/polynomial/multi_polynomial_ideal.py
Python | 4532 lines | 4412 code | 19 blank | 101 comment | 31 complexity | a698ba9da71429aa213a6477f583747f MD5 | raw file
Large files files are truncated, but you can click here to view the full file
- # -*- coding: utf-8 -*-
- r"""
- Ideals in multivariate polynomial rings.
- Sage has a powerful system to compute with multivariate polynomial
- rings. Most algorithms dealing with these ideals are centered 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.
- AUTHORS:
- - William Stein
- - Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of some
- Singular features
- - Martin Albrecht (2008,2007): refactoring, many Singular related
- functions
- - Martin Albrecht (2009): added Groebner basis over rings
- functionality from Singular 3.1
- - John Perry (2012): bug fixing equality & containment of ideals
- 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
- :class:`MPolynomialIdeal`::
- 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'>
-
- Groebner bases can be used to solve the ideal membership problem::
- 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
-
- We compute a Groebner basis for Cyclic 6, which is a standard
- benchmark and test ideal. ::
- 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
- We compute in a quotient of a polynomial ring over `\ZZ/17\ZZ`::
- 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
- Note that the result of a computation is not necessarily reduced::
- sage: (a+b)^17
- 256*a*b^16 + 256*b^17
- sage: S(17) == 0
- True
- Or we can work with `\ZZ/17\ZZ`` directly::
- 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
- sage: (a+b)^17
- a*b^16 + b^17
- sage: S(17) == 0
- True
- Working with a polynomial ring over `\ZZ`::
- 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
- We do a Groebner basis computation over a number field::
- 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
- Two examples from the Mathematica documentation (done in Sage):
- We compute a Groebner basis::
- 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]
- We show that three polynomials have no common root::
- sage: R.<x,y> = QQ[]
- sage: ideal(x+y, x^2 - 1, y^2 - 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: 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]
- 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: I.groebner_basis()
- [x + 130433*y + 59079*z, y^2 + 3*y + 17220, y*z + 5*y + 14504, 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: factor(164878)
- 2 * 7 * 11777
- sage: I.change_ring(P.change_ring( GF(2) )).groebner_basis()
- [x + y + z, y^2 + y, y*z + y, z^2 + 1]
- sage: I.change_ring(P.change_ring( GF(7) )).groebner_basis()
- [x - 1, y + 3, z - 2]
- sage: I.change_ring(P.change_ring( GF(11777 ))).groebner_basis()
- [x + 5633, y - 3007, z - 2626]
- The Groebner basis modulo any product of the prime factors is also non-trivial. ::
- sage: I.change_ring(P.change_ring( IntegerModRing(2*7) )).groebner_basis()
- [x + y + z, y^2 + 3*y, y*z + 11*y + 4, 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: I.change_ring( P.change_ring( GF(3) ) ).groebner_basis()
- [1]
- TESTS::
- 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: I == loads(dumps(I))
- True
- .. 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
- :class:`sage.rings.polynomial.multi_polynomial_sequence.PolynomialSequence_generic`.
-
- """
- #*****************************************************************************
- #
- # Sage
- #
- # Copyright (C) 2005 William Stein <wstein@gmail.com>
- # Copyright (C) 2008,2009 Martin Albrecht <malb@informatik.uni-bremen.de>
- #
- # Distributed under the terms of the GNU General Public License (GPL)
- #
- # This code is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # General Public License for more details.
- #
- # The full text of the GPL is available at:
- #
- # http://www.gnu.org/licenses/
- #*****************************************************************************
- from sage.interfaces.all import (singular as singular_default,
- macaulay2 as macaulay2_default,
- magma as magma_default)
- from sage.interfaces.expect import StdOutContext
- from sage.rings.ideal import Ideal_generic
- from sage.rings.noncommutative_ideals import Ideal_nc
- from sage.rings.integer import Integer
- from sage.structure.sequence import Sequence
- from sage.misc.cachefunc import cached_method
- from sage.misc.misc import prod, verbose, get_verbose
- from sage.misc.method_decorator import MethodDecorator
- from sage.rings.integer_ring import ZZ
- import sage.rings.polynomial.toy_buchberger as toy_buchberger
- import sage.rings.polynomial.toy_variety as toy_variety
- import sage.rings.polynomial.toy_d_basis as toy_d_basis
- from warnings import warn
- class LibSingularDefaultContext:
- def __init__(self, singular=singular_default):
- from sage.libs.singular.option import opt_ctx
- self.libsingular_option_context = opt_ctx
- def __enter__(self):
- """
- EXAMPLE::
- sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
- sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
- sage: I = sage.rings.ideal.Katsura(P,3)
- sage: singular.option('noredTail')
- sage: singular.option('noredThrough')
- sage: Is = I._singular_()
- sage: with SingularDefaultContext(): rgb = Is.groebner()
- sage: rgb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- 7*a-420*c^3+158*c^2+8*c-7
- """
- self.libsingular_option_context.__enter__()
- self.libsingular_option_context.opt.reset_default()
- self.libsingular_option_context.opt['red_sb'] = True
- self.libsingular_option_context.opt['red_tail'] = True
- self.libsingular_option_context.opt['deg_bound'] = 0
- self.libsingular_option_context.opt['mult_bound'] = 0
- def __exit__(self, typ, value, tb):
- """
- EXAMPLE::
- sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
- sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
- sage: I = sage.rings.ideal.Katsura(P,3)
- sage: singular.option('noredTail')
- sage: singular.option('noredThrough')
- sage: Is = I._singular_()
- sage: with SingularDefaultContext(): rgb = Is.groebner()
- sage: rgb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- 7*a-420*c^3+158*c^2+8*c-7
- """
- self.libsingular_option_context.__exit__(typ,value,tb)
- class SingularDefaultContext:
- """
- Within this context all Singular Groebner basis calculations are
- reduced automatically.
-
- AUTHORS:
- - Martin Albrecht
- - Simon King
- """
- def __init__(self, singular=singular_default):
- """
- Within this context all Singular Groebner basis calculations
- are reduced automatically.
-
- INPUT:
-
- - ``singular`` - Singular instance (default: default instance)
-
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
- sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
- sage: I = sage.rings.ideal.Katsura(P,3)
- sage: singular.option('noredTail')
- sage: singular.option('noredThrough')
- sage: Is = I._singular_()
- sage: gb = Is.groebner()
- sage: gb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- a+2*b+2*c-1
-
- ::
-
- sage: with SingularDefaultContext(): rgb = Is.groebner()
- sage: rgb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- 7*a-420*c^3+158*c^2+8*c-7
-
- Note that both bases are Groebner bases because they have
- pairwise prime leading monomials but that the monic version of
- the last element in ``rgb`` is smaller than the last element
- of ``gb`` with respect to the lexicographical term ordering. ::
-
- sage: (7*a-420*c^3+158*c^2+8*c-7)/7 < (a+2*b+2*c-1)
- True
-
- .. note::
- This context is used automatically internally whenever a
- Groebner basis is computed so the user does not need to use
- it manually.
- """
- self.singular = singular
- def __enter__(self):
- """
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
- sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
- sage: I = sage.rings.ideal.Katsura(P,3)
- sage: singular.option('noredTail')
- sage: singular.option('noredThrough')
- sage: Is = I._singular_()
- sage: with SingularDefaultContext(): rgb = Is.groebner()
- sage: rgb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- 7*a-420*c^3+158*c^2+8*c-7
- """
- try:
- self.bck_degBound = int(self.singular.eval('degBound'))
- except RuntimeError:
- self.bck_degBound = int(0)
- try:
- self.bck_multBound = int(self.singular.eval('multBound'))
- except RuntimeError:
- self.bck_multBound = int(0)
- self.o = self.singular.option("get")
- self.singular.option('set',self.singular._saved_options)
- self.singular.option("redSB")
- self.singular.option("redTail")
- try:
- self.singular.eval('degBound=0')
- except RuntimeError:
- pass
- try:
- self.singular.eval('multBound=0')
- except RuntimeError:
- pass
- def __exit__(self, typ, value, tb):
- """
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import SingularDefaultContext
- sage: P.<a,b,c> = PolynomialRing(QQ,3, order='lex')
- sage: I = sage.rings.ideal.Katsura(P,3)
- sage: singular.option('noredTail')
- sage: singular.option('noredThrough')
- sage: Is = I._singular_()
- sage: with SingularDefaultContext(): rgb = Is.groebner()
- sage: rgb
- 84*c^4-40*c^3+c^2+c,
- 7*b+210*c^3-79*c^2+3*c,
- 7*a-420*c^3+158*c^2+8*c-7
- """
- self.singular.option("set",self.o)
- try:
- self.singular.eval('degBound=%d'%self.bck_degBound)
- except RuntimeError:
- pass
- try:
- self.singular.eval('multBound=%d'%self.bck_multBound)
- except RuntimeError:
- pass
- def singular_standard_options(func):
- r"""
- Decorator to force a reduced Singular groebner basis.
-
- TESTS::
- sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
- sage: J = sage.rings.ideal.Cyclic(P).homogenize()
- sage: from sage.misc.sageinspect import sage_getsource
- sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest
- True
- The following tests against a bug that was fixed in trac ticket #11298::
- sage: from sage.misc.sageinspect import sage_getsourcelines, sage_getargspec
- sage: P.<x,y> = QQ[]
- sage: I = P*[x,y]
- sage: sage_getargspec(I.interreduced_basis)
- ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)
- sage: sage_getsourcelines(I.interreduced_basis)
- ([' @singular_standard_options\n',
- ' @libsingular_standard_options\n',
- ' def interreduced_basis(self):\n',
- ...
- ' return ret\n'], ...)
- .. note::
- This decorator is used automatically internally so the user
- does not need to use it manually.
- """
- from sage.misc.decorators import sage_wraps
- @sage_wraps(func)
- def wrapper(*args, **kwds):
- # """
- # Execute function in ``SingularDefaultContext``.
- # """
- with SingularDefaultContext():
- return func(*args, **kwds)
- return wrapper
- def libsingular_standard_options(func):
- r"""
- Decorator to force a reduced Singular groebner basis.
- TESTS::
- sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
- sage: J = sage.rings.ideal.Cyclic(P).homogenize()
- sage: from sage.misc.sageinspect import sage_getsource
- sage: "buchberger" in sage_getsource(J.interreduced_basis)
- True
- The following tests against a bug that was fixed in trac ticket #11298::
- sage: from sage.misc.sageinspect import sage_getsourcelines, sage_getargspec
- sage: P.<x,y> = QQ[]
- sage: I = P*[x,y]
- sage: sage_getargspec(I.interreduced_basis)
- ArgSpec(args=['self'], varargs=None, keywords=None, defaults=None)
- sage: sage_getsourcelines(I.interreduced_basis)
- ([' @singular_standard_options\n',
- ' @libsingular_standard_options\n',
- ' def interreduced_basis(self):\n',
- ...
- ' return ret\n'], ...)
- .. note::
- This decorator is used automatically internally so the user
- does not need to use it manually.
- """
- from sage.misc.decorators import sage_wraps
- @sage_wraps(func)
- def wrapper(*args, **kwds):
- """
- Execute function in ``LibSingularDefaultContext``.
- """
- with LibSingularDefaultContext():
- return func(*args, **kwds)
- return wrapper
- class MagmaDefaultContext:
- """
- Context to force preservation of verbosity options for Magma's
- Groebner basis computation.
- """
- def __init__(self, magma=magma_default):
- """
- INPUT:
- - ``magma`` - (default: ``magma_default``)
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
- sage: magma.SetVerbose('Groebner',1) # optional - magma
- sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
- 0
- """
- self.magma = magma
- def __enter__(self):
- """
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
- sage: magma.SetVerbose('Groebner',1) # optional - magma
- sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
- 0
- """
- self.groebner_basis_verbose = self.magma.GetVerbose('Groebner')
- self.magma.SetVerbose('Groebner',0)
- def __exit__(self, typ, value, tb):
- """
- EXAMPLE::
-
- sage: from sage.rings.polynomial.multi_polynomial_ideal import MagmaDefaultContext
- sage: magma.SetVerbose('Groebner',1) # optional - magma
- sage: with MagmaDefaultContext(): magma.GetVerbose('Groebner') # optional - magma
- 0
- sage: magma.GetVerbose('Groebner') # optional - magma
- 1
- """
- self.magma.SetVerbose('Groebner',self.groebner_basis_verbose)
- def magma_standard_options(func):
- """
- Decorator to force default options for Magma.
- EXAMPLE::
- sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
- sage: J = sage.rings.ideal.Cyclic(P).homogenize()
- sage: from sage.misc.sageinspect import sage_getsource
- sage: "mself" in sage_getsource(J._groebner_basis_magma)
- True
- """
- from sage.misc.decorators import sage_wraps
- @sage_wraps(func)
- def wrapper(*args, **kwds):
- """
- Execute function in ``MagmaDefaultContext``.
- """
- with MagmaDefaultContext():
- return func(*args, **kwds)
- return wrapper
- class RequireField(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.
- """
- def __call__(self, *args, **kwds):
- """
- EXAMPLE::
- sage: P.<x,y,z> = PolynomialRing(ZZ)
- sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
- sage: from sage.rings.polynomial.multi_polynomial_ideal import RequireField
- sage: class Foo(I.__class__):
- ... @RequireField
- ... def bar(I):
- ... return I.groebner_basis()
- ...
- sage: J = Foo(I.ring(), I.gens())
- sage: J.bar()
- Traceback (most recent call last):
- ...
- ValueError: Coefficient ring must be a field for function 'bar'.
- """
- R = self._instance.ring()
- if not R.base_ring().is_field():
- raise ValueError("Coefficient ring must be a field for function '%s'."%(self.f.__name__))
- return self.f(self._instance, *args, **kwds)
- require_field = RequireField
- def is_MPolynomialIdeal(x):
- """
- Return ``True`` if the provided argument ``x`` is an ideal in the
- multivariate polynomial ring.
-
- INPUT:
-
- - ``x`` - an arbitrary object
-
- EXAMPLES::
-
- sage: from sage.rings.polynomial.all import is_MPolynomialIdeal
- sage: P.<x,y,z> = PolynomialRing(QQ)
- sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y]
-
- Sage distinguishes between a list of generators for an ideal and
- the ideal itself. This distinction is inconsistent with Singular
- but matches Magma's behavior. ::
-
- sage: is_MPolynomialIdeal(I)
- False
-
- ::
-
- sage: I = Ideal(I)
- sage: is_MPolynomialIdeal(I)
- True
- """
- return isinstance(x, MPolynomialIdeal)
- class MPolynomialIdeal_magma_repr:
- def _magma_init_(self, magma):
- """
- Returns a Magma ideal matching this ideal if the base ring
- coerces to Magma and Magma is available.
-
- INPUT:
-
- - ``magma`` - Magma instance
-
- EXAMPLES::
-
- sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
- sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest
- sage: magma(I) # optional - magma
- Ideal of Polynomial ring of rank 10 over GF(127)
- Order: Graded Reverse Lexicographical
- Variables: a, b, c, d, e, f, g, h, i, j
- Basis:
- [
- a + b + c + d,
- a*b + b*c + a*d + c*d,
- a*b*c + a*b*d + a*c*d + b*c*d,
- a*b*c*d + 126
- ]
- """
- P = magma(self.ring())
- G = magma(self.gens())
- return 'ideal<%s|%s>'%(P.name(), G._ref())
- @magma_standard_options
- def _groebner_basis_magma(self, deg_bound=None, prot=False, magma=magma_default):
- """
- Computes a Groebner Basis for this ideal using Magma if
- available.
-
- INPUT:
-
- - ``deg_bound`` - only compute to degree ``deg_bound``, that
- is, ignore all S-polynomials of higher degree. (default:
- ``None``)
- - ``prot`` - if ``True`` Magma's protocol is printed to
- stdout.
- - ``magma`` - Magma instance or None (default instance) (default: None)
-
- EXAMPLES::
-
- sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
- sage: I = sage.rings.ideal.Cyclic(R,6)
- sage: gb = I.groebner_basis('magma:GroebnerBasis') # indirect doctest; optional - magma
- sage: len(gb) # optional - magma
- 45
- """
- R = self.ring()
- if not deg_bound:
- mself = magma(self)
- else:
- mself = magma(self.gens())
- if get_verbose() >= 2:
- prot = True
-
- from sage.interfaces.magma import MagmaGBLogPrettyPrinter
- if prot:
- log_parser = MagmaGBLogPrettyPrinter(verbosity=get_verbose()+ 1, style="sage" if prot=="sage" else "magma")
- else:
- log_parser = None
- ctx = StdOutContext(magma, silent=False if prot else True, stdout=log_parser)
- if prot:
- magma.SetVerbose('Groebner',1)
- with ctx:
- if deg_bound:
- mgb = mself.GroebnerBasis(deg_bound)
- else:
- mgb = mself.GroebnerBasis()
- if prot == "sage":
- print
- print "Highest degree reached during computation: %2d."%log_parser.max_deg
- # TODO: rewrite this to be much more sophisticated in multi-level nested cases.
- mgb = [str(mgb[i+1]) for i in range(len(mgb))]
- if R.base_ring().degree() > 1:
- a = str(R.base_ring().gen())
- mgb = [e.replace("$.1",a) for e in mgb]
- from sage.rings.polynomial.multi_polynomial_sequence import PolynomialSequence
- B = PolynomialSequence([R(e) for e in mgb], R, immutable=True)
- return B
- class MPolynomialIdeal_singular_base_repr:
- @require_field
- def syzygy_module(self):
- r"""
- Computes the first syzygy (i.e., the module of relations of the
- given generators) of the ideal.
-
- EXAMPLE::
-
- 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)
-
- ALGORITHM: Uses Singular's syz command
- """
- import sage.libs.singular
- syz = sage.libs.singular.ff.syz
- from sage.matrix.constructor import matrix
- #return self._singular_().syz().transpose().sage_matrix(self.ring())
- S = syz(self)
- return matrix(self.ring(), S)
- @libsingular_standard_options
- def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
- """
- Return the reduced Groebner basis of this ideal. If the
- Groebner basis for this ideal has been calculated before the
- cached Groebner basis is returned regardless of the requested
- algorithm.
-
- INPUT:
-
- - ``algorithm`` - see below for available algorithms
- - ``redsb`` - return a reduced Groebner basis (default: ``True``)
- - ``red_tail`` - perform tail reduction (default: ``True``)
- ALGORITHMS:
-
- 'groebner'
- Singular's heuristic script (default)
- 'std'
- Buchberger's algorithm
-
- 'slimgb'
- the *SlimGB* algorithm
- 'stdhilb'
- Hilbert Basis driven Groebner basis
-
- 'stdfglm'
- Buchberger and FGLM
-
- EXAMPLES:
-
- We compute a Groebner basis of 'cyclic 4' relative to
- lexicographic ordering. ::
-
- sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
- sage: I = sage.rings.ideal.Cyclic(R,4); I
- Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
- + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
- Ring in a, b, c, d over Rational Field
-
- ::
-
- sage: I._groebner_basis_libsingular()
- [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
- b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
- b^2 + 2*b*d + d^2, a + b + c + d]
-
- ALGORITHM:
- Uses libSINGULAR.
- """
- from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular
- from sage.libs.singular import singular_function
- from sage.libs.singular.option import opt
- import sage.libs.singular
- groebner = sage.libs.singular.ff.groebner
- if get_verbose()>=2:
- opt['prot'] = True
- for name,value in kwds.iteritems():
- if value is not None:
- opt[name] = value
- T = self.ring().term_order()
-
- if algorithm == "std":
- S = std_libsingular(self)
- elif algorithm == "slimgb":
- S = slimgb_libsingular(self)
- elif algorithm == "groebner":
- S = groebner(self)
- else:
- try:
- fnc = singular_function(algorithm)
- S = fnc(self)
- except NameError:
- raise NameError("Algorithm '%s' unknown"%algorithm)
- return S
- class MPolynomialIdeal_singular_repr(
- MPolynomialIdeal_singular_base_repr):
- """
- An ideal in a multivariate polynomial ring, which has an
- underlying Singular ring associated to it.
- """
- def _singular_(self, singular=singular_default):
- """
- Return Singular ideal corresponding to this ideal.
-
- EXAMPLES::
-
- sage: R.<x,y> = PolynomialRing(QQ, 2)
- sage: I = R.ideal([x^3 + y, y])
- sage: S = I._singular_()
- sage: S
- x^3+y,
- y
- """
- try:
- self.ring()._singular_(singular).set_ring()
- I = self.__singular
- if not (I.parent() is singular):
- raise ValueError
- I._check_valid()
- return I
- except (AttributeError, ValueError):
- self.ring()._singular_(singular).set_ring()
- try:
- # this may fail for quotient ring elements, but is
- # faster
- gens = [str(x) for x in self.gens()]
- if len(gens) == 0:
- gens = ['0']
- self.__singular = singular.ideal(gens)
- except TypeError:
- gens = [str(x.lift()) for x in self.gens()]
- if len(gens) == 0:
- gens = ['0']
- self.__singular = singular.ideal(gens)
- return self.__singular
- @cached_method
- def _groebner_strategy(self):
- """
- Return Singular's Groebner Strategy object for the Groebner
- basis of this ideal which implements some optimized functions.
- EXAMPLE::
- sage: R.<x,y> = PolynomialRing(QQ,2)
- sage: I = R.ideal([y^3 - x^2])
- sage: I._groebner_strategy()
- Groebner Strategy for ideal generated by 1 elements over
- Multivariate Polynomial Ring in x, y over Rational Field
- .. note::
- This function is mainly used internally.
- """
- from sage.libs.singular.groebner_strategy import GroebnerStrategy
- return GroebnerStrategy(MPolynomialIdeal(self.ring(), self.groebner_basis()))
- def plot(self, singular=singular_default):
- """
- If you somehow manage to install surf, perhaps you can use
- this function to implicitly plot the real zero locus of this
- ideal (if principal).
-
- INPUT:
-
-
- - ``self`` - must be a principal ideal in 2 or 3 vars
- over QQ.
-
-
- EXAMPLES:
- Implicit plotting in 2-d::
-
- sage: R.<x,y> = PolynomialRing(QQ,2)
- sage: I = R.ideal([y^3 - x^2])
- sage: I.plot() # cusp
- sage: I = R.ideal([y^2 - x^2 - 1])
- sage: I.plot() # hyperbola
- sage: I = R.ideal([y^2 + x^2*(1/4) - 1])
- sage: I.plot() # ellipse
- sage: I = R.ideal([y^2-(x^2-1)*(x-2)])
- sage: I.plot() # elliptic curve
-
- Implicit plotting in 3-d::
-
- sage: R.<x,y,z> = PolynomialRing(QQ,3)
- sage: I = R.ideal([y^2 + x^2*(1/4) - z])
- sage: I.plot() # a cone; optional - surf
- sage: I = R.ideal([y^2 + z^2*(1/4) - x])
- sage: I.plot() # same code, from a different angle; optional - surf
- sage: I = R.ideal([x^2*y^2+x^2*z^2+y^2*z^2-16*x*y*z])
- sage: I.plot() # Steiner surface; optional - surf
-
- AUTHORS:
- - David Joyner (2006-02-12)
- """
- if self.ring().characteristic() != 0:
- raise TypeError, "base ring must have characteristic 0"
- if not self.is_principal():
- raise TypeError, "self must be principal"
- singular.lib('surf')
- I = singular(self)
- I.plot()
- @require_field
- @libsingular_standard_options
- def complete_primary_decomposition(self, algorithm="sy"):
- r"""
- Return a list of primary ideals and their associated primes such
- that the intersection of the primary ideal `Q_i` 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 these `Q_i` and their associated
- primes.
-
- INPUT:
-
- - ``algorithm`` - string:
- - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
- - ``'gtz'`` - use the gianni-trager-zacharias algorithm
-
- OUTPUT:
-
- - ``list`` - a list of primary ideals and their
- associated primes [(primary ideal, associated prime), ...]
-
- EXAMPLES::
-
- 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.complete_primary_decomposition(); pd
- [(Ideal (z^6 + 4*z^3 + 4, y - z^2) 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),
- (Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field,
- Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
-
- sage: I.primary_decomposition_complete(algorithm = 'gtz')
- [(Ideal (z^6 + 4*z^3 + 4, y - z^2) 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),
- (Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
- Ideal (z^2 + 1, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field)]
-
- sage: reduce(lambda Qi,Qj: Qi.intersection(Qj), [Qi for (Qi,radQi) in pd]) == I
- True
-
- sage: [Qi.radical() == radQi for (Qi,radQi) in pd]
- [True, True]
- sage: P.<x,y,z> = PolynomialRing(ZZ)
- sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 )
- sage: I.complete_primary_decomposition()
- Traceback (most recent call last):
- ...
- ValueError: Coefficient ring must be a field for function 'complete_primary_decomposition'.
-
- ALGORITHM:
- Uses Singular.
- .. note::
-
- See [BW93]_ for an introduction to primary decomposition.
- """
- try:
- return self.__complete_primary_decomposition[algorithm]
- except AttributeError:
- self.__complete_primary_decomposition = {}
- except KeyError:
- pass
- import sage.libs.singular
- if algorithm == 'sy':
- primdecSY = sage.libs.singular.ff.primdec__lib.primdecSY
- P = primdecSY(self)
- elif algorithm == 'gtz':
- primdecGTZ = sage.libs.singular.ff.primdec__lib.primdecGTZ
- P = primdecGTZ(self)
- R = self.ring()
- V = [(R.ideal(X[0]), R.ideal(X[1])) for X in P]
- V = Sequence(V)
- self.__complete_primary_decomposition[algorithm] = V
- return self.__complete_primary_decomposition[algorithm]
- # Seems useful for Tab-Completion
- primary_decomposition_complete = complete_primary_decomposition
- @require_field
- def primary_decomposition(self, algorithm='sy'):
- r"""
- Return a list of primary ideals such that their 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 `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 these `Q_i`.
-
- INPUT:
-
- - ``algorithm`` - string:
-
- - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
-
- - ``'gtz'`` - use the gianni-trager-zacharias algorithm
-
- EXAMPLES::
-
- 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(); pd
- [Ideal (z^6 + 4*z^3 + 4, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
- Ideal (z^2 + 1, y + 1) of Multivariate Polynomial Ring in x, y, z over Rational Field]
-
- ::
-
- sage: 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.
- """
- return [I for I, _ in self.complete_primary_decomposition(algorithm)]
- @require_field
- def associated_primes(self, algorithm='sy'):
- r"""
- 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:
-
- - ``'sy'`` - (default) use the shimoyama-yokoyama algorithm
-
- - ``'gtz'`` - use the gianni-trager-zacharias algorithm
-
-
- OUTPUT:
-
- - ``list`` - a list of associated primes
-
- EXAMPLES::
-
- 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(); pd
- [Ideal (z^3 + 2, y - z^2) of Multivariate Polynomial Ring in x, y, z over Rational Field,
- Ideal (z^2 + 1, y + 1) 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.
- """
- return [P for _,P in self.complete_primary_decomposition(algorithm)]
- def is_prime(self, **kwds):
- r"""
- 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: 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
- The following is Trac #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: 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)
- """
- if not self.ring().base_ring().is_field():
- raise NotImplementedError
- CPD = self.complete_primary_decomposition(**kwds)
- if len(CPD) != 1:
- return False
- _, P = CPD[0]
- return self == P
-
- @require_field
- @singular_standard_options
- @libsingular_standard_options
- def triangular_decomposition(self, algorithm=None, singular=singular_default):
- """
- 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`` - decomp. of self into tri. systems
- plus factorization.
-
- - ``singular:triangM`` - decomposition of self into
- triangular systems (Moeller).
-
- OUTPUT: a 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.
-
- EXAMPLE::
-
- 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 - 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 - 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^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, x1^2) of Multivariate Polynomial Ring in x1, x2 over Rational Field,
- 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]
- TESTS::
- sage: R.<x,y> = QQ[]
- sage: J = Ideal(x^2+y^2-2, y^2-1)
- sage: J.triangular_decomposition()
- [Ideal (y^2 - 1, x^2 - 1) of Multivariate Polynomial Ring in x, y over Rational Field]
- """
- P = self.ring()
- is_groebner = self.basis_is_groebner()
- # make sure to work w.r.t. 'lex'
- if P.term_order() != 'lex':
- Q = P.change_ring(order='lex')
- else:
- Q = P
- # the Singular routines are quite picky about their input.
- if is_groebner:
- if Q == P:
- I = MPolynomialIdeal(P, self.interreduced_basis()[::-1])
- else:
- I = self
- I = MPolynomialIdeal(P, I.transformed_basis('fglm')[::-1]) # -> 'lex'
- I = I.change_ring(Q) # transform to 'lex' GB
- else:
- if Q == P:
- I = MPolynomialIdeal(P, self.groebner_basis()[::-1])
- else:
- I = self.change_ring(Q) # transform to 'lex' GB
- I = MPolynomialIdeal(Q, I.groebner_basis()[::-1])
- if I.dimension() != 0:
- raise TypeError, "dimension must be zero"
- from sage.libs.singular.function import singular_function
- from sage.libs.singular.function import lib as singular_lib
- singular_lib('triang.lib')
- if algorithm is None:
- algorithm = "singular:triangL"
-
- if algorithm in ("singular:triangL","singular:triangLfak","singular:triangM"):
- f = singular_function(algorithm[9:])
- Tbar = f(I, attributes={I:{'isSB':1}})
- else:
- raise TypeError, "algorithm '%s' unknown"%algorithm
- T = Sequence([ MPolynomialIdeal(Q,t) for t in Tbar])
- f = lambda x,y: cmp(x.gens(), y.gens())
- T.sort(f)
- return T
- @require_field
- def dimension(self, singular=singular_default):
- """
- The dimension of the ring modulo this ideal.
-
- EXAMPLE::
-
- sage: P.<x,y,z> = PolynomialRing(GF(32003),order='degrevlex')
- sage: I = ideal(x^2-y,x^3)
- sage: I.dimension()
- 1
-
- 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".
-
- EXAMPLE::
-
- sage: R.<x,y> = PolynomialRing(GF(2147483659),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.
- 0
- 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),order='lex')
- sage: I = R.ideal(0)
- sage: I.dimension()
- verbose 0 (...: multi_polynomial_ideal.py, dimension) Warning: falling back to very slow toy implementation.
- 2
- ALGORITHM:
- Uses Singular, unless …
Large files files are truncated, but you can click here to view the full file