Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Educational version of the `d`-Groebner Basis Algorithm over PIDs.
No attempt was made to optimize this algorithm as the emphasis of this implementation is a clean and easy presentation.
.. NOTE::
The notion of 'term' and 'monomial' in [BW93]_ is swapped from the notion of those words in Sage (or the other way around, however you prefer it). In Sage a term is a monomial multiplied by a coefficient, while in [BW93]_ a monomial is a term multiplied by a coefficient. Also, what is called LM (the leading monomial) in Sage is called HT (the head term) in [BW93]_.
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import d_basis
First, consider an example from arithmetic geometry::
sage: A.<x,y> = PolynomialRing(ZZ, 2) sage: B.<X,Y> = PolynomialRing(Rationals(),2) sage: f = -y^2 - y + x^3 + 7*x + 1 sage: fx = f.derivative(x) sage: fy = f.derivative(y) sage: I = B.ideal([B(f),B(fx),B(fy)]) sage: I.groebner_basis() [1]
Since the output is 1, we know that there are no generic singularities.
To look at the singularities of the arithmetic surface, we need to do the corresponding computation over `\ZZ`::
sage: I = A.ideal([f,fx,fy]) sage: gb = d_basis(I); gb [x - 2020, y - 11313, 22627]
sage: gb[-1].factor() 11^3 * 17
This Groebner Basis gives a lot of information. First, the only fibers (over `\ZZ`) that are not smooth are at 11 = 0, and 17 = 0. Examining the Groebner Basis, we see that we have a simple node in both the fiber at 11 and at 17. From the factorization, we see that the node at 17 is regular on the surface (an `I_1` node), but the node at 11 is not. After blowing up this non-regular point, we find that it is an `I_3` node.
Another example. This one is from the Magma Handbook::
sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex') sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z) sage: I = Ideal(d_basis(I)) sage: x.reduce(I) x sage: (2*x).reduce(I) y*z
To compute modulo 4, we can add the generator 4 to our basis.::
sage: I = ideal( x^2 - 1, y^2 - 1, 2*x*y - z, 4) sage: gb = d_basis(I) sage: R = P.change_ring(IntegerModRing(4)) sage: gb = [R(f) for f in gb if R(f)]; gb [x^2 - 1, x*z + 2*y, 2*x - y*z, y^2 - 1, z^2, 2*z]
A third example is also from the Magma Handbook.
This example shows how one can use Groebner bases over the integers 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(IntegerRing(), 3, order='degneglex') sage: I = ideal( x^2 - 3*y, y^3 - x*y, z^3 - x, x^4 - y*z + 1 ) sage: I.change_ring(P.change_ring(RationalField())).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: gb = d_basis(I); gb [z - 107196348594952664476180297953816049406949517534824683390654620424703403993052759002989622, y + 84382748470495086324437828161121754084154498572003307352857967748090984550697850484197972764799434672877850291328840, x + 105754645239745824529618668609551113725317621921665293762587811716173, 282687803443]
Now for each prime `p` dividing this integer 282687803443, 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(282687803443) 101 * 103 * 27173681
sage: I.change_ring( P.change_ring( GF(101) ) ).groebner_basis() [z - 33, y + 48, x + 19]
sage: I.change_ring( P.change_ring( GF(103) ) ).groebner_basis() [z - 18, y + 8, x + 39]
sage: I.change_ring( P.change_ring( GF(27173681) ) ).groebner_basis() [z + 10380032, y + 3186055, x - 536027]
Of course, 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]
AUTHOR:
- Martin Albrecht (2008-08): initial version """ from sage.rings.integer_ring import ZZ from sage.arith.all import xgcd, lcm, gcd from sage.rings.polynomial.toy_buchberger import inter_reduction from sage.structure.sequence import Sequence
def spol(g1, g2): """ Return S-Polynomial of ``g_1`` and ``g_2``.
Let `a_i t_i` be `LT(g_i)`, `b_i = a/a_i` with `a = LCM(a_i,a_j)`, and `s_i = t/t_i` with `t = LCM(t_i,t_j)`. Then the S-Polynomial is defined as: `b_1s_1g_1 - b_2s_2g_2`.
INPUT:
- ``g1`` - polynomial - ``g2`` - polynomial
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import spol sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex') sage: f = x^2 - 1 sage: g = 2*x*y - z sage: spol(f,g) x*z - 2*y """
def gpol(g1, g2): """ Return G-Polynomial of ``g_1`` and ``g_2``.
Let `a_i t_i` be `LT(g_i)`, `a = a_i*c_i + a_j*c_j` with `a = GCD(a_i,a_j)`, and `s_i = t/t_i` with `t = LCM(t_i,t_j)`. Then the G-Polynomial is defined as: `c_1s_1g_1 - c_2s_2g_2`.
INPUT:
- ``g1`` - polynomial - ``g2`` - polynomial
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import gpol sage: P.<x, y, z> = PolynomialRing(IntegerRing(), 3, order='lex') sage: f = x^2 - 1 sage: g = 2*x*y - z sage: gpol(f,g) x^2*y - y """
def d_basis(F, strat=True): r""" Return the `d`-basis for the Ideal ``F`` as defined in [BW93]_.
INPUT:
- ``F`` - an ideal - ``strat`` - use update strategy (default: ``True``)
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import d_basis sage: A.<x,y> = PolynomialRing(ZZ, 2) sage: f = -y^2 - y + x^3 + 7*x + 1 sage: fx = f.derivative(x) sage: fy = f.derivative(y) sage: I = A.ideal([f,fx,fy]) sage: gb = d_basis(I); gb [x - 2020, y - 11313, 22627] """
divides_ZZ( LC(g), LC(f1) ) and \ divides_ZZ( LC(g), LC(f2) ) \ for g in G): h0 *= -1 D = D.union( [(g,h0) for g in G] ) G.add(h0) else:
D = D.union( [(g,h0) for g in G] ) G.add( h0 ) else:
def select(P): """ The normal selection strategy.
INPUT:
- ``P`` - a list of critical pairs
OUTPUT: an element of P
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import select sage: A.<x,y> = PolynomialRing(ZZ, 2) sage: f = -y^2 - y + x^3 + 7*x + 1 sage: fx = f.derivative(x) sage: fy = f.derivative(y) sage: G = [f, fx, fy] sage: B = set((f1, f2) for f1 in G for f2 in G if f1 != f2) sage: select(B) (-2*y - 1, 3*x^2 + 7) """
def update(G, B, h): """ Update ``G`` using the list of critical pairs ``B`` and the polynomial ``h`` as presented in [BW93]_, page 230. For this, Buchberger's first and second criterion are tested.
This function uses the Gebauer-Moeller Installation.
INPUT:
- ``G`` - an intermediate Groebner basis - ``B`` - a list of critical pairs - ``h`` - a polynomial
OUTPUT: ``G,B`` where ``G`` and ``B`` are updated
EXAMPLES::
sage: from sage.rings.polynomial.toy_d_basis import update sage: A.<x,y> = PolynomialRing(ZZ, 2) sage: G = set([3*x^2 + 7, 2*y + 1, x^3 - y^2 + 7*x - y + 1]) sage: B = set([]) sage: h = x^2*y - x^2 + y - 3 sage: update(G,B,h) ({2*y + 1, 3*x^2 + 7, x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1}, {(x^2*y - x^2 + y - 3, 2*y + 1), (x^2*y - x^2 + y - 3, 3*x^2 + 7), (x^2*y - x^2 + y - 3, x^3 - y^2 + 7*x - y + 1)}) """
lcm(LC(h),LC(f[1])).divides(lcm(LC(h),LC(g1)))
(\ not any( lcm_divides(f,g1,h) for f in C ) \ and not any( lcm_divides(f,g1,h) for f in D ) \ ):
lcm(LC(g1),LC( h)) * R.monomial_lcm(LM(g1),LM( h)) == lcm_lg1_lg2 or \ lcm(LC( h),LC(g2)) * R.monomial_lcm(LM( h),LM(g2)) == lcm_lg1_lg2 :
|