Ticket #4539: plural-wrapper-2010-10-01.patch

File plural-wrapper-2010-10-01.patch, 158.6 KB (added by burcin, 4 years ago)

rebased to 4.5.3

  • module_list.py

    * * *
    * * *
    * * *
    Initial wrapper for Singular/Plural - Sage-Trac #4539.
    * * *
    MPolynomialRing_plural now accepts matrix parameters to specify commutativity
    relations. Added ExteriorAlgebra.
    * * *
    [mq]: plural_3.patch
    
    diff --git a/module_list.py b/module_list.py
    a b  
    13561356              include_dirs = [SAGE_ROOT +'/local/include/singular'], 
    13571357              depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 
    13581358 
     1359    Extension('sage.rings.polynomial.plural', 
     1360              sources = ['sage/rings/polynomial/plural.pyx'], 
     1361              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 
     1362              language="c++", 
     1363              include_dirs = [SAGE_ROOT +'/local/include/singular'], 
     1364              depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 
     1365 
    13591366    Extension('sage.rings.polynomial.multi_polynomial_libsingular', 
    13601367              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'], 
    13611368              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 
  • sage/algebras/free_algebra.py

    diff --git a/sage/algebras/free_algebra.py b/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` 
     
    167166    """ 
    168167    def __init__(self, R, n, names): 
    169168        """ 
     169        The free algebra on `n` generators over a base ring. 
    170170        INPUT: 
    171171         
    172          
    173172        -  ``R`` - ring 
    174173         
    175174        -  ``n`` - an integer 
    176175         
    177176        -  ``names`` - generator names 
     177     
     178        EXAMPLES:: 
     179     
     180        sage: F.<x,y,z> = FreeAlgebra(QQ, 3); F # indirect doctet 
     181        Free Algebra on 3 generators (x, y, z) over Rational Field 
    178182        """ 
    179183        if not isinstance(R, Ring): 
    180184            raise TypeError, "Argument R must be a ring." 
     
    254258            sage: print F 
    255259            Free Algebra on 3 generators (x0, x1, x2) over Rational Field 
    256260            sage: F.rename('QQ<<x0,x1,x2>>') 
    257             sage: print F 
     261            sage: print F #indirect doctest 
    258262            QQ<<x0,x1,x2>> 
    259263        """ 
    260264        return "Free Algebra on %s generators %s over %s"%( 
     
    313317         
    314318        :: 
    315319         
    316             sage: F._coerce_(x*y) 
     320            sage: F._coerce_(x*y) # indirect doctest 
    317321            x*y 
    318322         
    319323        Elements of the integers coerce in, since there is a coerce map 
     
    384388        return self._coerce_try(x, [self.base_ring()]) 
    385389 
    386390    def coerce_map_from_impl(self, R): 
     391        """ 
     392        Elements of the free algebra canonically coerce in. 
     393 
     394        EXAMPLES:: 
     395         
     396        sage: F.<x,y,z> = FreeAlgebra(GF(7),3); F 
     397        Free Algebra on 3 generators (x, y, z) over Finite Field of size 7 
     398         
     399        sage: F._coerce_(x*y) # indirect doctest 
     400        x*y 
     401        """ 
     402             
    387403        if R is self.__monoid: 
    388404            return True 
    389405 
     
    422438        which form a free basis for the module of A, and a list of 
    423439        matrices, which give the action of the free generators of A on this 
    424440        monomial basis. 
     441        Quaternion algebra defined in terms of three generators:: 
     442         
     443        sage: n = 3 
     444        sage: A = FreeAlgebra(QQ,n,'i') 
     445        sage: F = A.monoid() 
     446        sage: i, j, k = F.gens() 
     447        sage: mons = [ F(1), i, j, k ] 
     448        sage: M = MatrixSpace(QQ,4) 
     449        sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]),  M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]),  M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ] 
     450        sage: H.<i,j,k> = A.quotient(mons, mats); H 
     451        Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field 
    425452        """ 
    426453        import free_algebra_quotient 
    427454        return free_algebra_quotient.FreeAlgebraQuotient(self, mons, mats, names) 
     
    451478        """ 
    452479        return self.__monoid 
    453480     
    454                      
     481    def g_algebra(self, relations, order='degrevlex', check = True): 
     482        """ 
     483             
     484            The G-Algebra derrived from this algebra by relations. 
     485            By default is assumed, that two variables commute. 
     486 
     487             
     488            TODO: 
     489            * Coercion doesn't work yet, there is some cheating about assumptions 
     490            * The optional argument check controlls checking the degeneracy conditions  
     491            Furthermore, the default values interfere with non degeneracy conditions... 
     492             
     493            EXAMPLES: 
     494            sage: A.<x,y,z>=FreeAlgebra(QQ,3) 
     495            sage: G=A.g_algebra({y*x:-x*y}) 
     496            sage: (x,y,z)=G.gens() 
     497            sage: x*y 
     498            x*y 
     499            sage: y*x 
     500            -x*y 
     501            sage: z*x 
     502            x*z 
     503            sage: (x,y,z)=A.gens() 
     504            sage: G=A.g_algebra({y*x:-x*y+1}) 
     505            sage: (x,y,z)=G.gens() 
     506            sage: y*x 
     507            -x*y + 1 
     508            sage: (x,y,z)=A.gens() 
     509            sage: G=A.g_algebra({y*x:-x*y+z}) 
     510            sage: (x,y,z)=G.gens() 
     511            sage: y*x 
     512            -x*y + z 
     513        """ 
     514        from sage.matrix.constructor  import Matrix 
     515        from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     516         
     517        base_ring=self.base_ring() 
     518        n=self.ngens() 
     519        cmat=Matrix(base_ring,n) 
     520        dmat=Matrix(self,n) 
     521        for i in xrange(n): 
     522            for j in xrange(i+1,n): 
     523                cmat[i,j]=1 
     524        for (to_commute,commuted) in relations.iteritems(): 
     525            #This is dirty, coercion is broken 
     526            assert isinstance(to_commute,FreeAlgebraElement), to_commute.__class__ 
     527            assert isinstance(commuted,FreeAlgebraElement), commuted 
     528            ((v1,e1),(v2,e2))=list(list(to_commute)[0][1]) 
     529            assert e1==1 
     530            assert e2==1 
     531            assert v1>v2 
     532            c_coef=None 
     533            d_poly=None 
     534            for (c,m) in commuted: 
     535                if list(m)==[(v2,1),(v1,1)]: 
     536                    c_coef=c 
     537                    #buggy coercion workaround 
     538                    d_poly=commuted-self(c)*self(m) 
     539                    break 
     540            assert not c_coef is None,list(m) 
     541            v2_ind = self.gens().index(v2) 
     542            v1_ind = self.gens().index(v1) 
     543            cmat[v2_ind,v1_ind]=c_coef 
     544            if d_poly: 
     545                dmat[v2_ind,v1_ind]=d_poly 
     546         
     547        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat, order=order, check=check) 
     548             
     549             
    455550from sage.misc.cache import Cache 
    456551cache = Cache(FreeAlgebra_generic) 
  • sage/libs/singular/function.pxd

    diff --git a/sage/libs/singular/function.pxd b/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 --git a/sage/libs/singular/function.pyx b/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, NCPolynomial_plural, new_NCP 
     86from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal 
     87 
    8388from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal 
    8489 
    8590from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence 
     
    8994from sage.libs.singular.decl cimport iiMake_proc, iiExprArith1, iiExprArith2, iiExprArith3, iiExprArithM, iiLibCmd 
    9095from sage.libs.singular.decl cimport ggetid, IDEAL_CMD, CMD_M, POLY_CMD, PROC_CMD, RING_CMD, QRING_CMD, NUMBER_CMD, INT_CMD, INTVEC_CMD, RESOLUTION_CMD 
    9196from sage.libs.singular.decl cimport MODUL_CMD, LIST_CMD, MATRIX_CMD, VECTOR_CMD, STRING_CMD, V_LOAD_LIB, V_REDEFINE, INTMAT_CMD, NONE, PACKAGE_CMD 
    92 from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy 
     97from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy, rIsPluralRing, rPrint, rOrderingString 
    9398from sage.libs.singular.decl cimport IDROOT, enterid, currRingHdl, memcpy, IDNEXT, IDTYP, IDPACKAGE 
    9499from sage.libs.singular.decl cimport errorreported, verbose, Sy_bit, currentVoice, myynest 
    95100from sage.libs.singular.decl cimport intvec_new_int3, intvec_new, matrix, mpNew 
     
    122127     
    123128    for (i, p) in enumerate(v): 
    124129        component = <int>i+1 
    125         poly_component = p_Copy( 
    126             (<MPolynomial_libsingular>p)._poly, r) 
     130        poly_component = copy_sage_polynomial_into_singular_poly(p) 
    127131        p_iter = poly_component 
    128132        while p_iter!=NULL: 
    129133            p_SetComp(p_iter, component, r) 
     
    132136        res=p_Add_q(res, poly_component, r) 
    133137    return res 
    134138 
     139 
    135140cdef class RingWrap: 
    136141    """ 
    137142    A simple wrapper around Singular's rings. 
     
    148153            sage: ring(l, ring=P) 
    149154            <RingWrap> 
    150155        """ 
     156        if not self.is_commutative(): 
     157            return "<noncommutative RingWrap>" 
    151158        return "<RingWrap>" 
    152159     
    153160    def __dealloc__(self): 
    154161        if self._ring!=NULL: 
    155162            self._ring.ref -= 1 
    156163 
     164    def ngens(self): 
     165        """ 
     166        Get number of generators 
     167 
     168        EXAMPLE:: 
     169 
     170            sage: from sage.libs.singular.function import singular_function 
     171            sage: P.<x,y,z> = PolynomialRing(QQ) 
     172            sage: ringlist = singular_function("ringlist") 
     173            sage: l = ringlist(P) 
     174            sage: ring = singular_function("ring") 
     175            sage: ring(l, ring=P).ngens() 
     176            3 
     177        """ 
     178        return self._ring.N 
     179 
     180    def var_names(self): 
     181        """ 
     182        Get name of variables 
     183 
     184        EXAMPLE:: 
     185 
     186            sage: from sage.libs.singular.function import singular_function 
     187            sage: P.<x,y,z> = PolynomialRing(QQ) 
     188            sage: ringlist = singular_function("ringlist") 
     189            sage: l = ringlist(P) 
     190            sage: ring = singular_function("ring") 
     191            sage: ring(l, ring=P).var_names() 
     192            ['x', 'y', 'z'] 
     193        """ 
     194        return [self._ring.names[i] for i in range(self.ngens())] 
     195 
     196    def npars(self): 
     197        """ 
     198        Get number of parameters 
     199 
     200        EXAMPLE:: 
     201 
     202            sage: from sage.libs.singular.function import singular_function 
     203            sage: P.<x,y,z> = PolynomialRing(QQ) 
     204            sage: ringlist = singular_function("ringlist") 
     205            sage: l = ringlist(P) 
     206            sage: ring = singular_function("ring") 
     207            sage: ring(l, ring=P).npars() 
     208            0 
     209        """ 
     210        return self._ring.P 
     211 
     212    def ordering_string(self): 
     213        """ 
     214        Get Singular string defining monomial ordering 
     215 
     216        EXAMPLE:: 
     217 
     218            sage: from sage.libs.singular.function import singular_function 
     219            sage: P.<x,y,z> = PolynomialRing(QQ) 
     220            sage: ringlist = singular_function("ringlist") 
     221            sage: l = ringlist(P) 
     222            sage: ring = singular_function("ring") 
     223            sage: ring(l, ring=P).ordering_string() 
     224            'dp(3),C' 
     225        """ 
     226        return rOrderingString(self._ring) 
     227     
     228     
     229 
     230    def par_names(self): 
     231        """ 
     232        Get parameter names 
     233 
     234        EXAMPLE:: 
     235 
     236            sage: from sage.libs.singular.function import singular_function 
     237            sage: P.<x,y,z> = PolynomialRing(QQ) 
     238            sage: ringlist = singular_function("ringlist") 
     239            sage: l = ringlist(P) 
     240            sage: ring = singular_function("ring") 
     241            sage: ring(l, ring=P).par_names() 
     242            [] 
     243        """ 
     244        return [self._ring.parameter[i] for i in range(self.npars())] 
     245 
     246    def characteristic(self): 
     247        """ 
     248        Get characteristic 
     249 
     250        EXAMPLE:: 
     251 
     252            sage: from sage.libs.singular.function import singular_function 
     253            sage: P.<x,y,z> = PolynomialRing(QQ) 
     254            sage: ringlist = singular_function("ringlist") 
     255            sage: l = ringlist(P) 
     256            sage: ring = singular_function("ring") 
     257            sage: ring(l, ring=P).characteristic() 
     258            0 
     259        """ 
     260        return self._ring.ch 
     261 
     262    def is_commutative(self): 
     263        """ 
     264        Determine whether a given ring is  commutative 
     265 
     266        EXAMPLE:: 
     267 
     268            sage: from sage.libs.singular.function import singular_function 
     269            sage: P.<x,y,z> = PolynomialRing(QQ) 
     270            sage: ringlist = singular_function("ringlist") 
     271            sage: l = ringlist(P) 
     272            sage: ring = singular_function("ring") 
     273            sage: ring(l, ring=P).is_commutative() 
     274            True 
     275        """ 
     276        return not rIsPluralRing(self._ring) 
     277     
     278    def _output(self): # , debug = False 
     279        """ 
     280        Use Singular output 
     281 
     282        EXAMPLE:: 
     283 
     284            sage: from sage.libs.singular.function import singular_function 
     285            sage: P.<x,y,z> = PolynomialRing(QQ) 
     286            sage: ringlist = singular_function("ringlist") 
     287            sage: l = ringlist(P) 
     288            sage: ring = singular_function("ring") 
     289            sage: ring(l, ring=P)._output() 
     290        """ 
     291        rPrint(self._ring) 
     292#        if debug: 
     293#        rDebugPrint(self._ring) 
     294             
    157295cdef class Resolution: 
    158296    """ 
    159297    A simple wrapper around Singular's resolutions. 
     
    170308           sage: M = syz(I) 
    171309           sage: resolution = mres(M, 0) 
    172310        """ 
    173         assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular) 
    174         self.base_ring = <MPolynomialRing_libsingular> base_ring 
     311        #FIXME: still not working noncommutative 
     312        assert is_sage_wrapper_for_singular_ring(base_ring) 
     313        self.base_ring = base_ring 
    175314    def __repr__(self): 
    176315        """ 
    177316        EXAMPLE:: 
     
    229368    args.CleanUp() 
    230369    omFreeBin(args, sleftv_bin) 
    231370 
     371# ===================================== 
     372# = Singular/Plural Abstraction Layer = 
     373# ===================================== 
    232374 
    233 def all_polynomials(s): 
     375def is_sage_wrapper_for_singular_ring(ring): 
     376    """ 
     377    Check whether wrapped ring arises from Singular or Singular/Plural 
     378 
     379    EXAMPLE:: 
     380 
     381    sage: from sage.libs.singular.function import is_sage_wrapper_for_singular_ring 
     382    sage: P.<x,y,z> = QQ[] 
     383    sage: is_sage_wrapper_for_singular_ring(P) 
     384    True 
     385 
     386    sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     387    sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')  
     388    sage: is_sage_wrapper_for_singular_ring(P) 
     389    True 
     390 
     391    """ 
     392    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     393        return True 
     394    if PY_TYPE_CHECK(ring, NCPolynomialRing_plural): 
     395        return True 
     396    return False 
     397 
     398cdef new_sage_polynomial(ring,  poly *p): 
     399    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     400        return new_MP(ring, p) 
     401    else: 
     402        if PY_TYPE_CHECK(ring, NCPolynomialRing_plural): 
     403            return new_NCP(ring, p) 
     404    raise ValueError("not a singular or plural ring") 
     405 
     406def is_singular_poly_wrapper(p): 
     407    """ 
     408        checks if p is some data type corresponding to some singular ``poly```. 
     409         
     410        EXAMPLE:: 
     411            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     412            sage: from sage.matrix.constructor  import Matrix 
     413            sage: from sage.libs.singular.function import is_singular_poly_wrapper 
     414            sage: c=Matrix(2) 
     415            sage: c[0,1]=-1 
     416            sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 
     417            sage: (x,y)=P.gens() 
     418            sage: is_singular_poly_wrapper(x+y) 
     419            True 
     420         
     421    """ 
     422    return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p,  NCPolynomial_plural) 
     423 
     424def all_singular_poly_wrapper(s): 
    234425    """ 
    235426    Tests for a sequence ``s``, whether it consists of 
    236427    singular polynomials. 
    237428     
    238429    EXAMPLE:: 
    239430         
    240         sage: from sage.libs.singular.function import all_polynomials 
     431        sage: from sage.libs.singular.function import all_singular_poly_wrapper 
    241432        sage: P.<x,y,z> = QQ[] 
    242         sage: all_polynomials([x+1, y]) 
     433        sage: all_singular_poly_wrapper([x+1, y]) 
    243434        True 
    244         sage: all_polynomials([x+1, y, 1]) 
     435        sage: all_singular_poly_wrapper([x+1, y, 1]) 
    245436        False 
    246437    """ 
    247438    for p in s: 
    248         if not isinstance(p, MPolynomial_libsingular): 
     439        if not is_singular_poly_wrapper(p): 
    249440            return False 
    250441    return True 
    251442 
     443cdef poly* access_singular_poly(p) except <poly*> -1: 
     444    """ 
     445        Get the raw ``poly`` pointer from a wrapper object 
     446        EXAMPLE:: 
     447            # sage: P.<a,b,c> = PolynomialRing(QQ) 
     448            #  sage: p=a+b 
     449            #  sage: from sage.libs.singular.function import access_singular_poly 
     450            #  sage: access_singular_poly(p) 
     451    """ 
     452    if PY_TYPE_CHECK(p, MPolynomial_libsingular): 
     453        return (<MPolynomial_libsingular> p)._poly 
     454    else: 
     455        if PY_TYPE_CHECK(p, NCPolynomial_plural): 
     456            return (<NCPolynomial_plural> p)._poly 
     457    raise ValueError("not a singular polynomial wrapper") 
     458 
     459cdef ring* access_singular_ring(r) except <ring*> -1: 
     460    """ 
     461        Get the singular ``ring`` pointer from a  
     462        wrapper object. 
     463         
     464        EXAMPLE:: 
     465            # sage: P.<x,y,z> = QQ[] 
     466            # sage: from sage.libs.singular.function import access_singular_ring 
     467            # sage: access_singular_ring(P) 
     468 
     469    """ 
     470    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular): 
     471        return (<MPolynomialRing_libsingular> r )._ring 
     472    if PY_TYPE_CHECK(r, NCPolynomialRing_plural): 
     473        return (<NCPolynomialRing_plural> r )._ring 
     474    raise ValueError("not a singular polynomial ring wrapper") 
     475   
     476cdef poly* copy_sage_polynomial_into_singular_poly(p): 
     477    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent())) 
     478 
    252479def all_vectors(s): 
    253480    """ 
    254481    Checks if a sequence ``s`` consists of free module 
     
    269496        False 
    270497    """ 
    271498    for p in s: 
    272         if not (isinstance(p, FreeModuleElement_generic_dense)\ 
    273             and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)): 
     499        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\ 
     500            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())): 
    274501            return False 
    275502    return True 
    276503 
    277504 
    278505 
     506 
     507 
     508 
     509 
    279510cdef class Converter(SageObject): 
    280511    """ 
    281512    A :class:`Converter` interfaces between Sage objects and Singular 
     
    304535        """ 
    305536        cdef leftv *v 
    306537        self.args = NULL 
    307         self._ring = ring 
     538        self._sage_ring = ring 
     539        if ring is not None: 
     540            self._singular_ring = access_singular_ring(ring) 
     541         
    308542        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    309543        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
     544        from sage.matrix.matrix_generic_dense import Matrix_generic_dense 
    310545        for a in args: 
    311             if PY_TYPE_CHECK(a, MPolynomial_libsingular): 
    312                 v = self.append_polynomial(<MPolynomial_libsingular> a) 
     546            if is_singular_poly_wrapper(a): 
     547                v = self.append_polynomial(a) 
    313548 
    314             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
    315                 v = self.append_ring(<MPolynomialRing_libsingular> a) 
     549            elif is_sage_wrapper_for_singular_ring(a): 
     550                v = self.append_ring(a) 
    316551 
    317             elif PY_TYPE_CHECK(a, MPolynomialIdeal): 
     552            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     553                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    318554                v = self.append_ideal(a) 
    319555 
    320556            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long): 
     
    328564 
    329565            elif PY_TYPE_CHECK(a, Matrix_integer_dense): 
    330566                v = self.append_intmat(a) 
    331  
     567             
     568            elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\ 
     569                is_sage_wrapper_for_singular_ring(a.parent().base_ring()): 
     570                self.append_matrix(a) 
     571             
    332572            elif PY_TYPE_CHECK(a, Resolution): 
    333573                v = self.append_resolution(a) 
    334574 
    335575            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\ 
    336                 and isinstance( 
    337                     a.parent().base_ring(), 
    338                     MPolynomialRing_libsingular): 
     576                and is_sage_wrapper_for_singular_ring( 
     577                    a.parent().base_ring()): 
    339578                v = self.append_vector(a) 
    340579                 
    341580            # as output ideals get converted to sequences 
     
    343582            # this means, that Singular lists should not be converted to Sequences, 
    344583            # as we do not want ambiguities 
    345584            elif PY_TYPE_CHECK(a, Sequence)\ 
    346                 and all_polynomials(a): 
     585                and all_singular_poly_wrapper(a): 
    347586                v = self.append_ideal(ring.ideal(a)) 
    348587            elif PY_TYPE_CHECK(a, Sequence)\ 
    349588                and all_vectors(a): 
     
    362601                    v = self.append_intvec(a) 
    363602                else: 
    364603                    v = self.append_list(a) 
    365             elif a.parent() is self._ring.base_ring(): 
     604            elif a.parent() is self._sage_ring.base_ring(): 
    366605                v = self.append_number(a) 
    367606 
    368607            elif PY_TYPE_CHECK(a, Integer): 
     
    391630            sage: Converter([a,b,c],ring=P).ring() 
    392631            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    393632        """ 
    394         return self._ring 
     633        return self._sage_ring 
    395634 
    396635    def _repr_(self): 
    397636        """ 
     
    402641            sage: Converter([a,b,c],ring=P) # indirect doctest 
    403642            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    404643        """ 
    405         return "Singular Converter in %s"%(self._ring) 
     644        return "Singular Converter in %s"%(self._sage_ring) 
    406645 
    407646    def __dealloc__(self): 
    408647        if self.args: 
     
    467706        Convert singular matrix to matrix over the polynomial ring. 
    468707        """ 
    469708        from sage.matrix.constructor import Matrix 
    470         sage_ring = self._ring 
    471         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
    472             sage_ring)._ring 
     709        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
     710        #    self._sage_ring)._ring 
    473711        ncols = mat.ncols 
    474712        nrows = mat.nrows 
    475         result = Matrix(sage_ring, nrows, ncols) 
    476         cdef MPolynomial_libsingular p 
     713        result = Matrix(self._sage_ring, nrows, ncols) 
    477714        for i in xrange(nrows): 
    478715            for j in xrange(ncols): 
    479                 p = MPolynomial_libsingular(sage_ring) 
    480                 p._poly = mat.m[i*ncols+j] 
     716                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j]) 
    481717                mat.m[i*ncols+j]=NULL 
    482718                result[i,j] = p 
    483719        return result 
    484720     
    485721    cdef to_sage_vector_destructive(self, poly *p, free_module = None): 
    486         cdef ring *r=self._ring._ring 
     722        #cdef ring *r=self._ring._ring 
    487723        cdef int rank 
    488724        if free_module: 
    489725            rank = free_module.rank() 
    490726        else: 
    491             rank = singular_vector_maximal_component(p, r) 
    492             free_module = self._ring**rank 
     727            rank = singular_vector_maximal_component(p, self._singular_ring) 
     728            free_module = self._sage_ring**rank 
    493729        cdef poly *acc 
    494730        cdef poly *p_iter 
    495731        cdef poly *first 
     
    502738            first = NULL 
    503739            p_iter=p 
    504740            while p_iter != NULL: 
    505                 if p_GetComp(p_iter, r) == i: 
    506                     p_SetComp(p_iter,0, r) 
    507                     p_Setm(p_iter, r) 
     741                if p_GetComp(p_iter, self._singular_ring) == i: 
     742                    p_SetComp(p_iter,0, self._singular_ring) 
     743                    p_Setm(p_iter, self._singular_ring) 
    508744                    if acc == NULL: 
    509745                        first = p_iter 
    510746                    else: 
     
    519755                else: 
    520756                    previous = p_iter 
    521757                    p_iter = pNext(p_iter) 
    522             result.append(new_MP(self._ring, first)) 
     758             
     759            result.append(new_sage_polynomial(self._sage_ring, first)) 
    523760        return free_module(result) 
    524761           
    525762    cdef object to_sage_module_element_sequence_destructive( self, ideal *i): 
     
    533770        - ``r`` -- a SINGULAR ring 
    534771        - ``sage_ring`` -- a Sage ring matching r 
    535772        """ 
    536         cdef MPolynomialRing_libsingular sage_ring = self._ring 
     773        #cdef MPolynomialRing_libsingular sage_ring = self._ring 
    537774        cdef int j 
    538775        cdef int rank=i.rank 
    539         free_module = sage_ring**rank        
     776        free_module = self._sage_ring ** rank        
    540777        l = [] 
    541778 
    542779        for j from 0 <= j < IDELEMS(i): 
     
    565802        return result 
    566803     
    567804     
    568     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL: 
     805    cdef leftv *append_polynomial(self, p) except NULL: 
    569806        """ 
    570807        Append the polynomial ``p`` to the list. 
    571808        """ 
    572         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring) 
     809        cdef poly* _p 
     810        _p = copy_sage_polynomial_into_singular_poly(p) 
     811                 
    573812        return self._append(_p, POLY_CMD) 
    574813 
    575814    cdef leftv *append_ideal(self,  i) except NULL: 
     
    586825        """ 
    587826        rank = max([v.parent().rank() for v in m]) 
    588827        cdef ideal *result 
    589         cdef ring *r = self._ring._ring 
     828        cdef ring *r = self._singular_ring 
    590829        cdef ideal *i 
    591830        cdef int j = 0 
    592831 
     
    602841        """ 
    603842        Append the number ``n`` to the list. 
    604843        """ 
    605         cdef number *_n =  sa2si(n, self._ring._ring) 
     844        cdef number *_n =  sa2si(n, self._singular_ring) 
    606845        return self._append(<void *>_n, NUMBER_CMD) 
    607846 
    608     cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL: 
     847    cdef leftv *append_ring(self, r) except NULL: 
    609848        """ 
    610849        Append the ring ``r`` to the list. 
    611850        """ 
    612         cdef ring *_r =  <ring*> r._ring 
     851        cdef ring *_r =  access_singular_ring(r) 
    613852        _r.ref+=1 
    614853        return self._append(<void *>_r, RING_CMD) 
    615854 
    616855    cdef leftv *append_matrix(self, mat) except NULL: 
    617856         
    618857        sage_ring = mat.base_ring() 
    619         cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring 
     858        cdef ring *r=<ring*> access_singular_ring(sage_ring) 
    620859 
    621860        cdef poly *p 
    622861        ncols = mat.ncols() 
     
    624863        cdef matrix* _m=mpNew(nrows,ncols) 
    625864        for i in xrange(nrows): 
    626865            for j in xrange(ncols): 
    627                 p = p_Copy( 
    628                     (<MPolynomial_libsingular> mat[i,j])._poly, r) 
     866                #FIXME 
     867                p = copy_sage_polynomial_into_singular_poly(mat[i,j]) 
    629868                _m.m[ncols*i+j]=p 
    630869        return self._append(_m, MATRIX_CMD) 
    631870 
     
    643882        Append the list ``l`` to the list. 
    644883        """ 
    645884         
    646         cdef Converter c = Converter(l, self._ring) 
     885        cdef Converter c = Converter(l, self._sage_ring) 
    647886        n = len(c) 
    648887 
    649888        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin) 
     
    674913        Append vector ``v`` from free  
    675914        module over polynomial ring. 
    676915        """ 
    677         cdef ring *r = self._ring._ring 
     916        cdef ring *r = self._singular_ring 
    678917        cdef poly *p = sage_vector_to_poly(v, r) 
    679918        return self._append(<void*> p, VECTOR_CMD) 
    680919     
     
    714953 
    715954        - ``to_convert`` - a Singular ``leftv`` 
    716955        """ 
     956        #FIXME 
    717957        cdef MPolynomial_libsingular res_poly 
    718958        cdef int rtyp = to_convert.rtyp 
    719959        cdef lists *singular_list 
    720960        cdef Resolution res_resolution 
    721961        if rtyp == IDEAL_CMD: 
    722             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring) 
     962            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring) 
    723963 
    724964        elif rtyp == POLY_CMD: 
    725             res_poly = MPolynomial_libsingular(self._ring) 
     965            #FIXME 
     966            res_poly = MPolynomial_libsingular(self._sage_ring) 
    726967            res_poly._poly = <poly*>to_convert.data 
    727968            to_convert.data = NULL 
    728969            #prevent it getting free, when cleaning the leftv 
     
    732973            return <long>to_convert.data 
    733974         
    734975        elif rtyp == NUMBER_CMD: 
    735             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring()) 
     976            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring()) 
    736977 
    737978        elif rtyp == INTVEC_CMD: 
    738979            return si2sa_intvec(<intvec *>to_convert.data) 
     
    748989             
    749990 
    750991        elif rtyp == RING_CMD or rtyp==QRING_CMD: 
    751             ring_wrap_result=RingWrap() 
    752             (<RingWrap> ring_wrap_result)._ring=<ring*> to_convert.data 
    753             (<RingWrap> ring_wrap_result)._ring.ref+=1 
    754             return ring_wrap_result 
     992            return new_RingWrap( <ring*> to_convert.data ) 
    755993 
    756994        elif rtyp == MATRIX_CMD: 
    757995            return self.to_sage_matrix(<matrix*>  to_convert.data ) 
     
    7741012            return self.to_sage_integer_matrix( 
    7751013                <intvec*> to_convert.data) 
    7761014        elif rtyp == RESOLUTION_CMD: 
    777             res_resolution = Resolution(self._ring) 
     1015            res_resolution = Resolution(self._sage_ring) 
    7781016            res_resolution._resolution = <syStrategy*> to_convert.data 
    7791017            res_resolution._resolution.references += 1 
    7801018            return res_resolution 
     
    9431181        """ 
    9441182        return "%s (singular function)" %(self._name) 
    9451183 
    946     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None): 
     1184    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None): 
    9471185        """ 
    9481186        Call this function with the provided arguments ``args`` in the 
    9491187        ring ``R``. 
     
    10231261        """ 
    10241262        if ring is None: 
    10251263            ring = self.common_ring(args, ring) 
    1026         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     1264        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \ 
     1265                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)): 
    10271266            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring))) 
    10281267        return call_function(self, args, ring, interruptible, attributes) 
    10291268     
     
    10811320 
    10821321        return prefix + get_docstring(self._name) 
    10831322 
    1084     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None): 
     1323    cdef common_ring(self, tuple args, ring=None): 
    10851324        """ 
    10861325        Return the common ring for the argument list ``args``. 
    10871326 
     
    10991338        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    11001339        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
    11011340        for a in args: 
    1102             if PY_TYPE_CHECK(a, MPolynomialIdeal): 
     1341            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     1342                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    11031343                ring2 = a.ring() 
    1104             elif PY_TYPE_CHECK(a, MPolynomial_libsingular): 
     1344            elif is_singular_poly_wrapper(a): 
    11051345                ring2 = a.parent() 
    1106             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
     1346            elif is_sage_wrapper_for_singular_ring(a): 
    11071347                ring2 = a 
    1108             elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring): 
     1348            elif PY_TYPE_CHECK(a, int) or\ 
     1349                PY_TYPE_CHECK(a, long) or\ 
     1350                PY_TYPE_CHECK(a, basestring): 
    11091351                continue 
    11101352            elif PY_TYPE_CHECK(a, Matrix_integer_dense): 
    11111353                continue 
     
    11181360            elif PY_TYPE_CHECK(a, Resolution): 
    11191361                ring2 = (<Resolution> a).base_ring 
    11201362            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\ 
    1121                 and PY_TYPE_CHECK( 
    1122                     a.parent().base_ring(), 
    1123                      MPolynomialRing_libsingular): 
     1363                and is_sage_wrapper_for_singular_ring( 
     1364                    a.parent().base_ring()): 
    11241365                ring2 = a.parent().base_ring() 
    11251366            elif ring is not None: 
    11261367                a.parent() is ring 
     
    11321373                raise ValueError("Rings do not match up.") 
    11331374        if ring is None: 
    11341375            raise ValueError("Could not detect ring.") 
    1135         return <MPolynomialRing_libsingular>ring 
     1376        return ring 
    11361377 
    11371378    def __reduce__(self): 
    11381379        """ 
     
    11631404        else: 
    11641405            return cmp(self._name, (<SingularFunction>other)._name) 
    11651406 
    1166 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None): 
     1407cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None): 
    11671408    global currRingHdl 
    11681409    global errorreported 
    11691410    global currentVoice 
     
    11711412    global error_messages 
    11721413 
    11731414 
    1174     cdef ring *si_ring = R._ring 
    1175  
     1415    cdef ring *si_ring 
     1416    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular): 
     1417        si_ring = (<MPolynomialRing_libsingular>R)._ring 
     1418    else: 
     1419        si_ring = (<NCPolynomialRing_plural>R)._ring 
     1420  
    11761421    if si_ring != currRing: 
    11771422        rChangeCurrRing(si_ring) 
    11781423 
     
    14141659        <Resolution> 
    14151660        sage: singular_list(resolution) 
    14161661        [[(-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)]] 
    1417  
     1662        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     1663        sage: from sage.matrix.constructor  import Matrix 
     1664        sage: c=Matrix(2) 
     1665        sage: c[0,1]=-1 
     1666        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 
     1667        sage: (x,y)=P.gens() 
     1668        sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y) 
     1669        sage: twostd = singular_function("twostd") 
     1670        sage: twostd(I) 
     1671        [x + y, y^2] 
     1672        sage: M=syz(I) 
     1673        doctest... 
     1674        sage: M 
     1675        [(x + y, x*y)] 
     1676        sage: syz(M, ring=P) 
     1677        [(0)] 
     1678        sage: mres(I, 0) 
     1679        <Resolution> 
     1680        sage: M=P**3 
     1681        sage: v=M((100*x,5*y,10*y*x*y)) 
     1682        sage: leadcoef(v) 
     1683        -10 
     1684        sage: v = M([x+y,x*y+y**3,x]) 
     1685        sage: lead(v) 
     1686        (0, y^3) 
     1687        sage: jet(v, 2) 
     1688        (x + y, x*y, x) 
     1689        sage: l = ringlist(P) 
     1690        sage: len(l) 
     1691        6 
     1692        sage: ring(l, ring=P) 
     1693        <noncommutative RingWrap> 
     1694        sage: I=twostd(I) 
     1695        sage: l[3]=I 
     1696        sage: ring(l, ring=P) 
     1697        <noncommutative RingWrap> 
    14181698         
    14191699    """ 
    14201700 
     
    14861766                    ph = IDNEXT(ph) 
    14871767        h = IDNEXT(h) 
    14881768    return l 
     1769 
     1770 
     1771#cdef ring*? 
     1772cdef inline RingWrap new_RingWrap(ring* r): 
     1773    cdef RingWrap ring_wrap_result = PY_NEW(RingWrap) 
     1774    ring_wrap_result._ring = r 
     1775    ring_wrap_result._ring.ref += 1 
     1776     
     1777    return ring_wrap_result 
  • sage/libs/singular/singular-cdefs.pxi

    diff --git a/sage/libs/singular/singular-cdefs.pxi b/sage/libs/singular/singular-cdefs.pxi
    a b  
    149149        bint (*nGreaterZero)(number* a) 
    150150        void (*nPower)(number* a, int i, number* * result) 
    151151 
     152    # polynomials 
     153 
     154    ctypedef struct poly "polyrec": 
     155        poly *next 
     156 
     157    # ideals 
     158 
     159    ctypedef struct ideal "sip_sideal": 
     160        poly **m # gens array 
     161        long rank # rank of module, 1 for ideals 
     162        int nrows # always 1 
     163        int ncols # number of gens 
     164 
     165    # polynomial procs 
     166    ctypedef struct p_Procs_s "p_Procs_s": 
     167        pass 
    152168    # rings 
    153169 
    154170    ctypedef struct ring "ip_sring": 
     
    161177        int  CanShortOut # control printing capabilities 
    162178        number *minpoly # minpoly for base extension field 
    163179        char **names # variable names 
     180        p_Procs_s *p_Procs #polxnomial procs 
     181        ideal *qideal #quotient ideal 
     182         
    164183        char **parameter # parameter names 
    165184        ring *algring # base extension field 
    166185        short N # number of variables 
     
    198217        ringorder_Ws 
    199218        ringorder_L 
    200219 
    201     # polynomials 
    202220 
    203     ctypedef struct poly "polyrec": 
    204         poly *next 
    205221 
    206222    # groebner basis options 
    207223     
     
    9861002 
    9871003    cdef int LANG_TOP 
    9881004 
     1005# Non-commutative functions 
     1006    ctypedef enum nc_type: 
     1007      nc_error # Something's gone wrong! 
     1008      nc_general # yx=q xy+...  
     1009      nc_skew # yx=q xy  
     1010      nc_comm # yx= xy  
     1011      nc_lie,  # yx=xy+...  
     1012      nc_undef, # for internal reasons */ 
     1013      nc_exterior # 
     1014 
     1015   
     1016cdef extern from "gring.h": 
     1017    void ncRingType(ring *, nc_type) 
     1018    nc_type ncRingType_get "ncRingType" (ring *) 
     1019    int nc_CallPlural(matrix* CC, matrix* DD, poly* CN, poly* DN, ring* r) 
     1020    bint nc_SetupQuotient(ring *, ring *, bint) 
     1021     
     1022cdef extern from "sca.h": 
     1023    void sca_p_ProcsSet(ring *, p_Procs_s *) 
     1024    void scaFirstAltVar(ring *, int) 
     1025    void scaLastAltVar(ring *, int) 
     1026 
     1027cdef extern from "ring.h": 
     1028    bint rIsPluralRing(ring* r) 
     1029    void rPrint "rWrite"(ring* r) 
     1030    char* rOrderingString "rOrdStr"(ring* r) 
     1031#    void rDebugPrint(ring* r) 
     1032    void pDebugPrint "p_DebugPrint" (poly*p, ring* r) 
     1033     
    9891034cdef extern from "stairc.h": 
    9901035    # Computes the monomial basis for R[x]/I 
    9911036    ideal *scKBase(int deg, ideal *s, ideal *Q) 
  • sage/modules/free_module.py

    diff --git a/sage/modules/free_module.py b/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            warn("""You are constructing a free module   over a noncommutative ring. Sage does  
     356             not have a concept of left/right and both sided modules be careful. It's also 
     357             not guarantied that all multiplications are done from the right side.""") 
     358             
     359        #            raise TypeError, "The base_ring must be a commutative ring." 
     360 
    350361 
    351362        if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): 
    352363            return RealDoubleVectorSpace_class(rank) 
     
    558569            Category of modules with basis over Integer Ring 
    559570 
    560571        """ 
    561         if not isinstance(base_ring, commutative_ring.CommutativeRing): 
    562             raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring 
     572        if not base_ring.is_commutative(): 
     573            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.""") 
     574            #raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring 
     575             
    563576        rank = sage.rings.integer.Integer(rank) 
    564577        if rank < 0: 
    565578            raise ValueError, "rank (=%s) must be nonnegative"%rank 
  • sage/rings/ideal_monoid.py

    diff --git a/sage/rings/ideal_monoid.py b/sage/rings/ideal_monoid.py
    a b  
    4747            sage: M = sage.rings.ideal_monoid.IdealMonoid(R); M # indirect doctest 
    4848            Monoid of ideals of Number Field in a with defining polynomial x^2 + 23 
    4949        """ 
    50         if not is_CommutativeRing(R): 
    51             raise TypeError, "R must be a commutative ring" 
    5250        self.__R = R 
    5351        Parent.__init__(self, base = sage.rings.integer_ring.ZZ, category = Monoids()) 
    5452        self._populate_coercion_lists_() 
  • 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  
    353353        sage: P.<a,b,c,d,e> = PolynomialRing(GF(127)) 
    354354        sage: J = sage.rings.ideal.Cyclic(P).homogenize() 
    355355        sage: from sage.misc.sageinspect import sage_getsource 
    356         sage: "buchberger" in sage_getsource(J.interreduced_basis) 
     356        sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest 
    357357        True 
    358358 
    359359    .. note:: 
     
    451451        EXAMPLES:: 
    452452         
    453453            sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
    454             sage: I = sage.rings.ideal.Cyclic(R,4) 
    455             sage: magma(I)                                          # optional - magma 
     454            sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest 
     455            sage: magma(I)    # optional - magma 
    456456            Ideal of Polynomial ring of rank 10 over GF(127) 
    457457            Graded Reverse Lexicographical Order 
    458458            Variables: a, b, c, d, e, f, g, h, i, j 
     
    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_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. 
     
    11861296        self.__gb_singular = S 
    11871297        return S 
    11881298 
    1189     @redSB 
    1190     def _groebner_basis_libsingular(self, algorithm="groebner", redsb=True, red_tail=True): 
    1191         """ 
    1192         Return the reduced Groebner basis of this ideal. If the 
    1193         Groebner basis for this ideal has been calculated before the 
    1194         cached Groebner basis is returned regardless of the requested 
    1195         algorithm. 
    1196          
    1197         INPUT: 
    1198          
    1199         -  ``algorithm`` - see below for available algorithms 
    1200         - ``redsb`` - return a reduced Groebner basis (default: ``True``) 
    1201         - ``red_tail`` - perform tail reduction (default: ``True``) 
    1202  
    1203         ALGORITHMS: 
    1204          
    1205         'groebner' 
    1206             Singular's heuristic script (default) 
    1207  
    1208         'std' 
    1209             Buchberger's algorithm 
    1210          
    1211         'slimgb' 
    1212             the *SlimGB* algorithm 
    1213  
    1214         'stdhilb' 
    1215             Hilbert Basis driven Groebner basis 
    1216          
    1217         'stdfglm' 
    1218             Buchberger and FGLM 
    1219          
    1220         EXAMPLES: 
    1221          
    1222         We compute a Groebner basis of 'cyclic 4' relative to 
    1223         lexicographic ordering. :: 
    1224          
    1225             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
    1226             sage: I = sage.rings.ideal.Cyclic(R,4); I 
    1227             Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d 
    1228             + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
    1229             Ring in a, b, c, d over Rational Field 
    1230          
    1231         :: 
    1232          
    1233             sage: I._groebner_basis_libsingular() 
    1234             [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
    1235             b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
    1236             b^2 + 2*b*d + d^2, a + b + c + d] 
    1237          
    1238         ALGORITHM: Uses libSINGULAR. 
    1239         """ 
    1240         from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
    1241         from sage.libs.singular import singular_function 
    1242         from sage.libs.singular.option import opt 
    1243  
    1244         import sage.libs.singular 
    1245         groebner = sage.libs.singular.ff.groebner 
    1246  
    1247         opt['redSB'] = redsb 
    1248         opt['redTail'] = red_tail 
    1249  
    1250         T = self.ring().term_order() 
    1251          
    1252         if algorithm == "std": 
    1253             S = std_libsingular(self) 
    1254         elif algorithm == "slimgb": 
    1255             S = slimgb_libsingular(self) 
    1256         elif algorithm == "groebner": 
    1257             S = groebner(self) 
    1258         else: 
    1259             try: 
    1260                 fnc = singular_function(algorithm) 
    1261                 S = fnc(self) 
    1262             except NameError: 
    1263                 raise NameError("Algorithm '%s' unknown"%algorithm) 
    1264         return S 
    1265      
    12661299    @require_field 
    12671300    def genus(self): 
    12681301        """ 
     
    13231356            False 
    13241357        """ 
    13251358        R = self.ring() 
     1359 
    13261360        if not isinstance(other, MPolynomialIdeal_singular_repr) or other.ring() != R: 
    13271361            raise ValueError, "other must be an ideal in the ring of self, but it isn't." 
    13281362 
     
    14491483        ret = Sequence(normalI(self, p, int(r))[0], R, check=False, immutable=True) 
    14501484        return ret 
    14511485 
    1452     @require_field 
    1453     def syzygy_module(self): 
    1454         r""" 
    1455         Computes the first syzygy (i.e., the module of relations of the 
    1456         given generators) of the ideal. 
    1457          
    1458         EXAMPLE:: 
    1459          
    1460             sage: R.<x,y> = PolynomialRing(QQ) 
    1461             sage: f = 2*x^2 + y 
    1462             sage: g = y 
    1463             sage: h = 2*f + g 
    1464             sage: I = Ideal([f,g,h]) 
    1465             sage: M = I.syzygy_module(); M 
    1466             [       -2        -1         1] 
    1467             [       -y 2*x^2 + y         0] 
    1468             sage: G = vector(I.gens()) 
    1469             sage: M*G 
    1470             (0, 0) 
    1471          
    1472         ALGORITHM: Uses Singular's syz command 
    1473         """ 
    1474         import sage.libs.singular 
    1475         syz = sage.libs.singular.ff.syz 
    1476         from sage.matrix.constructor import matrix 
    1477  
    1478         #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
    1479         S = syz(self) 
    1480         return matrix(self.ring(), S) 
    1481  
    14821486    @redSB 
    14831487    def reduced_basis(self): 
    14841488        r""" 
     
    22102214    def _macaulay2_(self, macaulay2=None): 
    22112215        """ 
    22122216        Return Macaulay2 ideal corresponding to this ideal. 
     2217    EXAMPLES:: 
     2218     
     2219        sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4) 
     2220        sage: I = ideal(x*y-z^2, y^2-w^2)  #indirect doctest 
     2221        sage: macaulay2(I) # optional - macaulay2 
     2222        Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring 
    22132223        """ 
    22142224        if macaulay2 is None: macaulay2 = macaulay2_default 
    22152225        try: 
     
    22882298        R = self.ring() 
    22892299        return R(k) 
    22902300 
     2301class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_generic): 
     2302    def __init__(self, ring, gens, coerce=True): 
     2303        r""" 
     2304        Computes a non-commutative ideal. 
     2305         
     2306        EXAMPLES:: 
     2307         
     2308            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2309            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2310            sage: H.inject_variables() 
     2311            Defining x, y, z 
     2312 
     2313            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) # indirect doctest 
     2314        """ 
     2315        Ideal_generic.__init__(self, ring, gens, coerce=coerce) 
     2316 
     2317    def __call_singular(self, cmd, arg = None): 
     2318        """ 
     2319        Internal function for calling a Singular function 
     2320 
     2321        INPUTS: 
     2322 
     2323        - ``cmd`` - string, representing a Singular function 
     2324 
     2325        - ``arg`` (Default: None) - arguments for which cmd is called 
     2326 
     2327        OUTPUTS: 
     2328 
     2329        - result of the Singular function call 
     2330 
     2331        EXAMPLES:: 
     2332 
     2333            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2334            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2335            sage: H.inject_variables() 
     2336            Defining x, y, z 
     2337            sage: id = H.ideal(x + y, y + z) 
     2338            sage: id.std()  # indirect doctest 
     2339            Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x} 
     2340        """ 
     2341        from sage.libs.singular.function import singular_function 
     2342        fun = singular_function(cmd) 
     2343        if arg is None: 
     2344             return fun(self, ring=self.ring()) 
     2345         
     2346        return fun(self, arg, ring=self.ring()) 
     2347 
     2348    def std(self): 
     2349        r""" 
     2350        Computes a left GB of the ideal. 
     2351         
     2352        EXAMPLES:: 
     2353         
     2354            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2355            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2356            sage: H.inject_variables() 
     2357            Defining x, y, z 
     2358            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2359            sage: I.std() 
     2360            Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field... 
     2361         
     2362        ALGORITHM: Uses Singular's std command 
     2363        """ 
     2364        return self.ring().ideal( self.__call_singular('std') ) 
     2365#        return self.__call_singular('std') 
     2366 
     2367    def twostd(self): 
     2368        r""" 
     2369        Computes a two-sided GB of the ideal. 
     2370         
     2371        EXAMPLES:: 
     2372         
     2373            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2374            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2375            sage: H.inject_variables() 
     2376            Defining x, y, z 
     2377            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2378            sage: I.twostd() 
     2379            Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field... 
     2380         
     2381        ALGORITHM: Uses Singular's twostd command 
     2382        """ 
     2383        return self.ring().ideal( self.__call_singular('twostd') ) 
     2384#        return self.__call_singular('twostd') 
     2385 
     2386#    def syz(self): 
     2387#        return self.__call_singular('syz') 
     2388 
     2389    @require_field 
     2390    def syzygy_module(self): 
     2391        r""" 
     2392        Computes the first syzygy (i.e., the module of relations of the 
     2393        given generators) of the ideal. 
     2394         
     2395        EXAMPLE:: 
     2396         
     2397            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2398            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2399            sage: H.inject_variables() 
     2400            Defining x, y, z 
     2401            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2402            sage: G = vector(I.gens()); G  
     2403            doctest:357: UserWarning: You are constructing a free module   over a noncommutative ring. Sage does 
     2404                         not have a concept of left/right and both sided modules be careful. It's also 
     2405                         not guarantied that all multiplications are done from the right side. 
     2406            doctest:573: UserWarning: 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. 
     2407            (y^2, x^2, z^2 - 1) 
     2408            sage: M = I.syzygy_module(); M 
     2409            [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2] 
     2410            [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2] 
     2411            [                                                              x^2*z^2 + 8*x^2*z + 15*x^2                                                              -y^2*z^2 + 8*y^2*z - 15*y^2                                                                   -4*x*y*z + 2*z^2 + 2*z] 
     2412            [                 x^2*y*z^2 + 9*x^2*y*z - 6*x*z^3 + 20*x^2*y - 72*x*z^2 - 282*x*z - 360*x                                                              -y^3*z^2 + 7*y^3*z - 12*y^3                                                                                  6*y*z^2] 
     2413            [                                                              x^3*z^2 + 7*x^3*z + 12*x^3                 -x*y^2*z^2 + 9*x*y^2*z - 4*y*z^3 - 20*x*y^2 + 52*y*z^2 - 224*y*z + 320*y                                                                                 -6*x*z^2] 
     2414            [  x^2*y^2*z + 4*x^2*y^2 - 8*x*y*z^2 - 48*x*y*z + 12*z^3 - 64*x*y + 108*z^2 + 312*z + 288                                                                           -y^4*z + 4*y^4                                                                                        0] 
     2415            [                                                  2*x^3*y*z + 8*x^3*y + 9*x^2*z + 27*x^2                                   -2*x*y^3*z + 8*x*y^3 - 12*y^2*z^2 + 99*y^2*z - 195*y^2                                                                -36*x*y*z + 24*z^2 + 18*z] 
     2416            [                                                  2*x^3*y*z + 8*x^3*y + 9*x^2*z + 27*x^2                                   -2*x*y^3*z + 8*x*y^3 - 12*y^2*z^2 + 99*y^2*z - 195*y^2                                                                -36*x*y*z + 24*z^2 + 18*z] 
     2417            [                                                                           x^4*z + 4*x^4    -x^2*y^2*z + 4*x^2*y^2 - 4*x*y*z^2 + 32*x*y*z - 6*z^3 - 64*x*y + 66*z^2 - 240*z + 288                                                                                        0] 
     2418            [x^3*y^2*z + 4*x^3*y^2 + 18*x^2*y*z - 36*x*z^3 + 66*x^2*y - 432*x*z^2 - 1656*x*z - 2052*x                                      -x*y^4*z + 4*x*y^4 - 8*y^3*z^2 + 62*y^3*z - 114*y^3                                                                        48*y*z^2 - 36*y*z] 
     2419 
     2420            sage: M*G 
     2421            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
     2422         
     2423        ALGORITHM: Uses Singular's syz command 
     2424        """ 
     2425        import sage.libs.singular 
     2426        syz = sage.libs.singular.ff.syz 
     2427        from sage.matrix.constructor import matrix 
     2428 
     2429        #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
     2430        S = syz(self) 
     2431        return matrix(self.ring(), S) 
     2432 
     2433 
     2434    def res(self, length): 
     2435        r""" 
     2436        Computes the first syzygy (i.e., the module of relations of the 
     2437        given generators) of the ideal. 
     2438         
     2439        EXAMPLE:: 
     2440         
     2441            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2442            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2443            sage: H.inject_variables() 
     2444            Defining x, y, z 
     2445            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2446            sage: I.res(3) 
     2447            <Resolution> 
     2448        """ 
     2449        return self.__call_singular('res', length) 
     2450 
    22912451 
    22922452class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \ 
    22932453                        MPolynomialIdeal_macaulay2_repr, \ 
     
    29093069         
    29103070            sage: R.<x,y,z> = PolynomialRing(QQ) 
    29113071            sage: I = R.ideal(x^2-2*x*z+5, x*y^2+y*z+1, 3*y^2-8*x*z) 
    2912             sage: I.normal_basis() 
     3072            sage: I.normal_basis() #indirect doctest 
    29133073            [z^2, y*z, x*z, z, x*y, y, x, 1] 
    29143074        """ 
    29153075        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular 
  • 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/multi_polynomial_libsingular.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
    a b  
    18921892        EXAMPLES:: 
    18931893 
    18941894            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    1895             sage: 3/2*x + 1/2*y + 1 
     1895            sage: 3/2*x + 1/2*y + 1 #indirect doctest 
    18961896            3/2*x + 1/2*y + 1 
    18971897 
    18981898        """ 
     
    19091909        EXAMPLES:: 
    19101910 
    19111911            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    1912             sage: 3/2*x - 1/2*y - 1 
     1912            sage: 3/2*x - 1/2*y - 1 #indirect doctest 
    19131913            3/2*x - 1/2*y - 1 
    19141914 
    19151915        """ 
     
    19281928        EXAMPLES:: 
    19291929 
    19301930            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    1931             sage: 3/2*x 
     1931            sage: 3/2*x # indirect doctest 
    19321932            3/2*x 
    19331933        """ 
    19341934 
     
    19401940        return new_MP((<MPolynomialRing_libsingular>self._parent),_p) 
    19411941         
    19421942    cpdef ModuleElement _lmul_(self, RingElement right): 
    1943         # all currently implemented rings are commutative 
    1944         return self._rmul_(right) 
     1943        """ 
     1944        Multiply left and right. 
     1945 
     1946        EXAMPLES:: 
     1947 
     1948            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     1949            sage: (3/2*x - 1/2*y - 1) * (3/2) # indirect doctest 
     1950            9/4*x - 3/4*y - 3/2 
     1951        """ 
     1952        # all currently implemented baser rings are commutative 
     1953        return right._rmul_(self) 
    19451954         
    19461955    cpdef RingElement  _mul_(left, RingElement right): 
    19471956        """ 
     
    19501959        EXAMPLES:: 
    19511960 
    19521961            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    1953             sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) 
     1962            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest 
    19541963            9/4*x^2 - 1/4*y^2 - y - 1 
    19551964 
    19561965            sage: P.<x,y> = PolynomialRing(QQ,order='lex') 
     
    19731982        EXAMPLES:: 
    19741983 
    19751984            sage: R.<x,y>=PolynomialRing(QQ,2) 
    1976             sage: f = (x + y)/3 
     1985            sage: f = (x + y)/3 # indirect doctest 
    19771986            sage: f.parent() 
    19781987            Multivariate Polynomial Ring in x, y over Rational Field 
    19791988 
     
    21492158 
    21502159            sage: P.<x,y,z> = QQ[] 
    21512160            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
    2152             sage: latex(f) 
     2161            sage: latex(f)  # indirect doctest 
    21532162            - x^{2} y - \frac{25}{27} y^{3} - z^{2} 
    21542163        """ 
    21552164        cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring 
     
    41084117        EXAMPLES:: 
    41094118 
    41104119            sage: R.<x,y> = PolynomialRing(GF(7), 2) 
    4111             sage: f = (x^3 + 2*y^2*x)^7; f 
     4120            sage: f = (x^3 + 2*y^2*x)^7; f          # indirect doctest 
    41124121            x^21 + 2*x^7*y^14 
    41134122 
    41144123            sage: h = macaulay2(f); h               # optional 
  • new file sage/rings/polynomial/plural.pxd

    diff --git a/sage/rings/polynomial/plural.pxd b/sage/rings/polynomial/plural.pxd
    new file mode 100644
    - +  
     1include "../../libs/singular/singular-cdefs.pxi" 
     2 
     3from sage.rings.ring cimport Ring 
     4from sage.structure.element cimport RingElement, Element 
     5from sage.structure.parent cimport Parent 
     6from sage.libs.singular.function cimport RingWrap 
     7from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular  
     8 
     9 
     10cdef class NCPolynomialRing_plural(Ring): 
     11    cdef object __ngens 
     12    cdef object _c 
     13    cdef object _d 
     14    cdef object __term_order 
     15    cdef public object _has_singular 
     16    cdef public object _magma_gens, _magma_cache 
     17#    cdef _richcmp_c_impl(left, Parent right, int op) 
     18    cdef int _cmp_c_impl(left, Parent right) except -2 
     19     
     20    cdef ring *_ring 
     21#    cdef NCPolynomial_plural _one_element 
     22#    cdef NCPolynomial_plural _zero_element 
     23     
     24    cdef public object _relations 
     25    pass 
     26 
     27cdef class ExteriorAlgebra_plural(NCPolynomialRing_plural): 
     28    pass 
     29 
     30cdef class NCPolynomial_plural(RingElement): 
     31    cdef poly *_poly 
     32    cpdef _repr_short_(self) 
     33    cdef long _hash_c(self) 
     34    cpdef is_constant(self) 
     35#    cpdef _homogenize(self, int var) 
     36 
     37cdef NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, poly *juice) 
     38 
     39cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring) 
     40cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring) 
  • new file sage/rings/polynomial/plural.pyx

    diff --git a/sage/rings/polynomial/plural.pyx b/sage/rings/polynomial/plural.pyx
    new file mode 100644
    - +  
     1r""" 
     2Noncommutative Polynomials via libSINGULAR/Plural 
     3 
     4This module implements specialized and optimized implementations for 
     5noncommutative multivariate polynomials over many coefficient rings, via the 
     6shared library interface to SINGULAR. In particular, the following coefficient 
     7rings are supported by this implementation: 
     8 
     9- the rational numbers `\QQ`, and 
     10 
     11- finite fields `\GF{p}` for `p` prime 
     12 
     13AUTHORS: 
     14 
     15The PLURAL wrapper is due to 
     16 
     17  - Burcin Erocal (2008-11 and 2010-07): initial implementation and concept 
     18 
     19  - Michael Brickenstein (2008-11 and 2010-07): initial implementation and concept 
     20 
     21  - Oleksandr Motsak (2010-07): complete overall fnoncommutative unctionality and first release 
     22 
     23  - Alexander Dreyer (2010-07): noncommutative ring functionality and documentation 
     24 
     25The underlying libSINGULAR interface was implemented by 
     26 
     27- Martin Albrecht (2007-01): initial implementation 
     28 
     29- Joel Mohler (2008-01): misc improvements, polishing 
     30 
     31- Martin Albrecht (2008-08): added `\QQ(a)` and `\ZZ` support 
     32 
     33- Simon King (2009-04): improved coercion 
     34 
     35- Martin Albrecht (2009-05): added `\ZZ/n\ZZ` support, refactoring 
     36 
     37- Martin Albrecht (2009-06): refactored the code to allow better 
     38  re-use 
     39 
     40TODO: 
     41 
     42- extend functionality towards those of libSINGULARs commutative part 
     43 
     44EXAMPLES: 
     45 
     46We show how to construct various noncommutative polynomial rings:: 
     47 
     48    sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     49    sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     50    sage: P.inject_variables() 
     51    Defining x, y, z 
     52 
     53    sage: P 
     54    Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     55 
     56    sage: y*x + 1/2 
     57    -x*y + 1/2 
     58 
     59    sage: A.<x,y,z> = FreeAlgebra(GF(17), 3) 
     60    sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     61    sage: P.inject_variables() 
     62    Defining x, y, z 
     63 
     64    sage: P 
     65    Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 17, nc-relations: {y*x: -x*y} 
     66 
     67    sage: y*x + 7 
     68    -x*y + 7 
     69     
     70     
     71Raw use of this class:: 
     72    sage: from sage.matrix.constructor  import Matrix 
     73    sage: c = Matrix(3) 
     74    sage: c[0,1] = -2 
     75    sage: c[0,2] = 1 
     76    sage: c[1,2] = 1 
     77     
     78    sage: d = Matrix(3) 
     79    sage: d[0, 1] = 17 
     80     
     81    sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     82    sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex') 
     83    sage: R 
     84    Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -2*x*y + 17} 
     85 
     86    sage: R.term_order() 
     87    Lexicographic term order 
     88 
     89    sage: a,b,c = R.gens() 
     90    sage: f = 57 * a^2*b + 43 * c + 1; f 
     91    57*x^2*y + 43*z + 1 
     92 
     93    sage: R.term_order() 
     94    Lexicographic term order 
     95 
     96TESTS:: 
     97 
     98    sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     99    sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     100    sage: P.inject_variables() 
     101    Defining x, y, z 
     102 
     103    sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural, NCPolynomial_plural 
     104    sage: TestSuite(NCPolynomialRing_plural).run() 
     105    sage: TestSuite(NCPolynomial_plural).run() 
     106""" 
     107include "sage/ext/stdsage.pxi" 
     108include "sage/ext/interrupt.pxi" 
     109 
     110 
     111from sage.libs.singular.function cimport RingWrap 
     112from sage.structure.parent_base cimport ParentWithBase 
     113from sage.structure.parent_gens cimport ParentWithGens 
     114 
     115# singular rings 
     116from sage.libs.singular.ring cimport singular_ring_new, singular_ring_delete 
     117 
     118from sage.rings.integer cimport Integer 
     119from sage.structure.element cimport Element, ModuleElement 
     120 
     121from 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 
     122from sage.libs.singular.polynomial cimport singular_polynomial_deg, singular_polynomial_str_with_changed_varnames, singular_polynomial_latex, singular_polynomial_str, singular_polynomial_div_coeff 
     123 
     124from sage.rings.polynomial.polydict import ETuple 
     125 
     126from sage.libs.singular.singular cimport si2sa, sa2si, overflow_check 
     127from sage.rings.integer_ring import ZZ 
     128from term_order import TermOrder 
     129 
     130 
     131from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 
     132#from sage.rings.polynomial.multi_polynomial_libsingular cimport addwithcarry 
     133from sage.rings.polynomial.multi_polynomial_ring_generic import MPolynomialRing_generic  
     134 
     135 
     136from sage.structure.parent cimport Parent 
     137from sage.structure.element cimport CommutativeRingElement 
     138from sage.rings.finite_rings.finite_field_prime_modn import FiniteField_prime_modn 
     139from sage.rings.integer_ring import is_IntegerRing, ZZ 
     140 
     141cdef class NCPolynomialRing_plural(Ring): 
     142    def __init__(self, base_ring, n, names, c, d, order='degrevlex', check = True): 
     143        """ 
     144        Construct a noncommutative polynomial G-algebra subject to the following conditions: 
     145 
     146        INPUT: 
     147 
     148        - ``base_ring`` - base ring (must be either GF(q), ZZ, ZZ/nZZ, 
     149                          QQ or absolute number field) 
     150 
     151        - ``n`` - number of variables (must be at least 1) 
     152 
     153        - ``names`` - names of ring variables, may be string of list/tuple 
     154 
     155        - ``c``, ``d``- upper triangular matrices of coefficients, 
     156        resp. commutative polynomials, satisfying the nondegeneracy conditions, which 
     157        are to be tested if check == True. These matrices describe the noncommutative 
     158        relations:       
     159 
     160            self.gen(j)*self.gen(i) == c[i, j] * self.gen(i)*self.gen(j) + d[i, j],  
     161 
     162        where 0 <= i < j < self.ngens() 
     163         
     164        - ``order`` - term order (default: ``degrevlex``) 
     165 
     166        - ``check`` - check the noncommutative conditions (default: ``True``) 
     167 
     168        EXAMPLES:: 
     169 
     170            sage: from sage.matrix.constructor  import Matrix 
     171            sage: c = Matrix(3) 
     172            sage: c[0,1] = -1 
     173            sage: c[0,2] = 1 
     174            sage: c[1,2] = 1 
     175 
     176            sage: d = Matrix(3) 
     177            sage: d[0, 1] = 17 
     178 
     179            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     180            sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex') 
     181 
     182            sage: P # indirect doctest  
     183            Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y + 17} 
     184 
     185            sage: P(x*y) 
     186            x*y 
     187 
     188            sage: f = 27/113 * x^2 + y*z + 1/2; f 
     189            27/113*x^2 + y*z + 1/2 
     190 
     191            sage: P.term_order() 
     192            Lexicographic term order 
     193 
     194            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     195            sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), 3, c = c, d = d, order='degrevlex') 
     196 
     197            sage: P # indirect doctest  
     198            Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 7, nc-relations: {y*x: -x*y + 3} 
     199 
     200            sage: P(x*y) 
     201            x*y 
     202 
     203            sage: f = 3 * x^2 + y*z + 5; f 
     204            3*x^2 + y*z - 2 
     205 
     206            sage: P.term_order() 
     207            Degree reverse lexicographic term order 
     208 
     209        """ 
     210 
     211        self._relations = None 
     212        n = int(n) 
     213        if n < 0: 
     214            raise ValueError, "Multivariate Polynomial Rings must " + \ 
     215                  "have more than 0 variables." 
     216 
     217        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing 
     218 
     219        order = TermOrder(order,n) 
     220        P = PolynomialRing(base_ring, n, names, order=order) 
     221         
     222        self._c = c.change_ring(P) 
     223        self._d = d.change_ring(P) 
     224 
     225        from sage.libs.singular.function import singular_function 
     226        ncalgebra = singular_function('nc_algebra') 
     227 
     228        cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P) 
     229 
     230        #       rw._output() 
     231        self._ring = rw._ring 
     232        self._ring.ShortOut = 0 
     233 
     234        self.__ngens = n 
     235        self.__term_order = order 
     236 
     237        ParentWithGens.__init__(self, base_ring, names) 
     238        self._populate_coercion_lists_() 
     239         
     240        #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     241        #self._has_singular = True 
     242        assert(n == len(self._names)) 
     243         
     244        self._one_element = new_NCP(self, p_ISet(1, self._ring)) 
     245        self._zero_element = new_NCP(self, NULL) 
     246         
     247 
     248        if check: 
     249            import sage.libs.singular 
     250            test = sage.libs.singular.ff.nctools__lib.ndcond(ring = self) 
     251            if (len(test) != 1) or (test[0] != 0): 
     252                raise ValueError, "NDC check failed!" 
     253 
     254    def __dealloc__(self): 
     255        r""" 
     256        Carefully deallocate the ring, without changing "currRing" 
     257        (since this method can be at unpredictable times due to garbage 
     258        collection). 
     259 
     260        TESTS: 
     261        This example caused a segmentation fault with a previous version 
     262        of this method: 
     263            sage: import gc 
     264            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     265            sage: from sage.algebras.free_algebra import FreeAlgebra 
     266            sage: A1.<x,y,z> = FreeAlgebra(QQ, 3) 
     267            sage: R1 = A1.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) 
     268            sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3) 
     269            sage: R2 = A2.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) 
     270            sage: A3.<x,y,z> = FreeAlgebra(GF(11), 3) 
     271            sage: R3 = A3.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) 
     272            sage: A4.<x,y,z> = FreeAlgebra(GF(13), 3) 
     273            sage: R4 = A4.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}, order=TermOrder('degrevlex', 2)) 
     274            sage: _ = gc.collect() 
     275            sage: foo = R1.gen(0) 
     276            sage: del foo 
     277            sage: del R1 
     278            sage: _ = gc.collect() 
     279            sage: del R2 
     280            sage: _ = gc.collect() 
     281            sage: del R3 
     282            sage: _ = gc.collect() 
     283        """ 
     284        singular_ring_delete(self._ring) 
     285     
     286    def _element_constructor_(self, element): 
     287        """ 
     288        Make sure element is a valid member of self, and return the constructed element.  
     289 
     290        EXAMPLES:: 
     291            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     292 
     293            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     294 
     295        We can construct elements from the base ring:: 
     296 
     297            sage: P(1/2) 
     298            1/2 
     299             
     300 
     301        and all kinds of integers:: 
     302 
     303            sage: P(17) 
     304            17 
     305 
     306            sage: P(int(19)) 
     307            19 
     308 
     309            sage: P(long(19)) 
     310            19 
     311             
     312        TESTS:: 
     313 
     314        Check conversion from self:: 
     315            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     316            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     317            sage: P.inject_variables() 
     318            Defining x, y, z 
     319 
     320            sage: P._element_constructor_(1/2) 
     321            1/2 
     322 
     323            sage: P._element_constructor_(x*y) 
     324            x*y 
     325 
     326            sage: P._element_constructor_(y*x) 
     327            -x*y          
     328 
     329        Raw use of this class:: 
     330            sage: from sage.matrix.constructor  import Matrix 
     331            sage: c = Matrix(3) 
     332            sage: c[0,1] = -2 
     333            sage: c[0,2] = 1 
     334            sage: c[1,2] = 1 
     335 
     336            sage: d = Matrix(3) 
     337            sage: d[0, 1] = 17 
     338 
     339            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     340            sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex') 
     341            sage: R._element_constructor_(x*y) 
     342            x*y 
     343             
     344            sage: P._element_constructor_(17) 
     345            17 
     346 
     347            sage: P._element_constructor_(int(19)) 
     348            19 
     349 
     350        Testing special cases:: 
     351            sage: P._element_constructor_(1) 
     352            1 
     353 
     354            sage: P._element_constructor_(0) 
     355            0 
     356        """ 
     357 
     358        if element == 0: 
     359            return self._zero_element 
     360        if element == 1: 
     361            return self._one_element 
     362 
     363        cdef poly *_p 
     364        cdef ring *_ring, 
     365        cdef number *_n  
     366        
     367        _ring = self._ring 
     368        
     369        base_ring = self.base_ring() 
     370 
     371        if(_ring != currRing): rChangeCurrRing(_ring) 
     372 
     373 
     374        if PY_TYPE_CHECK(element, NCPolynomial_plural): 
     375 
     376            if element.parent() is <object>self: 
     377                return element 
     378            elif element.parent() == self: 
     379                # is this safe? 
     380                _p = p_Copy((<NCPolynomial_plural>element)._poly, _ring) 
     381 
     382        elif PY_TYPE_CHECK(element, CommutativeRingElement): 
     383            # base ring elements 
     384            if  <Parent>element.parent() is base_ring: 
     385                # shortcut for GF(p) 
     386                if isinstance(base_ring, FiniteField_prime_modn): 
     387                    _p = p_ISet(int(element) % _ring.ch, _ring) 
     388                else:  
     389                    _n = sa2si(element,_ring) 
     390                    _p = p_NSet(_n, _ring) 
     391                     
     392            # also accepting ZZ 
     393            elif is_IntegerRing(element.parent()): 
     394                if isinstance(base_ring, FiniteField_prime_modn): 
     395                    _p = p_ISet(int(element),_ring) 
     396                else: 
     397                    _n = sa2si(base_ring(element),_ring) 
     398                    _p = p_NSet(_n, _ring) 
     399            else: 
     400                # fall back to base ring 
     401                element = base_ring._coerce_c(element) 
     402                _n = sa2si(element,_ring) 
     403                _p = p_NSet(_n, _ring) 
     404 
     405        # Accepting int 
     406        elif PY_TYPE_CHECK(element, int): 
     407            if isinstance(base_ring, FiniteField_prime_modn): 
     408                _p = p_ISet(int(element) % _ring.ch,_ring) 
     409            else: 
     410                _n = sa2si(base_ring(element),_ring) 
     411                _p = p_NSet(_n, _ring) 
     412                 
     413        # and longs 
     414        elif PY_TYPE_CHECK(element, long): 
     415            if isinstance(base_ring, FiniteField_prime_modn): 
     416                element = element % self.base_ring().characteristic() 
     417                _p = p_ISet(int(element),_ring) 
     418            else: 
     419                _n = sa2si(base_ring(element),_ring) 
     420                _p = p_NSet(_n, _ring) 
     421 
     422        else: 
     423            raise NotImplementedError("not able to constructor "+repr(element) + 
     424                                      " of type "+ repr(type(element))) #### ?????? 
     425 
     426 
     427        return new_NCP(self,_p) 
     428 
     429 
     430         
     431    cpdef _coerce_map_from_(self, S): 
     432       """ 
     433       The only things that coerce into this ring are: 
     434           - the integer ring 
     435           - other localizations away from fewer primes 
     436 
     437         EXAMPLES:: 
     438           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     439           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     440 
     441           sage: P._coerce_map_from_(ZZ) 
     442           True 
     443       """ 
     444 
     445       if self.base_ring().has_coerce_map_from(S): 
     446           return True 
     447        
     448        
     449        
     450    def __hash__(self): 
     451       """ 
     452       Return a hash for this noncommutative ring, that is, a hash of the string 
     453       representation of this polynomial ring. 
     454 
     455       EXAMPLES:: 
     456           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     457           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     458           sage: hash(P)      # somewhat random output 
     459           ... 
     460 
     461       TESTS:: 
     462 
     463       Check conversion from self:: 
     464           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     465           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     466           sage: from sage.matrix.constructor  import Matrix 
     467           sage: c = Matrix(3) 
     468           sage: c[0,1] = -1 
     469           sage: c[0,2] = 1 
     470           sage: c[1,2] = 1 
     471 
     472           sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     473           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     474           sage: hash(R) == hash(P) 
     475           True 
     476       """ 
     477       return hash(str(self.__repr__()) + str(self.term_order()) ) 
     478 
     479 
     480    def __cmp__(self, right): 
     481        r""" 
     482        Multivariate polynomial rings are said to be equal if: 
     483         
     484        - their base rings match, 
     485        - their generator names match, 
     486        - their term orderings match, and 
     487        - their relations match. 
     488 
     489 
     490        EXAMPLES:: 
     491           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     492           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     493 
     494           sage: P == P 
     495           True 
     496           sage: Q = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     497           sage: Q == P 
     498           True 
     499                      
     500           sage: from sage.matrix.constructor  import Matrix 
     501           sage: c = Matrix(3) 
     502           sage: c[0,1] = -1 
     503           sage: c[0,2] = 1 
     504           sage: c[1,2] = 1 
     505           sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     506           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     507           sage: R == P 
     508           True 
     509            
     510           sage: c[0,1] = -2 
     511           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     512           sage: P == R 
     513           False 
     514        """ 
     515 
     516        if PY_TYPE_CHECK(right, NCPolynomialRing_plural): 
     517 
     518            return cmp( (self.base_ring(), map(str, self.gens()), 
     519                         self.term_order(), self._c, self._d), 
     520                        (right.base_ring(), map(str, right.gens()), 
     521                         right.term_order(), 
     522                         (<NCPolynomialRing_plural>right)._c, 
     523                         (<NCPolynomialRing_plural>right)._d) 
     524                        ) 
     525        else: 
     526            return cmp(type(self),type(right)) 
     527 
     528    def __pow__(self, n, _): 
     529        """ 
     530        Return the free module of rank `n` over this ring. 
     531 
     532        EXAMPLES:: 
     533            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     534            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     535            sage: P.inject_variables() 
     536            Defining x, y, z 
     537 
     538            sage: f = x^3 + y 
     539            sage: f^2 
     540            x^6 + y^2         
     541        """ 
     542        import sage.modules.all  
     543        return sage.modules.all.FreeModule(self, n) 
     544     
     545    def term_order(self): 
     546        """ 
     547        Return the term ordering of the noncommutative ring. 
     548 
     549        EXAMPLES:: 
     550         
     551        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     552        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     553        sage: P.term_order() 
     554        Lexicographic term order 
     555 
     556        sage: P = A.g_algebra(relations={y*x:-x*y}) 
     557        sage: P.term_order() 
     558        Degree reverse lexicographic term order 
     559        """ 
     560        return self.__term_order 
     561 
     562    def is_commutative(self): 
     563        """ 
     564        Return False. 
     565 
     566        EXAMPLES:: 
     567         
     568        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     569        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     570        sage: P.is_commutative() 
     571        False 
     572        """ 
     573        return False 
     574     
     575    def is_field(self): 
     576        """ 
     577        Return False. 
     578 
     579        EXAMPLES:: 
     580         
     581        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     582        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     583        sage: P.is_field() 
     584        False 
     585        """     
     586        return False 
     587     
     588    def _repr_(self): 
     589        """ 
     590        EXAMPLE: 
     591            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     592            sage: from sage.matrix.constructor  import Matrix 
     593            sage: c=Matrix(2) 
     594            sage: c[0,1]=-1 
     595            sage: P.<x,y> = NCPolynomialRing_plural(QQ, 2, c=c, d=Matrix(2)) 
     596            sage: P # indirect doctest 
     597            Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: {y*x: -x*y} 
     598            sage: x*y 
     599            x*y 
     600            sage: y*x 
     601            -x*y 
     602        """ 
     603#TODO: print the relations 
     604        varstr = ", ".join([ rRingVar(i,self._ring)  for i in range(self.__ngens) ]) 
     605        return "Noncommutative Multivariate Polynomial Ring in %s over %s, nc-relations: %s"%(varstr,self.base_ring(), self.relations()) 
     606 
     607 
     608    def _ringlist(self): 
     609        """ 
     610        Return an internal list representation of the noncummutative ring. 
     611 
     612        EXAMPLES:: 
     613        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     614        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     615        sage: P._ringlist() 
     616        [0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 -1  1] 
     617        [ 0  0  1] 
     618        [ 0  0  0], [0 0 0] 
     619        [0 0 0] 
     620        [0 0 0]] 
     621        """ 
     622        cdef ring* _ring = self._ring 
     623        if(_ring != currRing): rChangeCurrRing(_ring) 
     624        from sage.libs.singular.function import singular_function 
     625        ringlist = singular_function('ringlist') 
     626        result = ringlist(self, ring=self) 
     627        
     628 
     629 
     630 
     631        return result 
     632         
     633 
     634    def relations(self, add_commutative = False): 
     635        """ 
     636        EXAMPLE: 
     637            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     638            sage: from sage.matrix.constructor  import Matrix 
     639            sage: c=Matrix(2) 
     640            sage: c[0,1]=-1 
     641            sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 
     642            sage: P # indirect doctest 
     643            Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: ... 
     644        """ 
     645        if self._relations is not None: 
     646            return self._relations 
     647 
     648        from sage.algebras.free_algebra import FreeAlgebra 
     649        A = FreeAlgebra( self.base_ring(), self.ngens(), self.gens() ) 
     650 
     651        res = {} 
     652        n = self.ngens() 
     653        for r in range(0, n-1, 1): 
     654            for c in range(r+1, n, 1): 
     655                if  (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)) or add_commutative: 
     656                    res[ A.gen(c) * A.gen(r) ] = self.gen(c) * self.gen(r) # C[r, c] * P.gen(r) * P.gen(c) + D[r, c] 
     657         
     658             
     659        self._relations = res 
     660        return self._relations 
     661 
     662    def ngens(self): 
     663        """ 
     664        Returns the number of variables in this noncommutative polynomial ring. 
     665 
     666        EXAMPLES:: 
     667 
     668            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     669            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     670            sage: P.inject_variables() 
     671            Defining x, y, z 
     672 
     673            sage: P.ngens() 
     674            3 
     675        """ 
     676        return int(self.__ngens) 
     677 
     678    def gen(self, int n=0): 
     679        """ 
     680        Returns the ``n``-th generator of this noncommutative polynomial 
     681        ring. 
     682 
     683        INPUT: 
     684 
     685        - ``n`` -- an integer ``>= 0`` 
     686 
     687        EXAMPLES:: 
     688 
     689            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     690            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     691            sage: P.gen(),P.gen(1) 
     692            (x, y)           
     693 
     694            sage: P.gen(1) 
     695            y 
     696        """ 
     697        cdef poly *_p 
     698        cdef ring *_ring = self._ring 
     699 
     700        if n < 0 or n >= self.__ngens: 
     701            raise ValueError, "Generator not defined." 
     702 
     703        rChangeCurrRing(_ring) 
     704        _p = p_ISet(1,_ring) 
     705        p_SetExp(_p, n+1, 1, _ring) 
     706        p_Setm(_p, _ring); 
     707 
     708        return new_NCP(self,_p) 
     709 
     710    def ideal(self, *gens, **kwds): 
     711        """ 
     712        Create an ideal in this polynomial ring. 
     713 
     714        INPUT: 
     715  
     716        - ``*gens`` - list or tuple of generators (or several input arguments) 
     717 
     718        - ``coerce`` - bool (default: ``True``); this must be a 
     719          keyword argument. Only set it to ``False`` if you are certain 
     720          that each generator is already in the ring. 
     721 
     722        EXAMPLES:: 
     723            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     724            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     725            sage: P.inject_variables() 
     726            Defining x, y, z 
     727             
     728            sage: P.ideal([x + 2*y + 2*z-1, 2*x*y + 2*y*z-y, x^2 + 2*y^2 + 2*z^2-x]) 
     729            Ideal (x + 2*y + 2*z - 1, 2*x*y + 2*y*z - y, x^2 - x + 2*y^2 + 2*z^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     730        """ 
     731        from sage.rings.polynomial.multi_polynomial_ideal import \ 
     732                NCPolynomialIdeal 
     733        coerce = kwds.get('coerce', True) 
     734        if len(gens) == 1: 
     735            gens = gens[0] 
     736        #if is_SingularElement(gens): 
     737        #    gens = list(gens) 
     738        #    coerce = True 
     739        #elif is_Macaulay2Element(gens): 
     740        #    gens = list(gens) 
     741        #    coerce = True 
     742        if not isinstance(gens, (list, tuple)): 
     743            gens = [gens] 
     744        if coerce: 
     745            gens = [self(x) for x in gens]  # this will even coerce from singular ideals correctly! 
     746        return NCPolynomialIdeal(self, gens, coerce=False) 
     747 
     748    def _list_to_ring(self, L): 
     749        """ 
     750        Convert internal list representation to  noncommutative ring. 
     751 
     752        EXAMPLES:: 
     753 
     754           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     755           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     756           sage: rlist = P._ringlist(); 
     757           sage: Q = P._list_to_ring(rlist) 
     758           sage: Q # indirect doctest 
     759           <noncommutative RingWrap> 
     760        """ 
     761 
     762        cdef ring* _ring = self._ring 
     763        if(_ring != currRing): rChangeCurrRing(_ring) 
     764         
     765        from sage.libs.singular.function import singular_function 
     766        ring = singular_function('ring') 
     767        return ring(L, ring=self) 
     768 
     769    def quotient(self, I): 
     770        """ 
     771        Construct quotient ring of ``self`` and the two-sided Groebner basis of `ideal` 
     772 
     773        EXAMPLE:: 
     774 
     775        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     776        sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     777        sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd() 
     778 
     779        sage: Q = H.quotient(I); Q 
     780        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     781 
     782        TESTS:: 
     783 
     784        check coercion bug:: 
     785        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)       
     786        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     787        sage: rlist = P._ringlist(); 
     788        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     789        sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     790        sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd() 
     791        sage: Q = H.quotient(I); Q 
     792        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     793        sage: Q.gen(0)^2 
     794        0 
     795        sage: Q.gen(1) * Q.gen(0) 
     796        -x*y 
     797        """ 
     798        L = self._ringlist() 
     799        L[3] = I.twostd() 
     800        W = self._list_to_ring(L) 
     801        return new_NRing(W, self.base_ring()) 
     802 
     803 
     804    ### The following methods are handy for implementing Groebner 
     805    ### basis algorithms. They do only superficial type/sanity checks 
     806    ### and should be called carefully. 
     807 
     808    def monomial_quotient(self, NCPolynomial_plural f, NCPolynomial_plural g, coeff=False): 
     809        r""" 
     810        Return ``f/g``, where both ``f`` and`` ``g`` are treated as 
     811        monomials.  
     812 
     813        Coefficients are ignored by default. 
     814 
     815        INPUT: 
     816 
     817        - ``f`` - monomial 
     818        - ``g`` - monomial 
     819        - ``coeff`` - divide coefficients as well (default: ``False``) 
     820 
     821        EXAMPLES:: 
     822 
     823            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     824            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     825            sage: P.inject_variables() 
     826            Defining x, y, z 
     827 
     828            sage: P.monomial_quotient(3/2*x*y,x,coeff=True) 
     829            3/2*y 
     830 
     831        Note, that `\ZZ` behaves different if ``coeff=True``:: 
     832 
     833            sage: P.monomial_quotient(2*x,3*x) 
     834            1 
     835            sage: P.monomial_quotient(2*x,3*x,coeff=True) 
     836            2/3 
     837 
     838        TESTS:: 
     839            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     840            sage: R = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     841            sage: R.inject_variables() 
     842            Defining x, y, z 
     843         
     844            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     845            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     846            sage: P.inject_variables() 
     847            Defining x, y, z 
     848             
     849            sage: P.monomial_quotient(x*y,x) 
     850            y 
     851 
     852##             sage: P.monomial_quotient(x*y,R.gen()) 
     853##             y 
     854 
     855            sage: P.monomial_quotient(P(0),P(1)) 
     856            0 
     857 
     858            sage: P.monomial_quotient(P(1),P(0)) 
     859            Traceback (most recent call last): 
     860            ... 
     861            ZeroDivisionError 
     862 
     863            sage: P.monomial_quotient(P(3/2),P(2/3), coeff=True) 
     864            9/4 
     865 
     866            sage: P.monomial_quotient(x,P(1)) 
     867            x 
     868 
     869        TESTS:: 
     870 
     871            sage: P.monomial_quotient(x,y) # Note the wrong result 
     872            x*y^1048575*z^1048575 # 64-bit 
     873            x*y^65535 # 32-bit   
     874 
     875        .. warning:: 
     876 
     877           Assumes that the head term of f is a multiple of the head 
     878           term of g and return the multiplicant m. If this rule is 
     879           violated, funny things may happen. 
     880        """ 
     881        cdef poly *res 
     882        cdef ring *r = self._ring 
     883        cdef number *n, *denom 
     884         
     885        if not <ParentWithBase>self is f._parent: 
     886            f = self._coerce_c(f) 
     887        if not <ParentWithBase>self is g._parent: 
     888            g = self._coerce_c(g) 
     889 
     890        if(r != currRing): rChangeCurrRing(r) 
     891 
     892        if not f._poly: 
     893            return self._zero_element 
     894        if not g._poly: 
     895            raise ZeroDivisionError 
     896 
     897        res = pDivide(f._poly,g._poly) 
     898        if coeff: 
     899            if r.ringtype == 0 or r.cf.nDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r)): 
     900                n = r.cf.nDiv( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r)) 
     901                p_SetCoeff0(res, n, r) 
     902            else: 
     903                raise ArithmeticError("Cannot divide these coefficients.") 
     904        else: 
     905            p_SetCoeff0(res, n_Init(1, r), r) 
     906        return new_NCP(self, res) 
     907     
     908    def monomial_divides(self, NCPolynomial_plural a, NCPolynomial_plural b): 
     909        """ 
     910        Return ``False`` if a does not divide b and ``True`` 
     911        otherwise.  
     912 
     913        Coefficients are ignored. 
     914         
     915        INPUT: 
     916 
     917        - ``a`` -- monomial 
     918 
     919        - ``b`` -- monomial 
     920 
     921        EXAMPLES:: 
     922 
     923            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     924            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     925            sage: P.inject_variables() 
     926            Defining x, y, z 
     927 
     928            sage: P.monomial_divides(x*y*z, x^3*y^2*z^4) 
     929            True 
     930            sage: P.monomial_divides(x^3*y^2*z^4, x*y*z) 
     931            False 
     932 
     933        TESTS:: 
     934            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     935            sage: Q = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     936            sage: Q.inject_variables() 
     937            Defining x, y, z 
     938             
     939            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     940            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     941            sage: P.inject_variables() 
     942            Defining x, y, z 
     943             
     944            sage: P.monomial_divides(P(1), P(0)) 
     945            True 
     946            sage: P.monomial_divides(P(1), x) 
     947            True 
     948        """ 
     949        cdef poly *_a 
     950        cdef poly *_b 
     951        cdef ring *_r 
     952        if a._parent is not b._parent: 
     953            b = (<NCPolynomialRing_plural>a._parent)._coerce_c(b) 
     954 
     955        _a = a._poly 
     956        _b = b._poly 
     957        _r = (<NCPolynomialRing_plural>a._parent)._ring 
     958 
     959        if _a == NULL: 
     960            raise ZeroDivisionError 
     961        if _b == NULL: 
     962            return True 
     963         
     964        if not p_DivisibleBy(_a, _b, _r): 
     965            return False 
     966        else: 
     967            return True 
     968 
     969 
     970    def monomial_lcm(self, NCPolynomial_plural f, NCPolynomial_plural g): 
     971        """ 
     972        LCM for monomials. Coefficients are ignored. 
     973         
     974        INPUT: 
     975 
     976        - ``f`` - monomial 
     977         
     978        - ``g`` - monomial 
     979 
     980        EXAMPLES:: 
     981 
     982            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     983            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     984            sage: P.inject_variables() 
     985            Defining x, y, z 
     986             
     987            sage: P.monomial_lcm(3/2*x*y,x) 
     988            x*y 
     989 
     990        TESTS:: 
     991 
     992            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     993            sage: R = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     994            sage: R.inject_variables() 
     995            Defining x, y, z 
     996             
     997            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     998            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     999            sage: P.inject_variables() 
     1000            Defining x, y, z 
     1001             
     1002##             sage: P.monomial_lcm(x*y,R.gen()) 
     1003##             x*y 
     1004 
     1005            sage: P.monomial_lcm(P(3/2),P(2/3)) 
     1006            1 
     1007 
     1008            sage: P.monomial_lcm(x,P(1)) 
     1009            x 
     1010        """ 
     1011        cdef poly *m = p_ISet(1,self._ring) 
     1012         
     1013        if not <ParentWithBase>self is f._parent: 
     1014            f = self._coerce_c(f) 
     1015        if not <ParentWithBase>self is g._parent: 
     1016            g = self._coerce_c(g) 
     1017 
     1018        if f._poly == NULL: 
     1019            if g._poly == NULL: 
     1020                return self._zero_element 
     1021            else: 
     1022                raise ArithmeticError, "Cannot compute LCM of zero and nonzero element." 
     1023        if g._poly == NULL: 
     1024            raise ArithmeticError, "Cannot compute LCM of zero and nonzero element." 
     1025 
     1026        if(self._ring != currRing): rChangeCurrRing(self._ring) 
     1027         
     1028        pLcm(f._poly, g._poly, m) 
     1029        p_Setm(m, self._ring) 
     1030        return new_NCP(self,m) 
     1031         
     1032    def monomial_reduce(self, NCPolynomial_plural f, G): 
     1033        """ 
     1034        Try to find a ``g`` in ``G`` where ``g.lm()`` divides 
     1035        ``f``. If found ``(flt,g)`` is returned, ``(0,0)`` otherwise, 
     1036        where ``flt`` is ``f/g.lm()``. 
     1037 
     1038        It is assumed that ``G`` is iterable and contains *only* 
     1039        elements in this polynomial ring. 
     1040 
     1041        Coefficients are ignored. 
     1042         
     1043        INPUT: 
     1044 
     1045        - ``f`` - monomial 
     1046        - ``G`` - list/set of mpolynomials 
     1047             
     1048        EXAMPLES:: 
     1049 
     1050            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1051            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1052            sage: P.inject_variables() 
     1053            Defining x, y, z 
     1054 
     1055            sage: f = x*y^2 
     1056            sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ] 
     1057            sage: P.monomial_reduce(f,G) 
     1058            (y, 1/4*x*y + 2/7) 
     1059 
     1060        TESTS:: 
     1061            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1062            sage: Q = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1063            sage: Q.inject_variables() 
     1064            Defining x, y, z 
     1065             
     1066            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1067            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1068            sage: P.inject_variables() 
     1069            Defining x, y, z 
     1070            sage: f = x*y^2 
     1071            sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ] 
     1072 
     1073            sage: P.monomial_reduce(P(0),G) 
     1074            (0, 0) 
     1075 
     1076            sage: P.monomial_reduce(f,[P(0)]) 
     1077            (0, 0) 
     1078        """ 
     1079        cdef poly *m = f._poly 
     1080        cdef ring *r = self._ring 
     1081        cdef poly *flt 
     1082 
     1083        if not m: 
     1084            return f,f 
     1085         
     1086        for g in G: 
     1087            if PY_TYPE_CHECK(g, NCPolynomial_plural) \ 
     1088                   and (<NCPolynomial_plural>g) \ 
     1089                   and p_LmDivisibleBy((<NCPolynomial_plural>g)._poly, m, r): 
     1090                flt = pDivide(f._poly, (<NCPolynomial_plural>g)._poly) 
     1091                #p_SetCoeff(flt, n_Div( p_GetCoeff(f._poly, r) , p_GetCoeff((<NCPolynomial_plural>g)._poly, r), r), r) 
     1092                p_SetCoeff(flt, n_Init(1, r), r) 
     1093                return new_NCP(self,flt), g 
     1094        return self._zero_element,self._zero_element 
     1095 
     1096    def monomial_pairwise_prime(self, NCPolynomial_plural g, NCPolynomial_plural h): 
     1097        """ 
     1098        Return ``True`` if ``h`` and ``g`` are pairwise prime. Both 
     1099        are treated as monomials. 
     1100 
     1101        Coefficients are ignored. 
     1102 
     1103        INPUT: 
     1104 
     1105        - ``h`` - monomial 
     1106        - ``g`` - monomial 
     1107 
     1108        EXAMPLES:: 
     1109 
     1110            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1111            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1112            sage: P.inject_variables() 
     1113            Defining x, y, z 
     1114 
     1115            sage: P.monomial_pairwise_prime(x^2*z^3, y^4) 
     1116            True 
     1117 
     1118            sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3) 
     1119            False 
     1120 
     1121        TESTS:: 
     1122 
     1123            sage: A.<x1,y1,z1> = FreeAlgebra(QQ, 3) 
     1124            sage: Q = A.g_algebra(relations={y1*x1:-x1*y1},  order='lex') 
     1125            sage: Q.inject_variables() 
     1126            Defining x1, y1, z1 
     1127 
     1128            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1129            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1130            sage: P.inject_variables() 
     1131            Defining x, y, z 
     1132 
     1133##            sage: P.monomial_pairwise_prime(x^2*z^3, x1^4) 
     1134##            True 
     1135 
     1136##            sage: P.monomial_pairwise_prime((2)*x^3*y^2, Q.zero_element()) 
     1137##            True 
     1138 
     1139            sage: P.monomial_pairwise_prime(2*P.one_element(),x) 
     1140            False 
     1141        """ 
     1142        cdef int i 
     1143        cdef ring *r 
     1144        cdef poly *p, *q 
     1145 
     1146        if h._parent is not g._parent: 
     1147            g = (<NCPolynomialRing_plural>h._parent)._coerce_c(g) 
     1148 
     1149        r = (<NCPolynomialRing_plural>h._parent)._ring 
     1150        p = g._poly 
     1151        q = h._poly 
     1152 
     1153        if p == NULL: 
     1154            if q == NULL: 
     1155                return False #GCD(0,0) = 0 
     1156            else: 
     1157                return True #GCD(x,0) = 1 
     1158 
     1159        elif q == NULL: 
     1160            return True # GCD(0,x) = 1 
     1161 
     1162        elif p_IsConstant(p,r) or p_IsConstant(q,r): # assuming a base field 
     1163            return False 
     1164 
     1165        for i from 1 <= i <= r.N: 
     1166            if p_GetExp(p,i,r) and p_GetExp(q,i,r): 
     1167                return False 
     1168        return True 
     1169 
     1170    def monomial_all_divisors(self, NCPolynomial_plural t): 
     1171        """ 
     1172        Return a list of all monomials that divide ``t``. 
     1173 
     1174        Coefficients are ignored. 
     1175           
     1176        INPUT: 
     1177 
     1178        - ``t`` - a monomial 
     1179   
     1180        OUTPUT: 
     1181            a list of monomials 
     1182 
     1183 
     1184        EXAMPLES:: 
     1185 
     1186            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1187            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1188            sage: P.inject_variables() 
     1189            Defining x, y, z 
     1190 
     1191            sage: P.monomial_all_divisors(x^2*z^3) 
     1192            [x, x^2, z, x*z, x^2*z, z^2, x*z^2, x^2*z^2, z^3, x*z^3, x^2*z^3] 
     1193             
     1194        ALGORITHM: addwithcarry idea by Toon Segers 
     1195        """ 
     1196 
     1197        M = list() 
     1198 
     1199        cdef ring *_ring = self._ring 
     1200        cdef poly *maxvector = t._poly 
     1201        cdef poly *tempvector = p_ISet(1, _ring) 
     1202          
     1203        pos = 1 
     1204          
     1205        while not p_ExpVectorEqual(tempvector, maxvector, _ring): 
     1206          tempvector = addwithcarry(tempvector, maxvector, pos, _ring) 
     1207          M.append(new_NCP(self, p_Copy(tempvector,_ring))) 
     1208        return M 
     1209 
     1210 
     1211 
     1212cdef class NCPolynomial_plural(RingElement): 
     1213    """ 
     1214    A noncommutative multivariate polynomial implemented using libSINGULAR. 
     1215    """ 
     1216    def __init__(self, NCPolynomialRing_plural parent): 
     1217        """ 
     1218        Construct a zero element in parent. 
     1219 
     1220        EXAMPLES:: 
     1221 
     1222            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1223            sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1224            sage: from sage.rings.polynomial.plural import NCPolynomial_plural 
     1225            sage: NCPolynomial_plural(H) 
     1226            0 
     1227        """ 
     1228        self._poly = NULL 
     1229        self._parent = <ParentWithBase>parent 
     1230 
     1231    def __dealloc__(self): 
     1232        # TODO: Warn otherwise! 
     1233        # for some mysterious reason, various things may be NULL in some cases 
     1234        if self._parent is not <ParentWithBase>None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL: 
     1235            p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring) 
     1236 
     1237#    def __call__(self, *x, **kwds): # ? 
     1238 
     1239    # you may have to replicate this boilerplate code in derived classes if you override  
     1240    # __richcmp__.  The python documentation at  http://docs.python.org/api/type-structs.html  
     1241    # explains how __richcmp__, __hash__, and __cmp__ are tied together. 
     1242    def __hash__(self): 
     1243        """ 
     1244        This hash incorporates the variable name in an effort to 
     1245        respect the obvious inclusions into multi-variable polynomial 
     1246        rings. 
     1247 
     1248        The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm. 
     1249 
     1250        EXAMPLES:: 
     1251 
     1252            sage: R.<x>=QQ[] 
     1253            sage: S.<x,y>=QQ[] 
     1254            sage: hash(S(1/2))==hash(1/2)  # respect inclusions of the rationals 
     1255            True 
     1256            sage: hash(S.0)==hash(R.0)  # respect inclusions into mpoly rings 
     1257            True 
     1258            sage: # the point is to make for more flexible dictionary look ups 
     1259            sage: d={S.0:12} 
     1260            sage: d[R.0] 
     1261            12 
     1262        """ 
     1263        return self._hash_c() 
     1264 
     1265    def __richcmp__(left, right, int op): 
     1266        """ 
     1267        Compare left and right and return -1, 0, and 1 for <,==, and > 
     1268        respectively. 
     1269 
     1270        EXAMPLES:: 
     1271 
     1272            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1273            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1274            sage: P.inject_variables() 
     1275            Defining x, z, y 
     1276 
     1277            sage: x == x 
     1278            True 
     1279 
     1280            sage: x > y 
     1281            True 
     1282            sage: y^2 > x 
     1283            False 
     1284 
     1285##            sage: (2/3*x^2 + 1/2*y + 3) > (2/3*x^2 + 1/4*y + 10) 
     1286#            True 
     1287 
     1288        TESTS:: 
     1289 
     1290            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1291            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1292            sage: P.inject_variables() 
     1293            Defining x, z, y 
     1294 
     1295            sage: x > P(0) 
     1296            True 
     1297 
     1298            sage: P(0) == P(0) 
     1299            True 
     1300 
     1301            sage: P(0) < P(1) 
     1302            True 
     1303 
     1304            sage: x > P(1) 
     1305            True 
     1306             
     1307            sage: 1/2*x < 3/4*x 
     1308            True 
     1309 
     1310            sage: (x+1) > x 
     1311            True 
     1312 
     1313#            sage: f = 3/4*x^2*y + 1/2*x + 2/7 
     1314#            sage: f > f 
     1315#            False 
     1316#            sage: f < f 
     1317#            False 
     1318#            sage: f == f 
     1319#            True 
     1320 
     1321#            sage: P.<x,y,z> = PolynomialRing(GF(127), order='degrevlex') 
     1322#            sage: (66*x^2 + 23) > (66*x^2 + 2) 
     1323#            True 
     1324        """ 
     1325        return (<Element>left)._richcmp(right, op) 
     1326 
     1327    cdef int _cmp_c_impl(left, Element right) except -2: 
     1328        if left is right: 
     1329            return 0 
     1330        cdef poly *p = (<NCPolynomial_plural>left)._poly 
     1331        cdef poly *q = (<NCPolynomial_plural>right)._poly 
     1332        cdef ring *r = (<NCPolynomialRing_plural>left._parent)._ring 
     1333        return singular_polynomial_cmp(p, q, r) 
     1334 
     1335    cpdef ModuleElement _add_( left, ModuleElement right): 
     1336        """ 
     1337        Adds left and right. 
     1338 
     1339        EXAMPLES:: 
     1340 
     1341            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1342            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1343            sage: P.inject_variables() 
     1344            Defining x, z, y 
     1345            sage: 3/2*x + 1/2*y + 1 # indirect doctest 
     1346            3/2*x + 1/2*y + 1 
     1347        """ 
     1348        cdef poly *_p 
     1349        singular_polynomial_add(&_p, left._poly,  
     1350                                 (<NCPolynomial_plural>right)._poly, 
     1351                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     1352        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     1353 
     1354    cpdef ModuleElement _sub_( left, ModuleElement right): 
     1355        """ 
     1356        Subtract left and right. 
     1357 
     1358        EXAMPLES:: 
     1359 
     1360            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1361            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1362            sage: P.inject_variables() 
     1363            Defining x, z, y 
     1364            sage: 3/2*x - 1/2*y - 1 # indirect doctest 
     1365            3/2*x - 1/2*y - 1 
     1366 
     1367        """ 
     1368        cdef ring *_ring = (<NCPolynomialRing_plural>left._parent)._ring 
     1369 
     1370        cdef poly *_p 
     1371        singular_polynomial_sub(&_p, left._poly,  
     1372                                (<NCPolynomial_plural>right)._poly, 
     1373                                _ring) 
     1374        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     1375 
     1376    cpdef ModuleElement _rmul_(self, RingElement left): 
     1377        """ 
     1378        Multiply self with a base ring element. 
     1379 
     1380        EXAMPLES:: 
     1381 
     1382            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1383            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1384            sage: P.inject_variables() 
     1385            Defining x, z, y 
     1386            sage: 3/2*x # indirect doctest 
     1387            3/2*x 
     1388        """ 
     1389 
     1390        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1391        if not left: 
     1392            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     1393        cdef poly *_p 
     1394        singular_polynomial_rmul(&_p, self._poly, left, _ring) 
     1395        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     1396         
     1397    cpdef ModuleElement _lmul_(self, RingElement right): 
     1398        """ 
     1399        Multiply self with a base ring element. 
     1400 
     1401        EXAMPLES:: 
     1402 
     1403            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1404            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1405            sage: P.inject_variables() 
     1406            Defining x, z, y 
     1407            sage: x* (2/3) # indirect doctest 
     1408            2/3*x 
     1409        """ 
     1410        return self._rmul_(right) 
     1411         
     1412    cpdef RingElement  _mul_(left, RingElement right): 
     1413        """ 
     1414        Multiply left and right. 
     1415 
     1416        EXAMPLES:: 
     1417 
     1418            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1419            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1420            sage: P.inject_variables() 
     1421            Defining x, z, y 
     1422            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest 
     1423            9/4*x^2 + 3/2*x*y - 3/4*z - 1/4*y^2 - y - 1 
     1424 
     1425        TEST:: 
     1426         
     1427            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1428            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1429            sage: P.inject_variables() 
     1430            Defining x, z, y 
     1431            sage: (x^2^30) * x^2^30 
     1432            Traceback (most recent call last): 
     1433            ... 
     1434            OverflowError: Exponent overflow (...). 
     1435        """ 
     1436        # all currently implemented rings are commutative 
     1437        cdef poly *_p 
     1438        singular_polynomial_mul(&_p, left._poly,  
     1439                                 (<NCPolynomial_plural>right)._poly,  
     1440                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     1441        return new_NCP((<NCPolynomialRing_plural>left._parent),_p) 
     1442 
     1443    cpdef RingElement _div_(left, RingElement right): 
     1444        """ 
     1445        Divide left by right 
     1446 
     1447        EXAMPLES:: 
     1448 
     1449            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1450            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1451            sage: R.inject_variables() 
     1452            Defining x, z, y 
     1453            sage: f = (x + y)/3 # indirect doctest 
     1454            sage: f.parent() 
     1455            Noncommutative Multivariate Polynomial Ring in x, z, y over Rational Field, nc-relations: {y*x: -x*y + z} 
     1456 
     1457        TESTS:: 
     1458 
     1459            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1460            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1461            sage: R.inject_variables() 
     1462            Defining x, z, y 
     1463            sage: x/0 
     1464            Traceback (most recent call last): 
     1465            ... 
     1466            ZeroDivisionError: rational division by zero 
     1467        """ 
     1468        cdef poly *p  
     1469        cdef bint is_field = left._parent._base.is_field() 
     1470        if p_IsConstant((<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring): 
     1471            if is_field: 
     1472                singular_polynomial_div_coeff(&p, left._poly, (<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring) 
     1473                return new_NCP(left._parent, p) 
     1474            else: 
     1475                return left.change_ring(left.base_ring().fraction_field())/right 
     1476        else: 
     1477            return (<NCPolynomialRing_plural>left._parent).fraction_field()(left,right) 
     1478 
     1479    def __pow__(NCPolynomial_plural self, exp, ignored): 
     1480        """ 
     1481        Return ``self**(exp)``. 
     1482 
     1483        The exponent must be an integer. 
     1484 
     1485        EXAMPLES:: 
     1486 
     1487            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1488            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1489            sage: R.inject_variables() 
     1490            Defining x, z, y 
     1491            sage: f = x^3 + y 
     1492            sage: f^2 
     1493            x^6 + x^2*z + y^2 
     1494 
     1495        TESTS:: 
     1496         
     1497            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1498            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1499            sage: P.inject_variables() 
     1500            Defining x, z, y 
     1501            sage: (x+y^2^30)^10 
     1502            Traceback (most recent call last): 
     1503            .... 
     1504            OverflowError: Exponent overflow (...). 
     1505        """ 
     1506        if not PY_TYPE_CHECK_EXACT(exp, Integer) or \ 
     1507                PY_TYPE_CHECK_EXACT(exp, int): 
     1508                    try: 
     1509                        exp = Integer(exp) 
     1510                    except TypeError: 
     1511                        raise TypeError, "non-integral exponents not supported" 
     1512 
     1513        if exp < 0: 
     1514            return 1/(self**(-exp)) 
     1515        elif exp == 0: 
     1516            return (<NCPolynomialRing_plural>self._parent)._one_element 
     1517 
     1518        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1519        cdef poly *_p 
     1520        singular_polynomial_pow(&_p, self._poly, exp, _ring) 
     1521        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     1522 
     1523    def __neg__(self): 
     1524        """ 
     1525        Return ``-self``. 
     1526 
     1527        EXAMPLES:: 
     1528 
     1529            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1530            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1531            sage: R.inject_variables() 
     1532            Defining x, z, y 
     1533            sage: f = x^3 + y 
     1534            sage: -f 
     1535            -x^3 - y 
     1536        """ 
     1537        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1538 
     1539        cdef poly *p 
     1540        singular_polynomial_neg(&p, self._poly, _ring) 
     1541        return new_NCP((<NCPolynomialRing_plural>self._parent), p) 
     1542 
     1543    def _repr_(self): 
     1544        """ 
     1545        EXAMPLES:: 
     1546 
     1547            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1548            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1549            sage: R.inject_variables() 
     1550            Defining x, z, y 
     1551            sage: f = x^3 + y*x*z + z 
     1552            sage: f # indirect doctest 
     1553            x^3 - x*z*y + z^2 + z 
     1554        """ 
     1555        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1556        s = singular_polynomial_str(self._poly, _ring) 
     1557        return s 
     1558 
     1559    cpdef _repr_short_(self): 
     1560        """ 
     1561        This is a faster but less pretty way to print polynomials. If 
     1562        available it uses the short SINGULAR notation. 
     1563         
     1564        EXAMPLES:: 
     1565 
     1566            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1567            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1568            sage: R.inject_variables() 
     1569            Defining x, z, y 
     1570            sage: f = x^3 + y 
     1571            sage: f._repr_short_() 
     1572            'x3+y' 
     1573        """ 
     1574        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1575        rChangeCurrRing(_ring) 
     1576        if _ring.CanShortOut: 
     1577            _ring.ShortOut = 1 
     1578            s = p_String(self._poly, _ring, _ring) 
     1579            _ring.ShortOut = 0 
     1580        else: 
     1581            s = p_String(self._poly, _ring, _ring) 
     1582        return s 
     1583                                            
     1584    def _latex_(self): 
     1585        """ 
     1586        Return a polynomial LaTeX representation of this polynomial. 
     1587 
     1588        EXAMPLES:: 
     1589 
     1590            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1591            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1592            sage: R.inject_variables() 
     1593            Defining x, z, y 
     1594            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     1595            sage: latex(f) # indirect doctest 
     1596            - x^{2} y - z^{2} - \frac{25}{27} y^{3} 
     1597        """ 
     1598        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1599        gens = self.parent().latex_variable_names() 
     1600        base = self.parent().base() 
     1601        return singular_polynomial_latex(self._poly, _ring, base, gens) 
     1602     
     1603    def _repr_with_changed_varnames(self, varnames): 
     1604        """ 
     1605        Return string representing this polynomial but change the 
     1606        variable names to ``varnames``. 
     1607 
     1608        EXAMPLES:: 
     1609 
     1610            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1611            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1612            sage: R.inject_variables() 
     1613            Defining x, z, y 
     1614            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     1615            sage: print f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR']) 
     1616            -FOO^2*FOOBAR - BAR^2 - 25/27*FOOBAR^3 
     1617        """ 
     1618        return  singular_polynomial_str_with_changed_varnames(self._poly, (<NCPolynomialRing_plural>self._parent)._ring, varnames) 
     1619             
     1620    def degree(self, NCPolynomial_plural x=None): 
     1621        """ 
     1622        Return the maximal degree of this polynomial in ``x``, where 
     1623        ``x`` must be one of the generators for the parent of this 
     1624        polynomial. 
     1625 
     1626        INPUT: 
     1627 
     1628        - ``x`` - multivariate polynomial (a generator of the parent of 
     1629          self) If x is not specified (or is ``None``), return the total 
     1630          degree, which is the maximum degree of any monomial. 
     1631 
     1632        OUTPUT: 
     1633            integer 
     1634         
     1635        EXAMPLES:: 
     1636 
     1637            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1638            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1639            sage: R.inject_variables() 
     1640            Defining x, z, y 
     1641            sage: f = y^2 - x^9 - x 
     1642            sage: f.degree(x) 
     1643            9 
     1644            sage: f.degree(y) 
     1645            2 
     1646            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x) 
     1647            3 
     1648            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y) 
     1649            10 
     1650 
     1651        TESTS:: 
     1652 
     1653            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1654            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1655            sage: P.inject_variables() 
     1656            Defining x, z, y 
     1657            sage: P(0).degree(x) 
     1658            -1 
     1659            sage: P(1).degree(x) 
     1660            0 
     1661 
     1662        """ 
     1663        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1664        cdef poly *p = self._poly 
     1665        if not x: 
     1666            return singular_polynomial_deg(p,NULL,r) 
     1667 
     1668        # TODO: we can do this faster 
     1669        if not x in self._parent.gens(): 
     1670            raise TypeError("x must be one of the generators of the parent.") 
     1671 
     1672        return singular_polynomial_deg(p, (<NCPolynomial_plural>x)._poly, r) 
     1673 
     1674    def total_degree(self): 
     1675        """ 
     1676        Return the total degree of ``self``, which is the maximum degree 
     1677        of all monomials in ``self``. 
     1678 
     1679        EXAMPLES:: 
     1680 
     1681            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1682            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1683            sage: R.inject_variables() 
     1684            Defining x, z, y 
     1685            sage: f=2*x*y^3*z^2 
     1686            sage: f.total_degree() 
     1687            6 
     1688            sage: f=4*x^2*y^2*z^3 
     1689            sage: f.total_degree() 
     1690            7 
     1691            sage: f=99*x^6*y^3*z^9 
     1692            sage: f.total_degree() 
     1693            18 
     1694            sage: f=x*y^3*z^6+3*x^2 
     1695            sage: f.total_degree() 
     1696            10 
     1697            sage: f=z^3+8*x^4*y^5*z 
     1698            sage: f.total_degree() 
     1699            10 
     1700            sage: f=z^9+10*x^4+y^8*x^2 
     1701            sage: f.total_degree() 
     1702            10 
     1703 
     1704        TESTS:: 
     1705 
     1706            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1707            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1708            sage: R.inject_variables() 
     1709            Defining x, z, y 
     1710            sage: R(0).total_degree() 
     1711            -1 
     1712            sage: R(1).total_degree() 
     1713            0 
     1714        """ 
     1715        cdef poly *p = self._poly 
     1716        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1717        return singular_polynomial_deg(p,NULL,r) 
     1718 
     1719    def degrees(self): 
     1720        """  
     1721        Returns a tuple with the maximal degree of each variable in 
     1722        this polynomial.  The list of degrees is ordered by the order 
     1723        of the generators. 
     1724 
     1725        EXAMPLES:: 
     1726 
     1727            sage: A.<y0,y1,y2> = FreeAlgebra(QQ, 3) 
     1728            sage: R = A.g_algebra(relations={y1*y0:-y0*y1 + y2},  order='lex') 
     1729            sage: R.inject_variables() 
     1730            Defining y0, y1, y2 
     1731            sage: q = 3*y0*y1*y1*y2; q  
     1732            3*y0*y1^2*y2  
     1733            sage: q.degrees()  
     1734            (1, 2, 1) 
     1735            sage: (q + y0^5).degrees() 
     1736            (5, 2, 1) 
     1737        """ 
     1738        cdef poly *p = self._poly 
     1739        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1740        cdef int i 
     1741        cdef list d = [0 for _ in range(r.N)] 
     1742        while p: 
     1743            for i from 0 <= i < r.N: 
     1744                d[i] = max(d[i],p_GetExp(p, i+1, r)) 
     1745            p = pNext(p) 
     1746        return tuple(d) 
     1747 
     1748 
     1749    def coefficient(self, degrees): 
     1750        """ 
     1751        Return the coefficient of the variables with the degrees 
     1752        specified in the python dictionary ``degrees``. 
     1753        Mathematically, this is the coefficient in the base ring 
     1754        adjoined by the variables of this ring not listed in 
     1755        ``degrees``.  However, the result has the same parent as this 
     1756        polynomial. 
     1757 
     1758        This function contrasts with the function 
     1759        ``monomial_coefficient`` which returns the coefficient in the 
     1760        base ring of a monomial. 
     1761 
     1762        INPUT: 
     1763 
     1764        - ``degrees`` - Can be any of: 
     1765                - a dictionary of degree restrictions 
     1766                - a list of degree restrictions (with None in the unrestricted variables) 
     1767                - a monomial (very fast, but not as flexible) 
     1768 
     1769        OUTPUT: 
     1770            element of the parent of this element. 
     1771 
     1772        .. note:: 
     1773            
     1774           For coefficients of specific monomials, look at :meth:`monomial_coefficient`. 
     1775 
     1776        EXAMPLES:: 
     1777 
     1778            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1779            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1780            sage: R.inject_variables() 
     1781            Defining x, z, y 
     1782            sage: f=x*y+y+5 
     1783            sage: f.coefficient({x:0,y:1}) 
     1784            1 
     1785            sage: f.coefficient({x:0}) 
     1786            y + 5 
     1787            sage: f=(1+y+y^2)*(1+x+x^2) 
     1788            sage: f.coefficient({x:0}) 
     1789            z + y^2 + y + 1 
     1790 
     1791            sage: f.coefficient(x) 
     1792            y^2 - y + 1 
     1793           
     1794# f.coefficient([0,None]) # y^2 + y + 1 
     1795 
     1796        Be aware that this may not be what you think! The physical 
     1797        appearance of the variable x is deceiving -- particularly if 
     1798        the exponent would be a variable. :: 
     1799 
     1800            sage: f.coefficient(x^0) # outputs the full polynomial 
     1801            x^2*y^2 + x^2*y + x^2 + x*y^2 - x*y + x + z + y^2 + y + 1 
     1802 
     1803            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1804            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1805            sage: R.inject_variables() 
     1806            Defining x, z, y 
     1807            sage: f=x*y+5 
     1808            sage: c=f.coefficient({x:0,y:0}); c 
     1809            5 
     1810            sage: parent(c) 
     1811            Noncommutative Multivariate Polynomial Ring in x, z, y over Finite Field of size 389, nc-relations: {y*x: -x*y + z} 
     1812 
     1813        AUTHOR: 
     1814 
     1815        - Joel B. Mohler (2007.10.31) 
     1816        """ 
     1817        cdef poly *_degrees = <poly*>0 
     1818        cdef poly *p = self._poly 
     1819        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1820        cdef poly *newp = p_ISet(0,r) 
     1821        cdef poly *newptemp 
     1822        cdef int i 
     1823        cdef int flag 
     1824        cdef int gens = self._parent.ngens() 
     1825        cdef int *exps = <int*>sage_malloc(sizeof(int)*gens) 
     1826        for i from 0<=i<gens: 
     1827            exps[i] = -1 
     1828 
     1829        if PY_TYPE_CHECK(degrees, NCPolynomial_plural) and self._parent is (<NCPolynomial_plural>degrees)._parent: 
     1830            _degrees = (<NCPolynomial_plural>degrees)._poly 
     1831            if pLength(_degrees) != 1: 
     1832                raise TypeError, "degrees must be a monomial" 
     1833            for i from 0<=i<gens: 
     1834                if p_GetExp(_degrees,i+1,r)!=0: 
     1835                    exps[i] = p_GetExp(_degrees,i+1,r) 
     1836        elif type(degrees) is list: 
     1837            for i from 0<=i<gens: 
     1838                if degrees[i] is None: 
     1839                    exps[i] = -1 
     1840                else: 
     1841                    exps[i] = int(degrees[i]) 
     1842        elif type(degrees) is dict: 
     1843            # Extract the ordered list of degree specifications from the dictionary 
     1844            poly_vars = self.parent().gens() 
     1845            for i from 0<=i<gens: 
     1846                try: 
     1847                    exps[i] = degrees[poly_vars[i]] 
     1848                except KeyError: 
     1849                    pass 
     1850        else: 
     1851            raise TypeError, "The input degrees must be a dictionary of variables to exponents." 
     1852 
     1853        # Extract the monomials that match the specifications 
     1854        while(p): 
     1855            flag = 0 
     1856            for i from 0<=i<gens: 
     1857                if exps[i] != -1 and p_GetExp(p,i+1,r)!=exps[i]: 
     1858                    #print i, p_GetExp(p,i+1,r), exps[i] 
     1859                    flag = 1 
     1860            if flag == 0: 
     1861                newptemp = p_LmInit(p,r) 
     1862                p_SetCoeff(newptemp,n_Copy(p_GetCoeff(p,r),r),r) 
     1863                for i from 0<=i<gens: 
     1864                    if exps[i] != -1: 
     1865                        p_SetExp(newptemp,i+1,0,r) 
     1866                p_Setm(newptemp,r) 
     1867                newp = p_Add_q(newp,newptemp,r) 
     1868            p = pNext(p) 
     1869 
     1870        sage_free(exps) 
     1871 
     1872        return new_NCP(self.parent(),newp) 
     1873 
     1874    def monomial_coefficient(self, NCPolynomial_plural mon): 
     1875        """ 
     1876        Return the coefficient in the base ring of the monomial mon in 
     1877        ``self``, where mon must have the same parent as self. 
     1878 
     1879        This function contrasts with the function ``coefficient`` 
     1880        which returns the coefficient of a monomial viewing this 
     1881        polynomial in a polynomial ring over a base ring having fewer 
     1882        variables. 
     1883 
     1884        INPUT: 
     1885 
     1886        - ``mon`` - a monomial 
     1887 
     1888        OUTPUT: 
     1889            coefficient in base ring 
     1890 
     1891        SEE ALSO: 
     1892            For coefficients in a base ring of fewer variables, look at ``coefficient``. 
     1893 
     1894        EXAMPLES:: 
     1895 
     1896            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1897            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1898            sage: P.inject_variables() 
     1899            Defining x, z, y 
     1900 
     1901            The parent of the return is a member of the base ring. 
     1902            sage: f = 2 * x * y 
     1903            sage: c = f.monomial_coefficient(x*y); c 
     1904            2 
     1905            sage: c.parent() 
     1906            Finite Field of size 389 
     1907 
     1908            sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y 
     1909            sage: f.monomial_coefficient(y^2) 
     1910            1 
     1911            sage: f.monomial_coefficient(x*y) 
     1912            5 
     1913            sage: f.monomial_coefficient(x^9) 
     1914            388 
     1915            sage: f.monomial_coefficient(x^10) 
     1916            0 
     1917        """ 
     1918        cdef poly *p = self._poly 
     1919        cdef poly *m = mon._poly 
     1920        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1921 
     1922        if not mon._parent is self._parent: 
     1923            raise TypeError("mon must have same parent as self.") 
     1924         
     1925        while(p): 
     1926            if p_ExpVectorEqual(p, m, r) == 1: 
     1927                return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base) 
     1928            p = pNext(p) 
     1929 
     1930        return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     1931 
     1932    def dict(self): 
     1933        """ 
     1934        Return a dictionary representing self. This dictionary is in 
     1935        the same format as the generic MPolynomial: The dictionary 
     1936        consists of ``ETuple:coefficient`` pairs. 
     1937 
     1938        EXAMPLES:: 
     1939 
     1940            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1941            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1942            sage: R.inject_variables() 
     1943            Defining x, z, y 
     1944 
     1945            sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3)) 
     1946            sage: f.dict() 
     1947            {(0, 0, 0): 3, (2, 0, 0): 7, (1, 2, 3): 2} 
     1948        """ 
     1949        cdef poly *p 
     1950        cdef ring *r 
     1951        cdef int n 
     1952        cdef int v 
     1953        r = (<NCPolynomialRing_plural>self._parent)._ring 
     1954        if r!=currRing: rChangeCurrRing(r) 
     1955        base = (<NCPolynomialRing_plural>self._parent)._base 
     1956        p = self._poly 
     1957        pd = dict() 
     1958        while p: 
     1959            d = dict() 
     1960            for v from 1 <= v <= r.N: 
     1961                n = p_GetExp(p,v,r) 
     1962                if n!=0: 
     1963                    d[v-1] = n  
     1964                 
     1965            pd[ETuple(d,r.N)] = si2sa(p_GetCoeff(p, r), r, base) 
     1966 
     1967            p = pNext(p) 
     1968        return pd 
     1969 
     1970 
     1971    cdef long _hash_c(self): 
     1972        """ 
     1973        See ``self.__hash__`` 
     1974        """ 
     1975        cdef poly *p 
     1976        cdef ring *r 
     1977        cdef int n 
     1978        cdef int v 
     1979        r = (<NCPolynomialRing_plural>self._parent)._ring 
     1980        if r!=currRing: rChangeCurrRing(r) 
     1981        base = (<NCPolynomialRing_plural>self._parent)._base 
     1982        p = self._poly 
     1983        cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap 
     1984        cdef long result_mon 
     1985        var_name_hash = [hash(vn) for vn in self._parent.variable_names()] 
     1986        cdef long c_hash 
     1987        while p: 
     1988            c_hash = hash(si2sa(p_GetCoeff(p, r), r, base)) 
     1989            if c_hash != 0: # this is always going to be true, because we are sparse (correct?) 
     1990                # Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm. 
     1991                # I omit gen,exp pairs where the exponent is zero. 
     1992                result_mon = c_hash 
     1993                for v from 1 <= v <= r.N: 
     1994                    n = p_GetExp(p,v,r) 
     1995                    if n!=0: 
     1996                        result_mon = (1000003 * result_mon) ^ var_name_hash[v-1] 
     1997                        result_mon = (1000003 * result_mon) ^ n 
     1998                result += result_mon 
     1999 
     2000            p = pNext(p) 
     2001        if result == -1: 
     2002            return -2 
     2003        return result 
     2004 
     2005    def __getitem__(self,x): 
     2006        """ 
     2007        Same as ``self.monomial_coefficent`` but for exponent vectors. 
     2008         
     2009        INPUT: 
     2010 
     2011        - ``x`` - a tuple or, in case of a single-variable MPolynomial 
     2012        ring x can also be an integer. 
     2013         
     2014        EXAMPLES:: 
     2015 
     2016            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2017            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2018            sage: R.inject_variables() 
     2019            Defining x, z, y 
     2020            sage: f = (-10*x^3*y + 17*x*y)* ( 15*z^3 + 2*x*y*z - 1); f 
     2021            20*x^4*z*y^2 - 150*x^3*z^3*y - 20*x^3*z^2*y + 10*x^3*y - 34*x^2*z*y^2 - 134*x*z^3*y + 34*x*z^2*y - 17*x*y 
     2022            sage: f[4,1,2] 
     2023            20 
     2024            sage: f[1,0,1] 
     2025            372 
     2026            sage: f[0,0,0] 
     2027            0 
     2028 
     2029            sage: R.<x> = PolynomialRing(GF(7),1); R 
     2030            Multivariate Polynomial Ring in x over Finite Field of size 7 
     2031            sage: f = 5*x^2 + 3; f 
     2032            -2*x^2 + 3 
     2033            sage: f[2] 
     2034            5 
     2035        """ 
     2036        cdef poly *m  
     2037        cdef poly *p = self._poly 
     2038        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     2039        cdef int i 
     2040 
     2041        if PY_TYPE_CHECK(x, NCPolynomial_plural): 
     2042            return self.monomial_coefficient(x) 
     2043        if not PY_TYPE_CHECK(x, tuple): 
     2044            try: 
     2045                x = tuple(x) 
     2046            except TypeError: 
     2047                x = (x,) 
     2048 
     2049        if len(x) != (<NCPolynomialRing_plural>self._parent).__ngens: 
     2050            raise TypeError, "x must have length self.ngens()" 
     2051 
     2052        m = p_ISet(1,r) 
     2053        i = 1 
     2054        for e in x: 
     2055            overflow_check(e) 
     2056            p_SetExp(m, i, int(e), r) 
     2057            i += 1 
     2058        p_Setm(m, r) 
     2059 
     2060        while(p): 
     2061            if p_ExpVectorEqual(p, m, r) == 1: 
     2062                p_Delete(&m,r) 
     2063                return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base) 
     2064            p = pNext(p) 
     2065 
     2066        p_Delete(&m,r) 
     2067        return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2068 
     2069    def exponents(self, as_ETuples=True): 
     2070        """ 
     2071        Return the exponents of the monomials appearing in this polynomial. 
     2072         
     2073        INPUT: 
     2074 
     2075        - ``as_ETuples`` - (default: ``True``) if true returns the result as an list of ETuples 
     2076                          otherwise returns a list of tuples 
     2077 
     2078 
     2079        EXAMPLES:: 
     2080 
     2081            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2082            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2083            sage: R.inject_variables() 
     2084            Defining x, z, y 
     2085            sage: f = x^3 + y + 2*z^2 
     2086            sage: f.exponents() 
     2087            [(3, 0, 0), (0, 2, 0), (0, 0, 1)] 
     2088            sage: f.exponents(as_ETuples=False) 
     2089            [(3, 0, 0), (0, 2, 0), (0, 0, 1)] 
     2090        """ 
     2091        cdef poly *p 
     2092        cdef ring *r 
     2093        cdef int v 
     2094        cdef list pl, ml 
     2095 
     2096        r = (< NCPolynomialRing_plural>self._parent)._ring 
     2097        p = self._poly 
     2098 
     2099        pl = list() 
     2100        ml = range(r.N) 
     2101        while p: 
     2102            for v from 1 <= v <= r.N: 
     2103                ml[v-1] = p_GetExp(p,v,r) 
     2104 
     2105            if as_ETuples: 
     2106                pl.append(ETuple(ml)) 
     2107            else: 
     2108                pl.append(tuple(ml)) 
     2109 
     2110            p = pNext(p) 
     2111        return pl 
     2112 
     2113    def is_homogeneous(self): 
     2114        """ 
     2115        Return ``True`` if this polynomial is homogeneous. 
     2116 
     2117        EXAMPLES:: 
     2118 
     2119            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2120            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2121            sage: P.inject_variables() 
     2122            Defining x, z, y 
     2123            sage: (x+y+z).is_homogeneous() 
     2124            True 
     2125            sage: (x.parent()(0)).is_homogeneous() 
     2126            True 
     2127            sage: (x+y^2+z^3).is_homogeneous() 
     2128            False 
     2129            sage: (x^2 + y^2).is_homogeneous() 
     2130            True 
     2131            sage: (x^2 + y^2*x).is_homogeneous() 
     2132            False 
     2133            sage: (x^2*y + y^2*x).is_homogeneous() 
     2134            True 
     2135        """ 
     2136        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2137        if(_ring != currRing): rChangeCurrRing(_ring) 
     2138        return bool(pIsHomogeneous(self._poly)) 
     2139 
     2140 
     2141    def is_monomial(self): 
     2142        """ 
     2143        Return ``True`` if this polynomial is a monomial.  A monomial 
     2144        is defined to be a product of generators with coefficient 1. 
     2145 
     2146        EXAMPLES:: 
     2147 
     2148            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2149            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2150            sage: P.inject_variables() 
     2151            Defining x, z, y 
     2152            sage: x.is_monomial() 
     2153            True 
     2154            sage: (2*x).is_monomial() 
     2155            False 
     2156            sage: (x*y).is_monomial() 
     2157            True 
     2158            sage: (x*y + x).is_monomial() 
     2159            False 
     2160        """ 
     2161        cdef poly *_p 
     2162        cdef ring *_ring 
     2163        cdef number *_n 
     2164        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2165 
     2166        if self._poly == NULL: 
     2167            return True 
     2168         
     2169        if(_ring != currRing): rChangeCurrRing(_ring) 
     2170         
     2171        _p = p_Head(self._poly, _ring) 
     2172        _n = p_GetCoeff(_p, _ring) 
     2173 
     2174        ret = (not self._poly.next) and n_IsOne(_n, _ring) 
     2175 
     2176        p_Delete(&_p, _ring) 
     2177        return ret 
     2178 
     2179    def monomials(self): 
     2180        """ 
     2181        Return the list of monomials in self. The returned list is 
     2182        decreasingly ordered by the term ordering of 
     2183        ``self.parent()``. 
     2184 
     2185        EXAMPLES:: 
     2186 
     2187            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2188            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2189            sage: P.inject_variables() 
     2190            Defining x, z, y 
     2191            sage: f = x + (3*2)*y*z^2 + (2+3) 
     2192            sage: f.monomials() 
     2193            [x, z^2*y, 1] 
     2194            sage: f = P(3^2) 
     2195            sage: f.monomials() 
     2196            [1] 
     2197 
     2198        TESTS:: 
     2199 
     2200            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2201            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2202            sage: P.inject_variables() 
     2203            Defining x, z, y 
     2204            sage: f = x 
     2205            sage: f.monomials() 
     2206            [x] 
     2207            sage: f = P(0) 
     2208            sage: f.monomials() 
     2209            [0] 
     2210 
     2211        Check if #7152 is fixed:: 
     2212 
     2213            sage: x=var('x') 
     2214            sage: K.<rho> = NumberField(x**2 + 1) 
     2215            sage: R.<x,y> = QQ[] 
     2216            sage: p = rho*x 
     2217            sage: q = x 
     2218            sage: p.monomials() 
     2219            [x] 
     2220            sage: q.monomials() 
     2221            [x] 
     2222            sage: p.monomials() 
     2223            [x] 
     2224        """ 
     2225        l = list() 
     2226        cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent 
     2227        cdef ring *_ring = parent._ring 
     2228        if(_ring != currRing): rChangeCurrRing(_ring) 
     2229        cdef poly *p = p_Copy(self._poly, _ring) 
     2230        cdef poly *t 
     2231 
     2232        if p == NULL: 
     2233            return [parent._zero_element] 
     2234         
     2235        while p: 
     2236            t = pNext(p) 
     2237            p.next = NULL 
     2238            p_SetCoeff(p, n_Init(1,_ring), _ring) 
     2239            p_Setm(p, _ring) 
     2240            l.append( new_NCP(parent,p) ) 
     2241            p = t 
     2242 
     2243        return l 
     2244 
     2245    def constant_coefficient(self): 
     2246        """ 
     2247        Return the constant coefficient of this multivariate 
     2248        polynomial. 
     2249 
     2250        EXAMPLES:: 
     2251 
     2252            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2253            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2254            sage: P.inject_variables() 
     2255            Defining x, z, y 
     2256            sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 
     2257            sage: f.constant_coefficient() 
     2258            5 
     2259            sage: f = 3*x^2  
     2260            sage: f.constant_coefficient() 
     2261            0 
     2262        """ 
     2263        cdef poly *p = self._poly 
     2264        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     2265        if p == NULL: 
     2266            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2267 
     2268        while p.next: 
     2269            p = pNext(p) 
     2270 
     2271        if p_LmIsConstant(p, r): 
     2272            return si2sa( p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base ) 
     2273        else: 
     2274            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2275 
     2276    cpdef is_constant(self): 
     2277        """ 
     2278        Return ``True`` if this polynomial is constant. 
     2279 
     2280        EXAMPLES:: 
     2281 
     2282            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2283            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2284            sage: P.inject_variables() 
     2285            Defining x, z, y 
     2286            sage: x.is_constant() 
     2287            False 
     2288            sage: P(1).is_constant() 
     2289            True 
     2290        """ 
     2291        return bool(p_IsConstant(self._poly, (<NCPolynomialRing_plural>self._parent)._ring)) 
     2292 
     2293    def lm(NCPolynomial_plural self): 
     2294        """ 
     2295        Returns the lead monomial of self with respect to the term 
     2296        order of ``self.parent()``. In Sage a monomial is a product of 
     2297        variables in some power without a coefficient. 
     2298 
     2299        EXAMPLES:: 
     2300 
     2301            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2302            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2303            sage: R.inject_variables() 
     2304            Defining x, y, z 
     2305            sage: f = x^1*y^2 + y^3*z^4 
     2306            sage: f.lm() 
     2307            x*y^2 
     2308            sage: f = x^3*y^2*z^4 + x^3*y^2*z^1  
     2309            sage: f.lm() 
     2310            x^3*y^2*z^4 
     2311 
     2312            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2313            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='deglex') 
     2314            sage: R.inject_variables() 
     2315            Defining x, y, z 
     2316            sage: f = x^1*y^2*z^3 + x^3*y^2*z^0 
     2317            sage: f.lm() 
     2318            x*y^2*z^3 
     2319            sage: f = x^1*y^2*z^4 + x^1*y^1*z^5 
     2320            sage: f.lm() 
     2321            x*y^2*z^4 
     2322 
     2323            sage: A.<x,y,z> = FreeAlgebra(GF(127), 3) 
     2324            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='degrevlex') 
     2325            sage: R.inject_variables() 
     2326            Defining x, y, z 
     2327            sage: f = x^1*y^5*z^2 + x^4*y^1*z^3 
     2328            sage: f.lm() 
     2329            x*y^5*z^2 
     2330            sage: f = x^4*y^7*z^1 + x^4*y^2*z^3 
     2331            sage: f.lm() 
     2332            x^4*y^7*z 
     2333 
     2334        """ 
     2335        cdef poly *_p 
     2336        cdef ring *_ring 
     2337        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2338        if self._poly == NULL: 
     2339            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     2340        _p = p_Head(self._poly, _ring) 
     2341        p_SetCoeff(_p, n_Init(1,_ring), _ring) 
     2342        p_Setm(_p,_ring) 
     2343        return new_NCP((<NCPolynomialRing_plural>self._parent), _p) 
     2344 
     2345    def lc(NCPolynomial_plural self): 
     2346        """ 
     2347        Leading coefficient of this polynomial with respect to the 
     2348        term order of ``self.parent()``. 
     2349 
     2350        EXAMPLES:: 
     2351 
     2352            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2353            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2354            sage: R.inject_variables() 
     2355            Defining x, y, z 
     2356 
     2357            sage: f = 3*x^1*y^2 + 2*y^3*z^4 
     2358            sage: f.lc() 
     2359            3 
     2360 
     2361            sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1  
     2362            sage: f.lc() 
     2363            5 
     2364        """ 
     2365 
     2366        cdef poly *_p 
     2367        cdef ring *_ring 
     2368        cdef number *_n 
     2369        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2370 
     2371        if self._poly == NULL: 
     2372            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2373         
     2374        if(_ring != currRing): rChangeCurrRing(_ring) 
     2375         
     2376        _p = p_Head(self._poly, _ring)  
     2377        _n = p_GetCoeff(_p, _ring) 
     2378 
     2379        ret =  si2sa(_n, _ring, (<NCPolynomialRing_plural>self._parent)._base) 
     2380        p_Delete(&_p, _ring) 
     2381        return ret 
     2382 
     2383    def lt(NCPolynomial_plural self): 
     2384        """ 
     2385        Leading term of this polynomial. In Sage a term is a product 
     2386        of variables in some power and a coefficient. 
     2387 
     2388        EXAMPLES:: 
     2389 
     2390            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2391            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2392            sage: R.inject_variables() 
     2393            Defining x, y, z 
     2394 
     2395            sage: f = 3*x^1*y^2 + 2*y^3*z^4 
     2396            sage: f.lt() 
     2397            3*x*y^2 
     2398             
     2399            sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1  
     2400            sage: f.lt() 
     2401            -2*x^3*y^2*z^4 
     2402        """ 
     2403        if self._poly == NULL: 
     2404            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     2405 
     2406        return new_NCP((<NCPolynomialRing_plural>self._parent), 
     2407                                           p_Head(self._poly,(<NCPolynomialRing_plural>self._parent)._ring)) 
     2408 
     2409    def is_zero(self): 
     2410        """ 
     2411        Return ``True`` if this polynomial is zero. 
     2412 
     2413        EXAMPLES:: 
     2414 
     2415            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     2416            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2417            sage: R.inject_variables() 
     2418            Defining x, z, y 
     2419 
     2420            sage: x.is_zero() 
     2421            False 
     2422            sage: (x-x).is_zero() 
     2423            True 
     2424        """ 
     2425        if self._poly is NULL: 
     2426            return True 
     2427        else: 
     2428            return False 
     2429 
     2430    def __nonzero__(self): 
     2431        """ 
     2432        EXAMPLES:: 
     2433 
     2434            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     2435            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2436            sage: R.inject_variables() 
     2437            Defining x, z, y 
     2438 
     2439            sage: bool(x) # indirect doctest 
     2440            True 
     2441            sage: bool(x-x) 
     2442            False 
     2443        """ 
     2444        if self._poly: 
     2445            return True 
     2446        else: 
     2447            return False 
     2448 
     2449 
     2450##################################################################### 
     2451 
     2452 
     2453cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, 
     2454        poly *juice): 
     2455    """ 
     2456    Construct NCPolynomial_plural from parent and SINGULAR poly. 
     2457 
     2458    EXAMPLES:: 
     2459 
     2460     
     2461    """ 
     2462    cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural) 
     2463    p._parent = <ParentWithBase>parent 
     2464    p._poly = juice 
     2465    p_Normalize(p._poly, parent._ring) 
     2466    return p 
     2467 
     2468 
     2469 
     2470 
     2471cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring): 
     2472    """ 
     2473    Construct MPolynomialRing_libsingular from ringWrap, assumming the ground field to be base_ring 
     2474 
     2475    EXAMPLES:: 
     2476        sage: H.<x,y,z> = PolynomialRing(QQ, 3) 
     2477        sage: from sage.libs.singular.function import singular_function 
     2478 
     2479        sage: ringlist = singular_function('ringlist') 
     2480        sage: ring = singular_function("ring")  
     2481 
     2482        sage: L = ringlist(H, ring=H); L 
     2483        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0]] 
     2484 
     2485        sage: len(L) 
     2486        4 
     2487         
     2488        sage: W = ring(L, ring=H); W 
     2489        <RingWrap> 
     2490 
     2491        sage: from sage.rings.polynomial.plural import new_CRing 
     2492        sage: R = new_CRing(W, H.base_ring()) 
     2493        sage: R # indirect doctest 
     2494        Multivariate Polynomial Ring in x, y, z over Rational Field 
     2495    """ 
     2496    assert( rw.is_commutative() ) 
     2497        
     2498    cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>PY_NEW(MPolynomialRing_libsingular) 
     2499         
     2500    self._ring = rw._ring 
     2501    self._ring.ShortOut = 0 
     2502         
     2503    self.__ngens = rw.ngens() 
     2504    self.__term_order =  TermOrder(rw.ordering_string(), force=True) 
     2505         
     2506    ParentWithGens.__init__(self, base_ring, rw.var_names()) 
     2507#    self._populate_coercion_lists_()  # ??? 
     2508          
     2509    #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     2510    self._has_singular = True 
     2511#    self._relations = self.relations() 
     2512         
     2513    return self 
     2514     
     2515cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring): 
     2516    """ 
     2517    Construct NCPolynomialRing_plural from ringWrap, assumming the ground field to be base_ring 
     2518 
     2519    EXAMPLES:: 
     2520    EXAMPLES:: 
     2521         
     2522        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2523        sage: H = A.g_algebra({y*x:x*y-1}) 
     2524        sage: H.inject_variables() 
     2525        Defining x, y, z 
     2526        sage: z*x 
     2527        x*z 
     2528        sage: z*y 
     2529        y*z 
     2530        sage: y*x 
     2531        x*y - 1 
     2532        sage: I = H.ideal([y^2, x^2, z^2-1]) 
     2533        sage: I._groebner_basis_libsingular()  
     2534        [1] 
     2535 
     2536        sage: from sage.libs.singular.function import singular_function 
     2537 
     2538        sage: ringlist = singular_function('ringlist') 
     2539        sage: ring = singular_function("ring")  
     2540 
     2541        sage: L = ringlist(H, ring=H); L 
     2542        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 1 1] 
     2543        [0 0 1] 
     2544        [0 0 0], [ 0 -1  0] 
     2545        [ 0  0  0] 
     2546        [ 0  0  0]] 
     2547 
     2548        sage: len(L) 
     2549        6       
     2550 
     2551        sage: W = ring(L, ring=H); W 
     2552        <noncommutative RingWrap> 
     2553 
     2554        sage: from sage.rings.polynomial.plural import new_NRing 
     2555        sage: R = new_NRing(W, H.base_ring()) 
     2556        sage: R # indirect doctest 
     2557        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1} 
     2558    """ 
     2559 
     2560    assert( not rw.is_commutative() ) 
     2561     
     2562    cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>PY_NEW(NCPolynomialRing_plural) 
     2563    self._ring = rw._ring 
     2564    self._ring.ShortOut = 0 
     2565         
     2566    self.__ngens = rw.ngens() 
     2567    self.__term_order =  TermOrder(rw.ordering_string(), force=True) 
     2568         
     2569    ParentWithGens.__init__(self, base_ring, rw.var_names()) 
     2570#    self._populate_coercion_lists_()  # ??? 
     2571     
     2572    #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     2573    self._has_singular = True 
     2574    self._relations = self.relations() 
     2575         
     2576    return self 
     2577 
     2578 
     2579def new_Ring(RingWrap rw, base_ring): 
     2580    """ 
     2581    Constructs a Sage ring out of low level RingWrap, which wraps a pointer to a Singular ring. 
     2582    The constructed ring is either commutative or noncommutative depending on the Singular ring. 
     2583 
     2584    EXAMPLES:: 
     2585         
     2586        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2587        sage: H = A.g_algebra({y*x:x*y-1}) 
     2588        sage: H.inject_variables() 
     2589        Defining x, y, z 
     2590        sage: z*x 
     2591        x*z 
     2592        sage: z*y 
     2593        y*z 
     2594        sage: y*x 
     2595        x*y - 1 
     2596        sage: I = H.ideal([y^2, x^2, z^2-1]) 
     2597        sage: I._groebner_basis_libsingular()  
     2598        [1] 
     2599 
     2600        sage: from sage.libs.singular.function import singular_function 
     2601 
     2602        sage: ringlist = singular_function('ringlist') 
     2603        sage: ring = singular_function("ring")  
     2604 
     2605        sage: L = ringlist(H, ring=H); L 
     2606        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 1 1] 
     2607        [0 0 1] 
     2608        [0 0 0], [ 0 -1  0] 
     2609        [ 0  0  0] 
     2610        [ 0  0  0]] 
     2611 
     2612        sage: len(L) 
     2613        6       
     2614 
     2615        sage: W = ring(L, ring=H); W 
     2616        <noncommutative RingWrap> 
     2617 
     2618        sage: from sage.rings.polynomial.plural import new_Ring 
     2619        sage: R = new_Ring(W, H.base_ring()); R 
     2620        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1} 
     2621 
     2622    """ 
     2623    import warnings 
     2624#    warnings.warn("This is a hack. Please, use it on your own risk...") 
     2625    if rw.is_commutative(): 
     2626        return new_CRing(rw, base_ring) 
     2627    return new_NRing(rw, base_ring) 
     2628         
     2629 
     2630def SCA(base_ring, names, alt_vars, order='degrevlex'): 
     2631    """ 
     2632    Shortcut to construct a graded commutative algebra out of the following data:  
     2633 
     2634    Input:  
     2635         
     2636    - ``base_ring``: the ground field 
     2637    - ``names``: a list of variable names  
     2638    - ``alt_vars``: a list of indices of to be anti-commutative variables 
     2639    - ``order``: orderig to be used for the constructed algebra 
     2640 
     2641    EXAMPLES:: 
     2642 
     2643        sage: from sage.rings.polynomial.plural import SCA 
     2644        sage: E = SCA(QQ, ['x', 'y', 'z'], [0, 1], order = 'degrevlex') 
     2645        sage: E 
     2646        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     2647        sage: E.inject_variables() 
     2648        Defining x, y, z 
     2649        sage: y*x 
     2650        -x*y 
     2651        sage: x^2 
     2652        0 
     2653        sage: y^2 
     2654        0 
     2655        sage: z^2 
     2656        z^2 
     2657    """ 
     2658    n = len(names) 
     2659    alt_start = min(alt_vars) 
     2660    alt_end = max(alt_vars) 
     2661    assert( alt_start >= 0 ) 
     2662    assert( (alt_end >= alt_start) and (alt_end < n) ) 
     2663     
     2664    relations = {} # {y*x:-x*y} 
     2665    from sage.algebras.free_algebra import FreeAlgebra 
     2666    A = FreeAlgebra(base_ring, n, names) 
     2667    for r in range(0, n-1, 1): 
     2668        for c in range(r+1, n, 1): 
     2669            if (r in alt_vars) and (c in alt_vars): 
     2670                relations[ A.gen(c) * A.gen(r) ] = - A.gen(r) * A.gen(c) 
     2671     
     2672    H = A.g_algebra(relations=relations, order=order) 
     2673    I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd() 
     2674    return H.quotient(I) 
     2675 
     2676cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring): 
     2677    if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring): 
     2678      p_SetExp(tempvector, pos, p_GetExp(tempvector, pos, _ring)+1, _ring) 
     2679    else: 
     2680      p_SetExp(tempvector, pos, 0, _ring) 
     2681      tempvector = addwithcarry(tempvector, maxvector, pos + 1, _ring) 
     2682    p_Setm(tempvector, _ring) 
     2683    return tempvector 
  • sage/rings/polynomial/term_order.py

    diff --git a/sage/rings/polynomial/term_order.py b/sage/rings/polynomial/term_order.py
    a b  
    520520 
    521521            for block in block_names: 
    522522                try: 
    523                     block_name, block_length, _ = re.split(length_pattern,block) 
     523                    block_name, block_length, _ = re.split(pattern, block.strip()) 
     524                    block_length = int(block_length) 
     525                    assert( block_length > 0) 
     526                     
     527                    blocks.append( TermOrder(block_name, block_length, force=force) ) 
     528                    name_str.append("%s(%d)"%(block_name, block_length)) 
     529                    singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length)) 
     530                    macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length)) 
     531                    length += block_length 
    524532                except ValueError: 
    525                     raise TypeError, "%s is not a valid term ordering"%(name,) 
     533                    block_name = block.strip() 
     534                    if block_name.lower() != "c": 
     535                        raise TypeError, "%s is not a valid term ordering (wrong part: '%s')"%(name, block) 
    526536 
    527                 block_length = int(block_length) 
    528  
    529                 blocks.append( TermOrder(block_name,block_length,force=force) ) 
    530                 name_str.append("%s(%d)"%(block_name,block_length)) 
    531                 singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length)) 
    532                 macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length)) 
    533  
    534                 length += block_length 
     537                    blocks.append( TermOrder(block_name, force=force) ) 
     538                    name_str.append(block_name) 
     539                    singular_str.append( singular_name_mapping.get(block_name, block_name) ) 
     540#                    macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), 0)) 
     541  
    535542 
    536543            self.blocks = tuple(blocks) 
    537544            self.__length = length 
  • 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  
    984984            if not x.is_zero(): 
    985985                return x 
    986986 
     987    def ideal_monoid(self): 
     988        """ 
     989        Return the monoid of ideals of this ring. 
     990 
     991        EXAMPLES:: 
     992 
     993            sage: ZZ.ideal_monoid() 
     994            Monoid of ideals of Integer Ring 
     995            sage: R.<x>=QQ[]; R.ideal_monoid() 
     996            Monoid of ideals of Univariate Polynomial Ring in x over Rational Field 
     997        """ 
     998        if self.__ideal_monoid is not None: 
     999            return self.__ideal_monoid 
     1000        else: 
     1001            from sage.rings.ideal_monoid import IdealMonoid 
     1002            M = IdealMonoid(self) 
     1003            self.__ideal_monoid = M 
     1004            return M 
     1005 
    9871006cdef class CommutativeRing(Ring): 
    9881007    """ 
    9891008    Generic commutative ring. 
     
    11291148        """ 
    11301149        raise NotImplementedError 
    11311150 
    1132     def ideal_monoid(self): 
    1133         """ 
    1134         Return the monoid of ideals of this ring. 
    1135  
    1136         EXAMPLES:: 
    1137  
    1138             sage: ZZ.ideal_monoid() 
    1139             Monoid of ideals of Integer Ring 
    1140             sage: R.<x>=QQ[]; R.ideal_monoid() 
    1141             Monoid of ideals of Univariate Polynomial Ring in x over Rational Field 
    1142         """ 
    1143         if self.__ideal_monoid is not None: 
    1144             return self.__ideal_monoid 
    1145         else: 
    1146             from sage.rings.ideal_monoid import IdealMonoid 
    1147             M = IdealMonoid(self) 
    1148             self.__ideal_monoid = M 
    1149             return M 
    1150  
    11511151    def quotient(self, I, names=None): 
    11521152        """ 
    11531153        Create the quotient of R by the ideal I.