Ticket #1952: mpolynomial_ideal_refactor.patch

File mpolynomial_ideal_refactor.patch, 38.1 kB (added by malb, 5 months ago)
  • a/sage/crypto/mq/mpolynomialsystem.py

    old new  
    645645            sage: P = F.ring() 
    646646            sage: I = F.ideal() 
    647647            sage: I.elimination_ideal(P('s000*s001*s002*s003*w100*w101*w102*w103*x100*x101*x102*x103')) 
    648             Ideal (k002 + (a^2)*k003 + 1, (a^3)*k001 + (a^3 + a^2)*k003 +  
    649             (a^3 + a + 1), k000 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a),  
    650             (a^2)*k103 + (a^2 + a)*k003 + (a^2 + a + 1), (a^3)*k102 +  
    651             (a^3 + 1)*k003 + (a^2), (a^3)*k101 + (a^3)*k003 + (a^2 + 1),  
    652             (a^3)*k100 + (a^2 + a)*k003 + (a^2 + 1), k003^2 +  
    653             (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a)) of Multivariate  
    654             Polynomial Ring in k100, k101, k102, k103, x100, x101, x102,  
    655             x103, w100, w101, w102, w103, s000, s001, s002, s003,  
    656             k000, k001, k002, k003 over Finite Field in a of size 2^4 
     648            Ideal (k002 + (a^2)*k003 + 1,  
     649                   k001 + (a^3)*k003 + (a + 1), 
     650                   k000 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a),  
     651                   k103 + (a^3)*k003 + (a^2 + 1),  
     652                   k102 + (a^3 + a^2 + a)*k003 + (a^3 + 1),  
     653                   k101 + k003 + (a^2 + a),  
     654                   k100 + (a^2)*k003 + (a^2 + a),  
     655                   k003^2 + (a^3 + a^2 + a)*k003 + (a^3 + a^2 + a))  
     656            of Multivariate Polynomial Ring in k100, k101, k102, k103, 
     657            x100, x101, x102, x103, w100, w101, w102, w103, s000, 
     658            s001, s002, s003, k000, k001, k002, k003 over Finite Field 
     659            in a of size 2^4 
     660 
    657661        """ 
    658662        return self._ring.ideal(self.gens()) 
    659663 
  • a/sage/rings/polynomial/multi_polynomial_ideal.py

    old new  
    1313    -- William Stein 
    1414    -- Kiran S. Kedlaya (2006-02-12): added Macaulay2 analogues of 
    1515              some \Singular features 
    16     -- Martin Albrecht 
     16    -- Martin Albrecht <malb@informatik.uni-bremen> (2008,2007): 
     17       refactoring, many Singular related functions 
    1718 
    1819EXAMPLES: 
    1920 
     
    121122 
    122123#***************************************************************************** 
    123124# 
    124 #   SAGE: System for Algebra and Geometry Experimentation     
     125#                               Sage 
    125126# 
    126127#       Copyright (C) 2005 William Stein <wstein@gmail.com> 
     128#       Copyright (C) 2008 Martin Albrecht <malb@informatik.uni-bremen.de> 
    127129# 
    128130#  Distributed under the terms of the GNU General Public License (GPL) 
    129131# 
     
    138140#***************************************************************************** 
    139141from __future__ import with_statement 
    140142 
    141 from sage.rings.ideal import Ideal_generic 
    142143from sage.interfaces.all import singular as singular_default 
    143144from sage.interfaces.all import macaulay2 as macaulay2_default 
    144 singular = singular_default 
     145 
     146from sage.rings.ideal import Ideal_generic 
    145147from sage.rings.integer import Integer 
    146148from sage.structure.sequence import Sequence 
     149 
     150from sage.misc.cachefunc import CachedFunction 
     151from sage.misc.misc import prod 
    147152from sage.misc.sage_eval import sage_eval 
    148 from sage.misc.misc import prod 
     153 
    149154import sage.rings.integer_ring 
    150155import sage.rings.polynomial.toy_buchberger as toy_buchberger 
    151156 
    152 def is_MPolynomialIdeal(x)
    153     r""" 
    154     Return \code{True} if the provided argument \var{x} is an ideal in 
    155     the multivariate polynomial ring
     157class RedSBContext
     158    """ 
     159    Within this context all \Singular Groebner basis calculations are 
     160    reduced automatically
    156161 
    157     INPUT: 
    158         x -- an arbitrary object 
    159  
    160     EXAMPLE: 
    161         sage: P.<x,y,z> = PolynomialRing(QQ) 
    162         sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y] 
    163  
    164     \SAGE distinguishes between a list of generators for an ideal and 
    165     the ideal itself. This distinction is inconsisten with \Singular 
    166     but matches \Magma's behavior. 
    167  
    168         sage: is_MPolynomialIdeal(I) 
    169         False 
    170  
    171         sage: I = Ideal(I) 
    172         sage: is_MPolynomialIdeal(I) 
    173         True 
     162    AUTHOR: 
     163        -- Martin Albrecht 
    174164    """ 
    175     return isinstance(x, MPolynomialIdeal) 
    176  
    177 class MPolynomialIdeal_magma_repr: 
    178     def _magma_(self, magma=None): 
    179         r""" 
    180         Returns a \MAGMA ideal matching this ideal if the base ring is 
    181         coercable to \MAGMA and \MAGMA is available. 
    182  
    183         INPUT: 
    184             magma -- \MAGMA instance or None (default instance) 
    185                      (default: None) 
    186  
    187         EXAMPLES: 
    188             sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
    189             sage: I = sage.rings.ideal.Cyclic(R,4) 
    190             sage: I._magma_() #optional MAGMA 
    191             Ideal of Polynomial ring of rank 10 over GF(127) 
    192             Graded Reverse Lexicographical Order 
    193             Variables: a, b, c, d, e, f, g, h, i, j 
    194             Basis: 
    195             [ 
    196             a + b + c + d, 
    197             a*b + b*c + a*d + c*d, 
    198             a*b*c + a*b*d + a*c*d + b*c*d, 
    199             a*b*c*d + 126 
    200             ] 
    201         """ 
    202         if magma == None: 
    203             import sage.interfaces.magma 
    204             magma = sage.interfaces.magma.magma 
    205         return magma.ideal(self.gens()) 
    206  
    207     def _magma_groebner_basis(self, magma=None): 
    208         r""" 
    209         Computes a Groebner Basis for self using \MAGMA if available. 
    210  
    211         INPUT: 
    212             magma -- \MAGMA instance or None (default instance) 
    213                      (default: None) 
    214         EXAMPLES: 
    215             sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
    216             sage: I = sage.rings.ideal.Cyclic(R,6) 
    217             sage: gb = I.groebner_basis('magma:GroebnerBasis') #optional MAGMA, indirect doctest 
    218             sage: len(gb) #optional MAGMA 
    219             45 
    220         """ 
    221         try: 
    222             return self.__magma_groebner_basis 
    223         except AttributeError: 
    224             pass 
    225         R = self.ring() 
    226         mgb = self._magma_(magma=magma).GroebnerBasis() 
    227         mgb = [str(mgb[i+1]) for i in range(len(mgb))] 
    228         if R.base_ring().degree() > 1: 
    229             a = str(R.base_ring().gen()) 
    230             mgb = [e.replace("$.1",a) for e in mgb] 
    231         B = Sequence([R(e) for e in mgb], R, check=False, immutable=True) 
    232         self.__magma_groebner_basis = B 
    233         return B 
    234  
    235 class RedSBContext: 
    236165    def __init__(self, singular=singular_default): 
    237166        r""" 
    238167        Within this context all \Singular Groebner basis calculations 
     
    291220            7*b+210*c^3-79*c^2+3*c, 
    292221            7*a-420*c^3+158*c^2+8*c-7 
    293222        """ 
    294         self.o = singular.option("get") 
     223        self.o = self.singular.option("get") 
    295224        self.singular.option("redSB") 
    296225 
    297226    def __exit__(self, typ, value, tb): 
     
    327256    wrapper.__doc__=func.__doc__ 
    328257    return wrapper 
    329258 
     259class cached(CachedFunction): 
     260    r"""  
     261    Specialised \code{CachedFunction} for the application in 
     262    multivariate polynomial ideals. 
     263 
     264    AUTHOR: 
     265        -- Martin Albrecht 
     266    """ 
     267    def __call__(self, *args, **kwds): 
     268        """ 
     269        EXAMPLES: 
     270            sage: P = PolynomialRing(GF(32003),4,'x') 
     271            sage: I = sage.rings.ideal.Katsura(P) 
     272            sage: I.groebner_basis.clear_cache() 
     273            sage: gb = I.groebner_basis() # indirect doctest 
     274            sage: I.groebner_basis.cache 
     275            {(Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 32003,  
     276            (x0 + 2*x1 + 2*x2 + 2*x3 - 1,  
     277            x1^2 + 2*x0*x2 + 2*x1*x3 - x2,  
     278            2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1,  
     279            x0^2 + 2*x1^2 + 2*x2^2 + 2*x3^2 - x0),  
     280            (),  
     281            ()):  
     282            [x0 + 2*x1 + 2*x2 + 2*x3 - 1,  
     283            x2^2 + 2*x1*x3 - 13711*x2*x3 - 4568*x3^2 - 4572*x1 + 13715*x2 - 9145*x3,  
     284            x1*x2 - 2*x1*x3 - 9147*x2*x3 - 13719*x3^2 + 2286*x1 + 9144*x2 + 4573*x3,  
     285            x1^2 + 2*x1*x3 + 4573*x2*x3 - 9142*x3^2 - 9144*x1 - 4572*x2 + 13715*x3,  
     286            x2*x3^2 + 3557*x3^3 - 1778*x1*x3 - 3161*x2*x3 + 5926*x3^2 - 10075*x1 - 6124*x2 + 11853*x3, x1*x3^2 - 10668*x3^3 - 3556*x1*x3 - 10075*x2*x3 + 3556*x3^2 - 889*x1 - 11853*x2,  
     287            x3^4 + 12535*x3^3 + 7471*x1*x3 + 6188*x2*x3 + 10117*x3^2 + 10521*x1 + 11393*x2 + 11829*x3]} 
     288        """ 
     289        from sage.rings.polynomial.multi_polynomial_ring_generic import is_MPolynomialRing 
     290        k = self.gen_key(*args, **kwds) 
     291        if self.cache.has_key(k) and "nocache" not in kwds: 
     292            return self.cache[k] 
     293 
     294        w = self.f(self.instance, *args, **kwds) 
     295        if is_MPolynomialRing(self.instance.ring()): 
     296            self.cache[k] = w 
     297        return w 
     298 
     299    def clear_cache(self): 
     300        """ 
     301        Clear the cache. 
     302 
     303        EXAMPLE: 
     304            sage: P = PolynomialRing(GF(32003),4,'x') 
     305            sage: I = sage.rings.ideal.Katsura(P) 
     306            sage: I.groebner_basis.clear_cache() 
     307            sage: I.groebner_basis.cache 
     308            {} 
     309            sage: gb = I.groebner_basis() # indirect doctest 
     310            sage: len(I.groebner_basis.cache) 
     311            1 
     312            sage: I.groebner_basis.clear_cache() 
     313            sage: len(I.groebner_basis.cache) 
     314            0 
     315        """ 
     316        self.cache = {} 
     317 
     318    def gen_key(self, *args, **kwds):  
     319        """ 
     320        Generate a key to the cache. 
     321 
     322        EXAMPLE: 
     323            sage: P = PolynomialRing(GF(32003),4,'x') 
     324            sage: I = sage.rings.ideal.Katsura(P) 
     325            sage: I.groebner_basis.gen_key() 
     326            (Multivariate Polynomial Ring in x0, x1, x2, x3 over Finite Field of size 32003, 
     327            (x0 + 2*x1 + 2*x2 + 2*x3 - 1, 
     328            x1^2 + 2*x0*x2 + 2*x1*x3 - x2, 
     329            2*x0*x1 + 2*x1*x2 + 2*x2*x3 - x1, 
     330            x0^2 + 2*x1^2 + 2*x2^2 + 2*x3^2 - x0), 
     331            (), 
     332            ()) 
     333        """ 
     334        r = (self.instance.ring(), tuple(sorted(self.instance.gens())), args, tuple(kwds.iteritems())) 
     335        return r 
     336 
     337    def is_in_cache(self, *args, **kwds): 
     338        """ 
     339        Check whether key is already in cache. 
     340 
     341        EXAMPLE: 
     342            sage: P = PolynomialRing(GF(32003),3,'x') 
     343            sage: I = sage.rings.ideal.Katsura(P) 
     344            sage: I.groebner_basis.is_in_cache() 
     345            False 
     346            sage: gb = I.groebner_basis() 
     347            sage: I.groebner_basis.is_in_cache() 
     348            True 
     349        """ 
     350        return self.gen_key(*args, **kwds) in self.cache 
     351 
     352def is_MPolynomialIdeal(x): 
     353    r""" 
     354    Return \code{True} if the provided argument \var{x} is an ideal in 
     355    the multivariate polynomial ring. 
     356 
     357    INPUT: 
     358        x -- an arbitrary object 
     359 
     360    EXAMPLE: 
     361        sage: P.<x,y,z> = PolynomialRing(QQ) 
     362        sage: I = [x + 2*y + 2*z - 1, x^2 + 2*y^2 + 2*z^2 - x, 2*x*y + 2*y*z - y] 
     363 
     364    \SAGE distinguishes between a list of generators for an ideal and 
     365    the ideal itself. This distinction is inconsisten with \Singular 
     366    but matches \Magma's behavior. 
     367 
     368        sage: is_MPolynomialIdeal(I) 
     369        False 
     370 
     371        sage: I = Ideal(I) 
     372        sage: is_MPolynomialIdeal(I) 
     373        True 
     374    """ 
     375    return isinstance(x, MPolynomialIdeal) 
     376 
     377class MPolynomialIdeal_magma_repr: 
     378    def _magma_(self, magma=None): 
     379        r""" 
     380        Returns a \MAGMA ideal matching this ideal if the base ring is 
     381        coercable to \MAGMA and \MAGMA is available. 
     382 
     383        INPUT: 
     384            magma -- \MAGMA instance or None (default instance) 
     385                     (default: None) 
     386 
     387        EXAMPLES: 
     388            sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
     389            sage: I = sage.rings.ideal.Cyclic(R,4) 
     390            sage: I._magma_() #optional MAGMA 
     391            Ideal of Polynomial ring of rank 10 over GF(127) 
     392            Graded Reverse Lexicographical Order 
     393            Variables: a, b, c, d, e, f, g, h, i, j 
     394            Basis: 
     395            [ 
     396            a + b + c + d, 
     397            a*b + b*c + a*d + c*d, 
     398            a*b*c + a*b*d + a*c*d + b*c*d, 
     399            a*b*c*d + 126 
     400            ] 
     401        """ 
     402        if magma == None: 
     403            import sage.interfaces.magma 
     404            magma = sage.interfaces.magma.magma 
     405        return magma.ideal(self.gens()) 
     406 
     407    def _groebner_basis_magma(self, magma=None): 
     408        r""" 
     409        Computes a Groebner Basis for self using \MAGMA if available. 
     410 
     411        INPUT: 
     412            magma -- \MAGMA instance or None (default instance) 
     413                     (default: None) 
     414        EXAMPLES: 
     415            sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
     416            sage: I = sage.rings.ideal.Cyclic(R,6) 
     417            sage: gb = I.groebner_basis('magma:GroebnerBasis') #optional MAGMA, indirect doctest 
     418            sage: len(gb) #optional MAGMA 
     419            45 
     420        """ 
     421        R = self.ring() 
     422        mgb = self._magma_(magma=magma).GroebnerBasis() 
     423        mgb = [str(mgb[i+1]) for i in range(len(mgb))] 
     424        if R.base_ring().degree() > 1: 
     425            a = str(R.base_ring().gen()) 
     426            mgb = [e.replace("$.1",a) for e in mgb] 
     427        B = Sequence([R(e) for e in mgb], R, check=False, immutable=True) 
     428        return B 
     429 
    330430class MPolynomialIdeal_singular_repr: 
    331     """ 
     431    r""" 
    332432    An ideal in a multivariate polynomial ring, which has an 
    333433    underlying \Singular ring associated to it. 
    334434    """ 
    335     def __cmp__(self, other): 
    336         """ 
    337         EXAMPLE: 
    338             sage: R = PolynomialRing(QQ,'x,y,z') 
    339             sage: I = R.ideal() 
    340             sage: I == R.ideal() 
    341             True 
    342  
    343             sage: R = PolynomialRing(QQ, names=[]) 
    344             sage: R.ideal(0) == R.ideal(0) 
    345             True 
    346  
    347             sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens() 
    348             sage: I = (x^3 + y, y)*R 
    349             sage: J = (x^3 + y, y, y*x^3 + y^2)*R 
    350             sage: I == J 
    351             True 
    352         """ 
    353         l = self.groebner_basis() 
    354         r = other.groebner_basis() 
    355         return cmp(r,l) 
    356  
    357     def _singular_(self, singular=None): 
     435    def _singular_(self, singular=singular_default): 
    358436        r""" 
    359437        Return \Singular ideal corresponding to this ideal. 
    360438 
     
    366444            x^3+y, 
    367445            y 
    368446        """ 
    369         if singular is None: 
    370             singular = singular_default 
    371447        try: 
    372448            self.ring()._singular_(singular).set_ring()             
    373449            I = self.__singular 
     
    412488        g = f.reduce(self.groebner_basis()) 
    413489        return g.is_zero() 
    414490         
    415     def plot(self): 
     491    def plot(self, singular=singular_default): 
    416492        """ 
    417493        If you somehow manage to install surf, perhaps you can use 
    418494        this function to implicitly plot the real zero locus of this 
     
    628704        """ 
    629705        return [P for _,P in self.complete_primary_decomposition(algorithm)] 
    630706             
    631     def triangular_decomposition(self, algorithm=None): 
     707    def triangular_decomposition(self, algorithm=None, singular=singular_default): 
    632708        r""" 
    633709        Decompose zero-dimensional ideal \code{self} into triangular sets. 
    634710 
     
    766842 
    767843        return T 
    768844 
    769     def dimension(self): 
     845    def dimension(self, singular=singular_default): 
    770846        """ 
    771847        The dimension of the ring modulo this ideal. 
    772848 
     
    784860        try: 
    785861            return self.__dimension 
    786862        except AttributeError: 
    787             v = list(self.groebner_basis()) 
    788             if len(v) == 0: 
    789                 v = [0] 
    790             self.__dimension = Integer(singular(v,"ideal").dim()) 
     863            v = self._groebner_basis_singular_raw() 
     864            self.__dimension = Integer(v.dim()) 
    791865        return self.__dimension 
    792866 
    793867    def vector_space_dimension(self): 
     
    817891            return vdim 
    818892 
    819893    @redSB 
    820     def _groebner_basis_using_singular(self, algorithm="groebner", *args, **kwds): 
     894    def _groebner_basis_singular(self, algorithm="groebner", *args, **kwds): 
    821895        r""" 
    822896        Return the reduced Groebner basis of this ideal. If the Groebner 
    823897        basis for this ideal has been calculated before the cached 
     
    852926            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
    853927            Ring in a, b, c, d over Rational Field 
    854928 
    855             sage: I._groebner_basis_using_singular() 
     929            sage: I._groebner_basis_singular() 
    856930            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
    857931            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
    858932            b^2 + 2*b*d + d^2, a + b + c + d] 
     
    863937        method and the user usually doesn't need to bother with this 
    864938        one. 
    865939        """ 
     940        R = self.ring() 
     941        S = self._groebner_basis_singular_raw(algorithm=algorithm, *args, **kwds) 
     942        S =  Sequence([R(S[i+1]) for i in range(len(S))], R, check=False, immutable=True) 
     943        return S 
     944 
     945    def _groebner_basis_singular_raw(self, algorithm="groebner", singular=singular_default, *args, **kwds): 
     946        r""" 
     947        Return a Grobner basis in \Singular format. 
     948 
     949        EXAMPLE: 
     950            sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
     951            sage: I = sage.rings.ideal.Cyclic(R,4) 
     952            sage: I._groebner_basis_singular() # indirect doctest 
     953            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
     954            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
     955            b^2 + 2*b*d + d^2, a + b + c + d] 
     956        """ 
    866957        try: 
    867             return self.__groebner_basis 
     958            return self.__gb_singular 
    868959        except AttributeError: 
     960            pass 
     961        # singular options are preserved by @redSB so we don't 
     962        # need to do that here too 
     963        for o,v in kwds.iteritems():  
     964            if v:  
     965                singular.option(o)  
     966            else:  
     967                singular.option("no"+o) 
    869968 
    870             # singular options are preserved by @redSB so we don't 
    871             # need to do that here too 
    872             for o,v in kwds.iteritems():  
    873                 if v:  
    874                     singular.option(o)  
    875                 else:  
    876                     singular.option("no"+o) 
     969        if algorithm=="groebner": 
     970            S = self._singular_().groebner() 
     971        elif algorithm=="std": 
     972            S = self._singular_().std() 
     973        elif algorithm=="slimgb": 
     974            S = self._singular_().slimgb() 
     975        elif algorithm=="stdhilb": 
     976            S = self._singular_().stdhilb() 
     977        elif algorithm=="stdfglm": 
     978            S = self._singular_().stdfglm() 
     979        else: 
     980            raise TypeError, "algorithm '%s' unknown"%algorithm 
     981        self.__gb_singular = S 
     982        return S 
    877983 
    878             if algorithm=="groebner": 
    879                 S = self._singular_().groebner() 
    880             elif algorithm=="std": 
    881                 S = self._singular_().std() 
    882             elif algorithm=="slimgb": 
    883                 S = self._singular_().slimgb() 
    884             elif algorithm=="stdhilb": 
    885                 S = self._singular_().stdhilb() 
    886             elif algorithm=="stdfglm": 
    887                 S = self._singular_().stdfglm() 
    888             else: 
    889                 raise TypeError, "algorithm '%s' unknown"%algorithm 
    890             R = self.ring() 
    891             self.__singular_groebner_basis = S #remember this 
    892             self.__groebner_basis = Sequence([R(S[i+1]) for i in range(len(S))], R, 
    893                                              check=False, immutable=True) 
    894         return self.__groebner_basis 
    895  
    896     def _groebner_basis_using_libsingular(self, algorithm="std"): 
     984    def _groebner_basis_libsingular(self, algorithm="std"): 
    897985        r""" 
    898986        Return the reduced Groebner basis of this ideal. If the Groebner 
    899987        basis for this ideal has been calculated before the cached 
     
    9201008            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
    9211009            Ring in a, b, c, d over Rational Field 
    9221010 
    923             sage: I._groebner_basis_using_libsingular() 
     1011            sage: I._groebner_basis_libsingular() 
    9241012            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
    9251013            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
    9261014            b^2 + 2*b*d + d^2, a + b + c + d] 
     
    9291017        """ 
    9301018        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
    9311019 
    932         try: 
    933             return self.__groebner_basis 
    934         except AttributeError: 
    935             if algorithm=="std": 
    936                 S = std_libsingular(self) 
    937             elif algorithm=="slimgb": 
    938                 S = slimgb_libsingular(self) 
    939             else: 
    940                 raise TypeError, "algorithm '%s' unknown"%algorithm 
    941             self.__groebner_basis = S 
    942         return self.__groebner_basis 
     1020        if algorithm=="std": 
     1021            S = std_libsingular(self) 
     1022        elif algorithm=="slimgb": 
     1023            S = slimgb_libsingular(self) 
     1024        else: 
     1025            raise TypeError, "algorithm '%s' unknown"%algorithm 
     1026        return S 
    9431027 
    9441028    def genus(self): 
    9451029        """ 
     
    10641148        return S.ideal(r) 
    10651149 
    10661150    @redSB 
    1067     def integral_closure(self, p=0, r=True): 
     1151    def integral_closure(self, p=0, r=True, singular=singular_default): 
    10681152        r""" 
    10691153        Let $I$ = \code{self}. 
    10701154         
     
    10971181        ret = Sequence([ R(f) for f in Is.normalI(p,int(r))[1] ], R, 
    10981182                       check=False, immutable=True) 
    10991183        return ret 
    1100  
    1101  
    11021184 
    11031185    def syzygy_module(self): 
    11041186        r""" 
     
    11741256        ret = Sequence( ret, R, check=False, immutable=True) 
    11751257        return ret 
    11761258 
    1177     def basis_is_groebner(self): 
     1259    def basis_is_groebner(self, singular=singular_default): 
    11781260        r""" 
    11791261        Returns \code{True} if the generators of \code{self} 
    11801262        (\code{self.gens()}) form a Groebner basis. 
     
    12051287        result. So we may acutally use reduce to determine if self is 
    12061288        a Groebner basis. 
    12071289        """ 
    1208         singular = self._singular_().parent() 
     1290        self.ring()._singular_().set_ring() 
    12091291 
    12101292        F = singular( self.gens(), "module" ) 
    12111293        LTF = singular( [f.lt() for f in self.gens()] , "module" ) 
     
    12201302        return True 
    12211303 
    12221304    @redSB 
    1223     def transformed_basis(self,algorithm="gwalk", other_ring=None): 
     1305    def transformed_basis(self, algorithm="gwalk", other_ring=None, singular=singular_default): 
    12241306        r""" 
    12251307        Returns a lex or \var{other_ring} Groebner Basis for this 
    12261308        ideal. 
     
    12731355        if self.basis_is_groebner(): 
    12741356            Is = self._singular_() 
    12751357        else: 
    1276             Is = self._singular_().groebner() 
     1358            Is = self._groebner_basis_singular_raw() 
    12771359             
    12781360        R = self.ring() 
    12791361 
     
    13221404        if not isinstance(variables, (list,tuple)): 
    13231405            variables = (variables,) 
    13241406         
    1325         try: 
    1326             Is = self.__singular_groebner_basis 
    1327         except AttributeError: 
    1328             Is = self._singular_() 
    1329  
     1407        Is = self._groebner_basis_singular_raw() 
    13301408        R = self.ring() 
    13311409        return MPolynomialIdeal(R, [f.sage_poly(R) for f in Is.eliminate( prod(variables) ) ] ) 
    13321410 
     
    15421620        fp = ZZ(len(hp)-1).factorial() 
    15431621        return sum([ZZ(hp[i+1])*t**i for i in xrange(len(hp))])/fp 
    15441622 
    1545     def hilbert_series(self): 
     1623    def hilbert_series(self, singular=singular_default): 
    15461624        r""" 
    15471625        Return the Hilbert series of this ideal. 
    15481626 
     
    15841662        sage: I                                 # optional 
    15851663        Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring 
    15861664    """ 
    1587     #def __init__(self, ring, gens, coerce=True): 
    1588     #    MPolynomialIdeal.__init__(self, ring, gens, coerce=coerce) 
    1589  
    15901665    def _macaulay2_(self, macaulay2=None): 
    15911666        """ 
    15921667        Return Macaulay2 ideal corresponding to this ideal. 
     
    16131688        self.__macaulay2[macaulay2] = z 
    16141689        return z 
    16151690 
    1616     def _macaulay2_groebner_basis(self): 
     1691    def _groebner_basis_macaulay2(self): 
    16171692        r""" 
    1618         Return the Groebner basis for this ideal, computed using Macaulay2.  
     1693        Return the Groebner basis for this ideal, computed using 
     1694        Macaulay2. 
    16191695 
    16201696        ALGORITHM: Computed using Macaulay2.  A big advantage of 
    16211697        Macaulay2 is that it can compute Groebner basis of ideals in 
     
    16371713            sage: I.groebner_basis() # optional -- requires macaulay2 
    16381714            [361, y^2, x^3] 
    16391715        """ 
    1640         try: 
    1641             return self.__groebner_basis 
    1642         except AttributeError: 
    1643             I = self._macaulay2_() 
    1644             G = str(I.gb().generators().external_string()).replace('\n','') 
    1645             i = G.rfind('{{') 
    1646             j = G.rfind('}}') 
    1647             G = G[i+2:j].split(',') 
    1648             L = self.ring().gens_dict() 
    1649             B = [sage_eval(f, L) for f in G] 
    1650             B = Sequence(B, self.ring(), check=False) 
    1651             B.sort() 
    1652             B.set_immutable() 
    1653             self.__groebner_basis = B 
    1654             return B 
     1716        I = self._macaulay2_() 
     1717        G = str(I.gb().generators().external_string()).replace('\n','') 
     1718        i = G.rfind('{{') 
     1719        j = G.rfind('}}') 
     1720        G = G[i+2:j].split(',') 
     1721        L = self.ring().gens_dict() 
     1722        B = [sage_eval(f, L) for f in G] 
     1723        B = Sequence(B, self.ring(), check=False) 
     1724        B.sort() 
     1725        B.set_immutable() 
     1726        return B 
    16551727             
    16561728    def _reduce_using_macaulay2(self, f): 
    16571729        """ 
     
    16901762            Ideal (x0^2, x1^3) of Multivariate Polynomial Ring in x0, x1 over Finite Field of size 3 
    16911763        """ 
    16921764        Ideal_generic.__init__(self, ring, gens, coerce=coerce) 
     1765 
     1766    def __cmp__(self, other): 
     1767        """ 
     1768        EXAMPLE: 
     1769            sage: R = PolynomialRing(QQ,'x,y,z') 
     1770            sage: I = R.ideal() 
     1771            sage: I == R.ideal() 
     1772            True 
     1773 
     1774            sage: R = PolynomialRing(QQ, names=[]) 
     1775            sage: R.ideal(0) == R.ideal(0) 
     1776            True 
     1777 
     1778            sage: R, (x,y) = PolynomialRing(QQ, 2, 'xy').objgens() 
     1779            sage: I = (x^3 + y, y)*R 
     1780            sage: J = (x^3 + y, y, y*x^3 + y^2)*R 
     1781            sage: I == J 
     1782            True 
     1783 
     1784            sage: R = PolynomialRing(QQ, 'x,y,z', order='degrevlex') 
     1785            sage: S = PolynomialRing(QQ, 'x,y,z', order='invlex') 
     1786            sage: I = R.ideal([R.0,R.1]) 
     1787            sage: J = S.ideal([S.0,S.1]) 
     1788            sage: I == J 
     1789            True 
     1790            sage: cmp(I,J) 
     1791            0 
     1792            sage: I.__cmp__(J) 
     1793            0 
     1794        """ 
     1795        # first check the type 
     1796        if not isinstance(other, MPolynomialIdeal): 
     1797            return 1 
     1798 
     1799        # the ideals may be defined w.r.t. to different term orders 
     1800        # but are still the same. 
     1801        R = self.ring() 
     1802        S = other.ring() 
     1803        if R is not S: # rings are unique 
     1804            if type(R) == type(S) and (R.base_ring() == S.base_ring()) and (R.ngens() == S.ngens()): 
     1805                other = other.change_ring(R) 
     1806            else: 
     1807                return cmp((type(R), R.base_ring(), R.ngens()), (type(S), S.base_ring(), S.ngens())) 
     1808 
     1809        # now, check whether the GBs are cached already 
     1810        if self.groebner_basis.is_in_cache() and other.groebner_basis.is_in_cache(): 
     1811            l = self.groebner_basis() 
     1812            r = other.groebner_basis() 
     1813        else: # use easy GB otherwise 
     1814            try: 
     1815                l = self.change_ring(R.change_ring(order="degrevlex")).groebner_basis() 
     1816                r = other.change_ring(R.change_ring(order="degrevlex")).groebner_basis() 
     1817            except AttributeError: # e.g. quotient rings 
     1818                l = self.groebner_basis() 
     1819                r = other.groebner_basis() 
     1820        return cmp(l,r) 
    16931821 
    16941822    def groebner_fan(self, is_groebner_basis=False, symmetry=None, verbose=False): 
    16951823        r""" 
     
    17171845        return groebner_fan.GroebnerFan(self, is_groebner_basis=is_groebner_basis, 
    17181846                                        symmetry=symmetry, verbose=verbose) 
    17191847 
    1720     def groebner_basis(self, algorithm=None, *args, **kwds): 
     1848    @cached 
     1849    def groebner_basis(self, algorithm='', *args, **kwds): 
    17211850        r""" 
    17221851        Return the reduced Groebner basis of this ideal. A Groeber basis 
    17231852        $g_1,...,g_n$ for an ideal $I$ is a basis such that $<LT(g_i)> 
     
    17391868 
    17401869        ALGORITHMS: 
    17411870            \begin{description} 
    1742             \item[None] autoselect (default) 
     1871            \item[''] autoselect (default) 
    17431872            \item['singular:groebner'] \Singular's \code{groebner} command 
    17441873            \item['singular:std'] \Singular's \code{std} command 
    17451874            \item['singular:stdhilb'] \Singular's \code{stdhib} command 
     
    17521881            \item['macaulay2:gb'] Macaulay2's \code{gb} command (if available) 
    17531882            \item['magma:GroebnerBasis'] \MAGMA's \code{Groebnerbasis} command (if available) 
    17541883            \end{description} 
     1884 
     1885        If only a system is given -- e.g. 'magma' -- the default 
     1886        algorithm is chosen for that system. 
    17551887 
    17561888        NOTE: The \Singular and lib\Singular versions of the 
    17571889        respective algorithms are identically, but the former calls an 
     
    18311963        available), or toy implementation. 
    18321964 
    18331965        """ 
    1834         if algorithm is None: 
     1966        if algorithm.lower() == "magma": 
     1967            algorithm = "magma:GroebnerBasis" 
     1968        elif algorithm.lower() == "singular": 
     1969            algorithm = "singular:groebner" 
     1970        elif algorithm.lower() == "macaulay2": 
     1971            algorithm = "macaulay2:gb" 
     1972        elif algorithm.lower() == "toy": 
     1973            algorithm = "toy:buchberger2" 
     1974 
     1975        if algorithm is '': 
    18351976            if self.ring().base_ring() == sage.rings.integer_ring.ZZ: 
    1836                 gb = self._macaulay2_groebner_basis() 
     1977                gb = self._groebner_basis_macaulay2() 
    18371978            else: 
    18381979                try: 
    1839                     gb = self._groebner_basis_using_singular("groebner", *args, **kwds) 
     1980                    gb = self._groebner_basis_singular("groebner", *args, **kwds) 
    18401981                except TypeError: # conversion to Singular not supported 
    18411982                    # we might want to print a warning here 
    18421983                    if self.ring().term_order().is_global(): 
     
    18441985                    else: 
    18451986                        raise TypeError, "Local/unknown orderings not supported by 'toy_buchberger' implementation." 
    18461987        elif algorithm.startswith('singular:'): 
    1847             gb = self._groebner_basis_using_singular(algorithm[9:]) 
     1988            gb = self._groebner_basis_singular(algorithm[9:]) 
    18481989        elif algorithm.startswith('libsingular:'): 
    1849             gb = self._groebner_basis_using_libsingular(algorithm[len('libsingular:'):], *args, **kwds) 
     1990            gb = self._groebner_basis_libsingular(algorithm[len('libsingular:'):], *args, **kwds) 
    18501991        elif algorithm == 'macaulay2:gb': 
    1851             gb = self._macaulay2_groebner_basis(*args, **kwds) 
     1992            gb = self._groebner_basis_macaulay2(*args, **kwds) 
    18521993        elif algorithm == 'magma:GroebnerBasis': 
    1853             gb = self._magma_groebner_basis(*args, **kwds) 
     1994            gb = self._groebner_basis_magma(*args, **kwds) 
    18541995        elif algorithm == 'toy:buchberger': 
    18551996            gb = toy_buchberger.buchberger(self, *args, **kwds) 
    18561997        elif algorithm == 'toy:buchberger2': 
     
    18592000            raise TypeError, "algorithm '%s' unknown"%algorithm 
    18602001 
    18612002        if self.ring().base_ring().is_field(): 
    1862             return Sequence( [f*f.lc()**(-1) for f in gb], immutable=True, check=False) 
    1863         else: 
    1864             return gb 
     2003            gb = Sequence( [f*f.lc()**(-1) for f in gb], immutable=True, check=False) 
     2004        return gb 
    18652005 
    18662006    def change_ring(self, P): 
    18672007        r""" 
     
    19912131                return False 
    19922132        return True 
    19932133 
    1994     def _libsingular_normal_basis(self): 
    1995         """ 
     2134    def _normal_basis_libsingular(self): 
     2135        r""" 
    19962136        Returns the normal basis for a given groebner basis. It will use  
    19972137        the Groebner Basis as computed by 
    1998         self._groebner_basis_using_libsingular()
     2138        \code{MPolynomialIdeal._groebner_basis_libsingular()}
    19992139         
    20002140        EXAMPLES: 
    20012141            sage: R.<x,y,z> = PolynomialRing(QQ) 
     
    20052145             
    20062146        """ 
    20072147        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular 
    2008         gb = self._groebner_basis_using_libsingular() 
     2148        gb = self._groebner_basis_libsingular() 
    20092149         
    20102150        return kbase_libsingular(self.ring().ideal(gb)) 
    20112151         
    2012     def normal_basis(self, algorithm='libsingular'): 
     2152    def normal_basis(self, algorithm='libsingular', singular=singular_default): 
    20132153        """ 
    20142154        Returns a vector space basis (consisting of monomials) of the quotient 
    20152155        ring by the ideal, resp. of a free module by the module, in case it is 
     
    20302170        """ 
    20312171         
    20322172        if algorithm == 'libsingular': 
    2033             return self._libsingular_normal_basis() 
     2173            return self._normal_basis_libsingular() 
    20342174        else: 
    20352175            gb = self.groebner_basis() 
    20362176            return list(singular.kbase(self.ring().ideal(gb))) 
  • a/sage/rings/polynomial/pbori.pyx

    old new  
    30853085    def groebner_basis(self, **kwds): 
    30863086        r""" 
    30873087        Return a Groebner basis of this ideal. 
    3088  
    3089  
    3090  
    3091 selection_size, maximum number of polynomials for parallel reductions 
    30923088 
    30933089        INPUT: 
    30943090            other_ordering_first -- possible values are \code{False} or an 
  • a/sage/schemes/generic/algebraic_scheme.py

    old new  
    276276            sage: V.irreducible_components() 
    277277            [ 
    278278            Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 
    279             w^5 - 2*z^3*v^2, 
     279            w, 
     280            Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 
     281            x^2 - y^2 - z^2, 
    280282            Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 
    281283            x^2*z - v^3, 
    282284            Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 
    283             x^2 - y^2 - z^2, 
    284             Closed subscheme of Projective Space of dimension 4 over Rational Field defined by: 
    285             w 
     285            w^5 - 2*z^3*v^2 
    286286            ] 
    287287        """ 
    288288        try: 
  • a/sage/schemes/generic/divisor.py

    old new  
    1717    sage: D1.parent() is D2.parent() 
    1818    True 
    1919    sage: D = D1 - D2 + D3; D 
    20     10*(x + 2*z, y + z) + 3*(x, y) - (x, z) 
     20    -(x, z) + 3*(x, y) + 10*(x + 2*z, y + z) 
    2121    sage: D[1][0] 
    2222    3 
    2323    sage: D[1][1] 
    2424    Ideal (x, y) of Multivariate Polynomial Ring in x, y, z over Finite Field of size 5 
    2525    sage: C.divisor([(3, pts[0]), (-1, pts[1]), (10,pts[5])]) 
    26     10*(x + 2*z, y + z) + 3*(x, y) - (x, z) 
     26    -(x, z) + 3*(x, y) + 10*(x + 2*z, y + z) 
    2727""" 
    2828#******************************************************************************* 
    2929#  Copyright (C) 2005 David Kohel <kohel@maths.usyd.edu.au> 
     
    9898            sage: pts = C.rational_points(); pts 
    9999            [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] 
    100100            sage: D = C.divisor(pts[0])*3 - C.divisor(pts[1]); D 
    101             -(x - 2, y - 2) + 3*(x, y
     101            3*(x, y) - (x - 2, y - 2
    102102            sage: D.scheme() 
    103103            Affine Curve over Finite Field of size 5 defined by -x^9 + y^2 - x 
    104104        """ 
     
    135135        sage: E.divisor([P, P]) 
    136136        2*(x, y) 
    137137        sage: E.divisor([(3,P), (-4,5*P)]) 
    138         -4*(x - 1/4*z, y + 5/8*z) + 3*(x, y
     138        3*(x, y) - 4*(x - 1/4*z, y + 5/8*z
    139139    """ 
    140140    def __init__(self, v, check=True, reduce=True, parent=None): 
    141141        """ 
     
    221221            sage: pts = C.rational_points(); pts 
    222222            [(0, 0), (2, 2), (2, 3), (3, 1), (3, 4)] 
    223223            sage: D = C.divisor([(3,pts[0]), (-1, pts[1])]); D 
    224             -(x - 2, y - 2) + 3*(x, y
     224            3*(x, y) - (x - 2, y - 2
    225225            sage: D.support() 
    226226            [(0, 0), (2, 2)] 
    227227        "