Ticket #4539: plural_3.patch

File plural_3.patch, 53.7 KB (added by burcin, 4 years ago)

appy on top of 1 and 2, new classes for plural objects which don't inherit from the commutative ones

  • sage/algebras/free_algebra.py

    # HG changeset patch
    # User Burcin Erocal <burcin@erocal.org>
    # Date 1279186723 -7200
    # Node ID 053186693b24935314a71220fd25561875f174de
    # Parent  51207796acad184730ea938cafeb9e55af5ca1d5
    [mq]: plural_3.patch
    
    diff --git a/sage/algebras/free_algebra.py b/sage/algebras/free_algebra.py
    a b  
    483483            -x*y + z 
    484484        """ 
    485485        from sage.matrix.constructor  import Matrix 
    486         from sage.rings.polynomial.plural import MPolynomialRing_plural 
     486        from sage.rings.polynomial.plural import NCPolynomialRing_plural 
    487487         
    488488        base_ring=self.base_ring() 
    489489        n=self.ngens() 
     
    515515            if d_poly: 
    516516                dmat[v2_ind,v1_ind]=d_poly 
    517517         
    518         return MPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat,order=order) 
     518        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat,order=order) 
    519519             
    520520             
    521521from sage.misc.cache import Cache 
  • sage/libs/singular/function.pxd

    diff --git a/sage/libs/singular/function.pxd b/sage/libs/singular/function.pxd
    a b  
    2828 
    2929cdef class Converter(SageObject): 
    3030    cdef leftv *args 
    31     cdef MPolynomialRing_libsingular _ring 
     31    cdef object _sage_ring 
     32    cdef singular_ring* _singular_ring 
    3233    cdef leftv* pop_front(self) except NULL 
    3334    cdef leftv * _append_leftv(self, leftv *v) 
    3435    cdef leftv * _append(self, void* data, int res_type) 
    35     cdef leftv * append_polynomial(self, MPolynomial_libsingular p) except NULL 
     36    cdef leftv * append_polynomial(self, p) except NULL 
    3637    cdef leftv * append_ideal(self,  i) except NULL 
    3738    cdef leftv * append_number(self, n) except NULL 
    3839    cdef leftv * append_int(self, n) except NULL 
     
    7879    pass 
    7980 
    8081# the most direct function call interface 
    81 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=?, object attributes=?) 
     82cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=?, object attributes=?) 
  • sage/libs/singular/function.pyx

    diff --git a/sage/libs/singular/function.pyx b/sage/libs/singular/function.pyx
    a b  
    8080from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, new_MP 
    8181from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 
    8282 
     83from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, \ 
     84        NCPolynomial_plural 
     85from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal 
     86 
    8387from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal 
    8488 
    8589from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence 
     
    300304        """ 
    301305        cdef leftv *v 
    302306        self.args = NULL 
    303         self._ring = ring 
     307        self._sage_ring = ring 
     308        if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     309            self._singular_ring = (<MPolynomialRing_libsingular>ring)._ring 
     310        elif PY_TYPE_CHECK(ring, NCPolynomialRing_plural): 
     311            self._singular_ring = (<NCPolynomialRing_plural>ring)._ring 
     312         
    304313        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    305314        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
    306315        for a in args: 
    307             if PY_TYPE_CHECK(a, MPolynomial_libsingular): 
    308                 v = self.append_polynomial(<MPolynomial_libsingular> a) 
     316            if PY_TYPE_CHECK(a, MPolynomial_libsingular) or \ 
     317                    PY_TYPE_CHECK(a, NCPolynomial_plural): 
     318                v = self.append_polynomial(a) 
    309319 
    310             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
    311                 v = self.append_ring(<MPolynomialRing_libsingular> a) 
     320            elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular) or \ 
     321                    PY_TYPE_CHECK(a, NCPolynomialRing_plural): 
     322                v = self.append_ring(a) 
    312323 
    313             elif PY_TYPE_CHECK(a, MPolynomialIdeal): 
     324            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     325                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    314326                v = self.append_ideal(a) 
    315327 
    316328            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long): 
     
    358370                    v = self.append_intvec(a) 
    359371                else: 
    360372                    v = self.append_list(a) 
    361             elif a.parent() is self._ring.base_ring(): 
     373            elif a.parent() is self._sage_ring.base_ring(): 
    362374                v = self.append_number(a) 
    363375 
    364376            elif PY_TYPE_CHECK(a, Integer): 
     
    387399            sage: Converter([a,b,c],ring=P).ring() 
    388400            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    389401        """ 
    390         return self._ring 
     402        return self._sage_ring 
    391403 
    392404    def _repr_(self): 
    393405        """ 
     
    398410            sage: Converter([a,b,c],ring=P) # indirect doctest 
    399411            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    400412        """ 
    401         return "Singular Converter in %s"%(self._ring) 
     413        return "Singular Converter in %s"%(self._sage_ring) 
    402414 
    403415    def __dealloc__(self): 
    404416        if self.args: 
     
    463475        Convert singular matrix to matrix over the polynomial ring. 
    464476        """ 
    465477        from sage.matrix.constructor import Matrix 
    466         sage_ring = self._ring 
    467         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
    468             sage_ring)._ring 
     478        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
     479        #    self._sage_ring)._ring 
    469480        ncols = mat.ncols 
    470481        nrows = mat.nrows 
    471         result = Matrix(sage_ring, nrows, ncols) 
     482        result = Matrix(self._sage_ring, nrows, ncols) 
     483        #FIXME: NCPolynomial 
    472484        cdef MPolynomial_libsingular p 
    473485        for i in xrange(nrows): 
    474486            for j in xrange(ncols): 
    475                 p = MPolynomial_libsingular(sage_ring) 
     487                p = MPolynomial_libsingular(self._sage_ring) 
    476488                p._poly = mat.m[i*ncols+j] 
    477489                mat.m[i*ncols+j]=NULL 
    478490                result[i,j] = p 
    479491        return result 
    480492     
    481493    cdef to_sage_vector_destructive(self, poly *p, free_module = None): 
    482         cdef ring *r=self._ring._ring 
     494        #cdef ring *r=self._ring._ring 
    483495        cdef int rank 
    484496        if free_module: 
    485497            rank = free_module.rank() 
    486498        else: 
    487             rank = singular_vector_maximal_component(p, r) 
    488             free_module = self._ring**rank 
     499            rank = singular_vector_maximal_component(p, self._singular_ring) 
     500            free_module = self._sage_ring**rank 
    489501        cdef poly *acc 
    490502        cdef poly *p_iter 
    491503        cdef poly *first 
     
    498510            first = NULL 
    499511            p_iter=p 
    500512            while p_iter != NULL: 
    501                 if p_GetComp(p_iter, r) == i: 
    502                     p_SetComp(p_iter,0, r) 
    503                     p_Setm(p_iter, r) 
     513                if p_GetComp(p_iter, self._singular_ring) == i: 
     514                    p_SetComp(p_iter,0, self._singular_ring) 
     515                    p_Setm(p_iter, self._singular_ring) 
    504516                    if acc == NULL: 
    505517                        first = p_iter 
    506518                    else: 
     
    515527                else: 
    516528                    previous = p_iter 
    517529                    p_iter = pNext(p_iter) 
    518             result.append(new_MP(self._ring, first)) 
     530            result.append(new_MP(self._sage_ring, first)) 
    519531        return free_module(result) 
    520532           
    521533    cdef object to_sage_module_element_sequence_destructive( self, ideal *i): 
     
    529541        - ``r`` -- a SINGULAR ring 
    530542        - ``sage_ring`` -- a Sage ring matching r 
    531543        """ 
    532         cdef MPolynomialRing_libsingular sage_ring = self._ring 
     544        #cdef MPolynomialRing_libsingular sage_ring = self._ring 
    533545        cdef int j 
    534546        cdef int rank=i.rank 
    535         free_module = sage_ring**rank        
     547        free_module = self._sage_ring**rank        
    536548        l = [] 
    537549 
    538550        for j from 0 <= j < IDELEMS(i): 
     
    561573        return result 
    562574     
    563575     
    564     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL: 
     576    cdef leftv *append_polynomial(self, p) except NULL: 
    565577        """ 
    566578        Append the polynomial ``p`` to the list. 
    567579        """ 
    568         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring) 
     580        cdef poly* _p 
     581        if PY_TYPE_CHECK(p, MPolynomial_libsingular): 
     582            _p = p_Copy((<MPolynomial_libsingular>p)._poly, <ring*>((<MPolynomial_libsingular>p)._parent)._ring) 
     583        elif PY_TYPE_CHECK(p, NCPolynomial_plural): 
     584            _p = p_Copy((<NCPolynomial_plural>p)._poly, <ring*>((<NCPolynomial_plural>p)._parent)._ring) 
    569585        return self._append(_p, POLY_CMD) 
    570586 
    571587    cdef leftv *append_ideal(self,  i) except NULL: 
     
    582598        """ 
    583599        rank = max([v.parent().rank() for v in m]) 
    584600        cdef ideal *result 
    585         cdef ring *r = self._ring._ring 
     601        cdef ring *r = self._singular_ring 
    586602        cdef ideal *i 
    587603        cdef int j = 0 
    588604 
     
    598614        """ 
    599615        Append the number ``n`` to the list. 
    600616        """ 
    601         cdef number *_n =  sa2si(n, self._ring._ring) 
     617        cdef number *_n =  sa2si(n, self._singular_ring) 
    602618        return self._append(<void *>_n, NUMBER_CMD) 
    603619 
    604620    cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL: 
    605621        """ 
    606622        Append the ring ``r`` to the list. 
    607623        """ 
     624        #FIXME 
    608625        cdef ring *_r =  <ring*> r._ring 
    609626        _r.ref+=1 
    610627        return self._append(<void *>_r, RING_CMD) 
    611628 
    612629    cdef leftv *append_matrix(self, mat) except NULL: 
     630        #FIXME 
    613631         
    614632        sage_ring = mat.base_ring() 
    615633        cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring 
     
    620638        cdef matrix* _m=mpNew(nrows,ncols) 
    621639        for i in xrange(nrows): 
    622640            for j in xrange(ncols): 
     641                #FIXME 
    623642                p = p_Copy( 
    624643                    (<MPolynomial_libsingular> mat[i,j])._poly, r) 
    625644                _m.m[ncols*i+j]=p 
     
    639658        Append the list ``l`` to the list. 
    640659        """ 
    641660         
    642         cdef Converter c = Converter(l, self._ring) 
     661        cdef Converter c = Converter(l, self._sage_ring) 
    643662        n = len(c) 
    644663 
    645664        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin) 
     
    670689        Append vector ``v`` from free  
    671690        module over polynomial ring. 
    672691        """ 
    673         cdef ring *r = self._ring._ring 
     692        cdef ring *r = self._singular_ring 
    674693        cdef poly *p = sage_vector_to_poly(v, r) 
    675694        return self._append(<void*> p, VECTOR_CMD) 
    676695     
     
    710729 
    711730        - ``to_convert`` - a Singular ``leftv`` 
    712731        """ 
     732        #FIXME 
    713733        cdef MPolynomial_libsingular res_poly 
    714734        cdef int rtyp = to_convert.rtyp 
    715735        cdef lists *singular_list 
    716736        cdef Resolution res_resolution 
    717737        if rtyp == IDEAL_CMD: 
    718             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring) 
     738            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring) 
    719739 
    720740        elif rtyp == POLY_CMD: 
    721             res_poly = MPolynomial_libsingular(self._ring) 
     741            #FIXME 
     742            res_poly = MPolynomial_libsingular(self._sage_ring) 
    722743            res_poly._poly = <poly*>to_convert.data 
    723744            to_convert.data = NULL 
    724745            #prevent it getting free, when cleaning the leftv 
     
    728749            return <long>to_convert.data 
    729750         
    730751        elif rtyp == NUMBER_CMD: 
    731             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring()) 
     752            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring()) 
    732753 
    733754        elif rtyp == INTVEC_CMD: 
    734755            return si2sa_intvec(<intvec *>to_convert.data) 
     
    770791            return self.to_sage_integer_matrix( 
    771792                <intvec*> to_convert.data) 
    772793        elif rtyp == RESOLUTION_CMD: 
    773             res_resolution = Resolution(self._ring) 
     794            res_resolution = Resolution(self._sage_ring) 
    774795            res_resolution._resolution = <syStrategy*> to_convert.data 
    775796            res_resolution._resolution.references += 1 
    776797            return res_resolution 
     
    939960        """ 
    940961        return "%s (singular function)" %(self._name) 
    941962 
    942     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None): 
     963    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None): 
    943964        """ 
    944965        Call this function with the provided arguments ``args`` in the 
    945966        ring ``R``. 
     
    9981019        """ 
    9991020        if ring is None: 
    10001021            ring = self.common_ring(args, ring) 
    1001         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     1022        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \ 
     1023                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)): 
    10021024            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring))) 
    10031025        return call_function(self, args, ring, interruptible, attributes) 
    10041026     
     
    10741096        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    10751097        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
    10761098        for a in args: 
    1077             if PY_TYPE_CHECK(a, MPolynomialIdeal): 
     1099            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     1100                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    10781101                ring2 = a.ring() 
    1079             elif PY_TYPE_CHECK(a, MPolynomial_libsingular): 
     1102            elif PY_TYPE_CHECK(a, MPolynomial_libsingular) or \ 
     1103                    PY_TYPE_CHECK(a, NCPolynomial_plural): 
    10801104                ring2 = a.parent() 
    1081             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
     1105            elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular) or \ 
     1106                    PY_TYPE_CHECK(a, NCPolynomialRing_plural): 
    10821107                ring2 = a 
    10831108            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring): 
    10841109                continue 
     
    11381163        else: 
    11391164            return cmp(self._name, (<SingularFunction>other)._name) 
    11401165 
    1141 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None): 
     1166cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None): 
    11421167    global currRingHdl 
    11431168    global errorreported 
    1144  
    1145     cdef ring *si_ring = R._ring 
     1169     
     1170    cdef ring *si_ring 
     1171    if isinstance(R, MPolynomialRing_libsingular): 
     1172        si_ring = (<MPolynomialRing_libsingular>R)._ring 
     1173    else: 
     1174        si_ring = (<NCPolynomialRing_plural>R)._ring 
    11461175 
    11471176    if si_ring != currRing: 
    11481177        rChangeCurrRing(si_ring) 
  • sage/libs/singular/singular-cdefs.pxi

    diff --git a/sage/libs/singular/singular-cdefs.pxi b/sage/libs/singular/singular-cdefs.pxi
    a b  
    10261026      nc_lie,  # yx=xy+...  
    10271027      nc_undef, # for internal reasons */ 
    10281028      nc_exterior # 
     1029 
     1030    bint rIsPluralRing(ring* r) 
    10291031       
    10301032cdef extern from "sca.h": 
    10311033    void sca_p_ProcsSet(ring *, p_Procs_s *) 
  • sage/rings/ideal_monoid.py

    diff --git a/sage/rings/ideal_monoid.py b/sage/rings/ideal_monoid.py
    a b  
    1313 
    1414class IdealMonoid_c(Monoid_class): 
    1515    def __init__(self, R): 
    16         if not is_CommutativeRing(R): 
    17             raise TypeError, "R must be a commutative ring" 
     16        #if not is_CommutativeRing(R): 
     17        #    raise TypeError, "R must be a commutative ring" 
    1818        self.__R = R 
    1919        ParentWithGens.__init__(self, sage.rings.integer_ring.ZZ) 
    2020 
  • sage/rings/polynomial/multi_polynomial_ideal.py

    diff --git a/sage/rings/polynomial/multi_polynomial_ideal.py b/sage/rings/polynomial/multi_polynomial_ideal.py
    a b  
    495495        B = Sequence([R(e) for e in mgb], R, check=False, immutable=True) 
    496496        return B 
    497497 
    498 class MPolynomialIdeal_singular_repr: 
     498class MPolynomialIdeal_singular_base_repr: 
     499    @require_field 
     500    def syzygy_module(self): 
     501        r""" 
     502        Computes the first syzygy (i.e., the module of relations of the 
     503        given generators) of the ideal. 
     504         
     505        EXAMPLE:: 
     506         
     507            sage: R.<x,y> = PolynomialRing(QQ) 
     508            sage: f = 2*x^2 + y 
     509            sage: g = y 
     510            sage: h = 2*f + g 
     511            sage: I = Ideal([f,g,h]) 
     512            sage: M = I.syzygy_module(); M 
     513            [       -2        -1         1] 
     514            [       -y 2*x^2 + y         0] 
     515            sage: G = vector(I.gens()) 
     516            sage: M*G 
     517            (0, 0) 
     518         
     519        ALGORITHM: Uses Singular's syz command 
     520        """ 
     521        import sage.libs.singular 
     522        syz = sage.libs.singular.ff.syz 
     523        from sage.matrix.constructor import matrix 
     524 
     525        #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
     526        S = syz(self) 
     527        return matrix(self.ring(), S) 
     528 
     529    @redSB 
     530    def _groebner_basis_libsingular(self, algorithm="groebner", redsb=True, red_tail=True): 
     531        """ 
     532        Return the reduced Groebner basis of this ideal. If the 
     533        Groebner basis for this ideal has been calculated before the 
     534        cached Groebner basis is returned regardless of the requested 
     535        algorithm. 
     536         
     537        INPUT: 
     538         
     539        -  ``algorithm`` - see below for available algorithms 
     540        - ``redsb`` - return a reduced Groebner basis (default: ``True``) 
     541        - ``red_tail`` - perform tail reduction (default: ``True``) 
     542 
     543        ALGORITHMS: 
     544         
     545        'groebner' 
     546            Singular's heuristic script (default) 
     547 
     548        'std' 
     549            Buchberger's algorithm 
     550         
     551        'slimgb' 
     552            the *SlimGB* algorithm 
     553 
     554        'stdhilb' 
     555            Hilbert Basis driven Groebner basis 
     556         
     557        'stdfglm' 
     558            Buchberger and FGLM 
     559         
     560        EXAMPLES: 
     561         
     562        We compute a Groebner basis of 'cyclic 4' relative to 
     563        lexicographic ordering. :: 
     564         
     565            sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
     566            sage: I = sage.rings.ideal.Cyclic(R,4); I 
     567            Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d 
     568            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
     569            Ring in a, b, c, d over Rational Field 
     570         
     571        :: 
     572         
     573            sage: I._groebner_basis_libsingular() 
     574            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
     575            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
     576            b^2 + 2*b*d + d^2, a + b + c + d] 
     577         
     578        ALGORITHM: Uses libSINGULAR. 
     579        """ 
     580        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
     581        from sage.libs.singular import singular_function 
     582        from sage.libs.singular.option import opt 
     583 
     584        import sage.libs.singular 
     585        groebner = sage.libs.singular.ff.groebner 
     586 
     587        opt['redSB'] = redsb 
     588        opt['redTail'] = red_tail 
     589 
     590        T = self.ring().term_order() 
     591         
     592        if algorithm == "std": 
     593            S = std_libsingular(self) 
     594        elif algorithm == "slimgb": 
     595            S = slimgb_libsingular(self) 
     596        elif algorithm == "groebner": 
     597            S = groebner(self) 
     598        else: 
     599            try: 
     600                fnc = singular_function(algorithm) 
     601                S = fnc(self) 
     602            except NameError: 
     603                raise NameError("Algorithm '%s' unknown"%algorithm) 
     604        return S 
     605     
     606 
     607class MPolynomialIdeal_singular_commutative_repr( 
     608        MPolynomialIdeal_singular_base_repr): 
    499609    """ 
    500610    An ideal in a multivariate polynomial ring, which has an 
    501611    underlying Singular ring associated to it. 
     
    11791289        self.__gb_singular = S 
    11801290        return S 
    11811291 
    1182     @redSB 
    1183     def _groebner_basis_libsingular(self, algorithm="groebner", redsb=True, red_tail=True): 
    1184         """ 
    1185         Return the reduced Groebner basis of this ideal. If the 
    1186         Groebner basis for this ideal has been calculated before the 
    1187         cached Groebner basis is returned regardless of the requested 
    1188         algorithm. 
    1189          
    1190         INPUT: 
    1191          
    1192         -  ``algorithm`` - see below for available algorithms 
    1193         - ``redsb`` - return a reduced Groebner basis (default: ``True``) 
    1194         - ``red_tail`` - perform tail reduction (default: ``True``) 
    1195  
    1196         ALGORITHMS: 
    1197          
    1198         'groebner' 
    1199             Singular's heuristic script (default) 
    1200  
    1201         'std' 
    1202             Buchberger's algorithm 
    1203          
    1204         'slimgb' 
    1205             the *SlimGB* algorithm 
    1206  
    1207         'stdhilb' 
    1208             Hilbert Basis driven Groebner basis 
    1209          
    1210         'stdfglm' 
    1211             Buchberger and FGLM 
    1212          
    1213         EXAMPLES: 
    1214          
    1215         We compute a Groebner basis of 'cyclic 4' relative to 
    1216         lexicographic ordering. :: 
    1217          
    1218             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
    1219             sage: I = sage.rings.ideal.Cyclic(R,4); I 
    1220             Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d 
    1221             + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
    1222             Ring in a, b, c, d over Rational Field 
    1223          
    1224         :: 
    1225          
    1226             sage: I._groebner_basis_libsingular() 
    1227             [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
    1228             b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
    1229             b^2 + 2*b*d + d^2, a + b + c + d] 
    1230          
    1231         ALGORITHM: Uses libSINGULAR. 
    1232         """ 
    1233         from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
    1234         from sage.libs.singular import singular_function 
    1235         from sage.libs.singular.option import opt 
    1236  
    1237         import sage.libs.singular 
    1238         groebner = sage.libs.singular.ff.groebner 
    1239  
    1240         opt['redSB'] = redsb 
    1241         opt['redTail'] = red_tail 
    1242  
    1243         T = self.ring().term_order() 
    1244          
    1245         if algorithm == "std": 
    1246             S = std_libsingular(self) 
    1247         elif algorithm == "slimgb": 
    1248             S = slimgb_libsingular(self) 
    1249         elif algorithm == "groebner": 
    1250             S = groebner(self) 
    1251         else: 
    1252             try: 
    1253                 fnc = singular_function(algorithm) 
    1254                 S = fnc(self) 
    1255             except NameError: 
    1256                 raise NameError("Algorithm '%s' unknown"%algorithm) 
    1257         return S 
    1258      
    12591292    @require_field 
    12601293    def genus(self): 
    12611294        """ 
     
    14421475        ret = Sequence(normalI(self, p, int(r))[0], R, check=False, immutable=True) 
    14431476        return ret 
    14441477 
    1445     @require_field 
    1446     def syzygy_module(self): 
    1447         r""" 
    1448         Computes the first syzygy (i.e., the module of relations of the 
    1449         given generators) of the ideal. 
    1450          
    1451         EXAMPLE:: 
    1452          
    1453             sage: R.<x,y> = PolynomialRing(QQ) 
    1454             sage: f = 2*x^2 + y 
    1455             sage: g = y 
    1456             sage: h = 2*f + g 
    1457             sage: I = Ideal([f,g,h]) 
    1458             sage: M = I.syzygy_module(); M 
    1459             [       -2        -1         1] 
    1460             [       -y 2*x^2 + y         0] 
    1461             sage: G = vector(I.gens()) 
    1462             sage: M*G 
    1463             (0, 0) 
    1464          
    1465         ALGORITHM: Uses Singular's syz command 
    1466         """ 
    1467         import sage.libs.singular 
    1468         syz = sage.libs.singular.ff.syz 
    1469         from sage.matrix.constructor import matrix 
    1470  
    1471         #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
    1472         S = syz(self) 
    1473         return matrix(self.ring(), S) 
    1474  
    14751478    @redSB 
    14761479    def reduced_basis(self): 
    14771480        r""" 
     
    22712274        R = self.ring() 
    22722275        return R(k) 
    22732276 
     2277class NCPolynomialIdeal(MPolynomialIdeal_singular_base_repr, Ideal_generic): 
     2278    def __init__(self, ring, gens, coerce=True): 
     2279        Ideal_generic.__init__(self, ring, gens, coerce=coerce) 
    22742280 
    2275 class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \ 
     2281class MPolynomialIdeal( MPolynomialIdeal_singular_commutative_repr, \ 
    22762282                        MPolynomialIdeal_macaulay2_repr, \ 
    22772283                        MPolynomialIdeal_magma_repr, \ 
    22782284                        Ideal_generic ): 
  • sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_ideal_libsingular.pyx
    a b  
    6565from sage.libs.singular.decl cimport scKBase, poly, testHomog, idSkipZeroes, idRankFreeModule, kStd 
    6666from sage.libs.singular.decl cimport OPT_REDTAIL, singular_options, kInterRed, t_rep_gb, p_GetCoeff 
    6767from sage.libs.singular.decl cimport nInvers, pp_Mult_nn, p_Delete, n_Delete 
     68from sage.libs.singular.decl cimport rIsPluralRing 
    6869 
    6970from sage.structure.parent_base cimport ParentWithBase 
    7071 
    7172from sage.rings.polynomial.multi_polynomial_libsingular cimport new_MP 
     73from sage.rings.polynomial.plural cimport new_NCP 
    7274 
    7375from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal 
    7476from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular 
    7577from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 
    7678from sage.structure.sequence import Sequence 
    7779 
     80from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_plural 
     81 
    7882cdef object singular_ideal_to_sage_sequence(ideal *i, ring *r, object parent): 
    7983    """ 
    8084    convert a SINGULAR ideal to a Sage Sequence (the format Sage 
     
    8892    """ 
    8993    cdef int j 
    9094    cdef MPolynomial_libsingular p 
     95    cdef NCPolynomial_plural p_nc 
    9196                 
    9297    l = [] 
    9398 
    94     for j from 0 <= j < IDELEMS(i): 
    95         p = new_MP(parent, p_Copy(i.m[j], r)) 
    96         l.append( p ) 
     99    if rIsPluralRing(r): 
     100        for j from 0 <= j < IDELEMS(i): 
     101            p_nc = new_NCP(parent, p_Copy(i.m[j], r)) 
     102            l.append( p_nc ) 
     103    else: 
     104        for j from 0 <= j < IDELEMS(i): 
     105            p = new_MP(parent, p_Copy(i.m[j], r)) 
     106            l.append( p ) 
    97107 
    98108    return Sequence(l, check=False, immutable=True) 
    99109 
     
    113123    cdef ideal *i 
    114124    cdef int j = 0 
    115125 
    116     if not PY_TYPE_CHECK(R,MPolynomialRing_libsingular): 
     126    if PY_TYPE_CHECK(R,MPolynomialRing_libsingular): 
     127        r = (<MPolynomialRing_libsingular>R)._ring 
     128    elif PY_TYPE_CHECK(R, NCPolynomialRing_plural): 
     129        r = (<NCPolynomialRing_plural>R)._ring 
     130    else: 
    117131        raise TypeError("Ring must be of type 'MPolynomialRing_libsingular'") 
    118  
    119     r = (<MPolynomialRing_libsingular>R)._ring 
     132         
     133    #r = (<MPolynomialRing_libsingular>R)._ring 
    120134    rChangeCurrRing(r); 
    121135 
    122136    i = idInit(len(gens),1) 
    123137    for f in gens: 
    124         if not PY_TYPE_CHECK(f,MPolynomial_libsingular): 
     138        if PY_TYPE_CHECK(f,MPolynomial_libsingular): 
     139            i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r) 
     140        elif PY_TYPE_CHECK(f, NCPolynomial_plural): 
     141            i.m[j] = p_Copy((<NCPolynomial_plural>f)._poly, r) 
     142        else: 
    125143            id_Delete(&i, r) 
    126144            raise TypeError("All generators must be of type MPolynomial_libsingular.") 
    127         i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r) 
     145        #i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r) 
    128146        j+=1  
    129147    return i 
    130148 
  • sage/rings/polynomial/plural.pxd

    diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
    a b  
    11include "../../libs/singular/singular-cdefs.pxi" 
    22 
    3 from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular 
     3from sage.rings.ring cimport Ring 
     4from sage.structure.element cimport RingElement 
    45 
    5 cdef class MPolynomialRing_plural(MPolynomialRing_libsingular): 
     6cdef class NCPolynomialRing_plural(Ring): 
     7    cdef object __ngens 
     8    cdef object __term_order 
     9    cdef public object _has_singular 
     10    cdef public object _magma_gens, _magma_cache 
     11 
     12    cdef ring *_ring 
     13#    cdef NCPolynomial_plural _one_element 
     14#    cdef NCPolynomial_plural _zero_element 
    615    pass 
    716 
    8 cdef class ExteriorAlgebra_plural(MPolynomialRing_plural): 
     17cdef class ExteriorAlgebra_plural(NCPolynomialRing_plural): 
    918    pass 
     19 
     20cdef class NCPolynomial_plural(RingElement): 
     21    cdef poly *_poly 
     22    cpdef _repr_short_(self) 
     23    cdef long _hash_c(self) 
     24 
     25cdef NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, 
     26        poly *juice) 
  • sage/rings/polynomial/plural.pyx

    diff --git a/sage/rings/polynomial/plural.pyx b/sage/rings/polynomial/plural.pyx
    a b  
    11include "sage/ext/stdsage.pxi" 
    22include "sage/ext/interrupt.pxi" 
    33 
    4 from sage.matrix.constructor  import Matrix 
    54 
    6 cdef class MPolynomialRing_plural(MPolynomialRing_libsingular): 
     5from sage.libs.singular.function cimport RingWrap 
     6from sage.structure.parent_base cimport ParentWithBase 
     7from sage.structure.parent_gens cimport ParentWithGens 
     8 
     9from sage.rings.integer cimport Integer 
     10from sage.structure.element cimport Element, ModuleElement 
     11 
     12from sage.libs.singular.polynomial cimport singular_polynomial_call, singular_polynomial_cmp, singular_polynomial_add, singular_polynomial_sub, singular_polynomial_neg, singular_polynomial_pow, singular_polynomial_mul, singular_polynomial_rmul 
     13from sage.libs.singular.polynomial cimport singular_polynomial_deg, singular_polynomial_str_with_changed_varnames, singular_polynomial_latex, singular_polynomial_str, singular_polynomial_div_coeff 
     14 
     15from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check 
     16 
     17from term_order import TermOrder 
     18 
     19cdef class NCPolynomialRing_plural(Ring): 
    720    def __init__(self, base_ring, n, names, c, d, order='degrevlex'): 
    8         MPolynomialRing_libsingular.__init__(self, base_ring, n, names, order) 
    9         cdef matrix* matc=mpNew(n,n) 
    10         cdef matrix* matd=mpNew(n,n) 
    11         cdef MPolynomial_libsingular f 
     21        order = TermOrder(order,n) 
     22        n = int(n) 
     23        if n < 0: 
     24            raise ValueError, "Multivariate Polynomial Rings must " + \ 
     25                  "have more than 0 variables." 
     26        self.__ngens = n 
     27        self.__term_order = order 
     28 
     29        from sage.rings.polynomial.polynomial_ring_constructor import \ 
     30                PolynomialRing 
     31        P = PolynomialRing(base_ring, n, names, order) 
     32        c = c.change_ring(P) 
     33        d = d.change_ring(P) 
     34        #print "c:",c 
     35        #print "c.parent()",c.parent() 
     36        #print "type(c):",type(c) 
     37        #print "d:",d 
     38        #print "d.parent()",d.parent() 
     39        #print "type(d):",type(d) 
     40        from sage.libs.singular.function import singular_function 
     41        ncalgebra = singular_function('nc_algebra') 
     42        cdef RingWrap rw = ncalgebra(c, d, ring = P) 
     43        self._ring = rw._ring 
     44        self._ring.ShortOut = 0 
     45 
     46        self.__ngens = n 
     47        ParentWithGens.__init__(self, base_ring, names) 
     48        #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     49        #self._has_singular = True 
     50        assert(n == len(self._names)) 
    1251         
    13         for i from 0 <= i < n: 
    14             for j from i+1 <= j < n: 
    15                 if int(c[i,j])!=0: 
    16                     matc.m[n*i+j] = p_ISet(int(c[i,j]), self._ring) 
    17         if not d is None: 
    18             #have matrix 
    19             for i from 0 <= i < n: 
    20                 for j from i+1 <= j < n: 
    21                     commuted=d[i,j] 
    22                     if commuted and commuted!=0: 
    23                         f =self(commuted) 
    24                         matd.m[n*i+j] = p_Copy(f._poly, self._ring) 
    25      
    26         nc_CallPlural(matc,matd, NULL, NULL, self._ring) 
    27         id_Delete(<ideal**>&matc, self._ring) 
    28         id_Delete(<ideal**>&matd, self._ring) 
     52        self._one_element = new_NCP(self,p_ISet(1, self._ring)) 
     53        self._zero_element = new_NCP(self,NULL) 
     54 
     55    def term_order(self): 
     56        return self.__term_order 
    2957 
    3058    def _repr_(self): 
    3159        """ 
     
    4674        varstr = ", ".join([ rRingVar(i,self._ring)  for i in range(self.__ngens) ]) 
    4775        return "Noncommutative Multivariate Polynomial Ring in %s over %s"%(varstr,self.base_ring()) 
    4876 
    49 cdef class ExteriorAlgebra_plural(MPolynomialRing_plural): 
     77    def ngens(self): 
     78        """ 
     79        EXAMPLES:: 
     80        """ 
     81        return int(self.__ngens) 
     82 
     83    def gen(self, int n=0): 
     84        cdef poly *_p 
     85        cdef ring *_ring = self._ring 
     86 
     87        if n < 0 or n >= self.__ngens: 
     88            raise ValueError, "Generator not defined." 
     89 
     90        rChangeCurrRing(_ring) 
     91        _p = p_ISet(1,_ring) 
     92        p_SetExp(_p, n+1, 1, _ring) 
     93        p_Setm(_p, _ring); 
     94 
     95        return new_NCP(self,_p) 
     96 
     97    def ideal(self, *gens, **kwds): 
     98        """ 
     99        Create an ideal in this polynomial ring. 
     100 
     101        INPUT: 
     102  
     103        - ``*gens`` - list or tuple of generators (or several input arguments) 
     104 
     105        - ``coerce`` - bool (default: ``True``); this must be a 
     106          keyword argument. Only set it to ``False`` if you are certain 
     107          that each generator is already in the ring. 
     108 
     109        EXAMPLES:: 
     110 
     111        """ 
     112        from sage.rings.polynomial.multi_polynomial_ideal import \ 
     113                NCPolynomialIdeal 
     114        coerce = kwds.get('coerce', True) 
     115        if len(gens) == 1: 
     116            gens = gens[0] 
     117        #if is_SingularElement(gens): 
     118        #    gens = list(gens) 
     119        #    coerce = True 
     120        #elif is_Macaulay2Element(gens): 
     121        #    gens = list(gens) 
     122        #    coerce = True 
     123        if not isinstance(gens, (list, tuple)): 
     124            gens = [gens] 
     125        if coerce: 
     126            gens = [self(x) for x in gens]  # this will even coerce from singular ideals correctly! 
     127        return NCPolynomialIdeal(self, gens, coerce=False) 
     128 
     129cdef class ExteriorAlgebra_plural(NCPolynomialRing_plural): 
    50130    """docstring for ExteriorAlgebra_plural""" 
    51131    def __init__(self, base_ring, n, names): 
    52132        """ 
     
    61141            sage: P("x")*P("x") 
    62142            0 
    63143        """ 
     144        from sage.matrix.constructor  import Matrix 
    64145        c=Matrix(n) 
    65146        d=Matrix(n) 
    66147        for i from 0 <= i < n: 
     
    76157        scaFirstAltVar( self._ring, 1); 
    77158        scaLastAltVar( self._ring, n ); 
    78159        sca_p_ProcsSet(self._ring, self._ring.p_Procs); 
     160 
     161 
     162cdef class NCPolynomial_plural(RingElement): 
     163    def __init__(self, NCPolynomialRing_plural parent): 
     164        self._poly = NULL 
     165        self._parent = <ParentWithBase>parent 
     166 
     167    def __dealloc__(self): 
     168        # TODO: Warn otherwise! 
     169        # for some mysterious reason, various things may be NULL in some cases 
     170        if self._parent is not <ParentWithBase>None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL: 
     171            p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring) 
     172 
     173    def __hash__(self): 
     174        """ 
     175        This hash incorporates the variable name in an effort to 
     176        respect the obvious inclusions into multi-variable polynomial 
     177        rings. 
     178 
     179        The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm. 
     180 
     181        EXAMPLES:: 
     182 
     183            sage: R.<x>=QQ[] 
     184            sage: S.<x,y>=QQ[] 
     185            sage: hash(S(1/2))==hash(1/2)  # respect inclusions of the rationals 
     186            True 
     187            sage: hash(S.0)==hash(R.0)  # respect inclusions into mpoly rings 
     188            True 
     189            sage: # the point is to make for more flexible dictionary look ups 
     190            sage: d={S.0:12} 
     191            sage: d[R.0] 
     192            12 
     193        """ 
     194        return self._hash_c() 
     195 
     196    def __richcmp__(left, right, int op): 
     197        """ 
     198        Compare left and right and return -1, 0, and 1 for <,==, and > 
     199        respectively. 
     200 
     201        EXAMPLES:: 
     202 
     203            sage: P.<x,y,z> = PolynomialRing(QQ,order='degrevlex') 
     204            sage: x == x 
     205            True 
     206 
     207            sage: x > y 
     208            True 
     209            sage: y^2 > x 
     210            True 
     211 
     212            sage: (2/3*x^2 + 1/2*y + 3) > (2/3*x^2 + 1/4*y + 10) 
     213            True 
     214 
     215        TESTS:: 
     216 
     217            sage: P.<x,y,z> = PolynomialRing(QQ, order='degrevlex') 
     218            sage: x > P(0) 
     219            True 
     220 
     221            sage: P(0) == P(0) 
     222            True 
     223 
     224            sage: P(0) < P(1) 
     225            True 
     226 
     227            sage: x > P(1) 
     228            True 
     229             
     230            sage: 1/2*x < 3/4*x 
     231            True 
     232 
     233            sage: (x+1) > x 
     234            True 
     235 
     236            sage: f = 3/4*x^2*y + 1/2*x + 2/7 
     237            sage: f > f 
     238            False 
     239            sage: f < f 
     240            False 
     241            sage: f == f 
     242            True 
     243 
     244            sage: P.<x,y,z> = PolynomialRing(GF(127), order='degrevlex') 
     245            sage: (66*x^2 + 23) > (66*x^2 + 2) 
     246            True 
     247        """ 
     248        return (<Element>left)._richcmp(right, op) 
     249 
     250    cdef int _cmp_c_impl(left, Element right) except -2: 
     251        if left is right: 
     252            return 0 
     253        cdef poly *p = (<NCPolynomial_plural>left)._poly 
     254        cdef poly *q = (<NCPolynomial_plural>right)._poly 
     255        cdef ring *r = (<NCPolynomialRing_plural>left._parent)._ring 
     256        return singular_polynomial_cmp(p, q, r) 
     257 
     258    cpdef ModuleElement _add_( left, ModuleElement right): 
     259        """ 
     260        Add left and right. 
     261 
     262        EXAMPLES:: 
     263 
     264            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     265            sage: 3/2*x + 1/2*y + 1 
     266            3/2*x + 1/2*y + 1 
     267 
     268        """ 
     269        cdef poly *_p 
     270        singular_polynomial_add(&_p, left._poly,  
     271                                 (<NCPolynomial_plural>right)._poly, 
     272                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     273        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     274 
     275    cpdef ModuleElement _sub_( left, ModuleElement right): 
     276        """ 
     277        Subtract left and right. 
     278 
     279        EXAMPLES:: 
     280 
     281            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     282            sage: 3/2*x - 1/2*y - 1 
     283            3/2*x - 1/2*y - 1 
     284 
     285        """ 
     286        cdef ring *_ring = (<NCPolynomialRing_plural>left._parent)._ring 
     287 
     288        cdef poly *_p 
     289        singular_polynomial_sub(&_p, left._poly,  
     290                                (<NCPolynomial_plural>right)._poly, 
     291                                _ring) 
     292        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     293 
     294    cpdef ModuleElement _rmul_(self, RingElement left): 
     295        """ 
     296        Multiply self with a base ring element. 
     297 
     298        EXAMPLES:: 
     299 
     300            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     301            sage: 3/2*x 
     302            3/2*x 
     303        """ 
     304 
     305        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     306        if not left: 
     307            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     308        cdef poly *_p 
     309        singular_polynomial_rmul(&_p, self._poly, left, _ring) 
     310        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     311         
     312    cpdef ModuleElement _lmul_(self, RingElement right): 
     313        # all currently implemented rings are commutative 
     314        return self._rmul_(right) 
     315         
     316    cpdef RingElement  _mul_(left, RingElement right): 
     317        """ 
     318        Multiply left and right. 
     319 
     320        EXAMPLES:: 
     321 
     322            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     323            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) 
     324            9/4*x^2 - 1/4*y^2 - y - 1 
     325 
     326            sage: P.<x,y> = PolynomialRing(QQ,order='lex') 
     327            sage: (x^2^30) * x^2^30 
     328            Traceback (most recent call last): 
     329            ... 
     330            OverflowError: Exponent overflow (...). 
     331        """ 
     332        # all currently implemented rings are commutative 
     333        cdef poly *_p 
     334        singular_polynomial_mul(&_p, left._poly,  
     335                                 (<NCPolynomial_plural>right)._poly,  
     336                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     337        return new_NCP((<NCPolynomialRing_plural>left._parent),_p) 
     338 
     339    cpdef RingElement _div_(left, RingElement right): 
     340        """ 
     341        Divide left by right 
     342 
     343        EXAMPLES:: 
     344 
     345            sage: R.<x,y>=PolynomialRing(QQ,2) 
     346            sage: f = (x + y)/3 
     347            sage: f.parent() 
     348            Multivariate Polynomial Ring in x, y over Rational Field 
     349 
     350        Note that / is still a constructor for elements of the 
     351        fraction field in all cases as long as both arguments have the 
     352        same parent and right is not constant. :: 
     353 
     354            sage: R.<x,y>=PolynomialRing(QQ,2) 
     355            sage: f = x^3 + y 
     356            sage: g = x 
     357            sage: h = f/g; h 
     358            (x^3 + y)/x 
     359            sage: h.parent() 
     360            Fraction Field of Multivariate Polynomial Ring in x, y over Rational Field 
     361 
     362        If we divide over `\ZZ` the result is the same as multiplying 
     363        by 1/3 (i.e. base extension). :: 
     364         
     365            sage: R.<x,y> = ZZ[] 
     366            sage: f = (x + y)/3       
     367            sage: f.parent() 
     368            Multivariate Polynomial Ring in x, y over Rational Field 
     369            sage: f = (x + y) * 1/3       
     370            sage: f.parent() 
     371            Multivariate Polynomial Ring in x, y over Rational Field 
     372             
     373        But we get a true fraction field if the denominator is not in 
     374        the fraction field of the base ring."" 
     375         
     376            sage: f = x/y 
     377            sage: f.parent() 
     378            Fraction Field of Multivariate Polynomial Ring in x, y over Integer Ring 
     379 
     380        Division will fail for non-integral domains:: 
     381 
     382            sage: P.<x,y> = Zmod(1024)[] 
     383            sage: x/P(3) 
     384            Traceback (most recent call last): 
     385            ... 
     386            TypeError: self must be an integral domain. 
     387 
     388            sage: x/3 
     389            Traceback (most recent call last): 
     390            ... 
     391            TypeError: self must be an integral domain. 
     392 
     393        TESTS:: 
     394 
     395            sage: R.<x,y>=PolynomialRing(QQ,2) 
     396            sage: x/0 
     397            Traceback (most recent call last): 
     398            ... 
     399            ZeroDivisionError: rational division by zero 
     400        """ 
     401        cdef poly *p  
     402        cdef bint is_field = left._parent._base.is_field() 
     403        if p_IsConstant((<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring): 
     404            if is_field: 
     405                singular_polynomial_div_coeff(&p, left._poly, (<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring) 
     406                return new_NCP(left._parent, p) 
     407            else: 
     408                return left.change_ring(left.base_ring().fraction_field())/right 
     409        else: 
     410            return (<NCPolynomialRing_plural>left._parent).fraction_field()(left,right) 
     411 
     412    def __pow__(NCPolynomial_plural self, exp, ignored): 
     413        """ 
     414        Return ``self**(exp)``. 
     415 
     416        The exponent must be an integer. 
     417 
     418        EXAMPLES:: 
     419 
     420            sage: R.<x,y> = PolynomialRing(QQ,2) 
     421            sage: f = x^3 + y 
     422            sage: f^2 
     423            x^6 + 2*x^3*y + y^2 
     424            sage: g = f^(-1); g 
     425            1/(x^3 + y) 
     426            sage: type(g) 
     427            <type 'sage.rings.fraction_field_element.FractionFieldElement'> 
     428 
     429            sage: P.<x,y> = PolynomialRing(ZZ) 
     430            sage: P(2)**(-1) 
     431            1/2 
     432             
     433            sage: P.<u,v> = PolynomialRing(QQ, 2) 
     434            sage: u^(1/2) 
     435            Traceback (most recent call last): 
     436            ... 
     437            TypeError: non-integral exponents not supported 
     438 
     439            sage: P.<x,y> = PolynomialRing(QQ,order='lex') 
     440            sage: (x+y^2^30)^10 
     441            Traceback (most recent call last): 
     442            .... 
     443            OverflowError: Exponent overflow (...). 
     444        """ 
     445        if not PY_TYPE_CHECK_EXACT(exp, Integer) or \ 
     446                PY_TYPE_CHECK_EXACT(exp, int): 
     447                    try: 
     448                        exp = Integer(exp) 
     449                    except TypeError: 
     450                        raise TypeError, "non-integral exponents not supported" 
     451 
     452        if exp < 0: 
     453            return 1/(self**(-exp)) 
     454        elif exp == 0: 
     455            return (<NCPolynomialRing_plural>self._parent)._one_element 
     456 
     457        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     458        cdef poly *_p 
     459        singular_polynomial_pow(&_p, self._poly, exp, _ring) 
     460        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     461 
     462    def __neg__(self): 
     463        """ 
     464        Return ``-self``. 
     465 
     466        EXAMPLES:: 
     467 
     468            sage: R.<x,y>=PolynomialRing(QQ,2) 
     469            sage: f = x^3 + y 
     470            sage: -f 
     471            -x^3 - y 
     472        """ 
     473        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     474 
     475        cdef poly *p 
     476        singular_polynomial_neg(&p, self._poly, _ring) 
     477        return new_NCP((<NCPolynomialRing_plural>self._parent), p) 
     478 
     479    def _repr_(self): 
     480        """ 
     481        EXAMPLES:: 
     482 
     483            sage: R.<x,y>=PolynomialRing(QQ,2) 
     484            sage: f = x^3 + y 
     485            sage: f # indirect doctest 
     486            x^3 + y 
     487        """ 
     488        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     489        s = singular_polynomial_str(self._poly, _ring) 
     490        return s 
     491 
     492    cpdef _repr_short_(self): 
     493        """ 
     494        This is a faster but less pretty way to print polynomials. If 
     495        available it uses the short SINGULAR notation. 
     496         
     497        EXAMPLES:: 
     498 
     499            sage: R.<x,y>=PolynomialRing(QQ,2) 
     500            sage: f = x^3 + y 
     501            sage: f._repr_short_() 
     502            'x3+y' 
     503        """ 
     504        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     505        rChangeCurrRing(_ring) 
     506        if _ring.CanShortOut: 
     507            _ring.ShortOut = 1 
     508            s = p_String(self._poly, _ring, _ring) 
     509            _ring.ShortOut = 0 
     510        else: 
     511            s = p_String(self._poly, _ring, _ring) 
     512        return s 
     513                                            
     514    def _latex_(self): 
     515        """ 
     516        Return a polynomial LaTeX representation of this polynomial. 
     517 
     518        EXAMPLES:: 
     519 
     520            sage: P.<x,y,z> = QQ[] 
     521            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     522            sage: latex(f) 
     523            - x^{2} y - \frac{25}{27} y^{3} - z^{2} 
     524        """ 
     525        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     526        gens = self.parent().latex_variable_names() 
     527        base = self.parent().base() 
     528        return singular_polynomial_latex(self._poly, _ring, base, gens) 
     529     
     530    def _repr_with_changed_varnames(self, varnames): 
     531        """ 
     532        Return string representing this polynomial but change the 
     533        variable names to ``varnames``. 
     534 
     535        EXAMPLES:: 
     536 
     537            sage: P.<x,y,z> = QQ[] 
     538            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     539            sage: print f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR']) 
     540            -FOO^2*BAR - 25/27*BAR^3 - FOOBAR^2 
     541        """ 
     542        return  singular_polynomial_str_with_changed_varnames(self._poly, (<NCPolynomialRing_plural>self._parent)._ring, varnames) 
     543             
     544    def degree(self, NCPolynomial_plural x=None): 
     545        """ 
     546        Return the maximal degree of this polynomial in ``x``, where 
     547        ``x`` must be one of the generators for the parent of this 
     548        polynomial. 
     549 
     550        INPUT: 
     551 
     552        - ``x`` - multivariate polynomial (a generator of the parent of 
     553          self) If x is not specified (or is ``None``), return the total 
     554          degree, which is the maximum degree of any monomial. 
     555 
     556        OUTPUT: 
     557            integer 
     558         
     559        EXAMPLES:: 
     560 
     561            sage: R.<x, y> = QQ[] 
     562            sage: f = y^2 - x^9 - x 
     563            sage: f.degree(x) 
     564            9 
     565            sage: f.degree(y) 
     566            2 
     567            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x) 
     568            3 
     569            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y) 
     570            10 
     571 
     572        TESTS:: 
     573 
     574            sage: P.<x, y> = QQ[] 
     575            sage: P(0).degree(x) 
     576            -1 
     577            sage: P(1).degree(x) 
     578            0 
     579 
     580        """ 
     581        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     582        cdef poly *p = self._poly 
     583        if not x: 
     584            return singular_polynomial_deg(p,NULL,r) 
     585 
     586        # TODO: we can do this faster 
     587        if not x in self._parent.gens(): 
     588            raise TypeError("x must be one of the generators of the parent.") 
     589 
     590        return singular_polynomial_deg(p, (<NCPolynomial_plural>x)._poly, r) 
     591 
     592    def total_degree(self): 
     593        """ 
     594        Return the total degree of ``self``, which is the maximum degree 
     595        of all monomials in ``self``. 
     596 
     597        EXAMPLES:: 
     598 
     599            sage: R.<x,y,z> = QQ[] 
     600            sage: f=2*x*y^3*z^2 
     601            sage: f.total_degree() 
     602            6 
     603            sage: f=4*x^2*y^2*z^3 
     604            sage: f.total_degree() 
     605            7 
     606            sage: f=99*x^6*y^3*z^9 
     607            sage: f.total_degree() 
     608            18 
     609            sage: f=x*y^3*z^6+3*x^2 
     610            sage: f.total_degree() 
     611            10 
     612            sage: f=z^3+8*x^4*y^5*z 
     613            sage: f.total_degree() 
     614            10 
     615            sage: f=z^9+10*x^4+y^8*x^2 
     616            sage: f.total_degree() 
     617            10 
     618 
     619        TESTS:: 
     620 
     621            sage: R.<x,y,z> = QQ[] 
     622            sage: R(0).total_degree() 
     623            -1 
     624            sage: R(1).total_degree() 
     625            0 
     626        """ 
     627        cdef poly *p = self._poly 
     628        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     629        return singular_polynomial_deg(p,NULL,r) 
     630 
     631    def degrees(self): 
     632        """  
     633        Returns a tuple with the maximal degree of each variable in 
     634        this polynomial.  The list of degrees is ordered by the order 
     635        of the generators. 
     636 
     637        EXAMPLES:: 
     638 
     639            sage: R.<y0,y1,y2> = PolynomialRing(QQ,3) 
     640            sage: q = 3*y0*y1*y1*y2; q  
     641            3*y0*y1^2*y2  
     642            sage: q.degrees()  
     643            (1, 2, 1) 
     644            sage: (q + y0^5).degrees() 
     645            (5, 2, 1) 
     646        """ 
     647        cdef poly *p = self._poly 
     648        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     649        cdef int i 
     650        cdef list d = [0 for _ in range(r.N)] 
     651        while p: 
     652            for i from 0 <= i < r.N: 
     653                d[i] = max(d[i],p_GetExp(p, i+1, r)) 
     654            p = pNext(p) 
     655        return tuple(d) 
     656 
     657    cdef long _hash_c(self): 
     658        """ 
     659        See ``self.__hash__`` 
     660        """ 
     661        cdef poly *p 
     662        cdef ring *r 
     663        cdef int n 
     664        cdef int v 
     665        r = (<NCPolynomialRing_plural>self._parent)._ring 
     666        if r!=currRing: rChangeCurrRing(r) 
     667        base = (<NCPolynomialRing_plural>self._parent)._base 
     668        p = self._poly 
     669        cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap 
     670        cdef long result_mon 
     671        var_name_hash = [hash(vn) for vn in self._parent.variable_names()] 
     672        cdef long c_hash 
     673        while p: 
     674            c_hash = hash(si2sa(p_GetCoeff(p, r), r, base)) 
     675            if c_hash != 0: # this is always going to be true, because we are sparse (correct?) 
     676                # Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm. 
     677                # I omit gen,exp pairs where the exponent is zero. 
     678                result_mon = c_hash 
     679                for v from 1 <= v <= r.N: 
     680                    n = p_GetExp(p,v,r) 
     681                    if n!=0: 
     682                        result_mon = (1000003 * result_mon) ^ var_name_hash[v-1] 
     683                        result_mon = (1000003 * result_mon) ^ n 
     684                result += result_mon 
     685 
     686            p = pNext(p) 
     687        if result == -1: 
     688            return -2 
     689        return result 
     690 
     691 
     692cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, 
     693        poly *juice): 
     694    """ 
     695    Construct NCPolynomial_plural from parent and SINGULAR poly. 
     696    """ 
     697    cdef NCPolynomial_plural p 
     698    p = PY_NEW(NCPolynomial_plural) 
     699    p._parent = <ParentWithBase>parent 
     700    p._poly = juice 
     701    p_Normalize(p._poly, parent._ring) 
     702    return p 
  • sage/rings/ring.pxd

    diff --git a/sage/rings/ring.pxd b/sage/rings/ring.pxd
    a b  
    55    cdef public object _one_element 
    66    cdef public object _zero_ideal 
    77    cdef public object _unit_ideal 
     8    cdef public object __ideal_monoid 
    89    cdef _an_element_c_impl(self) 
    910 
    1011cdef class CommutativeRing(Ring): 
    1112    cdef public object __fraction_field 
    12     cdef public object __ideal_monoid 
    1313 
    1414cdef class IntegralDomain(CommutativeRing): 
    1515    pass 
  • sage/rings/ring.pyx

    diff --git a/sage/rings/ring.pyx b/sage/rings/ring.pyx
    a b  
    911911            if not x.is_zero(): 
    912912                return x 
    913913 
     914    def ideal_monoid(self): 
     915        """ 
     916        Return the monoid of ideals of this ring. 
     917 
     918        EXAMPLES:: 
     919 
     920            sage: ZZ.ideal_monoid() 
     921            Monoid of ideals of Integer Ring 
     922            sage: R.<x>=QQ[]; R.ideal_monoid() 
     923            Monoid of ideals of Univariate Polynomial Ring in x over Rational Field 
     924        """ 
     925        if self.__ideal_monoid is not None: 
     926            return self.__ideal_monoid 
     927        else: 
     928            from sage.rings.ideal_monoid import IdealMonoid 
     929            M = IdealMonoid(self) 
     930            self.__ideal_monoid = M 
     931            return M 
     932 
    914933cdef class CommutativeRing(Ring): 
    915934    """ 
    916935    Generic commutative ring. 
     
    10561075        """ 
    10571076        raise NotImplementedError 
    10581077 
    1059     def ideal_monoid(self): 
    1060         """ 
    1061         Return the monoid of ideals of this ring. 
    1062  
    1063         EXAMPLES:: 
    1064  
    1065             sage: ZZ.ideal_monoid() 
    1066             Monoid of ideals of Integer Ring 
    1067             sage: R.<x>=QQ[]; R.ideal_monoid() 
    1068             Monoid of ideals of Univariate Polynomial Ring in x over Rational Field 
    1069         """ 
    1070         if self.__ideal_monoid is not None: 
    1071             return self.__ideal_monoid 
    1072         else: 
    1073             from sage.rings.ideal_monoid import IdealMonoid 
    1074             M = IdealMonoid(self) 
    1075             self.__ideal_monoid = M 
    1076             return M 
    1077  
    10781078    def quotient(self, I, names=None): 
    10791079        """ 
    10801080        Create the quotient of R by the ideal I.