Ticket #4539: plural_folded-4.4.4.patch

File plural_folded-4.4.4.patch, 72.2 KB (added by OleksandrMotsak, 6 years ago)

i have just folded all the previous patches by Michael & Burcin into plural_folded-4.4.4.patch (should be applied before anything else)

  • module_list.py

    * * *
    Initial wrapper for plural.
    * * *
    MPolynomialRing_plural now accepts matrix parameters to specify commutativity
    relations. Added ExteriorAlgebra.
    * * *
    [mq]: plural_3.patch
    
    diff -r 8dec8b43ccca module_list.py
    a b  
    13021302              include_dirs = [SAGE_ROOT +'/local/include/singular'],
    13031303              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
    13041304
     1305    Extension('sage.rings.polynomial.plural',
     1306              sources = ['sage/rings/polynomial/plural.pyx'],
     1307              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
     1308              language="c++",
     1309              include_dirs = [SAGE_ROOT +'/local/include/singular'],
     1310              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
     1311
    13051312    Extension('sage.rings.polynomial.multi_polynomial_libsingular',
    13061313              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'],
    13071314              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
  • sage/algebras/free_algebra.py

    diff -r 8dec8b43ccca sage/algebras/free_algebra.py
    a b  
    6868
    6969import sage.structure.parent_gens
    7070
    71        
    7271def FreeAlgebra(R, n, names):
    7372    """
    7473    Return the free algebra over the ring `R` on `n`
     
    451450        """
    452451        return self.__monoid
    453452   
    454                    
     453    def g_algebra(self, relations, order='degrevlex'):
     454        """
     455           
     456            The G-Algebra derrived from this algebra by relations.
     457            By default is assumed, that two variables commute.
     458           
     459            TODO:
     460            * Coercion doesn't work yet, there is some cheating about assumptions
     461            * Check degeneracy conditions
     462            Furthermore, the default values interfere with non degeneracy conditions...
     463           
     464            EXAMPLES:
     465            sage: A.<x,y,z>=FreeAlgebra(QQ,3)
     466            sage: G=A.g_algebra({y*x:-x*y})
     467            sage: (x,y,z)=G.gens()
     468            sage: x*y
     469            x*y
     470            sage: y*x
     471            -x*y
     472            sage: z*x
     473            x*z
     474            sage: (x,y,z)=A.gens()
     475            sage: G=A.g_algebra({y*x:-x*y+1})
     476            sage: (x,y,z)=G.gens()
     477            sage: y*x
     478            -x*y + 1
     479            sage: (x,y,z)=A.gens()
     480            sage: G=A.g_algebra({y*x:-x*y+z})
     481            sage: (x,y,z)=G.gens()
     482            sage: y*x
     483            -x*y + z
     484        """
     485        from sage.matrix.constructor  import Matrix
     486        from sage.rings.polynomial.plural import NCPolynomialRing_plural
     487       
     488        base_ring=self.base_ring()
     489        n=self.ngens()
     490        cmat=Matrix(base_ring,n)
     491        dmat=Matrix(self,n)
     492        for i in xrange(n):
     493            for j in xrange(i+1,n):
     494                cmat[i,j]=1
     495        for (to_commute,commuted) in relations.iteritems():
     496            #This is dirty, coercion is broken
     497            assert isinstance(to_commute,FreeAlgebraElement), to_commute.__class__
     498            assert isinstance(commuted,FreeAlgebraElement), commuted
     499            ((v1,e1),(v2,e2))=list(list(to_commute)[0][1])
     500            assert e1==1
     501            assert e2==1
     502            assert v1>v2
     503            c_coef=None
     504            d_poly=None
     505            for (c,m) in commuted:
     506                if list(m)==[(v2,1),(v1,1)]:
     507                    c_coef=c
     508                    #buggy coercion workaround
     509                    d_poly=commuted-self(c)*self(m)
     510                    break
     511            assert not c_coef is None,list(m)
     512            v2_ind = self.gens().index(v2)
     513            v1_ind = self.gens().index(v1)
     514            cmat[v2_ind,v1_ind]=c_coef
     515            if d_poly:
     516                dmat[v2_ind,v1_ind]=d_poly
     517       
     518        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat,order=order)
     519           
     520           
    455521from sage.misc.cache import Cache
    456522cache = Cache(FreeAlgebra_generic)
  • sage/libs/singular/function.pxd

    diff -r 8dec8b43ccca sage/libs/singular/function.pxd
    a b  
    1919from sage.libs.singular.decl cimport ring as singular_ring
    2020from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular, MPolynomial_libsingular
    2121
     22cdef poly* access_singular_poly(p) except <poly*> -1
     23cdef singular_ring* access_singular_ring(r) except <singular_ring*> -1
     24
    2225cdef class RingWrap:
    2326    cdef singular_ring *_ring
    2427
    2528cdef class Resolution:
    2629    cdef syStrategy *_resolution
    27     cdef MPolynomialRing_libsingular base_ring
     30    cdef object base_ring
    2831
    2932cdef class Converter(SageObject):
    3033    cdef leftv *args
    31     cdef MPolynomialRing_libsingular _ring
     34    cdef object _sage_ring
     35    cdef singular_ring* _singular_ring
    3236    cdef leftv* pop_front(self) except NULL
    3337    cdef leftv * _append_leftv(self, leftv *v)
    3438    cdef leftv * _append(self, void* data, int res_type)
    35     cdef leftv * append_polynomial(self, MPolynomial_libsingular p) except NULL
     39    cdef leftv * append_polynomial(self, p) except NULL
    3640    cdef leftv * append_ideal(self,  i) except NULL
    3741    cdef leftv * append_number(self, n) except NULL
    3842    cdef leftv * append_int(self, n) except NULL
     
    4347    cdef leftv * append_intvec(self, v) except NULL
    4448    cdef leftv * append_list(self, l) except NULL
    4549    cdef leftv * append_matrix(self, a) except NULL
    46     cdef leftv * append_ring(self, MPolynomialRing_libsingular r) except NULL
     50    cdef leftv * append_ring(self, r) except NULL
    4751    cdef leftv * append_module(self, m) except NULL
    4852    cdef to_sage_integer_matrix(self, intvec *mat)
    4953    cdef object to_sage_module_element_sequence_destructive(self, ideal *i)
     
    6973
    7074    cdef BaseCallHandler get_call_handler(self)
    7175    cdef bint function_exists(self)
    72     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=?)
     76    cdef common_ring(self, tuple args, ring=?)
    7377
    7478cdef class SingularLibraryFunction(SingularFunction):
    7579    pass
     
    7882    pass
    7983
    8084# the most direct function call interface
    81 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=?, object attributes=?)
     85cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=?, object attributes=?)
  • sage/libs/singular/function.pyx

    diff -r 8dec8b43ccca sage/libs/singular/function.pyx
    a b  
    1313- Martin Albrecht (2009-07): clean up, enhancements, etc.
    1414- Michael Brickenstein (2009-10): extension to more Singular types
    1515- Martin Albrecht (2010-01): clean up, support for attributes
     16- Burcin Erocal (2010-7): plural support
     17- Michael Brickenstein (2010-7): plural support
    1618
    1719EXAMPLES:
    1820
     
    8082from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, new_MP
    8183from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
    8284
     85from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, \
     86        NCPolynomial_plural, new_NCP
     87from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
     88
    8389from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
    8490
    8591from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence
     
    118124   
    119125    for (i, p) in enumerate(v):
    120126        component = <int>i+1
    121         poly_component = p_Copy(
    122             (<MPolynomial_libsingular>p)._poly, r)
     127        poly_component = copy_sage_polynomial_into_singular_poly(p)
    123128        p_iter = poly_component
    124129        while p_iter!=NULL:
    125130            p_SetComp(p_iter, component, r)
     
    128133        res=p_Add_q(res, poly_component, r)
    129134    return res
    130135
     136
    131137cdef class RingWrap:
    132138    """
    133139    A simple wrapper around Singular's rings.
     
    166172           sage: M = syz(I)
    167173           sage: resolution = mres(M, 0)
    168174        """
    169         assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular)
    170         self.base_ring = <MPolynomialRing_libsingular> base_ring
     175        #FIXME: still not working noncommutative
     176        assert is_sage_wrapper_for_singular_ring(base_ring)
     177        self.base_ring = base_ring
    171178    def __repr__(self):
    172179        """
    173180        EXAMPLE::
     
    225232    args.CleanUp()
    226233    omFreeBin(args, sleftv_bin)
    227234
     235# =====================================
     236# = Singular/Plural Abstraction Layer =
     237# =====================================
    228238
    229 def all_polynomials(s):
     239def is_sage_wrapper_for_singular_ring(ring):
     240    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     241        return True
     242    if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     243        return True
     244    return False
     245
     246cdef new_sage_polynomial(ring,  poly *p):
     247    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     248        return new_MP(ring, p)
     249    else:
     250        if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     251            return new_NCP(ring, p)
     252    raise ValueError("not a singular or plural ring")
     253
     254def is_singular_poly_wrapper(p):
     255    """
     256        checks if p is some data type corresponding to some singular ``poly```.
     257       
     258        EXAMPLE::
     259            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
     260            sage: from sage.matrix.constructor  import Matrix
     261            sage: from sage.libs.singular.function import is_singular_poly_wrapper
     262            sage: c=Matrix(2)
     263            sage: c[0,1]=-1
     264            sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
     265            sage: (x,y)=P.gens()
     266            sage: is_singular_poly_wrapper(x+y)
     267            True
     268       
     269    """
     270    return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p,  NCPolynomial_plural)
     271
     272def all_singular_poly_wrapper(s):
    230273    """
    231274    Tests for a sequence ``s``, whether it consists of
    232275    singular polynomials.
    233276   
    234277    EXAMPLE::
    235278       
    236         sage: from sage.libs.singular.function import all_polynomials
     279        sage: from sage.libs.singular.function import all_singular_poly_wrapper
    237280        sage: P.<x,y,z> = QQ[]
    238         sage: all_polynomials([x+1, y])
     281        sage: all_singular_poly_wrapper([x+1, y])
    239282        True
    240         sage: all_polynomials([x+1, y, 1])
     283        sage: all_singular_poly_wrapper([x+1, y, 1])
    241284        False
    242285    """
    243286    for p in s:
    244         if not isinstance(p, MPolynomial_libsingular):
     287        if not is_singular_poly_wrapper(p):
    245288            return False
    246289    return True
    247290
     291cdef poly* access_singular_poly(p) except <poly*> -1:
     292    """
     293        Get the raw ``poly`` pointer from a wrapper object
     294        EXAMPLE::
     295            # sage: P.<a,b,c> = PolynomialRing(QQ)
     296            #  sage: p=a+b
     297            #  sage: from sage.libs.singular.function import access_singular_poly
     298            #  sage: access_singular_poly(p)
     299    """
     300    if PY_TYPE_CHECK(p, MPolynomial_libsingular):
     301        return (<MPolynomial_libsingular> p)._poly
     302    else:
     303        if PY_TYPE_CHECK(p, NCPolynomial_plural):
     304            return (<NCPolynomial_plural> p)._poly
     305    raise ValueError("not a singular polynomial wrapper")
     306
     307cdef ring* access_singular_ring(r) except <ring*> -1:
     308    """
     309        Get the singular ``ring`` pointer from a
     310        wrapper object.
     311       
     312        EXAMPLE::
     313            # sage: P.<x,y,z> = QQ[]
     314            # sage: from sage.libs.singular.function import access_singular_ring
     315            # sage: access_singular_ring(P)
     316
     317    """
     318    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular):
     319        return (<MPolynomialRing_libsingular> r )._ring
     320    if PY_TYPE_CHECK(r, NCPolynomialRing_plural):
     321        return (<NCPolynomialRing_plural> r )._ring
     322    raise ValueError("not a singular polynomial ring wrapper")
     323 
     324cdef poly* copy_sage_polynomial_into_singular_poly(p):
     325    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent()))
     326
    248327def all_vectors(s):
    249328    """
    250329    Checks if a sequence ``s`` consists of free module
     
    265344        False
    266345    """
    267346    for p in s:
    268         if not (isinstance(p, FreeModuleElement_generic_dense)\
    269             and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)):
     347        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\
     348            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())):
    270349            return False
    271350    return True
    272351
    273352
    274353
     354
     355
     356
     357
    275358cdef class Converter(SageObject):
    276359    """
    277360    A :class:`Converter` interfaces between Sage objects and Singular
     
    300383        """
    301384        cdef leftv *v
    302385        self.args = NULL
    303         self._ring = ring
     386        self._sage_ring = ring
     387        if ring is not None:
     388            self._singular_ring = access_singular_ring(ring)
     389       
    304390        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    305391        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
     392        from sage.matrix.matrix_generic_dense import Matrix_generic_dense
    306393        for a in args:
    307             if PY_TYPE_CHECK(a, MPolynomial_libsingular):
    308                 v = self.append_polynomial(<MPolynomial_libsingular> a)
     394            if is_singular_poly_wrapper(a):
     395                v = self.append_polynomial(a)
    309396
    310             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
    311                 v = self.append_ring(<MPolynomialRing_libsingular> a)
     397            elif is_sage_wrapper_for_singular_ring(a):
     398                v = self.append_ring(a)
    312399
    313             elif PY_TYPE_CHECK(a, MPolynomialIdeal):
     400            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     401                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    314402                v = self.append_ideal(a)
    315403
    316404            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long):
     
    324412
    325413            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    326414                v = self.append_intmat(a)
    327 
     415           
     416            elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\
     417                is_sage_wrapper_for_singular_ring(a.parent().base_ring()):
     418                self.append_matrix(a)
     419           
    328420            elif PY_TYPE_CHECK(a, Resolution):
    329421                v = self.append_resolution(a)
    330422
    331423            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    332                 and isinstance(
    333                     a.parent().base_ring(),
    334                     MPolynomialRing_libsingular):
     424                and is_sage_wrapper_for_singular_ring(
     425                    a.parent().base_ring()):
    335426                v = self.append_vector(a)
    336427               
    337428            # as output ideals get converted to sequences
     
    339430            # this means, that Singular lists should not be converted to Sequences,
    340431            # as we do not want ambiguities
    341432            elif PY_TYPE_CHECK(a, Sequence)\
    342                 and all_polynomials(a):
     433                and all_singular_poly_wrapper(a):
    343434                v = self.append_ideal(ring.ideal(a))
    344435            elif PY_TYPE_CHECK(a, Sequence)\
    345436                and all_vectors(a):
     
    358449                    v = self.append_intvec(a)
    359450                else:
    360451                    v = self.append_list(a)
    361             elif a.parent() is self._ring.base_ring():
     452            elif a.parent() is self._sage_ring.base_ring():
    362453                v = self.append_number(a)
    363454
    364455            elif PY_TYPE_CHECK(a, Integer):
     
    387478            sage: Converter([a,b,c],ring=P).ring()
    388479            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    389480        """
    390         return self._ring
     481        return self._sage_ring
    391482
    392483    def _repr_(self):
    393484        """
     
    398489            sage: Converter([a,b,c],ring=P) # indirect doctest
    399490            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    400491        """
    401         return "Singular Converter in %s"%(self._ring)
     492        return "Singular Converter in %s"%(self._sage_ring)
    402493
    403494    def __dealloc__(self):
    404495        if self.args:
     
    463554        Convert singular matrix to matrix over the polynomial ring.
    464555        """
    465556        from sage.matrix.constructor import Matrix
    466         sage_ring = self._ring
    467         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
    468             sage_ring)._ring
     557        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
     558        #    self._sage_ring)._ring
    469559        ncols = mat.ncols
    470560        nrows = mat.nrows
    471         result = Matrix(sage_ring, nrows, ncols)
    472         cdef MPolynomial_libsingular p
     561        result = Matrix(self._sage_ring, nrows, ncols)
    473562        for i in xrange(nrows):
    474563            for j in xrange(ncols):
    475                 p = MPolynomial_libsingular(sage_ring)
    476                 p._poly = mat.m[i*ncols+j]
     564                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j])
    477565                mat.m[i*ncols+j]=NULL
    478566                result[i,j] = p
    479567        return result
    480568   
    481569    cdef to_sage_vector_destructive(self, poly *p, free_module = None):
    482         cdef ring *r=self._ring._ring
     570        #cdef ring *r=self._ring._ring
    483571        cdef int rank
    484572        if free_module:
    485573            rank = free_module.rank()
    486574        else:
    487             rank = singular_vector_maximal_component(p, r)
    488             free_module = self._ring**rank
     575            rank = singular_vector_maximal_component(p, self._singular_ring)
     576            free_module = self._sage_ring**rank
    489577        cdef poly *acc
    490578        cdef poly *p_iter
    491579        cdef poly *first
     
    498586            first = NULL
    499587            p_iter=p
    500588            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)
     589                if p_GetComp(p_iter, self._singular_ring) == i:
     590                    p_SetComp(p_iter,0, self._singular_ring)
     591                    p_Setm(p_iter, self._singular_ring)
    504592                    if acc == NULL:
    505593                        first = p_iter
    506594                    else:
     
    515603                else:
    516604                    previous = p_iter
    517605                    p_iter = pNext(p_iter)
    518             result.append(new_MP(self._ring, first))
     606           
     607            result.append(new_sage_polynomial(self._sage_ring, first))
    519608        return free_module(result)
    520609         
    521610    cdef object to_sage_module_element_sequence_destructive( self, ideal *i):
     
    529618        - ``r`` -- a SINGULAR ring
    530619        - ``sage_ring`` -- a Sage ring matching r
    531620        """
    532         cdef MPolynomialRing_libsingular sage_ring = self._ring
     621        #cdef MPolynomialRing_libsingular sage_ring = self._ring
    533622        cdef int j
    534623        cdef int rank=i.rank
    535         free_module = sage_ring**rank       
     624        free_module = self._sage_ring ** rank       
    536625        l = []
    537626
    538627        for j from 0 <= j < IDELEMS(i):
     
    561650        return result
    562651   
    563652   
    564     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL:
     653    cdef leftv *append_polynomial(self, p) except NULL:
    565654        """
    566655        Append the polynomial ``p`` to the list.
    567656        """
    568         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring)
     657        cdef poly* _p
     658        _p = copy_sage_polynomial_into_singular_poly(p)
     659               
    569660        return self._append(_p, POLY_CMD)
    570661
    571662    cdef leftv *append_ideal(self,  i) except NULL:
     
    582673        """
    583674        rank = max([v.parent().rank() for v in m])
    584675        cdef ideal *result
    585         cdef ring *r = self._ring._ring
     676        cdef ring *r = self._singular_ring
    586677        cdef ideal *i
    587678        cdef int j = 0
    588679
     
    598689        """
    599690        Append the number ``n`` to the list.
    600691        """
    601         cdef number *_n =  sa2si(n, self._ring._ring)
     692        cdef number *_n =  sa2si(n, self._singular_ring)
    602693        return self._append(<void *>_n, NUMBER_CMD)
    603694
    604     cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL:
     695    cdef leftv *append_ring(self, r) except NULL:
    605696        """
    606697        Append the ring ``r`` to the list.
    607698        """
    608         cdef ring *_r =  <ring*> r._ring
     699        cdef ring *_r =  access_singular_ring(r)
    609700        _r.ref+=1
    610701        return self._append(<void *>_r, RING_CMD)
    611702
    612703    cdef leftv *append_matrix(self, mat) except NULL:
    613704       
    614705        sage_ring = mat.base_ring()
    615         cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring
     706        cdef ring *r=<ring*> access_singular_ring(sage_ring)
    616707
    617708        cdef poly *p
    618709        ncols = mat.ncols()
     
    620711        cdef matrix* _m=mpNew(nrows,ncols)
    621712        for i in xrange(nrows):
    622713            for j in xrange(ncols):
    623                 p = p_Copy(
    624                     (<MPolynomial_libsingular> mat[i,j])._poly, r)
     714                #FIXME
     715                p = copy_sage_polynomial_into_singular_poly(mat[i,j])
    625716                _m.m[ncols*i+j]=p
    626717        return self._append(_m, MATRIX_CMD)
    627718
     
    639730        Append the list ``l`` to the list.
    640731        """
    641732       
    642         cdef Converter c = Converter(l, self._ring)
     733        cdef Converter c = Converter(l, self._sage_ring)
    643734        n = len(c)
    644735
    645736        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin)
     
    670761        Append vector ``v`` from free
    671762        module over polynomial ring.
    672763        """
    673         cdef ring *r = self._ring._ring
     764        cdef ring *r = self._singular_ring
    674765        cdef poly *p = sage_vector_to_poly(v, r)
    675766        return self._append(<void*> p, VECTOR_CMD)
    676767   
     
    710801
    711802        - ``to_convert`` - a Singular ``leftv``
    712803        """
     804        #FIXME
    713805        cdef MPolynomial_libsingular res_poly
    714806        cdef int rtyp = to_convert.rtyp
    715807        cdef lists *singular_list
    716808        cdef Resolution res_resolution
    717809        if rtyp == IDEAL_CMD:
    718             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring)
     810            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring)
    719811
    720812        elif rtyp == POLY_CMD:
    721             res_poly = MPolynomial_libsingular(self._ring)
     813            #FIXME
     814            res_poly = MPolynomial_libsingular(self._sage_ring)
    722815            res_poly._poly = <poly*>to_convert.data
    723816            to_convert.data = NULL
    724817            #prevent it getting free, when cleaning the leftv
     
    728821            return <long>to_convert.data
    729822       
    730823        elif rtyp == NUMBER_CMD:
    731             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring())
     824            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring())
    732825
    733826        elif rtyp == INTVEC_CMD:
    734827            return si2sa_intvec(<intvec *>to_convert.data)
     
    770863            return self.to_sage_integer_matrix(
    771864                <intvec*> to_convert.data)
    772865        elif rtyp == RESOLUTION_CMD:
    773             res_resolution = Resolution(self._ring)
     866            res_resolution = Resolution(self._sage_ring)
    774867            res_resolution._resolution = <syStrategy*> to_convert.data
    775868            res_resolution._resolution.references += 1
    776869            return res_resolution
     
    9391032        """
    9401033        return "%s (singular function)" %(self._name)
    9411034
    942     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None):
     1035    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None):
    9431036        """
    9441037        Call this function with the provided arguments ``args`` in the
    9451038        ring ``R``.
     
    9981091        """
    9991092        if ring is None:
    10001093            ring = self.common_ring(args, ring)
    1001         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     1094        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \
     1095                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)):
    10021096            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring)))
    10031097        return call_function(self, args, ring, interruptible, attributes)
    10041098   
     
    10561150
    10571151        return prefix + get_docstring(self._name)
    10581152
    1059     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None):
     1153    cdef common_ring(self, tuple args, ring=None):
    10601154        """
    10611155        Return the common ring for the argument list ``args``.
    10621156
     
    10741168        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    10751169        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
    10761170        for a in args:
    1077             if PY_TYPE_CHECK(a, MPolynomialIdeal):
     1171            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     1172                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    10781173                ring2 = a.ring()
    1079             elif PY_TYPE_CHECK(a, MPolynomial_libsingular):
     1174            elif is_singular_poly_wrapper(a):
    10801175                ring2 = a.parent()
    1081             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
     1176            elif is_sage_wrapper_for_singular_ring(a):
    10821177                ring2 = a
    1083             elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring):
     1178            elif PY_TYPE_CHECK(a, int) or\
     1179                PY_TYPE_CHECK(a, long) or\
     1180                PY_TYPE_CHECK(a, basestring):
    10841181                continue
    10851182            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    10861183                continue
     
    10931190            elif PY_TYPE_CHECK(a, Resolution):
    10941191                ring2 = (<Resolution> a).base_ring
    10951192            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    1096                 and PY_TYPE_CHECK(
    1097                     a.parent().base_ring(),
    1098                      MPolynomialRing_libsingular):
     1193                and is_sage_wrapper_for_singular_ring(
     1194                    a.parent().base_ring()):
    10991195                ring2 = a.parent().base_ring()
    11001196            elif ring is not None:
    11011197                a.parent() is ring
     
    11071203                raise ValueError("Rings do not match up.")
    11081204        if ring is None:
    11091205            raise ValueError("Could not detect ring.")
    1110         return <MPolynomialRing_libsingular>ring
     1206        return ring
    11111207
    11121208    def __reduce__(self):
    11131209        """
     
    11381234        else:
    11391235            return cmp(self._name, (<SingularFunction>other)._name)
    11401236
    1141 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None):
     1237cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None):
    11421238    global currRingHdl
    11431239    global errorreported
    1144 
    1145     cdef ring *si_ring = R._ring
     1240   
     1241    cdef ring *si_ring
     1242    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular):
     1243        si_ring = (<MPolynomialRing_libsingular>R)._ring
     1244    else:
     1245        si_ring = (<NCPolynomialRing_plural>R)._ring
    11461246
    11471247    if si_ring != currRing:
    11481248        rChangeCurrRing(si_ring)
     
    13701470        <Resolution>
    13711471        sage: singular_list(resolution)
    13721472        [[(-2*y, 2, y + 1, 0), (0, -2, x - 1, 0), (x*y - y, -y + 1, 1, -y), (x^2 + 1, -x - 1, -1, -x)], [(-x - 1, y - 1, 2*x, -2*y)], [(0)]]
    1373 
     1473        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
     1474        sage: from sage.matrix.constructor  import Matrix
     1475        sage: c=Matrix(2)
     1476        sage: c[0,1]=-1
     1477        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
     1478        sage: (x,y)=P.gens()
     1479        sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y)
     1480        sage: twostd = singular_function("twostd")
     1481        sage: twostd(I)
     1482        [x + y, y^2]
     1483        sage: M=syz(I)
     1484        doctest...
     1485        sage: M
     1486        [(x + y, x*y)]
     1487        sage: syz(M, ring=P)
     1488        [(0)]
     1489        sage: mres(I, 0)
     1490        <Resolution>
     1491        sage: M=P**3
     1492        sage: v=M((100*x,5*y,10*y*x*y))
     1493        sage: leadcoef(v)
     1494        -10
     1495        sage: v = M([x+y,x*y+y**3,x])
     1496        sage: lead(v)
     1497        (0, y^3)
     1498        sage: jet(v, 2)
     1499        (x + y, x*y, x)
     1500        sage: l = ringlist(P)
     1501        sage: len(l)
     1502        6
     1503        sage: ring(l, ring=P)
     1504        <RingWrap>
     1505        sage: I=twostd(I)
     1506        sage: l[3]=I
     1507        sage: ring(l, ring=P)
     1508        <RingWrap>
    13741509       
    13751510    """
    13761511
  • sage/libs/singular/singular-cdefs.pxi

    diff -r 8dec8b43ccca sage/libs/singular/singular-cdefs.pxi
    a b  
    148148        bint (*nGreaterZero)(number* a)
    149149        void (*nPower)(number* a, int i, number* * result)
    150150
     151    # polynomials
     152
     153    ctypedef struct poly "polyrec":
     154        poly *next
     155
     156    # ideals
     157
     158    ctypedef struct ideal "ip_sideal":
     159        poly **m # gens array
     160        long rank # rank of module, 1 for ideals
     161        int nrows # always 1
     162        int ncols # number of gens
     163       
     164    # polynomial procs
     165    ctypedef struct p_Procs_s "p_Procs_s":
     166        pass
    151167    # rings
    152168
    153169    ctypedef struct ring "ip_sring":
     
    160176        int  CanShortOut # control printing capabilities
    161177        number *minpoly # minpoly for base extension field
    162178        char **names # variable names
     179        p_Procs_s *p_Procs #polxnomial procs
     180        ideal *qideal #quotient ideal
     181       
    163182        char **parameter # parameter names
    164183        ring *algring # base extension field
    165184        short N # number of variables
     
    197216        ringorder_Ws
    198217        ringorder_L
    199218
    200     # polynomials
    201219
    202     ctypedef struct poly "polyrec":
    203         poly *next
    204220
    205221       
    206222    # groebner basis options
     
    210226        isHomog
    211227        testHomog
    212228
    213     # ideals
    214 
    215     ctypedef struct ideal "ip_sideal":
    216         poly **m # gens array
    217         long rank # rank of module, 1 for ideals
    218         int nrows # always 1
    219         int ncols # number of gens
    220 
    221229    # dense matrices
    222230   
    223231    ctypedef struct matrix "ip_smatrix":
     
    9991007
    10001008    cdef int LANG_TOP
    10011009
     1010# Plural functions
     1011   
     1012    int nc_CallPlural(matrix* CC, matrix* DD, poly* CN, poly* DN, ring* r)
     1013
     1014# Plural functions
     1015   
     1016    int nc_CallPlural(matrix* CC, matrix* DD, poly* CN, poly* DN, ring* r)
     1017   
     1018    bint nc_SetupQuotient(ring *, ring *)
     1019 
     1020    ctypedef enum nc_type:
     1021   
     1022      nc_error # Something's gone wrong!
     1023      nc_general # yx=q xy+...
     1024      nc_skew # yx=q xy
     1025      nc_comm # yx= xy
     1026      nc_lie,  # yx=xy+...
     1027      nc_undef, # for internal reasons */
     1028      nc_exterior #
     1029
     1030    bint rIsPluralRing(ring* r)
     1031     
     1032cdef extern from "sca.h":
     1033    void sca_p_ProcsSet(ring *, p_Procs_s *)
     1034   
     1035    void scaFirstAltVar(ring *, int)
     1036   
     1037    void scaLastAltVar(ring *, int)
     1038   
     1039    void ncRingType(ring *, int)
     1040   
    10021041cdef extern from "stairc.h":
    10031042    # Computes the monomial basis for R[x]/I
    10041043    ideal *scKBase(int deg, ideal *s, ideal *Q)
  • sage/modules/free_module.py

    diff -r 8dec8b43ccca sage/modules/free_module.py
    a b  
    182182from sage.structure.parent_gens import ParentWithGens
    183183from sage.misc.cachefunc import cached_method
    184184
     185from warnings import warn
     186
    185187###############################################################################
    186188#
    187189# Constructor functions
     
    345347        if not isinstance(sparse,bool):
    346348            raise TypeError, "Argument sparse (= %s) must be True or False" % sparse
    347349
     350
     351        # We should have two sided, left sided and right sided ideals,
     352        # but that's another story ....
     353        #
    348354        if not base_ring.is_commutative():
    349             raise TypeError, "The base_ring must be a commutative ring."
     355           
     356            warn("""You are constructing a free module
     357             over a noncommutative ring. Sage does
     358             not have a concept of left/right
     359             and both sided modules be careful. It's also
     360             not guarantied that all multiplications
     361             are done from the right side.""")
     362           
     363        #            raise TypeError, "The base_ring must be a commutative ring."
     364
    350365
    351366        if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class):
    352367            return RealDoubleVectorSpace_class(rank)
     
    558573            Category of modules with basis over Integer Ring
    559574
    560575        """
    561         if not isinstance(base_ring, commutative_ring.CommutativeRing):
    562             raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
     576        if not base_ring.is_commutative():
     577            warn("""You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules be careful. It's also not guarantied that all multiplications are done from the right side.""")
     578            #raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
     579           
    563580        rank = sage.rings.integer.Integer(rank)
    564581        if rank < 0:
    565582            raise ValueError, "rank (=%s) must be nonnegative"%rank
  • sage/rings/ideal_monoid.py

    diff -r 8dec8b43ccca 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 -r 8dec8b43ccca 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 -r 8dec8b43ccca 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
  • new file sage/rings/polynomial/plural.pxd

    diff -r 8dec8b43ccca sage/rings/polynomial/plural.pxd
    - +  
     1include "../../libs/singular/singular-cdefs.pxi"
     2
     3from sage.rings.ring cimport Ring
     4from sage.structure.element cimport RingElement
     5
     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
     15    pass
     16
     17cdef class ExteriorAlgebra_plural(NCPolynomialRing_plural):
     18    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)
  • new file sage/rings/polynomial/plural.pyx

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

    diff -r 8dec8b43ccca 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 -r 8dec8b43ccca 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.