Ticket #4539: plural_3.patch

File plural_3.patch, 53.7 KB (added by burcin, 6 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.