Path: blob/master/src/sage/libs/singular/groebner_strategy.pyx
8815 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 *: # hack to get at cython macro20int 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)171if self._parent_ring:172singular_ring_delete(self._parent_ring)173174def _repr_(self):175"""176TEST::177178sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy179sage: P.<x,y,z> = PolynomialRing(GF(32003))180sage: I = Ideal([x + z, y + z])181sage: strat = GroebnerStrategy(I)182sage: strat # indirect doctest183Groebner Strategy for ideal generated by 2 elements over184Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003185"""186return "Groebner Strategy for ideal generated by %d elements over %s"%(self._ideal.ngens(),self._parent)187188def ideal(self):189"""190Return the ideal this strategy object is defined for.191192EXAMPLE::193194sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy195sage: P.<x,y,z> = PolynomialRing(GF(32003))196sage: I = Ideal([x + z, y + z])197sage: strat = GroebnerStrategy(I)198sage: strat.ideal()199Ideal (x + z, y + z) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003200"""201return self._ideal202203def ring(self):204"""205Return the ring this strategy object is defined over.206207EXAMPLE::208209sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy210sage: P.<x,y,z> = PolynomialRing(GF(32003))211sage: I = Ideal([x + z, y + z])212sage: strat = GroebnerStrategy(I)213sage: strat.ring()214Multivariate Polynomial Ring in x, y, z over Finite Field of size 32003215"""216return self._parent217218def __cmp__(self, other):219"""220EXAMPLE::221222sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy223sage: P.<x,y,z> = PolynomialRing(GF(19))224sage: I = Ideal([P(0)])225sage: strat = GroebnerStrategy(I)226sage: strat == GroebnerStrategy(I)227True228sage: I = Ideal([x+1,y+z])229sage: strat == GroebnerStrategy(I)230False231"""232if not isinstance(other, GroebnerStrategy):233return cmp(type(self),other(type))234else:235return cmp(self._ideal.gens(),(<GroebnerStrategy>other)._ideal.gens())236237def __reduce__(self):238"""239EXAMPLE::240241sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy242sage: P.<x,y,z> = PolynomialRing(GF(32003))243sage: I = Ideal([x + z, y + z])244sage: strat = GroebnerStrategy(I)245sage: loads(dumps(strat)) == strat246True247"""248return unpickle_GroebnerStrategy0, (self._ideal,)249250cpdef MPolynomial_libsingular normal_form(self, MPolynomial_libsingular p):251"""252Compute the normal form of ``p`` with respect to the253generators of this object.254255EXAMPLE::256257sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy258sage: P.<x,y,z> = PolynomialRing(QQ)259sage: I = Ideal([x + z, y + z])260sage: strat = GroebnerStrategy(I)261sage: strat.normal_form(x*y) # indirect doctest262z^2263sage: strat.normal_form(x + 1)264-z + 1265266TESTS::267268sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy269sage: P.<x,y,z> = PolynomialRing(QQ)270sage: I = Ideal([P(0)])271sage: strat = GroebnerStrategy(I)272sage: strat.normal_form(x)273x274sage: strat.normal_form(P(0))2750276"""277if unlikely(p._parent is not self._parent):278raise TypeError("parent(p) must be the same as this object's parent.")279if unlikely(self._parent._ring != currRing):280rChangeCurrRing(self._parent._ring)281282cdef int max_ind283cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat)284if likely(_p!=NULL):285_p = redtailBba(_p, max_ind, self._strat)286return new_MP(self._parent, _p)287288cdef class NCGroebnerStrategy(SageObject):289"""290A Wrapper for Singular's Groebner Strategy Object.291292This object provides functions for normal form computations and293other functions for Groebner basis computation.294295ALGORITHM:296297Uses Singular via libSINGULAR298"""299def __init__(self, L):300"""301Create a new :class:`GroebnerStrategy` object for the302generators of the ideal ``L``.303304INPUT:305306- ``L`` - an ideal in a g-algebra307308EXAMPLES::309310sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy311sage: A.<x,y,z> = FreeAlgebra(QQ, 3)312sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})313sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])314sage: NCGroebnerStrategy(I)315Groebner 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}316317TESTS::318319sage: strat = NCGroebnerStrategy(None)320Traceback (most recent call last):321...322TypeError: First parameter must be an ideal in a g-algebra.323324sage: P.<x,y,z> = PolynomialRing(CC,order='neglex')325sage: I = Ideal([x+z,y+z+1])326sage: strat = NCGroebnerStrategy(I)327Traceback (most recent call last):328...329TypeError: First parameter must be an ideal in a g-algebra.330331"""332if not isinstance(L, NCPolynomialIdeal):333raise TypeError("First parameter must be an ideal in a g-algebra.")334335if not isinstance(L.ring(), NCPolynomialRing_plural):336raise TypeError("First parameter's ring must be a g-algebra.")337338self._ideal = L339340cdef NCPolynomialRing_plural R = <NCPolynomialRing_plural>L.ring()341self._parent = R342343if not R.term_order().is_global():344raise NotImplementedError("The local case is not implemented yet.")345346if not R.base_ring().is_field():347raise NotImplementedError("Only coefficient fields are implemented so far.")348349if (R._ring != currRing):350rChangeCurrRing(R._ring)351352cdef ideal *i = sage_ideal_to_singular_ideal(L)353self._strat = new_skStrategy()354355self._strat.ak = idRankFreeModule(i, R._ring)356#- creating temp data structures357initBuchMoraCrit(self._strat)358self._strat.initEcart = initEcartBBA359self._strat.enterS = enterSBba360#- set S361self._strat.sl = -1362#- init local data struct363initS(i, NULL, self._strat)364365cdef int j366if R.base_ring().is_field():367for j in range(self._strat.sl+1)[::-1]:368pNorm(self._strat.S[j])369370id_Delete(&i, R._ring)371kTest(self._strat)372373def __dealloc__(self):374"""375TEST::376377sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy378sage: A.<x,y,z> = FreeAlgebra(QQ, 3)379sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})380sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])381sage: strat = NCGroebnerStrategy(I)382sage: del strat # indirect doctest383"""384cdef ring *oldRing = NULL385if self._strat:386omfree(self._strat.sevS)387omfree(self._strat.ecartS)388omfree(self._strat.T)389omfree(self._strat.sevT)390omfree(self._strat.R)391omfree(self._strat.S_2_R)392omfree(self._strat.L)393omfree(self._strat.B)394omfree(self._strat.fromQ)395id_Delete(&self._strat.Shdl, self._parent._ring)396397if self._parent._ring != currRing:398oldRing = currRing399rChangeCurrRing(self._parent._ring)400delete_skStrategy(self._strat)401rChangeCurrRing(oldRing)402else:403delete_skStrategy(self._strat)404405def _repr_(self):406"""407TEST::408409sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy410sage: A.<x,y,z> = FreeAlgebra(QQ, 3)411sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})412sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])413sage: strat = NCGroebnerStrategy(I)414sage: strat # indirect doctest415Groebner 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}416"""417return "Groebner Strategy for ideal generated by %d elements over %s"%(self._ideal.ngens(),self._parent)418419def ideal(self):420"""421Return the ideal this strategy object is defined for.422423EXAMPLE::424425sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy426sage: A.<x,y,z> = FreeAlgebra(QQ, 3)427sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})428sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])429sage: strat = NCGroebnerStrategy(I)430sage: strat.ideal() == I431True432433"""434return self._ideal435436def ring(self):437"""438Return the ring this strategy object is defined over.439440EXAMPLE::441442sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy443sage: A.<x,y,z> = FreeAlgebra(QQ, 3)444sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})445sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])446sage: strat = NCGroebnerStrategy(I)447sage: strat.ring() is H448True449"""450return self._parent451452def __cmp__(self, other):453"""454EXAMPLE::455456sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy457sage: A.<x,y,z> = FreeAlgebra(QQ, 3)458sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})459sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])460sage: strat = NCGroebnerStrategy(I)461sage: strat == NCGroebnerStrategy(I)462True463sage: I = H.ideal([y^2, x^2, z^2-H.one_element()], side='twosided')464sage: strat == NCGroebnerStrategy(I)465False466"""467if not isinstance(other, NCGroebnerStrategy):468return cmp(type(self),other(type))469else:470return cmp((self._ideal.gens(),self._ideal.side()),471((<NCGroebnerStrategy>other)._ideal.gens(),472(<NCGroebnerStrategy>other)._ideal.side()))473474def __reduce__(self):475"""476EXAMPLE::477478sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy479sage: A.<x,y,z> = FreeAlgebra(QQ, 3)480sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})481sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])482sage: strat = NCGroebnerStrategy(I)483sage: loads(dumps(strat)) == strat484True485"""486return unpickle_NCGroebnerStrategy0, (self._ideal,)487488cpdef NCPolynomial_plural normal_form(self, NCPolynomial_plural p):489"""490Compute the normal form of ``p`` with respect to the491generators of this object.492493EXAMPLE::494495sage: A.<x,y,z> = FreeAlgebra(QQ, 3)496sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})497sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])498sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')499sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy500sage: SL = NCGroebnerStrategy(JL.std())501sage: ST = NCGroebnerStrategy(JT.std())502sage: SL.normal_form(x*y^2)503x*y^2504sage: ST.normal_form(x*y^2)505y*z506507"""508if unlikely(p._parent is not self._parent):509raise TypeError("parent(p) must be the same as this object's parent.")510if unlikely(self._parent._ring != currRing):511rChangeCurrRing(self._parent._ring)512513cdef int max_ind514cdef poly *_p = redNF(p_Copy(p._poly, self._parent._ring), max_ind, 0, self._strat)515if likely(_p!=NULL):516_p = redtailBba(_p, max_ind, self._strat)517return new_NCP(self._parent, _p)518519def unpickle_NCGroebnerStrategy0(I):520"""521EXAMPLE::522523sage: from sage.libs.singular.groebner_strategy import NCGroebnerStrategy524sage: A.<x,y,z> = FreeAlgebra(QQ, 3)525sage: H.<x,y,z> = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})526sage: I = H.ideal([y^2, x^2, z^2-H.one_element()])527sage: strat = NCGroebnerStrategy(I)528sage: loads(dumps(strat)) == strat # indirect doctest529True530"""531return NCGroebnerStrategy(I)532533def unpickle_GroebnerStrategy0(I):534"""535EXAMPLE::536537sage: from sage.libs.singular.groebner_strategy import GroebnerStrategy538sage: P.<x,y,z> = PolynomialRing(GF(32003))539sage: I = Ideal([x + z, y + z])540sage: strat = GroebnerStrategy(I)541sage: loads(dumps(strat)) == strat # indirect doctest542True543"""544return GroebnerStrategy(I)545546547