Path: blob/master/sage/libs/singular/groebner_strategy.pyx
4085 views
"""1Singular's Groebner Strategy Objects23AUTHORS:45- Martin Albrecht (2009-07): initial implementation6- Michael Brickenstein (2009-07): initial implementation7- Hans Schoenemann (2009-07): initial implementation8"""910#*****************************************************************************11# Copyright (C) 2009 Martin Albrecht <[email protected]>12# Copyright (C) 2009 Michael Brickenstein <[email protected]>13# Copyright (C) 2009 Hans Schoenemann <[email protected]>14#15# Distributed under the terms of the GNU General Public License (GPL)16# http://www.gnu.org/licenses/17#*****************************************************************************1819cdef extern from "":20int unlikely(int)21int likely(int)2223from sage.libs.singular.decl cimport ideal, ring, poly, currRing24from sage.libs.singular.decl cimport rChangeCurrRing25from sage.libs.singular.decl cimport new_skStrategy, delete_skStrategy, idRankFreeModule26from sage.libs.singular.decl cimport initEcartBBA, enterSBba, initBuchMoraCrit, initS, pNorm, id_Delete, kTest27from sage.libs.singular.decl cimport omfree, redNF, p_Copy, redtailBba2829from sage.libs.singular.ring cimport singular_ring_reference, singular_ring_delete3031from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal, NCPolynomialIdeal32from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal33from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, MPolynomialRing_libsingular, new_MP34from sage.rings.polynomial.plural cimport new_NCP3536cdef class GroebnerStrategy(SageObject):37"""38A Wrapper for Singular's Groebner Strategy Object.3940This object provides functions for normal form computations and41other functions for Groebner basis computation.4243ALGORITHM:4445Uses Singular via libSINGULAR46"""47def __cinit__(self, L):48"""49Create a new :class:`GroebnerStrategy` object for the50generators of the ideal ``L``.5152INPUT:5354- ``L`` - a multivariate polynomial ideal5556EXAMPLES::5758sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy59sage: P.<x,y,z> = PolynomialRing(QQ)60sage: I = Ideal([x+z,y+z+1])61sage: strat = GroebnerStrategy(I); strat62Groebner Strategy for ideal generated by 2 elements63over Multivariate Polynomial Ring in x, y, z over Rational Field6465TESTS::6667sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy68sage: strat = GroebnerStrategy(None)69Traceback (most recent call last):70...71TypeError: First parameter must be a multivariate polynomial ideal.7273sage: P.<x,y,z> = PolynomialRing(QQ,order='neglex')74sage: I = Ideal([x+z,y+z+1])75sage: strat = GroebnerStrategy(I)76Traceback (most recent call last):77...78NotImplementedError: The local case is not implemented yet.7980sage: P.<x,y,z> = PolynomialRing(CC,order='neglex')81sage: I = Ideal([x+z,y+z+1])82sage: strat = GroebnerStrategy(I)83Traceback (most recent call last):84...85TypeError: First parameter's ring must be multivariate polynomial ring via libsingular.8687sage: P.<x,y,z> = PolynomialRing(ZZ)88sage: I = Ideal([x+z,y+z+1])89sage: strat = GroebnerStrategy(I)90Traceback (most recent call last):91...92NotImplementedError: Only coefficient fields are implemented so far.9394"""95if not isinstance(L, MPolynomialIdeal):96raise TypeError("First parameter must be a multivariate polynomial ideal.")9798if not isinstance(L.ring(), MPolynomialRing_libsingular):99raise TypeError("First parameter's ring must be multivariate polynomial ring via libsingular.")100101self._ideal = L102103cdef MPolynomialRing_libsingular R = <MPolynomialRing_libsingular>L.ring()104self._parent = R105self._parent_ring = singular_ring_reference(R._ring)106107if not R.term_order().is_global():108raise NotImplementedError("The local case is not implemented yet.")109110if not R.base_ring().is_field():111raise NotImplementedError("Only coefficient fields are implemented so far.")112113if (R._ring != currRing):114rChangeCurrRing(R._ring)115116cdef ideal *i = sage_ideal_to_singular_ideal(L)117self._strat = new_skStrategy()118119self._strat.ak = idRankFreeModule(i, R._ring)120#- creating temp data structures121initBuchMoraCrit(self._strat)122self._strat.initEcart = initEcartBBA123self._strat.enterS = enterSBba124#- set S125self._strat.sl = -1126#- init local data struct127initS(i, NULL, self._strat)128129cdef int j130cdef bint base_ring_is_field = R.base_ring().is_field()131if (R._ring != currRing): rChangeCurrRing(R._ring)132if base_ring_is_field:133for j in range(self._strat.sl+1)[::-1]:134pNorm(self._strat.S[j])135136id_Delete(&i, R._ring)137kTest(self._strat)138139def __dealloc__(self):140"""141TEST::142143sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy144sage: P.<x,y,z> = PolynomialRing(GF(32003))145sage: I = Ideal([x + z, y + z])146sage: strat = GroebnerStrategy(I)147sage: del strat148"""149# WARNING: the Cython class self._parent is no longer accessible!150# see http://trac.sagemath.org/sage_trac/ticket/11339151cdef ring *oldRing = NULL152if self._strat:153omfree(self._strat.sevS)154omfree(self._strat.ecartS)155omfree(self._strat.T)156omfree(self._strat.sevT)157omfree(self._strat.R)158omfree(self._strat.S_2_R)159omfree(self._strat.L)160omfree(self._strat.B)161omfree(self._strat.fromQ)162id_Delete(&self._strat.Shdl, self._parent_ring)163164if self._parent_ring != currRing:165oldRing = currRing166rChangeCurrRing(self._parent_ring)167delete_skStrategy(self._strat)168rChangeCurrRing(oldRing)169else:170delete_skStrategy(self._strat)171singular_ring_delete(self._parent_ring)172173def _repr_(self):174"""175TEST::176177sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy178sage: P.<x,y,z> = PolynomialRing(GF(32003))179sage: I = Ideal([x + z, y + z])180sage: strat = GroebnerStrategy(I)181sage: strat # indirect doctest182Groebner Strategy for ideal generated by 2 elements over183Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003184"""185return "Groebner Strategy for ideal generated by %d elements over %s"%(self._ideal.ngens(),self._parent)186187def ideal(self):188"""189Return the ideal this strategy object is defined for.190191EXAMPLE::192193sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy194sage: P.<x,y,z> = PolynomialRing(GF(32003))195sage: I = Ideal([x + z, y + z])196sage: strat = GroebnerStrategy(I)197sage: strat.ideal()198Ideal (x + z, y + z) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003199"""200return self._ideal201202def ring(self):203"""204Return the ring this strategy object is defined over.205206EXAMPLE::207208sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy209sage: P.<x,y,z> = PolynomialRing(GF(32003))210sage: I = Ideal([x + z, y + z])211sage: strat = GroebnerStrategy(I)212sage: strat.ring()213Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003214"""215return self._parent216217def __cmp__(self, other):218"""219EXAMPLE::220221sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy222sage: P.<x,y,z> = PolynomialRing(GF(19))223sage: I = Ideal([P(0)])224sage: strat = GroebnerStrategy(I)225sage: strat == GroebnerStrategy(I)226True227sage: I = Ideal([x+1,y+z])228sage: strat == GroebnerStrategy(I)229False230"""231if not isinstance(other, GroebnerStrategy):232return cmp(type(self),other(type))233else:234return cmp(self._ideal.gens(),(<GroebnerStrategy>other)._ideal.gens())235236def __reduce__(self):237"""238EXAMPLE::239240sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy241sage: P.<x,y,z> = PolynomialRing(GF(32003))242sage: I = Ideal([x + z, y + z])243sage: strat = GroebnerStrategy(I)244sage: loads(dumps(strat)) == strat245True246"""247return unpickle_GroebnerStrategy0, (self._ideal,)248249cpdef MPolynomial_libsingular normal_form(self, MPolynomial_libsingular p):250"""251Compute the normal form of ``p`` with respect to the252generators of this object.253254EXAMPLE::255256sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy257sage: P.<x,y,z> = PolynomialRing(QQ)258sage: I = Ideal([x + z, y + z])259sage: strat = GroebnerStrategy(I)260sage: strat.normal_form(x*y) # indirect doctest261z^2262sage: strat.normal_form(x + 1)263-z + 1264265TESTS::266267sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy268sage: P.<x,y,z> = PolynomialRing(QQ)269sage: I = Ideal([P(0)])270sage: strat = GroebnerStrategy(I)271sage: strat.normal_form(x)272x273sage: strat.normal_form(P(0))2740275"""276if unlikely(p._parent is not self._parent):277raise TypeError("parent(p) must be the same as this object's parent.")278if unlikely(self._parent._ring != currRing):279rChangeCurrRing(self._parent._ring)280281cdef int max_ind282cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat)283if likely(_p!=NULL):284_p = redtailBba(_p, max_ind, self._strat)285return new_MP(self._parent, _p)286287cdef class NCGroebnerStrategy(SageObject):288"""289A Wrapper for Singular's Groebner Strategy Object.290291This object provides functions for normal form computations and292other functions for Groebner basis computation.293294ALGORITHM:295296Uses Singular via libSINGULAR297"""298def __init__(self, L):299"""300Create a new :class:`GroebnerStrategy` object for the301generators of the ideal ``L``.302303INPUT:304305- ``L`` - an ideal in a g-algebra306307EXAMPLES::308309sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy310sage: A.<x,y,z> = FreeAlgebra(QQ, 3)311sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})312sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])313sage: NCGroebnerStrategy(I)314Groebner Strategy for ideal generated by 3 elements over Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}315316TESTS::317318sage: strat = NCGroebnerStrategy(None)319Traceback (most recent call last):320...321TypeError: First parameter must be an ideal in a g-algebra.322323sage: P.<x,y,z> = PolynomialRing(CC,order='neglex')324sage: I = Ideal([x+z,y+z+1])325sage: strat = NCGroebnerStrategy(I)326Traceback (most recent call last):327...328TypeError: First parameter must be an ideal in a g-algebra.329330"""331if not isinstance(L, NCPolynomialIdeal):332raise TypeError("First parameter must be an ideal in a g-algebra.")333334if not isinstance(L.ring(), NCPolynomialRing_plural):335raise TypeError("First parameter's ring must be a g-algebra.")336337self._ideal = L338339cdef NCPolynomialRing_plural R = <NCPolynomialRing_plural>L.ring()340self._parent = R341342if not R.term_order().is_global():343raise NotImplementedError("The local case is not implemented yet.")344345if not R.base_ring().is_field():346raise NotImplementedError("Only coefficient fields are implemented so far.")347348if (R._ring != currRing):349rChangeCurrRing(R._ring)350351cdef ideal *i = sage_ideal_to_singular_ideal(L)352self._strat = new_skStrategy()353354self._strat.ak = idRankFreeModule(i, R._ring)355#- creating temp data structures356initBuchMoraCrit(self._strat)357self._strat.initEcart = initEcartBBA358self._strat.enterS = enterSBba359#- set S360self._strat.sl = -1361#- init local data struct362initS(i, NULL, self._strat)363364cdef int j365if R.base_ring().is_field():366for j in range(self._strat.sl+1)[::-1]:367pNorm(self._strat.S[j])368369id_Delete(&i, R._ring)370kTest(self._strat)371372def __dealloc__(self):373"""374TEST::375376sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy377sage: A.<x,y,z> = FreeAlgebra(QQ, 3)378sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})379sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])380sage: strat = NCGroebnerStrategy(I)381sage: del strat # indirect doctest382"""383cdef ring *oldRing = NULL384if self._strat:385omfree(self._strat.sevS)386omfree(self._strat.ecartS)387omfree(self._strat.T)388omfree(self._strat.sevT)389omfree(self._strat.R)390omfree(self._strat.S_2_R)391omfree(self._strat.L)392omfree(self._strat.B)393omfree(self._strat.fromQ)394id_Delete(&self._strat.Shdl, self._parent._ring)395396if self._parent._ring != currRing:397oldRing = currRing398rChangeCurrRing(self._parent._ring)399delete_skStrategy(self._strat)400rChangeCurrRing(oldRing)401else:402delete_skStrategy(self._strat)403404def _repr_(self):405"""406TEST::407408sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy409sage: A.<x,y,z> = FreeAlgebra(QQ, 3)410sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})411sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])412sage: strat = NCGroebnerStrategy(I)413sage: strat # indirect doctest414Groebner Strategy for ideal generated by 3 elements over Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}415"""416return "Groebner Strategy for ideal generated by %d elements over %s"%(self._ideal.ngens(),self._parent)417418def ideal(self):419"""420Return the ideal this strategy object is defined for.421422EXAMPLE::423424sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy425sage: A.<x,y,z> = FreeAlgebra(QQ, 3)426sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})427sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])428sage: strat = NCGroebnerStrategy(I)429sage: strat.ideal() == I430True431432"""433return self._ideal434435def ring(self):436"""437Return the ring this strategy object is defined over.438439EXAMPLE::440441sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy442sage: A.<x,y,z> = FreeAlgebra(QQ, 3)443sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})444sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])445sage: strat = NCGroebnerStrategy(I)446sage: strat.ring() is H447True448"""449return self._parent450451def __cmp__(self, other):452"""453EXAMPLE::454455sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy456sage: A.<x,y,z> = FreeAlgebra(QQ, 3)457sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})458sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])459sage: strat = NCGroebnerStrategy(I)460sage: strat == NCGroebnerStrategy(I)461True462sage: I = H.ideal([y^2, x^2, z^2-H.one_element()], side='twosided')463sage: strat == NCGroebnerStrategy(I)464False465"""466if not isinstance(other, NCGroebnerStrategy):467return cmp(type(self),other(type))468else:469return cmp((self._ideal.gens(),self._ideal.side()),470((<NCGroebnerStrategy>other)._ideal.gens(),471(<NCGroebnerStrategy>other)._ideal.side()))472473def __reduce__(self):474"""475EXAMPLE::476477sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy478sage: A.<x,y,z> = FreeAlgebra(QQ, 3)479sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})480sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])481sage: strat = NCGroebnerStrategy(I)482sage: loads(dumps(strat)) == strat483True484"""485return unpickle_NCGroebnerStrategy0, (self._ideal,)486487cpdef NCPolynomial_plural normal_form(self, NCPolynomial_plural p):488"""489Compute the normal form of ``p`` with respect to the490generators of this object.491492EXAMPLE::493494sage: A.<x,y,z> = FreeAlgebra(QQ, 3)495sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})496sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])497sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')498sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy499sage: SL = NCGroebnerStrategy(JL.std())500sage: ST = NCGroebnerStrategy(JT.std())501sage: SL.normal_form(x*y^2)502x*y^2503sage: ST.normal_form(x*y^2)504y*z505506"""507if unlikely(p._parent is not self._parent):508raise TypeError("parent(p) must be the same as this object's parent.")509if unlikely(self._parent._ring != currRing):510rChangeCurrRing(self._parent._ring)511512cdef int max_ind513cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat)514if likely(_p!=NULL):515_p = redtailBba(_p, max_ind, self._strat)516return new_NCP(self._parent, _p)517518def unpickle_NCGroebnerStrategy0(I):519"""520EXAMPLE::521522sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy523sage: A.<x,y,z> = FreeAlgebra(QQ, 3)524sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})525sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])526sage: strat = NCGroebnerStrategy(I)527sage: loads(dumps(strat)) == strat # indirect doctest528True529"""530return NCGroebnerStrategy(I)531532def unpickle_GroebnerStrategy0(I):533"""534EXAMPLE::535536sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy537sage: P.<x,y,z> = PolynomialRing(GF(32003))538sage: I = Ideal([x + z, y + z])539sage: strat = GroebnerStrategy(I)540sage: loads(dumps(strat)) == strat # indirect doctest541True542"""543return GroebnerStrategy(I)544545546