diff --git a/src/sage/rings/polynomial/toy_buchberger.py b/src/sage/rings/polynomial/toy_buchberger.py
index c6b47eb4a57..808aae91997 100644
--- a/src/sage/rings/polynomial/toy_buchberger.py
+++ b/src/sage/rings/polynomial/toy_buchberger.py
@@ -12,7 +12,7 @@
method on multivariate polynomial objects.
-.. note::
+.. NOTE::
The notion of 'term' and 'monomial' in [BW1993]_ is swapped from the
notion of those words in Sage (or the other way around, however you
@@ -26,8 +26,8 @@
Consider Katsura-6 w.r.t. a ``degrevlex`` ordering.::
sage: from sage.rings.polynomial.toy_buchberger import *
- sage: P. = PolynomialRing(GF(32003),10)
- sage: I = sage.rings.ideal.Katsura(P,6)
+ sage: P. = PolynomialRing(GF(32003))
+ sage: I = sage.rings.ideal.Katsura(P, 6)
sage: g1 = buchberger(I)
sage: g2 = buchberger_improved(I)
@@ -47,10 +47,10 @@
sage: Ideal(g1) == Ideal(g2) == Ideal(g3)
True
-If ``get_verbose()`` is `>= 1` a protocol is provided::
+If ``get_verbose()`` is `>= 1`, a protocol is provided::
sage: set_verbose(1)
- sage: P. = PolynomialRing(GF(127),3)
+ sage: P. = PolynomialRing(GF(127))
sage: I = sage.rings.ideal.Katsura(P)
// sage... ideal
@@ -141,18 +141,19 @@
from sage.misc.misc import get_verbose
from sage.structure.sequence import Sequence
-#some aliases that conform to Becker and Weispfenning's notation:
+# some aliases that conform to Becker and Weispfenning's notation:
LCM = lambda f, g: f.parent().monomial_lcm(f, g)
LM = lambda f: f.lm()
LT = lambda f: f.lt()
-def spol(f,g):
+
+def spol(f, g):
"""
- Computes the S-polynomial of f and g.
+ Compute the S-polynomial of f and g.
INPUT:
- - ``f,g`` - polynomials
+ - ``f, g`` -- polynomials
OUTPUT:
@@ -160,7 +161,7 @@ def spol(f,g):
EXAMPLES::
- sage: R. = PolynomialRing(QQ,3)
+ sage: R. = PolynomialRing(QQ)
sage: from sage.rings.polynomial.toy_buchberger import spol
sage: spol(x^2 - z - 1, z^2 - y - 1)
x^2*y - z^3 + x^2 - z^2
@@ -171,18 +172,18 @@ def spol(f,g):
def buchberger(F):
"""
- The original version of Buchberger's algorithm as presented in
- [BW1993]_, page 214.
+ Compute a Groebner basis using the original version of Buchberger's
+ algorithm as presented in [BW1993]_, page 214.
INPUT:
- - ``F`` - an ideal in a multivariate polynomial ring
+ - ``F`` -- an ideal in a multivariate polynomial ring
OUTPUT:
a Groebner basis for F
- .. note::
+ .. NOTE::
The verbosity of this function may be controlled with a
``set_verbose()`` call. Any value >=1 will result in this
@@ -191,7 +192,7 @@ def buchberger(F):
EXAMPLES::
sage: from sage.rings.polynomial.toy_buchberger import buchberger
- sage: R. = PolynomialRing(QQ,3)
+ sage: R. = PolynomialRing(QQ)
sage: I = R.ideal([x^2 - z - 1, z^2 - y - 1, x*y^2 - x - 1])
sage: set_verbose(0)
sage: gb = buchberger(I)
@@ -206,14 +207,14 @@ def buchberger(F):
if get_verbose() >= 1:
reductions_to_zero = 0
- while B!=set():
- g1,g2 = select(B)
- B.remove( (g1,g2) )
+ while B:
+ g1, g2 = select(B)
+ B.remove((g1, g2))
- h = spol(g1,g2).reduce(G)
+ h = spol(g1, g2).reduce(G)
if h != 0:
- B = B.union( [(g,h) for g in G] )
- G.add( h )
+ B = B.union((g, h) for g in G)
+ G.add(h)
if get_verbose() >= 1:
print("(%s, %s) => %s" % (g1, g2, h))
@@ -226,23 +227,24 @@ def buchberger(F):
return Sequence(G)
+
def buchberger_improved(F):
"""
- An improved version of Buchberger's algorithm as presented in
- [BW1993]_, page 232.
+ Compute a Groebner basis using an improved version of Buchberger's
+ algorithm as presented in [BW1993]_, page 232.
This variant uses the Gebauer-Moeller Installation to apply
Buchberger's first and second criterion to avoid useless pairs.
INPUT:
- - ``F`` - an ideal in a multivariate polynomial ring
+ - ``F`` -- an ideal in a multivariate polynomial ring
OUTPUT:
a Groebner basis for F
- .. note::
+ .. NOTE::
The verbosity of this function may be controlled with a
``set_verbose()`` call. Any value ``>=1`` will result in this
@@ -251,9 +253,9 @@ def buchberger_improved(F):
EXAMPLES::
sage: from sage.rings.polynomial.toy_buchberger import buchberger_improved
- sage: R. = PolynomialRing(QQ,3)
+ sage: R. = PolynomialRing(QQ)
sage: set_verbose(0)
- sage: sorted(buchberger_improved(R.ideal([x^4-y-z,x*y*z-1])))
+ sage: sorted(buchberger_improved(R.ideal([x^4-y-z, x*y*z-1])))
[x*y*z - 1, x^3 - y^2*z - y*z^2, y^3*z^2 + y^2*z^3 - x^2]
"""
F = inter_reduction(F.gens())
@@ -261,20 +263,21 @@ def buchberger_improved(F):
G = set()
B = set()
- if get_verbose() >=1:
+ if get_verbose() >= 1:
reductions_to_zero = 0
- while F != set():
+ while F:
f = min(F)
F.remove(f)
- G,B = update(G,B,f)
+ G, B = update(G, B, f)
- while B != set():
+ while B:
- g1,g2 = select(B)
- B.remove((g1,g2))
- h = spol(g1,g2).reduce(G)
- if h!=0: G,B = update(G,B,h)
+ g1, g2 = select(B)
+ B.remove((g1, g2))
+ h = spol(g1, g2).reduce(G)
+ if h != 0:
+ G, B = update(G, B, h)
if get_verbose() >= 1:
print("(%s, %s) => %s" % (g1, g2, h))
@@ -287,9 +290,10 @@ def buchberger_improved(F):
return Sequence(inter_reduction(G))
-def update(G,B,h):
+
+def update(G, B, h):
"""
- Update ``G`` using the list of critical pairs ``B`` and the
+ Update ``G`` using the set of critical pairs ``B`` and the
polynomial ``h`` as presented in [BW1993]_, page 230. For this,
Buchberger's first and second criterion are tested.
@@ -297,81 +301,83 @@ def update(G,B,h):
INPUT:
- - ``G`` - an intermediate Groebner basis
- - ``B`` - a list of critical pairs
- - ``h`` - a polynomial
+ - ``G`` -- an intermediate Groebner basis
+ - ``B`` -- a set of critical pairs
+ - ``h`` -- a polynomial
OUTPUT:
- a tuple of an intermediate Groebner basis and a list of
+ a tuple of an intermediate Groebner basis and a set of
critical pairs
EXAMPLES::
sage: from sage.rings.polynomial.toy_buchberger import update
- sage: R. = PolynomialRing(QQ,3)
+ sage: R. = PolynomialRing(QQ)
sage: set_verbose(0)
- sage: update(set(),set(),x*y*z)
+ sage: update(set(), set(), x*y*z)
({x*y*z}, set())
- sage: G,B = update(set(),set(),x*y*z-1)
- sage: G,B = update(G,B,x*y^2-1)
- sage: G,B
+ sage: G, B = update(set(), set(), x*y*z-1)
+ sage: G, B = update(G, B, x*y^2-1)
+ sage: G, B
({x*y*z - 1, x*y^2 - 1}, {(x*y^2 - 1, x*y*z - 1)})
"""
R = h.parent()
- C = set([(h,g) for g in G])
+ C = set((h, g) for g in G)
D = set()
- while C != set():
- (h,g) = C.pop()
+ while C:
+ (h, g) = C.pop()
- lcm_divides = lambda rhs: R.monomial_divides( LCM(LM(h),LM(rhs[1])), LCM(LM(h),LM(g)))
+ lcm_divides = lambda rhs: R.monomial_divides(LCM(LM(h), LM(rhs[1])),
+ LCM(LM(h), LM(g)))
- if R.monomial_pairwise_prime(LM(h),LM(g)) or \
- (\
- not any( lcm_divides(f) for f in C ) \
- and
- not any( lcm_divides(f) for f in D ) \
- ):
- D.add( (h,g) )
+ if R.monomial_pairwise_prime(LM(h), LM(g)) or \
+ (
+ not any(lcm_divides(f) for f in C)
+ and
+ not any(lcm_divides(f) for f in D)
+ ):
+ D.add((h, g))
E = set()
- while D != set():
- (h,g) = D.pop()
- if not R.monomial_pairwise_prime(LM(h),LM(g)):
- E.add( (h,g) )
+ while D:
+ (h, g) = D.pop()
+ if not R.monomial_pairwise_prime(LM(h), LM(g)):
+ E.add((h, g))
B_new = set()
- while B != set():
- g1,g2 = B.pop()
- if not R.monomial_divides( LM(h), LCM(LM(g1),LM(g2)) ) or \
- R.monomial_lcm(LM(g1),LM( h)) == LCM(LM(g1),LM(g2)) or \
- R.monomial_lcm(LM( h),LM(g2)) == LCM(LM(g1),LM(g2)) :
- B_new.add( (g1,g2) )
+ while B:
+ g1, g2 = B.pop()
+ if not R.monomial_divides(LM(h), LCM(LM(g1), LM(g2))) or \
+ R.monomial_lcm(LM(g1), LM(h)) == LCM(LM(g1), LM(g2)) or \
+ R.monomial_lcm(LM(h), LM(g2)) == LCM(LM(g1), LM(g2)):
+ B_new.add((g1, g2))
- B_new = B_new.union( E )
+ B_new = B_new.union(E)
G_new = set()
- while G != set():
+ while G:
g = G.pop()
if not R.monomial_divides(LM(h), LM(g)):
G_new.add(g)
G_new.add(h)
- return G_new,B_new
+ return G_new, B_new
+
def select(P):
"""
- The normal selection strategy
+ Select a polynomial using the normal selection strategy.
INPUT:
- - ``P`` - a list of critical pairs
+ - ``P`` -- a list of critical pairs
OUTPUT:
@@ -380,18 +386,21 @@ def select(P):
EXAMPLES::
sage: from sage.rings.polynomial.toy_buchberger import select
- sage: R. = PolynomialRing(QQ,3, order='lex')
+ sage: R. = PolynomialRing(QQ, order='lex')
sage: ps = [x^3 - z -1, z^3 - y - 1, x^5 - y - 2]
- sage: pairs = [[ps[i],ps[j]] for i in range(3) for j in range(i+1,3)]
+ sage: pairs = [[ps[i], ps[j]] for i in range(3) for j in range(i+1, 3)]
sage: select(pairs)
[x^3 - z - 1, -y + z^3 - 1]
"""
- return min(P, key=lambda fi_fj: LCM(LM(fi_fj[0]), LM(fi_fj[1])).total_degree())
+ return min(P, key=lambda fi_fj: LCM(LM(fi_fj[0]),
+ LM(fi_fj[1])).total_degree())
def inter_reduction(Q):
r"""
- If ``Q`` is the set `(f_1, ..., f_n)` this method
+ Compute inter-reduced polynomials from a set of polynomials.
+
+ If ``Q`` is the set `(f_1, ..., f_n)`, this method
returns `(g_1, ..., g_s)` such that:
- ` = `
@@ -413,14 +422,14 @@ def inter_reduction(Q):
::
sage: P. = QQ[]
- sage: reduced = inter_reduction(set([x^2-5*y^2,x^3]))
+ sage: reduced = inter_reduction(set([x^2-5*y^2, x^3]))
sage: reduced == set([x*y^2, x^2-5*y^2])
True
- sage: reduced == inter_reduction(set([2*(x^2-5*y^2),x^3]))
+ sage: reduced == inter_reduction(set([2*(x^2-5*y^2), x^3]))
True
"""
if not Q:
- return Q # if Q is empty we cannot get a base ring
+ return Q # if Q is empty we cannot get a base ring
base_ring = next(iter(Q)).base_ring()
Q = set(Q)
@@ -429,9 +438,10 @@ def inter_reduction(Q):
for p in sorted(Qbar):
Q.remove(p)
h = p.reduce(Q)
- if h!=0:
+ if h != 0:
Q.add(h)
if Qbar == Q:
if base_ring.is_field():
- return set([f.lc()**(-1) * f for f in Qbar])
- else: return Qbar
+ return set(f.lc()**(-1) * f for f in Qbar)
+ else:
+ return Qbar