@@ -2997,16 +2997,25 @@ def _macaulay2_(self, macaulay2=None):
29972997 self .__macaulay2 [macaulay2 ] = z
29982998 return z
29992999
3000- def _groebner_basis_macaulay2 (self ):
3000+ def _groebner_basis_macaulay2 (self , strategy = None ):
30013001 r"""
30023002 Return the Groebner basis for this ideal, computed using
30033003 Macaulay2.
30043004
30053005 ALGORITHM:
30063006
3007- Computed using Macaulay2. A big advantage of Macaulay2 is that
3008- it can compute the Groebner basis of ideals in polynomial
3009- rings over the integers.
3007+ Compute the Groebner basis using the specified strategy in Macaulay2.
3008+ With no strategy option, the Macaulay2 ``gb`` command is used; other
3009+ possible strategies are "f4" and "mgb", which correspond to the "F4"
3010+ and "MGB" strategies in Macaulay2.
3011+
3012+ A big advantage of Macaulay2 is that it can compute the Groebner basis
3013+ of ideals in polynomial rings over the integers.
3014+
3015+ INPUT:
3016+
3017+ - ``strategy`` -- (default: ``'gb'``) argument specifying the strategy
3018+ to be used by Macaulay2; possiblities: ``'f4'``, ``'gb'``, ``'mgb'``.
30103019
30113020 EXAMPLES::
30123021
@@ -3027,11 +3036,41 @@ def _groebner_basis_macaulay2(self):
30273036 sage: I = ideal([y^2*z - x^3 - 19^2*x*z, y^2, 19^2])
30283037 sage: I.groebner_basis('macaulay2') # optional - macaulay2
30293038 [x^3, y^2, 361]
3039+
3040+ Over finite fields, Macaulay2 supports different algorithms to compute
3041+ Gröbner bases::
3042+
3043+ sage: R = PolynomialRing(GF(101), 'x', 4)
3044+ sage: I = sage.rings.ideal.Cyclic(R)
3045+ sage: gb1 = I.groebner_basis('macaulay2:gb') # optional - macaulay2
3046+ sage: I = sage.rings.ideal.Cyclic(R)
3047+ sage: gb2 = I.groebner_basis('macaulay2:mgb') # optional - macaulay2
3048+ sage: I = sage.rings.ideal.Cyclic(R)
3049+ sage: gb3 = I.groebner_basis('macaulay2:f4') # optional - macaulay2
3050+ sage: gb1 == gb2 == gb3 # optional - macaulay2
3051+ True
3052+
3053+ TESTS::
3054+
3055+ sage: R.<x,y,z> = ZZ[]
3056+ sage: I = ideal([y^2*z - x^3 - 19*x*z, y^2, 19^2])
3057+ sage: I.groebner_basis('macaulay2:gibberish') # optional - macaulay2
3058+ Traceback (most recent call last):
3059+ ...
3060+ ValueError: unsupported Macaulay2 strategy
30303061 """
30313062 from sage .rings .polynomial .multi_polynomial_sequence import PolynomialSequence
30323063
30333064 I = self ._macaulay2_ ()
3034- G = str (I .gb ().generators ().external_string ()).replace ('\n ' ,'' )
3065+ if strategy == "gb" or strategy is None :
3066+ m2G = I .gb ().generators ()
3067+ elif strategy == 'f4' :
3068+ m2G = I .groebnerBasis ('Strategy=>"F4"' )
3069+ elif strategy == 'mgb' :
3070+ m2G = I .groebnerBasis ('Strategy=>"MGB"' )
3071+ else :
3072+ raise ValueError ("unsupported Macaulay2 strategy" )
3073+ G = str (m2G .external_string ()).replace ('\n ' ,'' )
30353074 i = G .rfind ('{{' )
30363075 j = G .rfind ('}}' )
30373076 G = G [i + 2 :j ].split (',' )
@@ -3817,6 +3856,12 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal
38173856 'macaulay2:gb'
38183857 Macaulay2's ``gb`` command (if available)
38193858
3859+ 'macaulay2:f4'
3860+ Macaulay2's ``GroebnerBasis`` command with the strategy "F4" (if available)
3861+
3862+ 'macaulay2:mgb'
3863+ Macaulay2's ``GroebnerBasis`` command with the strategy "MGB" (if available)
3864+
38203865 'magma:GroebnerBasis'
38213866 Magma's ``Groebnerbasis`` command (if available)
38223867
@@ -3916,19 +3961,29 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal
39163961 sage: gb == gb.reduced()
39173962 False
39183963
3919- but that ``toy:buchberger2`` does.::
3964+ but that ``toy:buchberger2`` does. ::
39203965
39213966 sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
39223967 sage: gb = I.groebner_basis('toy:buchberger2'); gb
39233968 [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]
39243969 sage: gb == gb.reduced()
39253970 True
39263971
3927- ::
3972+ Here we use Macaulay2 with three different strategies over a finite
3973+ field. ::
39283974
3929- sage: I = sage.rings.ideal.Katsura(P,3) # regenerate to prevent caching
3930- sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2
3931- [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]
3975+ sage: R.<a,b,c> = PolynomialRing(GF(101), 3)
3976+ sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching
3977+ sage: I.groebner_basis('macaulay2:gb') # optional - macaulay2
3978+ [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]
3979+
3980+ sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching
3981+ sage: I.groebner_basis('macaulay2:f4') # optional - macaulay2
3982+ [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]
3983+
3984+ sage: I = sage.rings.ideal.Katsura(R,3) # regenerate to prevent caching
3985+ sage: I.groebner_basis('macaulay2:mgb') # optional - macaulay2
3986+ [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]
39323987
39333988 ::
39343989
@@ -3937,7 +3992,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal
39373992 [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]
39383993
39393994 Singular and libSingular can compute Groebner basis with degree
3940- restrictions.::
3995+ restrictions. ::
39413996
39423997 sage: R.<x,y> = QQ[]
39433998 sage: I = R*[x^3+y^2,x^2*y+1]
@@ -3980,7 +4035,7 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal
39804035 The list of available options is provided at
39814036 :class:`~sage.libs.singular.option.LibSingularOptions`.
39824037
3983- Note that Groebner bases over `\ZZ` can also be computed.::
4038+ Note that Groebner bases over `\ZZ` can also be computed. ::
39844039
39854040 sage: P.<a,b,c> = PolynomialRing(ZZ,3)
39864041 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)
@@ -4212,8 +4267,8 @@ def groebner_basis(self, algorithm='', deg_bound=None, mult_bound=None, prot=Fal
42124267 if prot == "sage" :
42134268 warn ("The libsingular interface does not support prot='sage', reverting to 'prot=True'." )
42144269 gb = self ._groebner_basis_libsingular (algorithm [len ('libsingular:' ):], deg_bound = deg_bound , mult_bound = mult_bound , prot = prot , * args , ** kwds )
4215- elif algorithm == ' macaulay2:gb' :
4216- gb = self ._groebner_basis_macaulay2 (* args , ** kwds )
4270+ elif algorithm . startswith ( " macaulay2:" ) :
4271+ gb = self ._groebner_basis_macaulay2 (strategy = algorithm . split ( ":" )[ 1 ], * args , ** kwds )
42174272 elif algorithm == 'magma:GroebnerBasis' :
42184273 gb = self ._groebner_basis_magma (prot = prot , deg_bound = deg_bound , * args , ** kwds )
42194274 elif algorithm == 'toy:buchberger' :
@@ -4745,7 +4800,7 @@ def random_element(self, degree, compute_gb=False, *args, **kwds):
47454800
47464801 EXAMPLES:
47474802
4748- We compute a uniformly random element up to the provided degree.::
4803+ We compute a uniformly random element up to the provided degree. ::
47494804
47504805 sage: P.<x,y,z> = GF(127)[]
47514806 sage: I = sage.rings.ideal.Katsura(P)
0 commit comments