Ticket #4539: trac4539_libplural_rel10903.patch

File trac4539_libplural_rel10903.patch, 165.3 KB (added by SimonKing, 3 years ago)

Combined patch relative to sage-4.7.2.alpha3 plus #11068, #11856 and #10903

  • module_list.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1300026255 -3600
    # Node ID 7571b89b89e2b6c4302ee418390eb6af5f8061da
    # Parent  c8a71f9470287d58039652fc90e92028a668ea95
    Wrapper for Singular/Plural - Sage-Trac #4539.
    * * *
    MPolynomialRing_plural now accepts matrix parameters to specify commutativity
    relations. Added ExteriorAlgebra. Ideals of g-algebras can be left- and twosided
    (cf. #11068).
    
    diff --git a/module_list.py b/module_list.py
    a b  
    14951495              include_dirs = [SAGE_INC + 'singular', SAGE_INC + 'factory'], 
    14961496              depends = singular_depends), 
    14971497 
     1498    Extension('sage.rings.polynomial.plural', 
     1499              sources = ['sage/rings/polynomial/plural.pyx'], 
     1500              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'], 
     1501              language="c++", 
     1502              include_dirs = [SAGE_ROOT +'/local/include/singular'], 
     1503              depends = [SAGE_ROOT + "/local/include/libsingular.h"]), 
     1504 
    14981505    Extension('sage.rings.polynomial.multi_polynomial_libsingular', 
    14991506              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'], 
    15001507              libraries = singular_libs, 
  • sage/algebras/free_algebra.py

    diff --git a/sage/algebras/free_algebra.py b/sage/algebras/free_algebra.py
    a b  
    6666 
    6767import sage.structure.parent_gens 
    6868 
    69          
    7069def FreeAlgebra(R, n, names): 
    7170    """ 
    7271    Return the free algebra over the ring `R` on `n` 
     
    7473     
    7574    INPUT: 
    7675     
    77      
    7876    -  ``R`` - ring 
    79      
    8077    -  ``n`` - integer 
    81      
    8278    -  ``names`` - string or list/tuple of n strings 
    8379     
    84      
    85     OUTPUT: a free algebra 
     80    OUTPUT: 
     81         
     82    A free algebra. 
    8683     
    8784    EXAMPLES:: 
    8885     
     
    110107        True 
    111108     
    112109    Free algebras commute with their base ring. 
    113      
    114110    :: 
    115111     
    116112        sage: K.<a,b> = FreeAlgebra(QQ,2) 
     
    166162    Element = FreeAlgebraElement 
    167163    def __init__(self, R, n, names): 
    168164        """ 
     165        The free algebra on `n` generators over a base ring. 
     166 
    169167        INPUT: 
    170168         
    171          
    172169        -  ``R`` - ring 
    173          
    174170        -  ``n`` - an integer 
    175          
    176171        -  ``names`` - generator names 
     172     
     173        EXAMPLES:: 
     174     
     175            sage: F.<x,y,z> = FreeAlgebra(QQ, 3); F # indirect doctet 
     176            Free Algebra on 3 generators (x, y, z) over Rational Field 
    177177        """ 
    178178        if not isinstance(R, Ring): 
    179179            raise TypeError, "Argument R must be a ring." 
     
    254254            sage: print F  # indirect doctest 
    255255            Free Algebra on 3 generators (x0, x1, x2) over Rational Field 
    256256            sage: F.rename('QQ<<x0,x1,x2>>') 
    257             sage: print F 
     257            sage: print F #indirect doctest 
    258258            QQ<<x0,x1,x2>> 
    259259            sage: FreeAlgebra(ZZ,1,['a']) 
    260260            Free Algebra on 1 generators (a,) over Integer Ring 
     
    315315         
    316316        :: 
    317317         
    318             sage: F._coerce_(x*y) 
     318            sage: F._coerce_(x*y) # indirect doctest 
    319319            x*y 
    320320         
    321321        Elements of the integers coerce in, since there is a coerce map 
     
    421421 
    422422    def quotient(self, mons, mats, names): 
    423423        """ 
    424         Returns a quotient algebra defined via the action of a free algebra 
     424        Returns a quotient algebra. 
     425         
     426        The quotient algebra is defined via the action of a free algebra 
    425427        A on a (finitely generated) free module. The input for the quotient 
    426428        algebra is a list of monomials (in the underlying monoid for A) 
    427429        which form a free basis for the module of A, and a list of 
    428430        matrices, which give the action of the free generators of A on this 
    429431        monomial basis. 
     432 
     433        EXAMPLE: 
     434 
     435        Here is the quaternion algebra defined in terms of three generators:: 
     436         
     437            sage: n = 3 
     438            sage: A = FreeAlgebra(QQ,n,'i') 
     439            sage: F = A.monoid() 
     440            sage: i, j, k = F.gens() 
     441            sage: mons = [ F(1), i, j, k ] 
     442            sage: M = MatrixSpace(QQ,4) 
     443            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]) ] 
     444            sage: H.<i,j,k> = A.quotient(mons, mats); H 
     445            Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field 
    430446        """ 
    431447        import free_algebra_quotient 
    432448        return free_algebra_quotient.FreeAlgebraQuotient(self, mons, mats, names) 
     
    456472        """ 
    457473        return self.__monoid 
    458474     
    459                      
     475    def g_algebra(self, relations, order='degrevlex', check = True): 
     476        """ 
     477        The G-Algebra derived from this algebra by relations. 
     478        By default is assumed, that two variables commute. 
     479 
     480        TODO: 
     481 
     482        - Coercion doesn't work yet, there is some cheating about assumptions 
     483        - The optional argument ``check`` controls checking the degeneracy 
     484          conditions. Furthermore, the default values interfere with 
     485          non-degeneracy conditions. 
     486             
     487        EXAMPLES:: 
     488 
     489            sage: A.<x,y,z>=FreeAlgebra(QQ,3) 
     490            sage: G=A.g_algebra({y*x:-x*y}) 
     491            sage: (x,y,z)=G.gens() 
     492            sage: x*y 
     493            x*y 
     494            sage: y*x 
     495            -x*y 
     496            sage: z*x 
     497            x*z 
     498            sage: (x,y,z)=A.gens() 
     499            sage: G=A.g_algebra({y*x:-x*y+1}) 
     500            sage: (x,y,z)=G.gens() 
     501            sage: y*x 
     502            -x*y + 1 
     503            sage: (x,y,z)=A.gens() 
     504            sage: G=A.g_algebra({y*x:-x*y+z}) 
     505            sage: (x,y,z)=G.gens() 
     506            sage: y*x 
     507            -x*y + z 
     508        """ 
     509        from sage.matrix.constructor  import Matrix 
     510        from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     511         
     512        base_ring=self.base_ring() 
     513        n=self.ngens() 
     514        cmat=Matrix(base_ring,n) 
     515        dmat=Matrix(self,n) 
     516        for i in xrange(n): 
     517            for j in xrange(i+1,n): 
     518                cmat[i,j]=1 
     519        for (to_commute,commuted) in relations.iteritems(): 
     520            #This is dirty, coercion is broken 
     521            assert isinstance(to_commute,FreeAlgebraElement), to_commute.__class__ 
     522            assert isinstance(commuted,FreeAlgebraElement), commuted 
     523            ((v1,e1),(v2,e2))=list(list(to_commute)[0][1]) 
     524            assert e1==1 
     525            assert e2==1 
     526            assert v1>v2 
     527            c_coef=None 
     528            d_poly=None 
     529            for (c,m) in commuted: 
     530                if list(m)==[(v2,1),(v1,1)]: 
     531                    c_coef=c 
     532                    #buggy coercion workaround 
     533                    d_poly=commuted-self(c)*self(m) 
     534                    break 
     535            assert not c_coef is None,list(m) 
     536            v2_ind = self.gens().index(v2) 
     537            v1_ind = self.gens().index(v1) 
     538            cmat[v2_ind,v1_ind]=c_coef 
     539            if d_poly: 
     540                dmat[v2_ind,v1_ind]=d_poly 
     541         
     542        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat, order=order, check=check) 
     543             
     544             
    460545from sage.misc.cache import Cache 
    461546cache = 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  
    1414- Michael Brickenstein (2009-10): extension to more Singular types 
    1515- Martin Albrecht (2010-01): clean up, support for attributes 
    1616- Simon King (2011-04): include the documentation provided by Singular as a code block. 
     17- Burcin Erocal, Michael Brickenstein, Oleksandr Motsak, Alexander Dreyer, Simon King 
     18  (2011-09) plural support 
    1719 
    1820EXAMPLES: 
    1921 
     
    8183from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, new_MP 
    8284from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular 
    8385 
     86from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_plural, new_NCP 
     87from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal 
     88 
    8489from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal 
    8590 
    8691from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence 
     
    9095from sage.libs.singular.decl cimport iiMake_proc, iiExprArith1, iiExprArith2, iiExprArith3, iiExprArithM, iiLibCmd 
    9196from 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 
    9297from 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 
    93 from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy 
     98from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy, rIsPluralRing, rPrint, rOrderingString 
    9499from sage.libs.singular.decl cimport IDROOT, enterid, currRingHdl, memcpy, IDNEXT, IDTYP, IDPACKAGE 
    95100from sage.libs.singular.decl cimport errorreported, verbose, Sy_bit, currentVoice, myynest 
    96101from sage.libs.singular.decl cimport intvec_new_int3, intvec_new, matrix, mpNew 
     
    123128     
    124129    for (i, p) in enumerate(v): 
    125130        component = <int>i+1 
    126         poly_component = p_Copy( 
    127             (<MPolynomial_libsingular>p)._poly, r) 
     131        poly_component = copy_sage_polynomial_into_singular_poly(p) 
    128132        p_iter = poly_component 
    129133        while p_iter!=NULL: 
    130134            p_SetComp(p_iter, component, r) 
     
    133137        res=p_Add_q(res, poly_component, r) 
    134138    return res 
    135139 
     140 
    136141cdef class RingWrap: 
    137142    """ 
    138143    A simple wrapper around Singular's rings. 
     
    149154            sage: ring(l, ring=P) 
    150155            <RingWrap> 
    151156        """ 
     157        if not self.is_commutative(): 
     158            return "<noncommutative RingWrap>" 
    152159        return "<RingWrap>" 
    153160     
    154161    def __dealloc__(self): 
    155162        if self._ring!=NULL: 
    156163            self._ring.ref -= 1 
    157164 
     165    def ngens(self): 
     166        """ 
     167        Get number of generators. 
     168 
     169        EXAMPLE:: 
     170 
     171            sage: from sage.libs.singular.function import singular_function 
     172            sage: P.<x,y,z> = PolynomialRing(QQ) 
     173            sage: ringlist = singular_function("ringlist") 
     174            sage: l = ringlist(P) 
     175            sage: ring = singular_function("ring") 
     176            sage: ring(l, ring=P).ngens() 
     177            3 
     178        """ 
     179        return self._ring.N 
     180 
     181    def var_names(self): 
     182        """ 
     183        Get names of variables. 
     184 
     185        EXAMPLE:: 
     186 
     187            sage: from sage.libs.singular.function import singular_function 
     188            sage: P.<x,y,z> = PolynomialRing(QQ) 
     189            sage: ringlist = singular_function("ringlist") 
     190            sage: l = ringlist(P) 
     191            sage: ring = singular_function("ring") 
     192            sage: ring(l, ring=P).var_names() 
     193            ['x', 'y', 'z'] 
     194        """ 
     195        return [self._ring.names[i] for i in range(self.ngens())] 
     196 
     197    def npars(self): 
     198        """ 
     199        Get number of parameters. 
     200 
     201        EXAMPLE:: 
     202 
     203            sage: from sage.libs.singular.function import singular_function 
     204            sage: P.<x,y,z> = PolynomialRing(QQ) 
     205            sage: ringlist = singular_function("ringlist") 
     206            sage: l = ringlist(P) 
     207            sage: ring = singular_function("ring") 
     208            sage: ring(l, ring=P).npars() 
     209            0 
     210        """ 
     211        return self._ring.P 
     212 
     213    def ordering_string(self): 
     214        """ 
     215        Get Singular string defining monomial ordering. 
     216 
     217        EXAMPLE:: 
     218 
     219            sage: from sage.libs.singular.function import singular_function 
     220            sage: P.<x,y,z> = PolynomialRing(QQ) 
     221            sage: ringlist = singular_function("ringlist") 
     222            sage: l = ringlist(P) 
     223            sage: ring = singular_function("ring") 
     224            sage: ring(l, ring=P).ordering_string() 
     225            'dp(3),C' 
     226        """ 
     227        return rOrderingString(self._ring) 
     228     
     229     
     230 
     231    def par_names(self): 
     232        """ 
     233        Get parameter names. 
     234 
     235        EXAMPLE:: 
     236 
     237            sage: from sage.libs.singular.function import singular_function 
     238            sage: P.<x,y,z> = PolynomialRing(QQ) 
     239            sage: ringlist = singular_function("ringlist") 
     240            sage: l = ringlist(P) 
     241            sage: ring = singular_function("ring") 
     242            sage: ring(l, ring=P).par_names() 
     243            [] 
     244        """ 
     245        return [self._ring.parameter[i] for i in range(self.npars())] 
     246 
     247    def characteristic(self): 
     248        """ 
     249        Get characteristic. 
     250 
     251        EXAMPLE:: 
     252 
     253            sage: from sage.libs.singular.function import singular_function 
     254            sage: P.<x,y,z> = PolynomialRing(QQ) 
     255            sage: ringlist = singular_function("ringlist") 
     256            sage: l = ringlist(P) 
     257            sage: ring = singular_function("ring") 
     258            sage: ring(l, ring=P).characteristic() 
     259            0 
     260        """ 
     261        return self._ring.ch 
     262 
     263    def is_commutative(self): 
     264        """ 
     265        Determine whether a given ring is commutative. 
     266 
     267        EXAMPLE:: 
     268 
     269            sage: from sage.libs.singular.function import singular_function 
     270            sage: P.<x,y,z> = PolynomialRing(QQ) 
     271            sage: ringlist = singular_function("ringlist") 
     272            sage: l = ringlist(P) 
     273            sage: ring = singular_function("ring") 
     274            sage: ring(l, ring=P).is_commutative() 
     275            True 
     276        """ 
     277        return not rIsPluralRing(self._ring) 
     278     
     279    def _output(self): 
     280        """ 
     281        Use Singular output. 
     282 
     283        EXAMPLE:: 
     284 
     285            sage: from sage.libs.singular.function import singular_function 
     286            sage: P.<x,y,z> = PolynomialRing(QQ) 
     287            sage: ringlist = singular_function("ringlist") 
     288            sage: l = ringlist(P) 
     289            sage: ring = singular_function("ring") 
     290            sage: ring(l, ring=P)._output() 
     291        """ 
     292        rPrint(self._ring) 
     293 
    158294cdef class Resolution: 
    159295    """ 
    160296    A simple wrapper around Singular's resolutions. 
     
    171307           sage: M = syz(I) 
    172308           sage: resolution = mres(M, 0) 
    173309        """ 
    174         assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular) 
    175         self.base_ring = <MPolynomialRing_libsingular> base_ring 
     310        #FIXME: still not working noncommutative 
     311        assert is_sage_wrapper_for_singular_ring(base_ring) 
     312        self.base_ring = base_ring 
    176313    def __repr__(self): 
    177314        """ 
    178315        EXAMPLE:: 
     
    209346    INPUT: 
    210347 
    211348    - ``data`` - some Singular data this interpreter object points to 
    212  
    213349    - ``res_type`` - the type of that data 
    214350    """ 
    215351    cdef leftv* res 
     
    230366    args.CleanUp(r) 
    231367    omFreeBin(args, sleftv_bin) 
    232368 
     369# ===================================== 
     370# = Singular/Plural Abstraction Layer = 
     371# ===================================== 
    233372 
    234 def all_polynomials(s): 
     373def is_sage_wrapper_for_singular_ring(ring): 
     374    """ 
     375    Check whether wrapped ring arises from Singular or Singular/Plural. 
     376 
     377    EXAMPLE:: 
     378 
     379        sage: from sage.libs.singular.function import is_sage_wrapper_for_singular_ring 
     380        sage: P.<x,y,z> = QQ[] 
     381        sage: is_sage_wrapper_for_singular_ring(P) 
     382        True 
     383 
     384    :: 
     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 
     412        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     413        sage: from sage.matrix.constructor  import Matrix 
     414        sage: from sage.libs.singular.function import is_singular_poly_wrapper 
     415        sage: c=Matrix(2) 
     416        sage: c[0,1]=-1 
     417        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 
     418        sage: (x,y)=P.gens() 
     419        sage: is_singular_poly_wrapper(x+y) 
     420        True 
     421         
     422    """ 
     423    return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p,  NCPolynomial_plural) 
     424 
     425def all_singular_poly_wrapper(s): 
    235426    """ 
    236427    Tests for a sequence ``s``, whether it consists of 
    237428    singular polynomials. 
    238429     
    239430    EXAMPLE:: 
    240431         
    241         sage: from sage.libs.singular.function import all_polynomials 
     432        sage: from sage.libs.singular.function import all_singular_poly_wrapper 
    242433        sage: P.<x,y,z> = QQ[] 
    243         sage: all_polynomials([x+1, y]) 
     434        sage: all_singular_poly_wrapper([x+1, y]) 
    244435        True 
    245         sage: all_polynomials([x+1, y, 1]) 
     436        sage: all_singular_poly_wrapper([x+1, y, 1]) 
    246437        False 
    247438    """ 
    248439    for p in s: 
    249         if not isinstance(p, MPolynomial_libsingular): 
     440        if not is_singular_poly_wrapper(p): 
    250441            return False 
    251442    return True 
    252443 
     444cdef poly* access_singular_poly(p) except <poly*> -1: 
     445    """ 
     446    Get the raw ``poly`` pointer from a wrapper object. 
     447    """ 
     448    if PY_TYPE_CHECK(p, MPolynomial_libsingular): 
     449        return (<MPolynomial_libsingular> p)._poly 
     450    else: 
     451        if PY_TYPE_CHECK(p, NCPolynomial_plural): 
     452            return (<NCPolynomial_plural> p)._poly 
     453    raise ValueError("not a singular polynomial wrapper") 
     454 
     455cdef ring* access_singular_ring(r) except <ring*> -1: 
     456    """ 
     457    Get the singular ``ring`` pointer from a wrapper object. 
     458    """ 
     459    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular): 
     460        return (<MPolynomialRing_libsingular> r )._ring 
     461    if PY_TYPE_CHECK(r, NCPolynomialRing_plural): 
     462        return (<NCPolynomialRing_plural> r )._ring 
     463    raise ValueError("not a singular polynomial ring wrapper") 
     464   
     465cdef poly* copy_sage_polynomial_into_singular_poly(p): 
     466    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent())) 
     467 
    253468def all_vectors(s): 
    254469    """ 
    255470    Checks if a sequence ``s`` consists of free module 
     
    270485        False 
    271486    """ 
    272487    for p in s: 
    273         if not (isinstance(p, FreeModuleElement_generic_dense)\ 
    274             and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)): 
     488        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\ 
     489            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())): 
    275490            return False 
    276491    return True 
    277492 
    278493 
    279  
    280494cdef class Converter(SageObject): 
    281495    """ 
    282496    A :class:`Converter` interfaces between Sage objects and Singular 
     
    290504        INPUT: 
    291505 
    292506        - ``args`` - a list of Python objects 
    293  
    294507        - ``ring`` - a multivariate polynomial ring 
    295  
    296508        - ``attributes`` - an optional dictionary of Singular 
    297                            attributes (default: ``None``) 
     509          attributes (default: ``None``) 
    298510 
    299511        EXAMPLE:: 
    300512 
     
    305517        """ 
    306518        cdef leftv *v 
    307519        self.args = NULL 
    308         self._ring = ring 
     520        self._sage_ring = ring 
     521        if ring is not None: 
     522            self._singular_ring = access_singular_ring(ring) 
     523         
    309524        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    310525        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
     526        from sage.matrix.matrix_generic_dense import Matrix_generic_dense 
    311527        for a in args: 
    312             if PY_TYPE_CHECK(a, MPolynomial_libsingular): 
    313                 v = self.append_polynomial(<MPolynomial_libsingular> a) 
     528            if is_singular_poly_wrapper(a): 
     529                v = self.append_polynomial(a) 
    314530 
    315             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
    316                 v = self.append_ring(<MPolynomialRing_libsingular> a) 
     531            elif is_sage_wrapper_for_singular_ring(a): 
     532                v = self.append_ring(a) 
    317533 
    318             elif PY_TYPE_CHECK(a, MPolynomialIdeal): 
     534            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     535                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    319536                v = self.append_ideal(a) 
    320537 
    321538            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long): 
     
    329546 
    330547            elif PY_TYPE_CHECK(a, Matrix_integer_dense): 
    331548                v = self.append_intmat(a) 
    332  
     549             
     550            elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\ 
     551                is_sage_wrapper_for_singular_ring(a.parent().base_ring()): 
     552                self.append_matrix(a) 
     553             
    333554            elif PY_TYPE_CHECK(a, Resolution): 
    334555                v = self.append_resolution(a) 
    335556 
    336557            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\ 
    337                 and isinstance( 
    338                     a.parent().base_ring(), 
    339                     MPolynomialRing_libsingular): 
     558                and is_sage_wrapper_for_singular_ring( 
     559                    a.parent().base_ring()): 
    340560                v = self.append_vector(a) 
    341561                 
    342562            # as output ideals get converted to sequences 
     
    344564            # this means, that Singular lists should not be converted to Sequences, 
    345565            # as we do not want ambiguities 
    346566            elif PY_TYPE_CHECK(a, Sequence_generic)\ 
    347                 and all_polynomials(a): 
     567                and all_singular_poly_wrapper(a): 
    348568                v = self.append_ideal(ring.ideal(a)) 
    349569            elif PY_TYPE_CHECK(a, PolynomialSequence): 
    350570                v = self.append_ideal(ring.ideal(a)) 
     
    365585                    v = self.append_intvec(a) 
    366586                else: 
    367587                    v = self.append_list(a) 
    368             elif a.parent() is self._ring.base_ring(): 
     588            elif a.parent() is self._sage_ring.base_ring(): 
    369589                v = self.append_number(a) 
    370590 
    371591            elif PY_TYPE_CHECK(a, Integer): 
     
    394614            sage: Converter([a,b,c],ring=P).ring() 
    395615            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    396616        """ 
    397         return self._ring 
     617        return self._sage_ring 
    398618 
    399619    def _repr_(self): 
    400620        """ 
     
    405625            sage: Converter([a,b,c],ring=P) # indirect doctest 
    406626            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127 
    407627        """ 
    408         return "Singular Converter in %s"%(self._ring) 
     628        return "Singular Converter in %s"%(self._sage_ring) 
    409629 
    410630    def __dealloc__(self): 
    411         cdef ring *r = (<MPolynomialRing_libsingular>self._ring)._ring 
     631        cdef ring *r = access_singular_ring(self._sage_ring) 
    412632        if self.args: 
    413633            free_leftv(self.args, r) 
    414634     
     
    461681        INPUT: 
    462682 
    463683        - ``data`` - the raw data 
    464  
    465684        - ``res_type`` - the type of the data 
    466685        """ 
    467686        return self._append_leftv( new_leftv(data, res_type) ) 
     
    471690        Convert singular matrix to matrix over the polynomial ring. 
    472691        """ 
    473692        from sage.matrix.constructor import Matrix 
    474         sage_ring = self._ring 
    475         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
    476             sage_ring)._ring 
     693        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\ 
     694        #    self._sage_ring)._ring 
    477695        ncols = mat.ncols 
    478696        nrows = mat.nrows 
    479         result = Matrix(sage_ring, nrows, ncols) 
    480         cdef MPolynomial_libsingular p 
     697        result = Matrix(self._sage_ring, nrows, ncols) 
    481698        for i in xrange(nrows): 
    482699            for j in xrange(ncols): 
    483                 p = MPolynomial_libsingular(sage_ring) 
    484                 p._poly = mat.m[i*ncols+j] 
     700                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j]) 
    485701                mat.m[i*ncols+j]=NULL 
    486702                result[i,j] = p 
    487703        return result 
    488704     
    489705    cdef to_sage_vector_destructive(self, poly *p, free_module = None): 
    490         cdef ring *r=self._ring._ring 
     706        #cdef ring *r=self._ring._ring 
    491707        cdef int rank 
    492708        if free_module: 
    493709            rank = free_module.rank() 
    494710        else: 
    495             rank = singular_vector_maximal_component(p, r) 
    496             free_module = self._ring**rank 
     711            rank = singular_vector_maximal_component(p, self._singular_ring) 
     712            free_module = self._sage_ring**rank 
    497713        cdef poly *acc 
    498714        cdef poly *p_iter 
    499715        cdef poly *first 
     
    506722            first = NULL 
    507723            p_iter=p 
    508724            while p_iter != NULL: 
    509                 if p_GetComp(p_iter, r) == i: 
    510                     p_SetComp(p_iter,0, r) 
    511                     p_Setm(p_iter, r) 
     725                if p_GetComp(p_iter, self._singular_ring) == i: 
     726                    p_SetComp(p_iter,0, self._singular_ring) 
     727                    p_Setm(p_iter, self._singular_ring) 
    512728                    if acc == NULL: 
    513729                        first = p_iter 
    514730                    else: 
     
    523739                else: 
    524740                    previous = p_iter 
    525741                    p_iter = pNext(p_iter) 
    526             result.append(new_MP(self._ring, first)) 
     742             
     743            result.append(new_sage_polynomial(self._sage_ring, first)) 
    527744        return free_module(result) 
    528745           
    529746    cdef object to_sage_module_element_sequence_destructive( self, ideal *i): 
     
    537754        - ``r`` -- a SINGULAR ring 
    538755        - ``sage_ring`` -- a Sage ring matching r 
    539756        """ 
    540         cdef MPolynomialRing_libsingular sage_ring = self._ring 
     757        #cdef MPolynomialRing_libsingular sage_ring = self._ring 
    541758        cdef int j 
    542759        cdef int rank=i.rank 
    543         free_module = sage_ring**rank        
     760        free_module = self._sage_ring ** rank        
    544761        l = [] 
    545762 
    546763        for j from 0 <= j < IDELEMS(i):             
     
    568785        return result 
    569786     
    570787     
    571     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL: 
     788    cdef leftv *append_polynomial(self, p) except NULL: 
    572789        """ 
    573790        Append the polynomial ``p`` to the list. 
    574791        """ 
    575         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring) 
     792        cdef poly* _p 
     793        _p = copy_sage_polynomial_into_singular_poly(p) 
     794                 
    576795        return self._append(_p, POLY_CMD) 
    577796 
    578797    cdef leftv *append_ideal(self,  i) except NULL: 
     
    589808        """ 
    590809        rank = max([v.parent().rank() for v in m]) 
    591810        cdef ideal *result 
    592         cdef ring *r = self._ring._ring 
     811        cdef ring *r = self._singular_ring 
    593812        cdef ideal *i 
    594813        cdef int j = 0 
    595814 
     
    605824        """ 
    606825        Append the number ``n`` to the list. 
    607826        """ 
    608         cdef number *_n =  sa2si(n, self._ring._ring) 
     827        cdef number *_n =  sa2si(n, self._singular_ring) 
    609828        return self._append(<void *>_n, NUMBER_CMD) 
    610829 
    611     cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL: 
     830    cdef leftv *append_ring(self, r) except NULL: 
    612831        """ 
    613832        Append the ring ``r`` to the list. 
    614833        """ 
    615         cdef ring *_r =  <ring*> r._ring 
     834        cdef ring *_r =  access_singular_ring(r) 
    616835        _r.ref+=1 
    617836        return self._append(<void *>_r, RING_CMD) 
    618837 
    619838    cdef leftv *append_matrix(self, mat) except NULL: 
    620839         
    621840        sage_ring = mat.base_ring() 
    622         cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring 
     841        cdef ring *r=<ring*> access_singular_ring(sage_ring) 
    623842 
    624843        cdef poly *p 
    625844        ncols = mat.ncols() 
     
    627846        cdef matrix* _m=mpNew(nrows,ncols) 
    628847        for i in xrange(nrows): 
    629848            for j in xrange(ncols): 
    630                 p = p_Copy( 
    631                     (<MPolynomial_libsingular> mat[i,j])._poly, r) 
     849                #FIXME 
     850                p = copy_sage_polynomial_into_singular_poly(mat[i,j]) 
    632851                _m.m[ncols*i+j]=p 
    633852        return self._append(_m, MATRIX_CMD) 
    634853 
     
    646865        Append the list ``l`` to the list. 
    647866        """ 
    648867         
    649         cdef Converter c = Converter(l, self._ring) 
     868        cdef Converter c = Converter(l, self._sage_ring) 
    650869        n = len(c) 
    651870 
    652871        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin) 
     
    677896        Append vector ``v`` from free  
    678897        module over polynomial ring. 
    679898        """ 
    680         cdef ring *r = self._ring._ring 
     899        cdef ring *r = self._singular_ring 
    681900        cdef poly *p = sage_vector_to_poly(v, r) 
    682901        return self._append(<void*> p, VECTOR_CMD) 
    683902     
     
    717936 
    718937        - ``to_convert`` - a Singular ``leftv`` 
    719938        """ 
     939        #FIXME 
    720940        cdef MPolynomial_libsingular res_poly 
    721941        cdef int rtyp = to_convert.rtyp 
    722942        cdef lists *singular_list 
    723943        cdef Resolution res_resolution 
    724944        if rtyp == IDEAL_CMD: 
    725             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring) 
     945            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring) 
    726946 
    727947        elif rtyp == POLY_CMD: 
    728             res_poly = MPolynomial_libsingular(self._ring) 
     948            #FIXME 
     949            res_poly = MPolynomial_libsingular(self._sage_ring) 
    729950            res_poly._poly = <poly*>to_convert.data 
    730951            to_convert.data = NULL 
    731952            #prevent it getting free, when cleaning the leftv 
     
    735956            return <long>to_convert.data 
    736957         
    737958        elif rtyp == NUMBER_CMD: 
    738             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring()) 
     959            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring()) 
    739960 
    740961        elif rtyp == INTVEC_CMD: 
    741962            return si2sa_intvec(<intvec *>to_convert.data) 
     
    751972             
    752973 
    753974        elif rtyp == RING_CMD or rtyp==QRING_CMD: 
    754             ring_wrap_result=RingWrap() 
    755             (<RingWrap> ring_wrap_result)._ring=<ring*> to_convert.data 
    756             (<RingWrap> ring_wrap_result)._ring.ref+=1 
    757             return ring_wrap_result 
     975            return new_RingWrap( <ring*> to_convert.data ) 
    758976 
    759977        elif rtyp == MATRIX_CMD: 
    760978            return self.to_sage_matrix(<matrix*>  to_convert.data ) 
     
    777995            return self.to_sage_integer_matrix( 
    778996                <intvec*> to_convert.data) 
    779997        elif rtyp == RESOLUTION_CMD: 
    780             res_resolution = Resolution(self._ring) 
     998            res_resolution = Resolution(self._sage_ring) 
    781999            res_resolution._resolution = <syStrategy*> to_convert.data 
    7821000            res_resolution._resolution.references += 1 
    7831001            return res_resolution 
     
    9511169        """ 
    9521170        return "%s (singular function)" %(self._name) 
    9531171 
    954     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None): 
     1172    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None): 
    9551173        """ 
    9561174        Call this function with the provided arguments ``args`` in the 
    9571175        ring ``R``. 
     
    9591177        INPUT: 
    9601178 
    9611179        - ``args`` - a list of arguments 
    962  
    9631180        - ``ring`` - a multivariate polynomial ring 
    964  
    9651181        - ``interruptible`` - if ``True`` pressing Ctrl-C during the 
    966                               execution of this function will 
    967                               interrupt the computation (default: ``True``) 
     1182          execution of this function will interrupt the computation 
     1183          (default: ``True``) 
    9681184 
    9691185        - ``attributes`` - a dictionary of optional Singular 
    970                            attributes assigned to Singular objects (default: ``None``) 
     1186          attributes assigned to Singular objects (default: ``None``) 
    9711187 
    9721188        EXAMPLE:: 
    9731189 
     
    10311247        """ 
    10321248        if ring is None: 
    10331249            ring = self.common_ring(args, ring) 
    1034         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular): 
     1250        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \ 
     1251                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)): 
    10351252            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring))) 
    10361253        return call_function(self, args, ring, interruptible, attributes) 
    10371254     
     
    10901307        singular_doc = get_docstring(self._name).split('\n') 
    10911308        return prefix + "\n::\n\n"+'\n'.join(["    "+L for L in singular_doc]) 
    10921309 
    1093     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None): 
     1310    cdef common_ring(self, tuple args, ring=None): 
    10941311        """ 
    10951312        Return the common ring for the argument list ``args``. 
    10961313 
     
    11021319        INPUT: 
    11031320 
    11041321        - ``args`` - a list of Python objects 
    1105  
    11061322        - ``ring`` - an optional ring to check 
    11071323        """ 
    11081324        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense 
    11091325        from sage.matrix.matrix_integer_dense import Matrix_integer_dense 
    11101326        for a in args: 
    1111             if PY_TYPE_CHECK(a, MPolynomialIdeal): 
     1327            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \ 
     1328                    PY_TYPE_CHECK(a, NCPolynomialIdeal): 
    11121329                ring2 = a.ring() 
    1113             elif PY_TYPE_CHECK(a, MPolynomial_libsingular): 
     1330            elif is_singular_poly_wrapper(a): 
    11141331                ring2 = a.parent() 
    1115             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular): 
     1332            elif is_sage_wrapper_for_singular_ring(a): 
    11161333                ring2 = a 
    1117             elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring): 
     1334            elif PY_TYPE_CHECK(a, int) or\ 
     1335                PY_TYPE_CHECK(a, long) or\ 
     1336                PY_TYPE_CHECK(a, basestring): 
    11181337                continue 
    11191338            elif PY_TYPE_CHECK(a, Matrix_integer_dense): 
    11201339                continue 
     
    11271346            elif PY_TYPE_CHECK(a, Resolution): 
    11281347                ring2 = (<Resolution> a).base_ring 
    11291348            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\ 
    1130                 and PY_TYPE_CHECK( 
    1131                     a.parent().base_ring(), 
    1132                      MPolynomialRing_libsingular): 
     1349                and is_sage_wrapper_for_singular_ring( 
     1350                    a.parent().base_ring()): 
    11331351                ring2 = a.parent().base_ring() 
    11341352            elif ring is not None: 
    11351353                a.parent() is ring 
     
    11411359                raise ValueError("Rings do not match up.") 
    11421360        if ring is None: 
    11431361            raise ValueError("Could not detect ring.") 
    1144         return <MPolynomialRing_libsingular>ring 
     1362        return ring 
    11451363 
    11461364    def __reduce__(self): 
    11471365        """ 
     
    11721390        else: 
    11731391            return cmp(self._name, (<SingularFunction>other)._name) 
    11741392 
    1175 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None): 
     1393cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None): 
    11761394    global currRingHdl 
    11771395    global errorreported 
    11781396    global currentVoice 
     
    11801398    global error_messages 
    11811399 
    11821400 
    1183     cdef ring *si_ring = R._ring 
     1401    cdef ring *si_ring 
     1402    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular): 
     1403        si_ring = (<MPolynomialRing_libsingular>R)._ring 
     1404    else: 
     1405        si_ring = (<NCPolynomialRing_plural>R)._ring 
    11841406 
    11851407    if si_ring != currRing: rChangeCurrRing(si_ring) 
    11861408 
     
    14211643        <Resolution> 
    14221644        sage: singular_list(resolution) 
    14231645        [[(-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)]] 
     1646 
     1647        sage: A.<x,y> = FreeAlgebra(QQ) 
     1648        sage: P.<x,y> = A.g_algebra({y*x:-x*y}) 
     1649        sage: I= Sequence([x*y,x+y], check=False, immutable=True) 
     1650        sage: twostd = singular_function("twostd") 
     1651        sage: twostd(I) 
     1652        [x + y, y^2] 
     1653        sage: M=syz(I) 
     1654        doctest... 
     1655        sage: M 
     1656        [(x + y, x*y)] 
     1657        sage: syz(M, ring=P) 
     1658        [(0)] 
     1659        sage: mres(I, 0) 
     1660        <Resolution> 
     1661        sage: M=P**3 
     1662        sage: v=M((100*x,5*y,10*y*x*y)) 
     1663        sage: leadcoef(v) 
     1664        -10 
     1665        sage: v = M([x+y,x*y+y**3,x]) 
     1666        sage: lead(v) 
     1667        (0, y^3) 
     1668        sage: jet(v, 2) 
     1669        (x + y, x*y, x) 
     1670        sage: l = ringlist(P) 
     1671        sage: len(l) 
     1672        6 
     1673        sage: ring(l, ring=P) 
     1674        <noncommutative RingWrap> 
     1675        sage: I=twostd(I) 
     1676        sage: l[3]=I 
     1677        sage: ring(l, ring=P) 
     1678        <noncommutative RingWrap> 
     1679 
    14241680    """ 
    14251681 
    14261682    cdef SingularFunction fnc 
     
    14911747                    ph = IDNEXT(ph) 
    14921748        h = IDNEXT(h) 
    14931749    return l 
     1750 
     1751 
     1752#cdef ring*? 
     1753cdef inline RingWrap new_RingWrap(ring* r): 
     1754    cdef RingWrap ring_wrap_result = PY_NEW(RingWrap) 
     1755    ring_wrap_result._ring = r 
     1756    ring_wrap_result._ring.ref += 1 
     1757     
     1758    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  
    148148        bint (*nGreaterZero)(number* a) 
    149149        void (*nPower)(number* a, int i, number* * result) 
    150150 
     151    # polynomials 
     152 
     153    ctypedef struct poly "polyrec": 
     154        poly *next 
     155 
     156    # ideals 
     157 
     158    ctypedef struct ideal "sip_sideal": 
     159        poly **m # gens array 
     160        long rank # rank of module, 1 for ideals 
     161        int nrows # always 1 
     162        int ncols # number of gens 
     163 
     164    # polynomial procs 
     165    ctypedef struct p_Procs_s "p_Procs_s": 
     166        pass 
    151167    # rings 
    152168 
    153169    ctypedef struct ring "ip_sring": 
     
    160176        int  CanShortOut # control printing capabilities 
    161177        number *minpoly # minpoly for base extension field 
    162178        char **names # variable names 
     179        p_Procs_s *p_Procs #polxnomial procs 
     180        ideal *qideal #quotient ideal 
     181         
    163182        char **parameter # parameter names 
    164183        ring *algring # base extension field 
    165184        short N # number of variables 
     
    198217        ringorder_Ws 
    199218        ringorder_L 
    200219 
    201     # polynomials 
    202220 
    203     ctypedef struct poly "polyrec": 
    204         poly *next 
    205221 
    206222    # groebner basis options 
    207223     
     
    962978 
    963979    cdef int LANG_TOP 
    964980 
     981# Non-commutative functions 
     982    ctypedef enum nc_type: 
     983      nc_error # Something's gone wrong! 
     984      nc_general # yx=q xy+...  
     985      nc_skew # yx=q xy  
     986      nc_comm # yx= xy  
     987      nc_lie,  # yx=xy+...  
     988      nc_undef, # for internal reasons */ 
     989      nc_exterior # 
     990 
     991   
     992cdef extern from "gring.h": 
     993    void ncRingType(ring *, nc_type) 
     994    nc_type ncRingType_get "ncRingType" (ring *) 
     995    int nc_CallPlural(matrix* CC, matrix* DD, poly* CN, poly* DN, ring* r) 
     996    bint nc_SetupQuotient(ring *, ring *, bint) 
     997     
     998cdef extern from "sca.h": 
     999    void sca_p_ProcsSet(ring *, p_Procs_s *) 
     1000    void scaFirstAltVar(ring *, int) 
     1001    void scaLastAltVar(ring *, int) 
     1002 
     1003cdef extern from "ring.h": 
     1004    bint rIsPluralRing(ring* r) 
     1005    void rPrint "rWrite"(ring* r) 
     1006    char* rOrderingString "rOrdStr"(ring* r) 
     1007#    void rDebugPrint(ring* r) 
     1008    void pDebugPrint "p_DebugPrint" (poly*p, ring* r) 
     1009     
    9651010cdef extern from "stairc.h": 
    9661011    # Computes the monomial basis for R[x]/I 
    9671012    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  
    187187from sage.structure.parent_gens import ParentWithGens 
    188188from sage.misc.cachefunc import cached_method 
    189189 
     190from warnings import warn 
     191 
    190192############################################################################### 
    191193# 
    192194# Constructor functions 
     
    317319        sage: FreeModule(ZZ,2,inner_product_matrix=[[1,2],[3,4]]).inner_product_matrix() 
    318320        [1 2] 
    319321        [3 4] 
     322 
     323    .. todo:: Refactor modules such that it only counts what category the base 
     324    ring belongs to, but not what is its Python class. 
     325 
    320326    """ 
    321327    def create_key(self, base_ring, rank, sparse=False, inner_product_matrix=None): 
    322328        """ 
     
    351357            raise TypeError, "Argument sparse (= %s) must be True or False" % sparse 
    352358 
    353359        if not (hasattr(base_ring,'is_commutative') and base_ring.is_commutative()): 
    354             raise TypeError, "The base_ring must be a commutative ring." 
    355  
    356         if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): 
    357             return RealDoubleVectorSpace_class(rank) 
    358  
    359         elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class): 
    360             return ComplexDoubleVectorSpace_class(rank) 
    361  
    362         elif base_ring.is_field(): 
    363             return FreeModule_ambient_field(base_ring, rank, sparse=sparse) 
    364  
    365         elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain): 
    366             return FreeModule_ambient_pid(base_ring, rank, sparse=sparse) 
    367  
    368         elif isinstance(base_ring, sage.rings.number_field.order.Order) \ 
    369             and base_ring.is_maximal() and base_ring.class_number() == 1: 
     360            warn("""You are constructing a free module 
     361over a noncommutative ring. Sage does not have a concept 
     362of left/right and both sided modules, so be careful. 
     363It's also not guaranteed that all multiplications are  
     364done from the right side.""") 
     365 
     366        #            raise TypeError, "The base_ring must be a commutative ring." 
     367 
     368        try: 
     369            if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class): 
     370                return RealDoubleVectorSpace_class(rank) 
     371 
     372            elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class): 
     373                return ComplexDoubleVectorSpace_class(rank) 
     374 
     375            elif base_ring.is_field(): 
     376                return FreeModule_ambient_field(base_ring, rank, sparse=sparse) 
     377 
     378            elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain): 
    370379                return FreeModule_ambient_pid(base_ring, rank, sparse=sparse) 
    371          
    372         elif isinstance(base_ring, integral_domain.IntegralDomain) or base_ring.is_integral_domain(): 
    373             return FreeModule_ambient_domain(base_ring, rank, sparse=sparse) 
    374              
    375         else: 
     380 
     381            elif isinstance(base_ring, sage.rings.number_field.order.Order) \ 
     382                and base_ring.is_maximal() and base_ring.class_number() == 1: 
     383                return FreeModule_ambient_pid(base_ring, rank, sparse=sparse) 
     384 
     385            elif isinstance(base_ring, integral_domain.IntegralDomain) or base_ring.is_integral_domain(): 
     386                return FreeModule_ambient_domain(base_ring, rank, sparse=sparse) 
     387 
     388            else: 
     389                return FreeModule_ambient(base_ring, rank, sparse=sparse) 
     390        except NotImplementedError: 
    376391            return FreeModule_ambient(base_ring, rank, sparse=sparse) 
    377392 
    378393 
     
    563578            Category of modules with basis over Integer Ring 
    564579 
    565580        """ 
    566         if not isinstance(base_ring, commutative_ring.CommutativeRing): 
    567             raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring 
     581        if not base_ring.is_commutative(): 
     582            warn("""You are constructing a free module 
     583over a noncommutative ring. Sage does not have a concept 
     584of left/right and both sided modules, so be careful. 
     585It's also not guaranteed that all multiplications are  
     586done from the right side.""") 
    568587        rank = sage.rings.integer.Integer(rank) 
    569588        if rank < 0: 
    570589            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  
    239239from sage.interfaces.expect import StdOutContext 
    240240 
    241241from sage.rings.ideal import Ideal_generic 
     242from sage.rings.noncommutative_ideals import Ideal_nc 
    242243from sage.rings.integer import Integer 
    243244from sage.structure.sequence import Sequence 
    244245 
     
    429430        sage: P.<a,b,c,d,e> = PolynomialRing(GF(127)) 
    430431        sage: J = sage.rings.ideal.Cyclic(P).homogenize() 
    431432        sage: from sage.misc.sageinspect import sage_getsource 
    432         sage: "buchberger" in sage_getsource(J.interreduced_basis) 
     433        sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest 
    433434        True 
    434435 
    435436    The following tests against a bug that was fixed in trac ticket #11298:: 
     
    645646        EXAMPLES:: 
    646647         
    647648            sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10) 
    648             sage: I = sage.rings.ideal.Cyclic(R,4) 
    649             sage: magma(I)                                          # optional - magma 
     649            sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest 
     650            sage: magma(I)    # optional - magma 
    650651            Ideal of Polynomial ring of rank 10 over GF(127) 
    651652            Order: Graded Reverse Lexicographical 
    652653            Variables: a, b, c, d, e, f, g, h, i, j 
     
    728729        B = PolynomialSequence([R(e) for e in mgb], R, immutable=True) 
    729730        return B 
    730731 
    731 class MPolynomialIdeal_singular_repr: 
     732class MPolynomialIdeal_singular_base_repr: 
     733    @require_field 
     734    def syzygy_module(self): 
     735        r""" 
     736        Computes the first syzygy (i.e., the module of relations of the 
     737        given generators) of the ideal. 
     738         
     739        EXAMPLE:: 
     740         
     741            sage: R.<x,y> = PolynomialRing(QQ) 
     742            sage: f = 2*x^2 + y 
     743            sage: g = y 
     744            sage: h = 2*f + g 
     745            sage: I = Ideal([f,g,h]) 
     746            sage: M = I.syzygy_module(); M 
     747            [       -2        -1         1] 
     748            [       -y 2*x^2 + y         0] 
     749            sage: G = vector(I.gens()) 
     750            sage: M*G 
     751            (0, 0) 
     752         
     753        ALGORITHM: Uses Singular's syz command 
     754        """ 
     755        import sage.libs.singular 
     756        syz = sage.libs.singular.ff.syz 
     757        from sage.matrix.constructor import matrix 
     758 
     759        #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
     760        S = syz(self) 
     761        return matrix(self.ring(), S) 
     762 
     763    @libsingular_standard_options 
     764    def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds): 
     765        """ 
     766        Return the reduced Groebner basis of this ideal. If the 
     767        Groebner basis for this ideal has been calculated before the 
     768        cached Groebner basis is returned regardless of the requested 
     769        algorithm. 
     770         
     771        INPUT: 
     772         
     773        -  ``algorithm`` - see below for available algorithms 
     774        - ``redsb`` - return a reduced Groebner basis (default: ``True``) 
     775        - ``red_tail`` - perform tail reduction (default: ``True``) 
     776 
     777        ALGORITHMS: 
     778         
     779        'groebner' 
     780            Singular's heuristic script (default) 
     781 
     782        'std' 
     783            Buchberger's algorithm 
     784         
     785        'slimgb' 
     786            the *SlimGB* algorithm 
     787 
     788        'stdhilb' 
     789            Hilbert Basis driven Groebner basis 
     790         
     791        'stdfglm' 
     792            Buchberger and FGLM 
     793         
     794        EXAMPLES: 
     795         
     796        We compute a Groebner basis of 'cyclic 4' relative to 
     797        lexicographic ordering. :: 
     798         
     799            sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
     800            sage: I = sage.rings.ideal.Cyclic(R,4); I 
     801            Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d 
     802            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
     803            Ring in a, b, c, d over Rational Field 
     804         
     805        :: 
     806         
     807            sage: I._groebner_basis_libsingular() 
     808            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
     809            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
     810            b^2 + 2*b*d + d^2, a + b + c + d] 
     811         
     812        ALGORITHM: 
     813 
     814        Uses libSINGULAR. 
     815        """ 
     816        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
     817        from sage.libs.singular import singular_function 
     818        from sage.libs.singular.option import opt 
     819 
     820        import sage.libs.singular 
     821        groebner = sage.libs.singular.ff.groebner 
     822 
     823        if get_verbose()>=2: 
     824            opt['prot'] = True 
     825        for name,value in kwds.iteritems(): 
     826            if value is not None: 
     827                opt[name] = value 
     828 
     829        T = self.ring().term_order() 
     830         
     831        if algorithm == "std": 
     832            S = std_libsingular(self) 
     833        elif algorithm == "slimgb": 
     834            S = slimgb_libsingular(self) 
     835        elif algorithm == "groebner": 
     836            S = groebner(self) 
     837        else: 
     838            try: 
     839                fnc = singular_function(algorithm) 
     840                S = fnc(self) 
     841            except NameError: 
     842                raise NameError("Algorithm '%s' unknown"%algorithm) 
     843        return S 
     844 
     845 
     846class MPolynomialIdeal_singular_repr( 
     847        MPolynomialIdeal_singular_base_repr): 
    732848    """ 
    733849    An ideal in a multivariate polynomial ring, which has an 
    734850    underlying Singular ring associated to it. 
     
    15211637            print "Highest degree reached during computation: %2d."%log_parser.max_deg 
    15221638        return S 
    15231639 
    1524     @libsingular_standard_options 
    1525     def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds): 
    1526         """ 
    1527         Return the reduced Groebner basis of this ideal. If the 
    1528         Groebner basis for this ideal has been calculated before the 
    1529         cached Groebner basis is returned regardless of the requested 
    1530         algorithm. 
    1531          
    1532         INPUT: 
    1533          
    1534         -  ``algorithm`` - see below for available algorithms 
    1535         - ``redsb`` - return a reduced Groebner basis (default: ``True``) 
    1536         - ``red_tail`` - perform tail reduction (default: ``True``) 
    1537  
    1538         ALGORITHMS: 
    1539          
    1540         'groebner' 
    1541             Singular's heuristic script (default) 
    1542  
    1543         'std' 
    1544             Buchberger's algorithm 
    1545          
    1546         'slimgb' 
    1547             the *SlimGB* algorithm 
    1548  
    1549         'stdhilb' 
    1550             Hilbert Basis driven Groebner basis 
    1551          
    1552         'stdfglm' 
    1553             Buchberger and FGLM 
    1554          
    1555         EXAMPLES: 
    1556          
    1557         We compute a Groebner basis of 'cyclic 4' relative to 
    1558         lexicographic ordering. :: 
    1559          
    1560             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex') 
    1561             sage: I = sage.rings.ideal.Cyclic(R,4); I 
    1562             Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d 
    1563             + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial 
    1564             Ring in a, b, c, d over Rational Field 
    1565          
    1566         :: 
    1567          
    1568             sage: I._groebner_basis_libsingular() 
    1569             [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d, 
    1570             b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2, 
    1571             b^2 + 2*b*d + d^2, a + b + c + d] 
    1572          
    1573         ALGORITHM: 
    1574  
    1575         Uses libSINGULAR. 
    1576         """ 
    1577         from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular 
    1578         from sage.libs.singular import singular_function 
    1579         from sage.libs.singular.option import opt 
    1580  
    1581         import sage.libs.singular 
    1582         groebner = sage.libs.singular.ff.groebner 
    1583  
    1584         if get_verbose()>=2: 
    1585             opt['prot'] = True 
    1586         for name,value in kwds.iteritems(): 
    1587             if value is not None: 
    1588                 opt[name] = value 
    1589  
    1590         T = self.ring().term_order() 
    1591          
    1592         if algorithm == "std": 
    1593             S = std_libsingular(self) 
    1594         elif algorithm == "slimgb": 
    1595             S = slimgb_libsingular(self) 
    1596         elif algorithm == "groebner": 
    1597             S = groebner(self) 
    1598         else: 
    1599             try: 
    1600                 fnc = singular_function(algorithm) 
    1601                 S = fnc(self) 
    1602             except NameError: 
    1603                 raise NameError("Algorithm '%s' unknown"%algorithm) 
    1604         return S 
    1605      
    16061640    @require_field 
    16071641    def genus(self): 
    16081642        """ 
     
    16631697            False 
    16641698        """ 
    16651699        R = self.ring() 
     1700 
    16661701        if not isinstance(other, MPolynomialIdeal_singular_repr) or other.ring() != R: 
    16671702            raise ValueError, "other must be an ideal in the ring of self, but it isn't." 
    16681703 
     
    25692604         
    25702605            sage: R.<x,y,z> = PolynomialRing(QQ) 
    25712606            sage: I = R.ideal(x^2-2*x*z+5, x*y^2+y*z+1, 3*y^2-8*x*z) 
    2572             sage: I.normal_basis() 
     2607            sage: I.normal_basis() #indirect doctest 
    25732608            [z^2, y*z, x*z, z, x*y, y, x, 1] 
    25742609        """ 
    25752610        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular 
     
    26252660    def _macaulay2_(self, macaulay2=None): 
    26262661        """ 
    26272662        Return Macaulay2 ideal corresponding to this ideal. 
     2663    EXAMPLES:: 
     2664     
     2665        sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4) 
     2666        sage: I = ideal(x*y-z^2, y^2-w^2)  #indirect doctest 
     2667        sage: macaulay2(I) # optional - macaulay2 
     2668        Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring 
    26282669        """ 
    26292670        if macaulay2 is None: macaulay2 = macaulay2_default 
    26302671        try: 
     
    27062747        R = self.ring() 
    27072748        return R(k) 
    27082749 
     2750class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc): 
     2751    def __init__(self, ring, gens, coerce=True, side = "left"): 
     2752        r""" 
     2753        Creates a non-commutative polynomial ideal. 
     2754 
     2755        INPUT: 
     2756 
     2757        - ``ring`` - the g-algebra to which this ideal belongs 
     2758        - ``gens`` - the generators of this ideal 
     2759        - ``coerce`` (optional - default True) - generators are 
     2760          coerced into the ring before creating the ideal 
     2761        - ``side`` - optional string, either "left" (default) 
     2762          or "twosided"; defines whether this ideal is left 
     2763          of two-sided. 
     2764         
     2765        EXAMPLES:: 
     2766         
     2767            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2768            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2769            sage: H.inject_variables() 
     2770            Defining x, y, z 
     2771            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) # indirect doctest 
     2772            sage: I 
     2773            Left Ideal (y^2, x^2, z^2 - 1) 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} 
     2774            sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="twosided") 
     2775            Twosided Ideal (y^2, x^2, z^2 - 1) 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} 
     2776            sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="right") 
     2777            Traceback (most recent call last): 
     2778            ... 
     2779            ValueError: Only left and two-sided ideals are allowed. 
     2780 
     2781        """ 
     2782        if side == "right": 
     2783            raise ValueError, "Only left and two-sided ideals are allowed."  
     2784        Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side) 
     2785 
     2786    def __call_singular(self, cmd, arg = None): 
     2787        """ 
     2788        Internal function for calling a Singular function. 
     2789 
     2790        INPUT: 
     2791 
     2792        - ``cmd`` - string, representing a Singular function 
     2793        - ``arg`` (Default: None) - arguments for which cmd is called 
     2794 
     2795        OUTPUT: 
     2796 
     2797        - result of the Singular function call 
     2798 
     2799        EXAMPLES:: 
     2800 
     2801            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2802            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2803            sage: H.inject_variables() 
     2804            Defining x, y, z 
     2805            sage: id = H.ideal(x + y, y + z) 
     2806            sage: id.std()  # indirect doctest 
     2807            Left 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} 
     2808        """ 
     2809        from sage.libs.singular.function import singular_function 
     2810        fun = singular_function(cmd) 
     2811        if arg is None: 
     2812             return fun(self, ring=self.ring()) 
     2813         
     2814        return fun(self, arg, ring=self.ring()) 
     2815 
     2816    @cached_method 
     2817    def std(self): 
     2818        r""" 
     2819        Computes a GB of the ideal. It is two-sided if and only if the ideal is two-sided. 
     2820         
     2821        EXAMPLES:: 
     2822         
     2823            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2824            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2825            sage: H.inject_variables() 
     2826            Defining x, y, z 
     2827            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2828            sage: I.std() 
     2829            Left 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, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x} 
     2830 
     2831        If the ideal is a left ideal, then std returns a left 
     2832        Groebner basis. But if it is a two-sided ideal, then 
     2833        the output of std and :meth:`twostd` coincide:: 
     2834 
     2835            sage: JL = H.ideal([x^3, y^3, z^3 - 4*z]) 
     2836            sage: JL 
     2837            Left Ideal (x^3, y^3, z^3 - 4*z) 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} 
     2838            sage: JL.std() 
     2839            Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) 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} 
     2840            sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided') 
     2841            sage: JT 
     2842            Twosided Ideal (x^3, y^3, z^3 - 4*z) 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} 
     2843            sage: JT.std() 
     2844            Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) 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} 
     2845            sage: JT.std() == JL.twostd() 
     2846            True 
     2847 
     2848        ALGORITHM: Uses Singular's std command 
     2849        """ 
     2850        if self.side()  == 'twosided': 
     2851            return self.twostd() 
     2852        return self.ring().ideal( self.__call_singular('std'), side=self.side()) 
     2853#        return self.__call_singular('std') 
     2854 
     2855    @cached_method 
     2856    def twostd(self): 
     2857        r""" 
     2858        Computes a two-sided GB of the ideal (even if it is a left ideal). 
     2859         
     2860        EXAMPLES:: 
     2861         
     2862            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2863            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2864            sage: H.inject_variables() 
     2865            Defining x, y, z 
     2866            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2867            sage: I.twostd() 
     2868            Twosided 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... 
     2869         
     2870        ALGORITHM: Uses Singular's twostd command 
     2871        """ 
     2872        return self.ring().ideal( self.__call_singular('twostd'), side='twosided') 
     2873#        return self.__call_singular('twostd') 
     2874 
     2875#    def syz(self): 
     2876#        return self.__call_singular('syz') 
     2877 
     2878    @require_field 
     2879    def syzygy_module(self): 
     2880        r""" 
     2881        Computes the first syzygy (i.e., the module of relations of the 
     2882        given generators) of the ideal. 
     2883 
     2884        NOTE: 
     2885 
     2886        Only left syzygies can be computed. So, even if the ideal is 
     2887        two-sided, then the syzygies are only one-sided. In that case, 
     2888        a warning is printed. 
     2889 
     2890        EXAMPLE:: 
     2891         
     2892            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2893            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2894            sage: H.inject_variables() 
     2895            Defining x, y, z 
     2896            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2897            sage: G = vector(I.gens()); G 
     2898            d...: UserWarning: You are constructing a free module 
     2899            over a noncommutative ring. Sage does not have a concept 
     2900            of left/right and both sided modules, so be careful. 
     2901            It's also not guaranteed that all multiplications are 
     2902            done from the right side. 
     2903            d...: UserWarning: You are constructing a free module 
     2904            over a noncommutative ring. Sage does not have a concept 
     2905            of left/right and both sided modules, so be careful. 
     2906            It's also not guaranteed that all multiplications are 
     2907            done from the right side. 
     2908            (y^2, x^2, z^2 - 1) 
     2909            sage: M = I.syzygy_module(); M 
     2910            [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2] 
     2911            [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2] 
     2912            [                                                              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] 
     2913            [                 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] 
     2914            [                                                              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] 
     2915            [  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] 
     2916            [                                                  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] 
     2917            [                                                  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] 
     2918            [                                                                           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] 
     2919            [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] 
     2920 
     2921            sage: M*G 
     2922            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) 
     2923         
     2924        ALGORITHM: Uses Singular's syz command 
     2925        """ 
     2926        if self.side() == 'twosided': 
     2927            warn("The result of this Syzygy computation is one-sided (left)!") 
     2928        import sage.libs.singular 
     2929        syz = sage.libs.singular.ff.syz 
     2930        from sage.matrix.constructor import matrix 
     2931 
     2932        #return self._singular_().syz().transpose().sage_matrix(self.ring()) 
     2933        S = syz(self) 
     2934        return matrix(self.ring(), S) 
     2935 
     2936 
     2937    def res(self, length): 
     2938        r""" 
     2939        Computes the resoltuion up to a given length of the ideal. 
     2940         
     2941        NOTE: 
     2942 
     2943        Only left syzygies can be computed. So, even if the ideal is 
     2944        two-sided, then the resolution is only one-sided. In that case, 
     2945        a warning is printed. 
     2946 
     2947        EXAMPLE:: 
     2948         
     2949            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2950            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     2951            sage: H.inject_variables() 
     2952            Defining x, y, z 
     2953            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) 
     2954            sage: I.res(3) 
     2955            <Resolution> 
     2956        """ 
     2957        if self.side() == 'twosided': 
     2958            warn("The resulting resolution is one-sided (left)!") 
     2959        return self.__call_singular('res', length) 
     2960 
    27092961 
    27102962class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \ 
    27112963                        MPolynomialIdeal_macaulay2_repr, \ 
  • 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 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'") 
    118132 
    119     r = (<MPolynomialRing_libsingular>R)._ring 
    120133    rChangeCurrRing(r); 
    121134 
    122135    i = idInit(len(gens),1) 
    123136    for j,f in enumerate(gens): 
    124         if not PY_TYPE_CHECK(f,MPolynomial_libsingular): 
     137        if PY_TYPE_CHECK(f,MPolynomial_libsingular): 
     138            i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r) 
     139        elif PY_TYPE_CHECK(f, NCPolynomial_plural): 
     140            i.m[j] = p_Copy((<NCPolynomial_plural>f)._poly, r) 
     141        else: 
    125142            id_Delete(&i, r) 
    126143            raise TypeError("All generators must be of type MPolynomial_libsingular.") 
    127         i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r) 
    128144    return i 
    129145 
    130146def kbase_libsingular(I): 
  • 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  
    21372137        EXAMPLES:: 
    21382138 
    21392139            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    2140             sage: 3/2*x + 1/2*y + 1 
     2140            sage: 3/2*x + 1/2*y + 1 #indirect doctest 
    21412141            3/2*x + 1/2*y + 1 
    21422142        """ 
    21432143        cdef ring *r = (<MPolynomial_libsingular>left)._parent_ring 
     
    21532153        EXAMPLES:: 
    21542154 
    21552155            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    2156             sage: 3/2*x - 1/2*y - 1 
     2156            sage: 3/2*x - 1/2*y - 1 #indirect doctest 
    21572157            3/2*x - 1/2*y - 1 
    21582158        """ 
    21592159        cdef ring *_ring = (<MPolynomial_libsingular>left)._parent_ring 
     
    21702170        EXAMPLES:: 
    21712171 
    21722172            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    2173             sage: 3/2*x 
     2173            sage: 3/2*x # indirect doctest 
    21742174            3/2*x 
    21752175        """ 
    21762176 
     
    21822182        return new_MP((<MPolynomial_libsingular>self)._parent, _p) 
    21832183         
    21842184    cpdef ModuleElement _lmul_(self, RingElement right): 
    2185         # all currently implemented rings are commutative 
     2185        """ 
     2186        Multiply left and right. 
     2187 
     2188        EXAMPLES:: 
     2189 
     2190            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
     2191            sage: (3/2*x - 1/2*y - 1) * (3/2) # indirect doctest 
     2192            9/4*x - 3/4*y - 3/2 
     2193        """ 
     2194        # Note that the argument to _rmul_ and _lmul_ is an 
     2195        # element of the base ring. 
     2196        # All currently implemented base rings are commutative, 
     2197        # So, calling _rmul_ is the correct thing to do. 
    21862198        return self._rmul_(right) 
    21872199         
    21882200    cpdef RingElement _mul_(left, RingElement right): 
     
    21922204        EXAMPLES:: 
    21932205 
    21942206            sage: P.<x,y,z>=PolynomialRing(QQ,3) 
    2195             sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) 
     2207            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest 
    21962208            9/4*x^2 - 1/4*y^2 - y - 1 
    21972209 
    21982210            sage: P.<x,y> = PolynomialRing(QQ,order='lex') 
     
    22152227        EXAMPLES:: 
    22162228 
    22172229            sage: R.<x,y>=PolynomialRing(QQ,2) 
    2218             sage: f = (x + y)/3 
     2230            sage: f = (x + y)/3 # indirect doctest 
    22192231            sage: f.parent() 
    22202232            Multivariate Polynomial Ring in x, y over Rational Field 
    22212233 
     
    23922404 
    23932405            sage: P.<x,y,z> = QQ[] 
    23942406            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
    2395             sage: latex(f) 
     2407            sage: latex(f)  # indirect doctest 
    23962408            - x^{2} y - \frac{25}{27} y^{3} - z^{2} 
    23972409        """ 
    23982410        cdef ring *_ring = self._parent_ring 
     
    43664378        EXAMPLES:: 
    43674379 
    43684380            sage: R.<x,y> = PolynomialRing(GF(7), 2) 
    4369             sage: f = (x^3 + 2*y^2*x)^7; f 
     4381            sage: f = (x^3 + 2*y^2*x)^7; f          # indirect doctest 
    43704382            x^21 + 2*x^7*y^14 
    43714383 
    43724384            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 
     140from sage.categories.algebras import Algebras 
     141from sage.rings.ring import check_default_category 
     142 
     143cdef class NCPolynomialRing_plural(Ring): 
     144    """ 
     145    A non-commutative polynomial ring. 
     146 
     147    EXAMPLES:: 
     148 
     149        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     150        sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y}) 
     151        sage: H._is_category_initialized() 
     152        True 
     153        sage: H.catego 
     154        H.categories  H.category 
     155        sage: H.category() 
     156        Category of algebras over Rational Field 
     157 
     158    """ 
     159    def __init__(self, base_ring, n, names, c, d, order='degrevlex',  
     160                 check = True, category=None): 
     161        """ 
     162        Construct a noncommutative polynomial G-algebra subject to the following conditions: 
     163 
     164        INPUT: 
     165 
     166        - ``base_ring`` - base ring (must be either GF(q), ZZ, ZZ/nZZ, 
     167                          QQ or absolute number field) 
     168        - ``n`` - number of variables (must be at least 1) 
     169        - ``names`` - names of ring variables, may be string of list/tupl 
     170        - ``c``, ``d``- upper triangular matrices of coefficients, 
     171          resp. commutative polynomials, satisfying the nondegeneracy 
     172          conditions, which are to be tested if check == True. These 
     173          matrices describe the noncommutative relations:       
     174 
     175            ``self.gen(j)*self.gen(i) == c[i, j] * self.gen(i)*self.gen(j) + d[i, j],`` 
     176 
     177          where ``0 <= i < j < self.ngens()``. 
     178        - ``order`` - term order (default: ``degrevlex``) 
     179        - ``check`` - check the noncommutative conditions (default: ``True``) 
     180        - ``category`` - optional category. The resulting ring 
     181          will belong to that category and to the category of 
     182          algebras over the base ring. 
     183 
     184        EXAMPLES:: 
     185 
     186            sage: from sage.matrix.constructor  import Matrix 
     187            sage: c = Matrix(3) 
     188            sage: c[0,1] = -1 
     189            sage: c[0,2] = 1 
     190            sage: c[1,2] = 1 
     191 
     192            sage: d = Matrix(3) 
     193            sage: d[0, 1] = 17 
     194 
     195            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     196            sage: P.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex') 
     197 
     198            sage: P # indirect doctest  
     199            Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y + 17} 
     200 
     201            sage: P(x*y) 
     202            x*y 
     203 
     204            sage: f = 27/113 * x^2 + y*z + 1/2; f 
     205            27/113*x^2 + y*z + 1/2 
     206 
     207            sage: P.term_order() 
     208            Lexicographic term order 
     209 
     210            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     211            sage: P.<x,y,z> = NCPolynomialRing_plural(GF(7), 3, c = c, d = d, order='degrevlex') 
     212 
     213            sage: P # indirect doctest  
     214            Noncommutative Multivariate Polynomial Ring in x, y, z over Finite Field of size 7, nc-relations: {y*x: -x*y + 3} 
     215 
     216            sage: P(x*y) 
     217            x*y 
     218 
     219            sage: f = 3 * x^2 + y*z + 5; f 
     220            3*x^2 + y*z - 2 
     221 
     222            sage: P.term_order() 
     223            Degree reverse lexicographic term order 
     224 
     225        """ 
     226 
     227        self._relations = None 
     228        n = int(n) 
     229        if n < 0: 
     230            raise ValueError, "Multivariate Polynomial Rings must " + \ 
     231                  "have more than 0 variables." 
     232 
     233        from sage.rings.polynomial.polynomial_ring_constructor import PolynomialRing 
     234 
     235        order = TermOrder(order,n) 
     236        P = PolynomialRing(base_ring, n, names, order=order) 
     237         
     238        self._c = c.change_ring(P) 
     239        self._d = d.change_ring(P) 
     240 
     241        from sage.libs.singular.function import singular_function 
     242        ncalgebra = singular_function('nc_algebra') 
     243 
     244        cdef RingWrap rw = ncalgebra(self._c, self._d, ring = P) 
     245 
     246        #       rw._output() 
     247        self._ring = rw._ring 
     248        self._ring.ShortOut = 0 
     249 
     250        self.__ngens = n 
     251        self.__term_order = order 
     252 
     253        Ring.__init__(self, base_ring, names,  
     254                      category=check_default_category(Algebras(base_ring),category)) 
     255        self._populate_coercion_lists_() 
     256         
     257        #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     258        #self._has_singular = True 
     259        assert(n == len(self._names)) 
     260         
     261        self._one_element = new_NCP(self, p_ISet(1, self._ring)) 
     262        self._zero_element = new_NCP(self, NULL) 
     263         
     264 
     265        if check: 
     266            import sage.libs.singular 
     267            test = sage.libs.singular.ff.nctools__lib.ndcond(ring = self) 
     268            if (len(test) != 1) or (test[0] != 0): 
     269                raise ValueError, "NDC check failed!" 
     270 
     271    def __dealloc__(self): 
     272        r""" 
     273        Carefully deallocate the ring, without changing "currRing" 
     274        (since this method can be at unpredictable times due to garbage 
     275        collection). 
     276 
     277        TESTS: 
     278        This example caused a segmentation fault with a previous version 
     279        of this method: 
     280            sage: import gc 
     281            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     282            sage: from sage.algebras.free_algebra import FreeAlgebra 
     283            sage: A1.<x,y,z> = FreeAlgebra(QQ, 3) 
     284            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)) 
     285            sage: A2.<x,y,z> = FreeAlgebra(GF(5), 3) 
     286            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)) 
     287            sage: A3.<x,y,z> = FreeAlgebra(GF(11), 3) 
     288            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)) 
     289            sage: A4.<x,y,z> = FreeAlgebra(GF(13), 3) 
     290            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)) 
     291            sage: _ = gc.collect() 
     292            sage: foo = R1.gen(0) 
     293            sage: del foo 
     294            sage: del R1 
     295            sage: _ = gc.collect() 
     296            sage: del R2 
     297            sage: _ = gc.collect() 
     298            sage: del R3 
     299            sage: _ = gc.collect() 
     300        """ 
     301        singular_ring_delete(self._ring) 
     302     
     303    def _element_constructor_(self, element): 
     304        """ 
     305        Make sure element is a valid member of self, and return the constructed element.  
     306 
     307        EXAMPLES:: 
     308            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     309 
     310            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     311 
     312        We can construct elements from the base ring:: 
     313 
     314            sage: P(1/2) 
     315            1/2 
     316             
     317 
     318        and all kinds of integers:: 
     319 
     320            sage: P(17) 
     321            17 
     322 
     323            sage: P(int(19)) 
     324            19 
     325 
     326            sage: P(long(19)) 
     327            19 
     328             
     329        TESTS:: 
     330 
     331        Check conversion from self:: 
     332            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     333            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     334            sage: P.inject_variables() 
     335            Defining x, y, z 
     336 
     337            sage: P._element_constructor_(1/2) 
     338            1/2 
     339 
     340            sage: P._element_constructor_(x*y) 
     341            x*y 
     342 
     343            sage: P._element_constructor_(y*x) 
     344            -x*y          
     345 
     346        Raw use of this class:: 
     347            sage: from sage.matrix.constructor  import Matrix 
     348            sage: c = Matrix(3) 
     349            sage: c[0,1] = -2 
     350            sage: c[0,2] = 1 
     351            sage: c[1,2] = 1 
     352 
     353            sage: d = Matrix(3) 
     354            sage: d[0, 1] = 17 
     355 
     356            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     357            sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = d, order='lex') 
     358            sage: R._element_constructor_(x*y) 
     359            x*y 
     360             
     361            sage: P._element_constructor_(17) 
     362            17 
     363 
     364            sage: P._element_constructor_(int(19)) 
     365            19 
     366 
     367        Testing special cases:: 
     368            sage: P._element_constructor_(1) 
     369            1 
     370 
     371            sage: P._element_constructor_(0) 
     372            0 
     373        """ 
     374 
     375        if element == 0: 
     376            return self._zero_element 
     377        if element == 1: 
     378            return self._one_element 
     379 
     380        cdef poly *_p 
     381        cdef ring *_ring, 
     382        cdef number *_n  
     383        
     384        _ring = self._ring 
     385        
     386        base_ring = self.base_ring() 
     387 
     388        if(_ring != currRing): rChangeCurrRing(_ring) 
     389 
     390 
     391        if PY_TYPE_CHECK(element, NCPolynomial_plural): 
     392 
     393            if element.parent() is <object>self: 
     394                return element 
     395            elif element.parent() == self: 
     396                # is this safe? 
     397                _p = p_Copy((<NCPolynomial_plural>element)._poly, _ring) 
     398 
     399        elif PY_TYPE_CHECK(element, CommutativeRingElement): 
     400            # base ring elements 
     401            if  <Parent>element.parent() is base_ring: 
     402                # shortcut for GF(p) 
     403                if isinstance(base_ring, FiniteField_prime_modn): 
     404                    _p = p_ISet(int(element) % _ring.ch, _ring) 
     405                else:  
     406                    _n = sa2si(element,_ring) 
     407                    _p = p_NSet(_n, _ring) 
     408                     
     409            # also accepting ZZ 
     410            elif is_IntegerRing(element.parent()): 
     411                if isinstance(base_ring, FiniteField_prime_modn): 
     412                    _p = p_ISet(int(element),_ring) 
     413                else: 
     414                    _n = sa2si(base_ring(element),_ring) 
     415                    _p = p_NSet(_n, _ring) 
     416            else: 
     417                # fall back to base ring 
     418                element = base_ring._coerce_c(element) 
     419                _n = sa2si(element,_ring) 
     420                _p = p_NSet(_n, _ring) 
     421 
     422        # Accepting int 
     423        elif PY_TYPE_CHECK(element, int): 
     424            if isinstance(base_ring, FiniteField_prime_modn): 
     425                _p = p_ISet(int(element) % _ring.ch,_ring) 
     426            else: 
     427                _n = sa2si(base_ring(element),_ring) 
     428                _p = p_NSet(_n, _ring) 
     429                 
     430        # and longs 
     431        elif PY_TYPE_CHECK(element, long): 
     432            if isinstance(base_ring, FiniteField_prime_modn): 
     433                element = element % self.base_ring().characteristic() 
     434                _p = p_ISet(int(element),_ring) 
     435            else: 
     436                _n = sa2si(base_ring(element),_ring) 
     437                _p = p_NSet(_n, _ring) 
     438 
     439        else: 
     440            raise NotImplementedError("not able to constructor "+repr(element) + 
     441                                      " of type "+ repr(type(element))) #### ?????? 
     442 
     443 
     444        return new_NCP(self,_p) 
     445 
     446 
     447         
     448    cpdef _coerce_map_from_(self, S): 
     449       """ 
     450       The only things that coerce into this ring are: 
     451           - the integer ring 
     452           - other localizations away from fewer primes 
     453 
     454         EXAMPLES:: 
     455           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     456           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     457 
     458           sage: P._coerce_map_from_(ZZ) 
     459           True 
     460       """ 
     461 
     462       if self.base_ring().has_coerce_map_from(S): 
     463           return True 
     464        
     465        
     466        
     467    def __hash__(self): 
     468       """ 
     469       Return a hash for this noncommutative ring, that is, a hash of the string 
     470       representation of this polynomial ring. 
     471 
     472       EXAMPLES:: 
     473           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     474           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     475           sage: hash(P)      # somewhat random output 
     476           ... 
     477 
     478       TESTS:: 
     479 
     480       Check conversion from self:: 
     481           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     482           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     483           sage: from sage.matrix.constructor  import Matrix 
     484           sage: c = Matrix(3) 
     485           sage: c[0,1] = -1 
     486           sage: c[0,2] = 1 
     487           sage: c[1,2] = 1 
     488 
     489           sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     490           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     491           sage: hash(R) == hash(P) 
     492           True 
     493       """ 
     494       return hash(str(self.__repr__()) + str(self.term_order()) ) 
     495 
     496 
     497    def __cmp__(self, right): 
     498        r""" 
     499        Non-commutative polynomial rings are said to be equal if: 
     500         
     501        - their base rings match, 
     502        - their generator names match, 
     503        - their term orderings match, and 
     504        - their relations match. 
     505 
     506        EXAMPLES:: 
     507 
     508           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     509           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     510 
     511           sage: P == P 
     512           True 
     513           sage: Q = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     514           sage: Q == P 
     515           True 
     516                      
     517           sage: from sage.matrix.constructor  import Matrix 
     518           sage: c = Matrix(3) 
     519           sage: c[0,1] = -1 
     520           sage: c[0,2] = 1 
     521           sage: c[1,2] = 1 
     522           sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     523           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     524           sage: R == P 
     525           True 
     526            
     527           sage: c[0,1] = -2 
     528           sage: R.<x,y,z> = NCPolynomialRing_plural(QQ, 3, c = c, d = Matrix(3), order='lex') 
     529           sage: P == R 
     530           False 
     531        """ 
     532 
     533        if PY_TYPE_CHECK(right, NCPolynomialRing_plural): 
     534 
     535            return cmp( (self.base_ring(), map(str, self.gens()), 
     536                         self.term_order(), self._c, self._d), 
     537                        (right.base_ring(), map(str, right.gens()), 
     538                         right.term_order(), 
     539                         (<NCPolynomialRing_plural>right)._c, 
     540                         (<NCPolynomialRing_plural>right)._d) 
     541                        ) 
     542        else: 
     543            return cmp(type(self),type(right)) 
     544 
     545    def __pow__(self, n, _): 
     546        """ 
     547        Return the free module of rank `n` over this ring. 
     548 
     549        EXAMPLES:: 
     550            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     551            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     552            sage: P.inject_variables() 
     553            Defining x, y, z 
     554 
     555            sage: f = x^3 + y 
     556            sage: f^2 
     557            x^6 + y^2         
     558        """ 
     559        import sage.modules.all  
     560        return sage.modules.all.FreeModule(self, n) 
     561     
     562    def term_order(self): 
     563        """ 
     564        Return the term ordering of the noncommutative ring. 
     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.term_order() 
     571        Lexicographic term order 
     572 
     573        sage: P = A.g_algebra(relations={y*x:-x*y}) 
     574        sage: P.term_order() 
     575        Degree reverse lexicographic term order 
     576        """ 
     577        return self.__term_order 
     578 
     579    def is_commutative(self): 
     580        """ 
     581        Return False. 
     582 
     583        EXAMPLES:: 
     584         
     585        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     586        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     587        sage: P.is_commutative() 
     588        False 
     589        """ 
     590        return False 
     591     
     592    def is_field(self): 
     593        """ 
     594        Return False. 
     595 
     596        EXAMPLES:: 
     597         
     598        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     599        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     600        sage: P.is_field() 
     601        False 
     602        """     
     603        return False 
     604     
     605    def _repr_(self): 
     606        """ 
     607        EXAMPLE: 
     608            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     609            sage: from sage.matrix.constructor  import Matrix 
     610            sage: c=Matrix(2) 
     611            sage: c[0,1]=-1 
     612            sage: P.<x,y> = NCPolynomialRing_plural(QQ, 2, c=c, d=Matrix(2)) 
     613            sage: P # indirect doctest 
     614            Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: {y*x: -x*y} 
     615            sage: x*y 
     616            x*y 
     617            sage: y*x 
     618            -x*y 
     619        """ 
     620#TODO: print the relations 
     621        varstr = ", ".join([ rRingVar(i,self._ring)  for i in range(self.__ngens) ]) 
     622        return "Noncommutative Multivariate Polynomial Ring in %s over %s, nc-relations: %s"%(varstr,self.base_ring(), self.relations()) 
     623 
     624 
     625    def _ringlist(self): 
     626        """ 
     627        Return an internal list representation of the noncummutative ring. 
     628 
     629        EXAMPLES:: 
     630        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     631        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     632        sage: P._ringlist() 
     633        [0, ['x', 'y', 'z'], [['lp', (1, 1, 1)], ['C', (0,)]], [0], [ 0 -1  1] 
     634        [ 0  0  1] 
     635        [ 0  0  0], [0 0 0] 
     636        [0 0 0] 
     637        [0 0 0]] 
     638        """ 
     639        cdef ring* _ring = self._ring 
     640        if(_ring != currRing): rChangeCurrRing(_ring) 
     641        from sage.libs.singular.function import singular_function 
     642        ringlist = singular_function('ringlist') 
     643        result = ringlist(self, ring=self) 
     644        
     645 
     646 
     647 
     648        return result 
     649         
     650 
     651    def relations(self, add_commutative = False): 
     652        """ 
     653        EXAMPLE:: 
     654 
     655            sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural 
     656            sage: from sage.matrix.constructor  import Matrix 
     657            sage: c=Matrix(2) 
     658            sage: c[0,1]=-1 
     659            sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2)) 
     660            sage: P # indirect doctest 
     661            Noncommutative Multivariate Polynomial Ring in x, y over Rational Field, nc-relations: ... 
     662        """ 
     663        if self._relations is not None: 
     664            return self._relations 
     665 
     666        from sage.algebras.free_algebra import FreeAlgebra 
     667        A = FreeAlgebra( self.base_ring(), self.ngens(), self.gens() ) 
     668 
     669        res = {} 
     670        n = self.ngens() 
     671        for r in range(0, n-1, 1): 
     672            for c in range(r+1, n, 1): 
     673                if  (self.gen(c) * self.gen(r) != self.gen(r) * self.gen(c)) or add_commutative: 
     674                    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] 
     675         
     676             
     677        self._relations = res 
     678        return self._relations 
     679 
     680    def ngens(self): 
     681        """ 
     682        Returns the number of variables in this noncommutative polynomial ring. 
     683 
     684        EXAMPLES:: 
     685 
     686            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     687            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     688            sage: P.inject_variables() 
     689            Defining x, y, z 
     690 
     691            sage: P.ngens() 
     692            3 
     693        """ 
     694        return int(self.__ngens) 
     695 
     696    def gen(self, int n=0): 
     697        """ 
     698        Returns the ``n``-th generator of this noncommutative polynomial 
     699        ring. 
     700 
     701        INPUT: 
     702 
     703        - ``n`` -- an integer ``>= 0`` 
     704 
     705        EXAMPLES:: 
     706 
     707            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     708            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     709            sage: P.gen(),P.gen(1) 
     710            (x, y)           
     711 
     712            sage: P.gen(1) 
     713            y 
     714        """ 
     715        cdef poly *_p 
     716        cdef ring *_ring = self._ring 
     717 
     718        if n < 0 or n >= self.__ngens: 
     719            raise ValueError, "Generator not defined." 
     720 
     721        rChangeCurrRing(_ring) 
     722        _p = p_ISet(1,_ring) 
     723        p_SetExp(_p, n+1, 1, _ring) 
     724        p_Setm(_p, _ring); 
     725 
     726        return new_NCP(self,_p) 
     727 
     728    def ideal(self, *gens, **kwds): 
     729        """ 
     730        Create an ideal in this polynomial ring. 
     731 
     732        INPUT: 
     733  
     734        - ``*gens`` - list or tuple of generators (or several input arguments) 
     735 
     736        - ``coerce`` - bool (default: ``True``); this must be a 
     737          keyword argument. Only set it to ``False`` if you are certain 
     738          that each generator is already in the ring. 
     739 
     740        EXAMPLES:: 
     741            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     742            sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     743            sage: P.inject_variables() 
     744            Defining x, y, z 
     745             
     746            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]) 
     747            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} 
     748        """ 
     749        from sage.rings.polynomial.multi_polynomial_ideal import \ 
     750                NCPolynomialIdeal 
     751        coerce = kwds.get('coerce', True) 
     752        if len(gens) == 1: 
     753            gens = gens[0] 
     754        #if is_SingularElement(gens): 
     755        #    gens = list(gens) 
     756        #    coerce = True 
     757        #elif is_Macaulay2Element(gens): 
     758        #    gens = list(gens) 
     759        #    coerce = True 
     760        if not isinstance(gens, (list, tuple)): 
     761            gens = [gens] 
     762        if coerce: 
     763            gens = [self(x) for x in gens]  # this will even coerce from singular ideals correctly! 
     764        return NCPolynomialIdeal(self, gens, coerce=False, side=kwds.get('side','left')) 
     765 
     766    def _list_to_ring(self, L): 
     767        """ 
     768        Convert internal list representation to  noncommutative ring. 
     769 
     770        EXAMPLES:: 
     771 
     772           sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     773           sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     774           sage: rlist = P._ringlist(); 
     775           sage: Q = P._list_to_ring(rlist) 
     776           sage: Q # indirect doctest 
     777           <noncommutative RingWrap> 
     778        """ 
     779 
     780        cdef ring* _ring = self._ring 
     781        if(_ring != currRing): rChangeCurrRing(_ring) 
     782         
     783        from sage.libs.singular.function import singular_function 
     784        ring = singular_function('ring') 
     785        return ring(L, ring=self) 
     786 
     787    def quotient(self, I): 
     788        """ 
     789        Construct quotient ring of ``self`` and the two-sided Groebner basis of `ideal` 
     790 
     791        EXAMPLE:: 
     792 
     793        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     794        sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     795        sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd() 
     796 
     797        sage: Q = H.quotient(I); Q 
     798        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     799 
     800        TESTS:: 
     801 
     802        check coercion bug:: 
     803        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)       
     804        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex') 
     805        sage: rlist = P._ringlist(); 
     806        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     807        sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     808        sage: I = H.ideal([H.gen(i) ^2 for i in [0, 1]]).twostd() 
     809        sage: Q = H.quotient(I); Q 
     810        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     811        sage: Q.gen(0)^2 
     812        0 
     813        sage: Q.gen(1) * Q.gen(0) 
     814        -x*y 
     815        """ 
     816        L = self._ringlist() 
     817        L[3] = I.twostd() 
     818        W = self._list_to_ring(L) 
     819        return new_NRing(W, self.base_ring()) 
     820 
     821 
     822    ### The following methods are handy for implementing Groebner 
     823    ### basis algorithms. They do only superficial type/sanity checks 
     824    ### and should be called carefully. 
     825 
     826    def monomial_quotient(self, NCPolynomial_plural f, NCPolynomial_plural g, coeff=False): 
     827        r""" 
     828        Return ``f/g``, where both ``f`` and`` ``g`` are treated as 
     829        monomials.  
     830 
     831        Coefficients are ignored by default. 
     832 
     833        INPUT: 
     834 
     835        - ``f`` - monomial 
     836        - ``g`` - monomial 
     837        - ``coeff`` - divide coefficients as well (default: ``False``) 
     838 
     839        EXAMPLES:: 
     840 
     841            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     842            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     843            sage: P.inject_variables() 
     844            Defining x, y, z 
     845 
     846            sage: P.monomial_quotient(3/2*x*y,x,coeff=True) 
     847            3/2*y 
     848 
     849        Note, that `\ZZ` behaves different if ``coeff=True``:: 
     850 
     851            sage: P.monomial_quotient(2*x,3*x) 
     852            1 
     853            sage: P.monomial_quotient(2*x,3*x,coeff=True) 
     854            2/3 
     855 
     856        TESTS:: 
     857            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     858            sage: R = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     859            sage: R.inject_variables() 
     860            Defining x, y, z 
     861         
     862            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     863            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     864            sage: P.inject_variables() 
     865            Defining x, y, z 
     866             
     867            sage: P.monomial_quotient(x*y,x) 
     868            y 
     869 
     870##             sage: P.monomial_quotient(x*y,R.gen()) 
     871##             y 
     872 
     873            sage: P.monomial_quotient(P(0),P(1)) 
     874            0 
     875 
     876            sage: P.monomial_quotient(P(1),P(0)) 
     877            Traceback (most recent call last): 
     878            ... 
     879            ZeroDivisionError 
     880 
     881            sage: P.monomial_quotient(P(3/2),P(2/3), coeff=True) 
     882            9/4 
     883 
     884            sage: P.monomial_quotient(x,P(1)) 
     885            x 
     886 
     887        TESTS:: 
     888 
     889            sage: P.monomial_quotient(x,y) # Note the wrong result 
     890            x*y^...  
     891 
     892        .. warning:: 
     893 
     894           Assumes that the head term of f is a multiple of the head 
     895           term of g and return the multiplicant m. If this rule is 
     896           violated, funny things may happen. 
     897        """ 
     898        cdef poly *res 
     899        cdef ring *r = self._ring 
     900        cdef number *n, *denom 
     901         
     902        if not <ParentWithBase>self is f._parent: 
     903            f = self._coerce_c(f) 
     904        if not <ParentWithBase>self is g._parent: 
     905            g = self._coerce_c(g) 
     906 
     907        if(r != currRing): rChangeCurrRing(r) 
     908 
     909        if not f._poly: 
     910            return self._zero_element 
     911        if not g._poly: 
     912            raise ZeroDivisionError 
     913 
     914        res = pDivide(f._poly,g._poly) 
     915        if coeff: 
     916            if r.ringtype == 0 or r.cf.nDivBy(p_GetCoeff(f._poly, r), p_GetCoeff(g._poly, r)): 
     917                n = r.cf.nDiv( p_GetCoeff(f._poly, r) , p_GetCoeff(g._poly, r)) 
     918                p_SetCoeff0(res, n, r) 
     919            else: 
     920                raise ArithmeticError("Cannot divide these coefficients.") 
     921        else: 
     922            p_SetCoeff0(res, n_Init(1, r), r) 
     923        return new_NCP(self, res) 
     924     
     925    def monomial_divides(self, NCPolynomial_plural a, NCPolynomial_plural b): 
     926        """ 
     927        Return ``False`` if a does not divide b and ``True`` 
     928        otherwise.  
     929 
     930        Coefficients are ignored. 
     931         
     932        INPUT: 
     933 
     934        - ``a`` -- monomial 
     935 
     936        - ``b`` -- monomial 
     937 
     938        EXAMPLES:: 
     939 
     940            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     941            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     942            sage: P.inject_variables() 
     943            Defining x, y, z 
     944 
     945            sage: P.monomial_divides(x*y*z, x^3*y^2*z^4) 
     946            True 
     947            sage: P.monomial_divides(x^3*y^2*z^4, x*y*z) 
     948            False 
     949 
     950        TESTS:: 
     951            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     952            sage: Q = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     953            sage: Q.inject_variables() 
     954            Defining x, y, z 
     955             
     956            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     957            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     958            sage: P.inject_variables() 
     959            Defining x, y, z 
     960             
     961            sage: P.monomial_divides(P(1), P(0)) 
     962            True 
     963            sage: P.monomial_divides(P(1), x) 
     964            True 
     965        """ 
     966        cdef poly *_a 
     967        cdef poly *_b 
     968        cdef ring *_r 
     969        if a._parent is not b._parent: 
     970            b = (<NCPolynomialRing_plural>a._parent)._coerce_c(b) 
     971 
     972        _a = a._poly 
     973        _b = b._poly 
     974        _r = (<NCPolynomialRing_plural>a._parent)._ring 
     975 
     976        if _a == NULL: 
     977            raise ZeroDivisionError 
     978        if _b == NULL: 
     979            return True 
     980         
     981        if not p_DivisibleBy(_a, _b, _r): 
     982            return False 
     983        else: 
     984            return True 
     985 
     986 
     987    def monomial_lcm(self, NCPolynomial_plural f, NCPolynomial_plural g): 
     988        """ 
     989        LCM for monomials. Coefficients are ignored. 
     990         
     991        INPUT: 
     992 
     993        - ``f`` - monomial 
     994         
     995        - ``g`` - monomial 
     996 
     997        EXAMPLES:: 
     998 
     999            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1000            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1001            sage: P.inject_variables() 
     1002            Defining x, y, z 
     1003             
     1004            sage: P.monomial_lcm(3/2*x*y,x) 
     1005            x*y 
     1006 
     1007        TESTS:: 
     1008 
     1009            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1010            sage: R = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1011            sage: R.inject_variables() 
     1012            Defining x, y, z 
     1013             
     1014            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1015            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1016            sage: P.inject_variables() 
     1017            Defining x, y, z 
     1018             
     1019##             sage: P.monomial_lcm(x*y,R.gen()) 
     1020##             x*y 
     1021 
     1022            sage: P.monomial_lcm(P(3/2),P(2/3)) 
     1023            1 
     1024 
     1025            sage: P.monomial_lcm(x,P(1)) 
     1026            x 
     1027        """ 
     1028        cdef poly *m = p_ISet(1,self._ring) 
     1029         
     1030        if not <ParentWithBase>self is f._parent: 
     1031            f = self._coerce_c(f) 
     1032        if not <ParentWithBase>self is g._parent: 
     1033            g = self._coerce_c(g) 
     1034 
     1035        if f._poly == NULL: 
     1036            if g._poly == NULL: 
     1037                return self._zero_element 
     1038            else: 
     1039                raise ArithmeticError, "Cannot compute LCM of zero and nonzero element." 
     1040        if g._poly == NULL: 
     1041            raise ArithmeticError, "Cannot compute LCM of zero and nonzero element." 
     1042 
     1043        if(self._ring != currRing): rChangeCurrRing(self._ring) 
     1044         
     1045        pLcm(f._poly, g._poly, m) 
     1046        p_Setm(m, self._ring) 
     1047        return new_NCP(self,m) 
     1048         
     1049    def monomial_reduce(self, NCPolynomial_plural f, G): 
     1050        """ 
     1051        Try to find a ``g`` in ``G`` where ``g.lm()`` divides 
     1052        ``f``. If found ``(flt,g)`` is returned, ``(0,0)`` otherwise, 
     1053        where ``flt`` is ``f/g.lm()``. 
     1054 
     1055        It is assumed that ``G`` is iterable and contains *only* 
     1056        elements in this polynomial ring. 
     1057 
     1058        Coefficients are ignored. 
     1059         
     1060        INPUT: 
     1061 
     1062        - ``f`` - monomial 
     1063        - ``G`` - list/set of mpolynomials 
     1064             
     1065        EXAMPLES:: 
     1066 
     1067            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1068            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1069            sage: P.inject_variables() 
     1070            Defining x, y, z 
     1071 
     1072            sage: f = x*y^2 
     1073            sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ] 
     1074            sage: P.monomial_reduce(f,G) 
     1075            (y, 1/4*x*y + 2/7) 
     1076 
     1077        TESTS:: 
     1078            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1079            sage: Q = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1080            sage: Q.inject_variables() 
     1081            Defining x, y, z 
     1082             
     1083            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1084            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1085            sage: P.inject_variables() 
     1086            Defining x, y, z 
     1087            sage: f = x*y^2 
     1088            sage: G = [ 3/2*x^3 + y^2 + 1/2, 1/4*x*y + 2/7, 1/2  ] 
     1089 
     1090            sage: P.monomial_reduce(P(0),G) 
     1091            (0, 0) 
     1092 
     1093            sage: P.monomial_reduce(f,[P(0)]) 
     1094            (0, 0) 
     1095        """ 
     1096        cdef poly *m = f._poly 
     1097        cdef ring *r = self._ring 
     1098        cdef poly *flt 
     1099 
     1100        if not m: 
     1101            return f,f 
     1102         
     1103        for g in G: 
     1104            if PY_TYPE_CHECK(g, NCPolynomial_plural) \ 
     1105                   and (<NCPolynomial_plural>g) \ 
     1106                   and p_LmDivisibleBy((<NCPolynomial_plural>g)._poly, m, r): 
     1107                flt = pDivide(f._poly, (<NCPolynomial_plural>g)._poly) 
     1108                #p_SetCoeff(flt, n_Div( p_GetCoeff(f._poly, r) , p_GetCoeff((<NCPolynomial_plural>g)._poly, r), r), r) 
     1109                p_SetCoeff(flt, n_Init(1, r), r) 
     1110                return new_NCP(self,flt), g 
     1111        return self._zero_element,self._zero_element 
     1112 
     1113    def monomial_pairwise_prime(self, NCPolynomial_plural g, NCPolynomial_plural h): 
     1114        """ 
     1115        Return ``True`` if ``h`` and ``g`` are pairwise prime. Both 
     1116        are treated as monomials. 
     1117 
     1118        Coefficients are ignored. 
     1119 
     1120        INPUT: 
     1121 
     1122        - ``h`` - monomial 
     1123        - ``g`` - monomial 
     1124 
     1125        EXAMPLES:: 
     1126 
     1127            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1128            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1129            sage: P.inject_variables() 
     1130            Defining x, y, z 
     1131 
     1132            sage: P.monomial_pairwise_prime(x^2*z^3, y^4) 
     1133            True 
     1134 
     1135            sage: P.monomial_pairwise_prime(1/2*x^3*y^2, 3/4*y^3) 
     1136            False 
     1137 
     1138        TESTS:: 
     1139 
     1140            sage: A.<x1,y1,z1> = FreeAlgebra(QQ, 3) 
     1141            sage: Q = A.g_algebra(relations={y1*x1:-x1*y1},  order='lex') 
     1142            sage: Q.inject_variables() 
     1143            Defining x1, y1, z1 
     1144 
     1145            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1146            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1147            sage: P.inject_variables() 
     1148            Defining x, y, z 
     1149 
     1150##            sage: P.monomial_pairwise_prime(x^2*z^3, x1^4) 
     1151##            True 
     1152 
     1153##            sage: P.monomial_pairwise_prime((2)*x^3*y^2, Q.zero_element()) 
     1154##            True 
     1155 
     1156            sage: P.monomial_pairwise_prime(2*P.one_element(),x) 
     1157            False 
     1158        """ 
     1159        cdef int i 
     1160        cdef ring *r 
     1161        cdef poly *p, *q 
     1162 
     1163        if h._parent is not g._parent: 
     1164            g = (<NCPolynomialRing_plural>h._parent)._coerce_c(g) 
     1165 
     1166        r = (<NCPolynomialRing_plural>h._parent)._ring 
     1167        p = g._poly 
     1168        q = h._poly 
     1169 
     1170        if p == NULL: 
     1171            if q == NULL: 
     1172                return False #GCD(0,0) = 0 
     1173            else: 
     1174                return True #GCD(x,0) = 1 
     1175 
     1176        elif q == NULL: 
     1177            return True # GCD(0,x) = 1 
     1178 
     1179        elif p_IsConstant(p,r) or p_IsConstant(q,r): # assuming a base field 
     1180            return False 
     1181 
     1182        for i from 1 <= i <= r.N: 
     1183            if p_GetExp(p,i,r) and p_GetExp(q,i,r): 
     1184                return False 
     1185        return True 
     1186 
     1187    def monomial_all_divisors(self, NCPolynomial_plural t): 
     1188        """ 
     1189        Return a list of all monomials that divide ``t``. 
     1190 
     1191        Coefficients are ignored. 
     1192           
     1193        INPUT: 
     1194 
     1195        - ``t`` - a monomial 
     1196   
     1197        OUTPUT: 
     1198            a list of monomials 
     1199 
     1200 
     1201        EXAMPLES:: 
     1202 
     1203            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     1204            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1205            sage: P.inject_variables() 
     1206            Defining x, y, z 
     1207 
     1208            sage: P.monomial_all_divisors(x^2*z^3) 
     1209            [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] 
     1210             
     1211        ALGORITHM: addwithcarry idea by Toon Segers 
     1212        """ 
     1213 
     1214        M = list() 
     1215 
     1216        cdef ring *_ring = self._ring 
     1217        cdef poly *maxvector = t._poly 
     1218        cdef poly *tempvector = p_ISet(1, _ring) 
     1219          
     1220        pos = 1 
     1221          
     1222        while not p_ExpVectorEqual(tempvector, maxvector, _ring): 
     1223          tempvector = addwithcarry(tempvector, maxvector, pos, _ring) 
     1224          M.append(new_NCP(self, p_Copy(tempvector,_ring))) 
     1225        return M 
     1226 
     1227 
     1228 
     1229cdef class NCPolynomial_plural(RingElement): 
     1230    """ 
     1231    A noncommutative multivariate polynomial implemented using libSINGULAR. 
     1232    """ 
     1233    def __init__(self, NCPolynomialRing_plural parent): 
     1234        """ 
     1235        Construct a zero element in parent. 
     1236 
     1237        EXAMPLES:: 
     1238 
     1239            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1240            sage: H = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1241            sage: from sage.rings.polynomial.plural import NCPolynomial_plural 
     1242            sage: NCPolynomial_plural(H) 
     1243            0 
     1244        """ 
     1245        self._poly = NULL 
     1246        self._parent = <ParentWithBase>parent 
     1247 
     1248    def __dealloc__(self): 
     1249        # TODO: Warn otherwise! 
     1250        # for some mysterious reason, various things may be NULL in some cases 
     1251        if self._parent is not <ParentWithBase>None and (<NCPolynomialRing_plural>self._parent)._ring != NULL and self._poly != NULL: 
     1252            p_Delete(&self._poly, (<NCPolynomialRing_plural>self._parent)._ring) 
     1253 
     1254#    def __call__(self, *x, **kwds): # ? 
     1255 
     1256    # you may have to replicate this boilerplate code in derived classes if you override  
     1257    # __richcmp__.  The python documentation at  http://docs.python.org/api/type-structs.html  
     1258    # explains how __richcmp__, __hash__, and __cmp__ are tied together. 
     1259    def __hash__(self): 
     1260        """ 
     1261        This hash incorporates the variable name in an effort to 
     1262        respect the obvious inclusions into multi-variable polynomial 
     1263        rings. 
     1264 
     1265        The tuple algorithm is borrowed from http://effbot.org/zone/python-hash.htm. 
     1266 
     1267        EXAMPLES:: 
     1268 
     1269            sage: R.<x>=QQ[] 
     1270            sage: S.<x,y>=QQ[] 
     1271            sage: hash(S(1/2))==hash(1/2)  # respect inclusions of the rationals 
     1272            True 
     1273            sage: hash(S.0)==hash(R.0)  # respect inclusions into mpoly rings 
     1274            True 
     1275            sage: # the point is to make for more flexible dictionary look ups 
     1276            sage: d={S.0:12} 
     1277            sage: d[R.0] 
     1278            12 
     1279        """ 
     1280        return self._hash_c() 
     1281 
     1282    def __richcmp__(left, right, int op): 
     1283        """ 
     1284        Compare left and right and return -1, 0, and 1 for <,==, and > 
     1285        respectively. 
     1286 
     1287        EXAMPLES:: 
     1288 
     1289            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1290            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1291            sage: P.inject_variables() 
     1292            Defining x, z, y 
     1293 
     1294            sage: x == x 
     1295            True 
     1296 
     1297            sage: x > y 
     1298            True 
     1299            sage: y^2 > x 
     1300            False 
     1301 
     1302##            sage: (2/3*x^2 + 1/2*y + 3) > (2/3*x^2 + 1/4*y + 10) 
     1303#            True 
     1304 
     1305        TESTS:: 
     1306 
     1307            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1308            sage: P = A.g_algebra(relations={y*x:-x*y},  order='lex') 
     1309            sage: P.inject_variables() 
     1310            Defining x, z, y 
     1311 
     1312            sage: x > P(0) 
     1313            True 
     1314 
     1315            sage: P(0) == P(0) 
     1316            True 
     1317 
     1318            sage: P(0) < P(1) 
     1319            True 
     1320 
     1321            sage: x > P(1) 
     1322            True 
     1323             
     1324            sage: 1/2*x < 3/4*x 
     1325            True 
     1326 
     1327            sage: (x+1) > x 
     1328            True 
     1329 
     1330#            sage: f = 3/4*x^2*y + 1/2*x + 2/7 
     1331#            sage: f > f 
     1332#            False 
     1333#            sage: f < f 
     1334#            False 
     1335#            sage: f == f 
     1336#            True 
     1337 
     1338#            sage: P.<x,y,z> = PolynomialRing(GF(127), order='degrevlex') 
     1339#            sage: (66*x^2 + 23) > (66*x^2 + 2) 
     1340#            True 
     1341        """ 
     1342        return (<Element>left)._richcmp(right, op) 
     1343 
     1344    cdef int _cmp_c_impl(left, Element right) except -2: 
     1345        if left is right: 
     1346            return 0 
     1347        cdef poly *p = (<NCPolynomial_plural>left)._poly 
     1348        cdef poly *q = (<NCPolynomial_plural>right)._poly 
     1349        cdef ring *r = (<NCPolynomialRing_plural>left._parent)._ring 
     1350        return singular_polynomial_cmp(p, q, r) 
     1351 
     1352    cpdef ModuleElement _add_( left, ModuleElement right): 
     1353        """ 
     1354        Adds left and right. 
     1355 
     1356        EXAMPLES:: 
     1357 
     1358            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1359            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1360            sage: P.inject_variables() 
     1361            Defining x, z, y 
     1362            sage: 3/2*x + 1/2*y + 1 # indirect doctest 
     1363            3/2*x + 1/2*y + 1 
     1364        """ 
     1365        cdef poly *_p 
     1366        singular_polynomial_add(&_p, left._poly,  
     1367                                 (<NCPolynomial_plural>right)._poly, 
     1368                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     1369        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     1370 
     1371    cpdef ModuleElement _sub_( left, ModuleElement right): 
     1372        """ 
     1373        Subtract left and right. 
     1374 
     1375        EXAMPLES:: 
     1376 
     1377            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1378            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1379            sage: P.inject_variables() 
     1380            Defining x, z, y 
     1381            sage: 3/2*x - 1/2*y - 1 # indirect doctest 
     1382            3/2*x - 1/2*y - 1 
     1383 
     1384        """ 
     1385        cdef ring *_ring = (<NCPolynomialRing_plural>left._parent)._ring 
     1386 
     1387        cdef poly *_p 
     1388        singular_polynomial_sub(&_p, left._poly,  
     1389                                (<NCPolynomial_plural>right)._poly, 
     1390                                _ring) 
     1391        return new_NCP((<NCPolynomialRing_plural>left._parent), _p) 
     1392 
     1393    cpdef ModuleElement _rmul_(self, RingElement left): 
     1394        """ 
     1395        Multiply self with a base ring element. 
     1396 
     1397        EXAMPLES:: 
     1398 
     1399            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1400            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1401            sage: P.inject_variables() 
     1402            Defining x, z, y 
     1403            sage: 3/2*x # indirect doctest 
     1404            3/2*x 
     1405        """ 
     1406 
     1407        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1408        if not left: 
     1409            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     1410        cdef poly *_p 
     1411        singular_polynomial_rmul(&_p, self._poly, left, _ring) 
     1412        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     1413         
     1414    cpdef ModuleElement _lmul_(self, RingElement right): 
     1415        """ 
     1416        Multiply self with a base ring element. 
     1417 
     1418        EXAMPLES:: 
     1419 
     1420            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1421            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1422            sage: P.inject_variables() 
     1423            Defining x, z, y 
     1424            sage: x* (2/3) # indirect doctest 
     1425            2/3*x 
     1426        """ 
     1427        return self._rmul_(right) 
     1428         
     1429    cpdef RingElement  _mul_(left, RingElement right): 
     1430        """ 
     1431        Multiply left and right. 
     1432 
     1433        EXAMPLES:: 
     1434 
     1435            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1436            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1437            sage: P.inject_variables() 
     1438            Defining x, z, y 
     1439            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest 
     1440            9/4*x^2 + 3/2*x*y - 3/4*z - 1/4*y^2 - y - 1 
     1441 
     1442        TEST:: 
     1443         
     1444            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1445            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1446            sage: P.inject_variables() 
     1447            Defining x, z, y 
     1448            sage: (x^2^30) * x^2^30 
     1449            Traceback (most recent call last): 
     1450            ... 
     1451            OverflowError: Exponent overflow (...). 
     1452        """ 
     1453        # all currently implemented rings are commutative 
     1454        cdef poly *_p 
     1455        singular_polynomial_mul(&_p, left._poly,  
     1456                                 (<NCPolynomial_plural>right)._poly,  
     1457                                 (<NCPolynomialRing_plural>left._parent)._ring) 
     1458        return new_NCP((<NCPolynomialRing_plural>left._parent),_p) 
     1459 
     1460    cpdef RingElement _div_(left, RingElement right): 
     1461        """ 
     1462        Divide left by right 
     1463 
     1464        EXAMPLES:: 
     1465 
     1466            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1467            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1468            sage: R.inject_variables() 
     1469            Defining x, z, y 
     1470            sage: f = (x + y)/3 # indirect doctest 
     1471            sage: f.parent() 
     1472            Noncommutative Multivariate Polynomial Ring in x, z, y over Rational Field, nc-relations: {y*x: -x*y + z} 
     1473 
     1474        TESTS:: 
     1475 
     1476            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1477            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1478            sage: R.inject_variables() 
     1479            Defining x, z, y 
     1480            sage: x/0 
     1481            Traceback (most recent call last): 
     1482            ... 
     1483            ZeroDivisionError: rational division by zero 
     1484        """ 
     1485        cdef poly *p  
     1486        cdef bint is_field = left._parent._base.is_field() 
     1487        if p_IsConstant((<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring): 
     1488            if is_field: 
     1489                singular_polynomial_div_coeff(&p, left._poly, (<NCPolynomial_plural>right)._poly, (<NCPolynomialRing_plural>right._parent)._ring) 
     1490                return new_NCP(left._parent, p) 
     1491            else: 
     1492                return left.change_ring(left.base_ring().fraction_field())/right 
     1493        else: 
     1494            return (<NCPolynomialRing_plural>left._parent).fraction_field()(left,right) 
     1495 
     1496    def __pow__(NCPolynomial_plural self, exp, ignored): 
     1497        """ 
     1498        Return ``self**(exp)``. 
     1499 
     1500        The exponent must be an integer. 
     1501 
     1502        EXAMPLES:: 
     1503 
     1504            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1505            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1506            sage: R.inject_variables() 
     1507            Defining x, z, y 
     1508            sage: f = x^3 + y 
     1509            sage: f^2 
     1510            x^6 + x^2*z + y^2 
     1511 
     1512        TESTS:: 
     1513         
     1514            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1515            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1516            sage: P.inject_variables() 
     1517            Defining x, z, y 
     1518            sage: (x+y^2^30)^10 
     1519            Traceback (most recent call last): 
     1520            .... 
     1521            OverflowError: Exponent overflow (...). 
     1522        """ 
     1523        if not PY_TYPE_CHECK_EXACT(exp, Integer) or \ 
     1524                PY_TYPE_CHECK_EXACT(exp, int): 
     1525                    try: 
     1526                        exp = Integer(exp) 
     1527                    except TypeError: 
     1528                        raise TypeError, "non-integral exponents not supported" 
     1529 
     1530        if exp < 0: 
     1531            return 1/(self**(-exp)) 
     1532        elif exp == 0: 
     1533            return (<NCPolynomialRing_plural>self._parent)._one_element 
     1534 
     1535        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1536        cdef poly *_p 
     1537        singular_polynomial_pow(&_p, self._poly, exp, _ring) 
     1538        return new_NCP((<NCPolynomialRing_plural>self._parent),_p) 
     1539 
     1540    def __neg__(self): 
     1541        """ 
     1542        Return ``-self``. 
     1543 
     1544        EXAMPLES:: 
     1545 
     1546            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1547            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1548            sage: R.inject_variables() 
     1549            Defining x, z, y 
     1550            sage: f = x^3 + y 
     1551            sage: -f 
     1552            -x^3 - y 
     1553        """ 
     1554        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1555 
     1556        cdef poly *p 
     1557        singular_polynomial_neg(&p, self._poly, _ring) 
     1558        return new_NCP((<NCPolynomialRing_plural>self._parent), p) 
     1559 
     1560    def _repr_(self): 
     1561        """ 
     1562        EXAMPLES:: 
     1563 
     1564            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1565            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1566            sage: R.inject_variables() 
     1567            Defining x, z, y 
     1568            sage: f = x^3 + y*x*z + z 
     1569            sage: f # indirect doctest 
     1570            x^3 - x*z*y + z^2 + z 
     1571        """ 
     1572        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1573        s = singular_polynomial_str(self._poly, _ring) 
     1574        return s 
     1575 
     1576    cpdef _repr_short_(self): 
     1577        """ 
     1578        This is a faster but less pretty way to print polynomials. If 
     1579        available it uses the short SINGULAR notation. 
     1580         
     1581        EXAMPLES:: 
     1582 
     1583            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1584            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1585            sage: R.inject_variables() 
     1586            Defining x, z, y 
     1587            sage: f = x^3 + y 
     1588            sage: f._repr_short_() 
     1589            'x3+y' 
     1590        """ 
     1591        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1592        rChangeCurrRing(_ring) 
     1593        if _ring.CanShortOut: 
     1594            _ring.ShortOut = 1 
     1595            s = p_String(self._poly, _ring, _ring) 
     1596            _ring.ShortOut = 0 
     1597        else: 
     1598            s = p_String(self._poly, _ring, _ring) 
     1599        return s 
     1600                                            
     1601    def _latex_(self): 
     1602        """ 
     1603        Return a polynomial LaTeX representation of this polynomial. 
     1604 
     1605        EXAMPLES:: 
     1606 
     1607            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1608            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1609            sage: R.inject_variables() 
     1610            Defining x, z, y 
     1611            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     1612            sage: latex(f) # indirect doctest 
     1613            - x^{2} y - z^{2} - \frac{25}{27} y^{3} 
     1614        """ 
     1615        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     1616        gens = self.parent().latex_variable_names() 
     1617        base = self.parent().base() 
     1618        return singular_polynomial_latex(self._poly, _ring, base, gens) 
     1619     
     1620    def _repr_with_changed_varnames(self, varnames): 
     1621        """ 
     1622        Return string representing this polynomial but change the 
     1623        variable names to ``varnames``. 
     1624 
     1625        EXAMPLES:: 
     1626 
     1627            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1628            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1629            sage: R.inject_variables() 
     1630            Defining x, z, y 
     1631            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2 
     1632            sage: print f._repr_with_changed_varnames(['FOO', 'BAR', 'FOOBAR']) 
     1633            -FOO^2*FOOBAR - BAR^2 - 25/27*FOOBAR^3 
     1634        """ 
     1635        return  singular_polynomial_str_with_changed_varnames(self._poly, (<NCPolynomialRing_plural>self._parent)._ring, varnames) 
     1636             
     1637    def degree(self, NCPolynomial_plural x=None): 
     1638        """ 
     1639        Return the maximal degree of this polynomial in ``x``, where 
     1640        ``x`` must be one of the generators for the parent of this 
     1641        polynomial. 
     1642 
     1643        INPUT: 
     1644 
     1645        - ``x`` - multivariate polynomial (a generator of the parent of 
     1646          self) If x is not specified (or is ``None``), return the total 
     1647          degree, which is the maximum degree of any monomial. 
     1648 
     1649        OUTPUT: 
     1650            integer 
     1651         
     1652        EXAMPLES:: 
     1653 
     1654            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1655            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1656            sage: R.inject_variables() 
     1657            Defining x, z, y 
     1658            sage: f = y^2 - x^9 - x 
     1659            sage: f.degree(x) 
     1660            9 
     1661            sage: f.degree(y) 
     1662            2 
     1663            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(x) 
     1664            3 
     1665            sage: (y^10*x - 7*x^2*y^5 + 5*x^3).degree(y) 
     1666            10 
     1667 
     1668        TESTS:: 
     1669 
     1670            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1671            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1672            sage: P.inject_variables() 
     1673            Defining x, z, y 
     1674            sage: P(0).degree(x) 
     1675            -1 
     1676            sage: P(1).degree(x) 
     1677            0 
     1678 
     1679        """ 
     1680        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1681        cdef poly *p = self._poly 
     1682        if not x: 
     1683            return singular_polynomial_deg(p,NULL,r) 
     1684 
     1685        # TODO: we can do this faster 
     1686        if not x in self._parent.gens(): 
     1687            raise TypeError("x must be one of the generators of the parent.") 
     1688 
     1689        return singular_polynomial_deg(p, (<NCPolynomial_plural>x)._poly, r) 
     1690 
     1691    def total_degree(self): 
     1692        """ 
     1693        Return the total degree of ``self``, which is the maximum degree 
     1694        of all monomials in ``self``. 
     1695 
     1696        EXAMPLES:: 
     1697 
     1698            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1699            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1700            sage: R.inject_variables() 
     1701            Defining x, z, y 
     1702            sage: f=2*x*y^3*z^2 
     1703            sage: f.total_degree() 
     1704            6 
     1705            sage: f=4*x^2*y^2*z^3 
     1706            sage: f.total_degree() 
     1707            7 
     1708            sage: f=99*x^6*y^3*z^9 
     1709            sage: f.total_degree() 
     1710            18 
     1711            sage: f=x*y^3*z^6+3*x^2 
     1712            sage: f.total_degree() 
     1713            10 
     1714            sage: f=z^3+8*x^4*y^5*z 
     1715            sage: f.total_degree() 
     1716            10 
     1717            sage: f=z^9+10*x^4+y^8*x^2 
     1718            sage: f.total_degree() 
     1719            10 
     1720 
     1721        TESTS:: 
     1722 
     1723            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1724            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1725            sage: R.inject_variables() 
     1726            Defining x, z, y 
     1727            sage: R(0).total_degree() 
     1728            -1 
     1729            sage: R(1).total_degree() 
     1730            0 
     1731        """ 
     1732        cdef poly *p = self._poly 
     1733        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1734        return singular_polynomial_deg(p,NULL,r) 
     1735 
     1736    def degrees(self): 
     1737        """  
     1738        Returns a tuple with the maximal degree of each variable in 
     1739        this polynomial.  The list of degrees is ordered by the order 
     1740        of the generators. 
     1741 
     1742        EXAMPLES:: 
     1743 
     1744            sage: A.<y0,y1,y2> = FreeAlgebra(QQ, 3) 
     1745            sage: R = A.g_algebra(relations={y1*y0:-y0*y1 + y2},  order='lex') 
     1746            sage: R.inject_variables() 
     1747            Defining y0, y1, y2 
     1748            sage: q = 3*y0*y1*y1*y2; q  
     1749            3*y0*y1^2*y2  
     1750            sage: q.degrees()  
     1751            (1, 2, 1) 
     1752            sage: (q + y0^5).degrees() 
     1753            (5, 2, 1) 
     1754        """ 
     1755        cdef poly *p = self._poly 
     1756        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1757        cdef int i 
     1758        cdef list d = [0 for _ in range(r.N)] 
     1759        while p: 
     1760            for i from 0 <= i < r.N: 
     1761                d[i] = max(d[i],p_GetExp(p, i+1, r)) 
     1762            p = pNext(p) 
     1763        return tuple(d) 
     1764 
     1765 
     1766    def coefficient(self, degrees): 
     1767        """ 
     1768        Return the coefficient of the variables with the degrees 
     1769        specified in the python dictionary ``degrees``. 
     1770        Mathematically, this is the coefficient in the base ring 
     1771        adjoined by the variables of this ring not listed in 
     1772        ``degrees``.  However, the result has the same parent as this 
     1773        polynomial. 
     1774 
     1775        This function contrasts with the function 
     1776        ``monomial_coefficient`` which returns the coefficient in the 
     1777        base ring of a monomial. 
     1778 
     1779        INPUT: 
     1780 
     1781        - ``degrees`` - Can be any of: 
     1782                - a dictionary of degree restrictions 
     1783                - a list of degree restrictions (with None in the unrestricted variables) 
     1784                - a monomial (very fast, but not as flexible) 
     1785 
     1786        OUTPUT: 
     1787            element of the parent of this element. 
     1788 
     1789        .. note:: 
     1790            
     1791           For coefficients of specific monomials, look at :meth:`monomial_coefficient`. 
     1792 
     1793        EXAMPLES:: 
     1794 
     1795            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     1796            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1797            sage: R.inject_variables() 
     1798            Defining x, z, y 
     1799            sage: f=x*y+y+5 
     1800            sage: f.coefficient({x:0,y:1}) 
     1801            1 
     1802            sage: f.coefficient({x:0}) 
     1803            y + 5 
     1804            sage: f=(1+y+y^2)*(1+x+x^2) 
     1805            sage: f.coefficient({x:0}) 
     1806            z + y^2 + y + 1 
     1807 
     1808            sage: f.coefficient(x) 
     1809            y^2 - y + 1 
     1810           
     1811# f.coefficient([0,None]) # y^2 + y + 1 
     1812 
     1813        Be aware that this may not be what you think! The physical 
     1814        appearance of the variable x is deceiving -- particularly if 
     1815        the exponent would be a variable. :: 
     1816 
     1817            sage: f.coefficient(x^0) # outputs the full polynomial 
     1818            x^2*y^2 + x^2*y + x^2 + x*y^2 - x*y + x + z + y^2 + y + 1 
     1819 
     1820            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1821            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1822            sage: R.inject_variables() 
     1823            Defining x, z, y 
     1824            sage: f=x*y+5 
     1825            sage: c=f.coefficient({x:0,y:0}); c 
     1826            5 
     1827            sage: parent(c) 
     1828            Noncommutative Multivariate Polynomial Ring in x, z, y over Finite Field of size 389, nc-relations: {y*x: -x*y + z} 
     1829 
     1830        AUTHOR: 
     1831 
     1832        - Joel B. Mohler (2007.10.31) 
     1833        """ 
     1834        cdef poly *_degrees = <poly*>0 
     1835        cdef poly *p = self._poly 
     1836        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1837        cdef poly *newp = p_ISet(0,r) 
     1838        cdef poly *newptemp 
     1839        cdef int i 
     1840        cdef int flag 
     1841        cdef int gens = self._parent.ngens() 
     1842        cdef int *exps = <int*>sage_malloc(sizeof(int)*gens) 
     1843        for i from 0<=i<gens: 
     1844            exps[i] = -1 
     1845 
     1846        if PY_TYPE_CHECK(degrees, NCPolynomial_plural) and self._parent is (<NCPolynomial_plural>degrees)._parent: 
     1847            _degrees = (<NCPolynomial_plural>degrees)._poly 
     1848            if pLength(_degrees) != 1: 
     1849                raise TypeError, "degrees must be a monomial" 
     1850            for i from 0<=i<gens: 
     1851                if p_GetExp(_degrees,i+1,r)!=0: 
     1852                    exps[i] = p_GetExp(_degrees,i+1,r) 
     1853        elif type(degrees) is list: 
     1854            for i from 0<=i<gens: 
     1855                if degrees[i] is None: 
     1856                    exps[i] = -1 
     1857                else: 
     1858                    exps[i] = int(degrees[i]) 
     1859        elif type(degrees) is dict: 
     1860            # Extract the ordered list of degree specifications from the dictionary 
     1861            poly_vars = self.parent().gens() 
     1862            for i from 0<=i<gens: 
     1863                try: 
     1864                    exps[i] = degrees[poly_vars[i]] 
     1865                except KeyError: 
     1866                    pass 
     1867        else: 
     1868            raise TypeError, "The input degrees must be a dictionary of variables to exponents." 
     1869 
     1870        # Extract the monomials that match the specifications 
     1871        while(p): 
     1872            flag = 0 
     1873            for i from 0<=i<gens: 
     1874                if exps[i] != -1 and p_GetExp(p,i+1,r)!=exps[i]: 
     1875                    #print i, p_GetExp(p,i+1,r), exps[i] 
     1876                    flag = 1 
     1877            if flag == 0: 
     1878                newptemp = p_LmInit(p,r) 
     1879                p_SetCoeff(newptemp,n_Copy(p_GetCoeff(p,r),r),r) 
     1880                for i from 0<=i<gens: 
     1881                    if exps[i] != -1: 
     1882                        p_SetExp(newptemp,i+1,0,r) 
     1883                p_Setm(newptemp,r) 
     1884                newp = p_Add_q(newp,newptemp,r) 
     1885            p = pNext(p) 
     1886 
     1887        sage_free(exps) 
     1888 
     1889        return new_NCP(self.parent(),newp) 
     1890 
     1891    def monomial_coefficient(self, NCPolynomial_plural mon): 
     1892        """ 
     1893        Return the coefficient in the base ring of the monomial mon in 
     1894        ``self``, where mon must have the same parent as self. 
     1895 
     1896        This function contrasts with the function ``coefficient`` 
     1897        which returns the coefficient of a monomial viewing this 
     1898        polynomial in a polynomial ring over a base ring having fewer 
     1899        variables. 
     1900 
     1901        INPUT: 
     1902 
     1903        - ``mon`` - a monomial 
     1904 
     1905        OUTPUT: 
     1906            coefficient in base ring 
     1907 
     1908        SEE ALSO: 
     1909            For coefficients in a base ring of fewer variables, look at ``coefficient``. 
     1910 
     1911        EXAMPLES:: 
     1912 
     1913            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1914            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1915            sage: P.inject_variables() 
     1916            Defining x, z, y 
     1917 
     1918            The parent of the return is a member of the base ring. 
     1919            sage: f = 2 * x * y 
     1920            sage: c = f.monomial_coefficient(x*y); c 
     1921            2 
     1922            sage: c.parent() 
     1923            Finite Field of size 389 
     1924 
     1925            sage: f = y^2 + y^2*x - x^9 - 7*x + 5*x*y 
     1926            sage: f.monomial_coefficient(y^2) 
     1927            1 
     1928            sage: f.monomial_coefficient(x*y) 
     1929            5 
     1930            sage: f.monomial_coefficient(x^9) 
     1931            388 
     1932            sage: f.monomial_coefficient(x^10) 
     1933            0 
     1934        """ 
     1935        cdef poly *p = self._poly 
     1936        cdef poly *m = mon._poly 
     1937        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     1938 
     1939        if not mon._parent is self._parent: 
     1940            raise TypeError("mon must have same parent as self.") 
     1941         
     1942        while(p): 
     1943            if p_ExpVectorEqual(p, m, r) == 1: 
     1944                return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base) 
     1945            p = pNext(p) 
     1946 
     1947        return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     1948 
     1949    def dict(self): 
     1950        """ 
     1951        Return a dictionary representing self. This dictionary is in 
     1952        the same format as the generic MPolynomial: The dictionary 
     1953        consists of ``ETuple:coefficient`` pairs. 
     1954 
     1955        EXAMPLES:: 
     1956 
     1957            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     1958            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     1959            sage: R.inject_variables() 
     1960            Defining x, z, y 
     1961 
     1962            sage: f = (2*x*y^3*z^2 + (7)*x^2 + (3)) 
     1963            sage: f.dict() 
     1964            {(0, 0, 0): 3, (2, 0, 0): 7, (1, 2, 3): 2} 
     1965        """ 
     1966        cdef poly *p 
     1967        cdef ring *r 
     1968        cdef int n 
     1969        cdef int v 
     1970        r = (<NCPolynomialRing_plural>self._parent)._ring 
     1971        if r!=currRing: rChangeCurrRing(r) 
     1972        base = (<NCPolynomialRing_plural>self._parent)._base 
     1973        p = self._poly 
     1974        pd = dict() 
     1975        while p: 
     1976            d = dict() 
     1977            for v from 1 <= v <= r.N: 
     1978                n = p_GetExp(p,v,r) 
     1979                if n!=0: 
     1980                    d[v-1] = n  
     1981                 
     1982            pd[ETuple(d,r.N)] = si2sa(p_GetCoeff(p, r), r, base) 
     1983 
     1984            p = pNext(p) 
     1985        return pd 
     1986 
     1987 
     1988    cdef long _hash_c(self): 
     1989        """ 
     1990        See ``self.__hash__`` 
     1991        """ 
     1992        cdef poly *p 
     1993        cdef ring *r 
     1994        cdef int n 
     1995        cdef int v 
     1996        r = (<NCPolynomialRing_plural>self._parent)._ring 
     1997        if r!=currRing: rChangeCurrRing(r) 
     1998        base = (<NCPolynomialRing_plural>self._parent)._base 
     1999        p = self._poly 
     2000        cdef long result = 0 # store it in a c-int and just let the overflowing additions wrap 
     2001        cdef long result_mon 
     2002        var_name_hash = [hash(vn) for vn in self._parent.variable_names()] 
     2003        cdef long c_hash 
     2004        while p: 
     2005            c_hash = hash(si2sa(p_GetCoeff(p, r), r, base)) 
     2006            if c_hash != 0: # this is always going to be true, because we are sparse (correct?) 
     2007                # Hash (self[i], gen_a, exp_a, gen_b, exp_b, gen_c, exp_c, ...) as a tuple according to the algorithm. 
     2008                # I omit gen,exp pairs where the exponent is zero. 
     2009                result_mon = c_hash 
     2010                for v from 1 <= v <= r.N: 
     2011                    n = p_GetExp(p,v,r) 
     2012                    if n!=0: 
     2013                        result_mon = (1000003 * result_mon) ^ var_name_hash[v-1] 
     2014                        result_mon = (1000003 * result_mon) ^ n 
     2015                result += result_mon 
     2016 
     2017            p = pNext(p) 
     2018        if result == -1: 
     2019            return -2 
     2020        return result 
     2021 
     2022    def __getitem__(self,x): 
     2023        """ 
     2024        Same as ``self.monomial_coefficent`` but for exponent vectors. 
     2025         
     2026        INPUT: 
     2027 
     2028        - ``x`` - a tuple or, in case of a single-variable MPolynomial 
     2029        ring x can also be an integer. 
     2030         
     2031        EXAMPLES:: 
     2032 
     2033            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2034            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2035            sage: R.inject_variables() 
     2036            Defining x, z, y 
     2037            sage: f = (-10*x^3*y + 17*x*y)* ( 15*z^3 + 2*x*y*z - 1); f 
     2038            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 
     2039            sage: f[4,1,2] 
     2040            20 
     2041            sage: f[1,0,1] 
     2042            372 
     2043            sage: f[0,0,0] 
     2044            0 
     2045 
     2046            sage: R.<x> = PolynomialRing(GF(7),1); R 
     2047            Multivariate Polynomial Ring in x over Finite Field of size 7 
     2048            sage: f = 5*x^2 + 3; f 
     2049            -2*x^2 + 3 
     2050            sage: f[2] 
     2051            5 
     2052        """ 
     2053        cdef poly *m  
     2054        cdef poly *p = self._poly 
     2055        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     2056        cdef int i 
     2057 
     2058        if PY_TYPE_CHECK(x, NCPolynomial_plural): 
     2059            return self.monomial_coefficient(x) 
     2060        if not PY_TYPE_CHECK(x, tuple): 
     2061            try: 
     2062                x = tuple(x) 
     2063            except TypeError: 
     2064                x = (x,) 
     2065 
     2066        if len(x) != (<NCPolynomialRing_plural>self._parent).__ngens: 
     2067            raise TypeError, "x must have length self.ngens()" 
     2068 
     2069        m = p_ISet(1,r) 
     2070        i = 1 
     2071        for e in x: 
     2072            overflow_check(e, r) 
     2073            p_SetExp(m, i, int(e), r) 
     2074            i += 1 
     2075        p_Setm(m, r) 
     2076 
     2077        while(p): 
     2078            if p_ExpVectorEqual(p, m, r) == 1: 
     2079                p_Delete(&m,r) 
     2080                return si2sa(p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base) 
     2081            p = pNext(p) 
     2082 
     2083        p_Delete(&m,r) 
     2084        return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2085 
     2086    def exponents(self, as_ETuples=True): 
     2087        """ 
     2088        Return the exponents of the monomials appearing in this polynomial. 
     2089         
     2090        INPUT: 
     2091 
     2092        - ``as_ETuples`` - (default: ``True``) if true returns the result as an list of ETuples 
     2093                          otherwise returns a list of tuples 
     2094 
     2095 
     2096        EXAMPLES:: 
     2097 
     2098            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2099            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2100            sage: R.inject_variables() 
     2101            Defining x, z, y 
     2102            sage: f = x^3 + y + 2*z^2 
     2103            sage: f.exponents() 
     2104            [(3, 0, 0), (0, 2, 0), (0, 0, 1)] 
     2105            sage: f.exponents(as_ETuples=False) 
     2106            [(3, 0, 0), (0, 2, 0), (0, 0, 1)] 
     2107        """ 
     2108        cdef poly *p 
     2109        cdef ring *r 
     2110        cdef int v 
     2111        cdef list pl, ml 
     2112 
     2113        r = (< NCPolynomialRing_plural>self._parent)._ring 
     2114        p = self._poly 
     2115 
     2116        pl = list() 
     2117        ml = range(r.N) 
     2118        while p: 
     2119            for v from 1 <= v <= r.N: 
     2120                ml[v-1] = p_GetExp(p,v,r) 
     2121 
     2122            if as_ETuples: 
     2123                pl.append(ETuple(ml)) 
     2124            else: 
     2125                pl.append(tuple(ml)) 
     2126 
     2127            p = pNext(p) 
     2128        return pl 
     2129 
     2130    def is_homogeneous(self): 
     2131        """ 
     2132        Return ``True`` if this polynomial is homogeneous. 
     2133 
     2134        EXAMPLES:: 
     2135 
     2136            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2137            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2138            sage: P.inject_variables() 
     2139            Defining x, z, y 
     2140            sage: (x+y+z).is_homogeneous() 
     2141            True 
     2142            sage: (x.parent()(0)).is_homogeneous() 
     2143            True 
     2144            sage: (x+y^2+z^3).is_homogeneous() 
     2145            False 
     2146            sage: (x^2 + y^2).is_homogeneous() 
     2147            True 
     2148            sage: (x^2 + y^2*x).is_homogeneous() 
     2149            False 
     2150            sage: (x^2*y + y^2*x).is_homogeneous() 
     2151            True 
     2152        """ 
     2153        cdef ring *_ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2154        if(_ring != currRing): rChangeCurrRing(_ring) 
     2155        return bool(pIsHomogeneous(self._poly)) 
     2156 
     2157 
     2158    def is_monomial(self): 
     2159        """ 
     2160        Return ``True`` if this polynomial is a monomial.  A monomial 
     2161        is defined to be a product of generators with coefficient 1. 
     2162 
     2163        EXAMPLES:: 
     2164 
     2165            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2166            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2167            sage: P.inject_variables() 
     2168            Defining x, z, y 
     2169            sage: x.is_monomial() 
     2170            True 
     2171            sage: (2*x).is_monomial() 
     2172            False 
     2173            sage: (x*y).is_monomial() 
     2174            True 
     2175            sage: (x*y + x).is_monomial() 
     2176            False 
     2177        """ 
     2178        cdef poly *_p 
     2179        cdef ring *_ring 
     2180        cdef number *_n 
     2181        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2182 
     2183        if self._poly == NULL: 
     2184            return True 
     2185         
     2186        if(_ring != currRing): rChangeCurrRing(_ring) 
     2187         
     2188        _p = p_Head(self._poly, _ring) 
     2189        _n = p_GetCoeff(_p, _ring) 
     2190 
     2191        ret = bool((not self._poly.next) and _ring.cf.nIsOne(_n)) 
     2192 
     2193        p_Delete(&_p, _ring) 
     2194        return ret 
     2195 
     2196    def monomials(self): 
     2197        """ 
     2198        Return the list of monomials in self. The returned list is 
     2199        decreasingly ordered by the term ordering of 
     2200        ``self.parent()``. 
     2201 
     2202        EXAMPLES:: 
     2203 
     2204            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2205            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2206            sage: P.inject_variables() 
     2207            Defining x, z, y 
     2208            sage: f = x + (3*2)*y*z^2 + (2+3) 
     2209            sage: f.monomials() 
     2210            [x, z^2*y, 1] 
     2211            sage: f = P(3^2) 
     2212            sage: f.monomials() 
     2213            [1] 
     2214 
     2215        TESTS:: 
     2216 
     2217            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2218            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2219            sage: P.inject_variables() 
     2220            Defining x, z, y 
     2221            sage: f = x 
     2222            sage: f.monomials() 
     2223            [x] 
     2224            sage: f = P(0) 
     2225            sage: f.monomials() 
     2226            [0] 
     2227 
     2228        Check if #7152 is fixed:: 
     2229 
     2230            sage: x=var('x') 
     2231            sage: K.<rho> = NumberField(x**2 + 1) 
     2232            sage: R.<x,y> = QQ[] 
     2233            sage: p = rho*x 
     2234            sage: q = x 
     2235            sage: p.monomials() 
     2236            [x] 
     2237            sage: q.monomials() 
     2238            [x] 
     2239            sage: p.monomials() 
     2240            [x] 
     2241        """ 
     2242        l = list() 
     2243        cdef NCPolynomialRing_plural parent = <NCPolynomialRing_plural>self._parent 
     2244        cdef ring *_ring = parent._ring 
     2245        if(_ring != currRing): rChangeCurrRing(_ring) 
     2246        cdef poly *p = p_Copy(self._poly, _ring) 
     2247        cdef poly *t 
     2248 
     2249        if p == NULL: 
     2250            return [parent._zero_element] 
     2251         
     2252        while p: 
     2253            t = pNext(p) 
     2254            p.next = NULL 
     2255            p_SetCoeff(p, n_Init(1,_ring), _ring) 
     2256            p_Setm(p, _ring) 
     2257            l.append( new_NCP(parent,p) ) 
     2258            p = t 
     2259 
     2260        return l 
     2261 
     2262    def constant_coefficient(self): 
     2263        """ 
     2264        Return the constant coefficient of this multivariate 
     2265        polynomial. 
     2266 
     2267        EXAMPLES:: 
     2268 
     2269            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2270            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2271            sage: P.inject_variables() 
     2272            Defining x, z, y 
     2273            sage: f = 3*x^2 - 2*y + 7*x^2*y^2 + 5 
     2274            sage: f.constant_coefficient() 
     2275            5 
     2276            sage: f = 3*x^2  
     2277            sage: f.constant_coefficient() 
     2278            0 
     2279        """ 
     2280        cdef poly *p = self._poly 
     2281        cdef ring *r = (<NCPolynomialRing_plural>self._parent)._ring 
     2282        if p == NULL: 
     2283            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2284 
     2285        while p.next: 
     2286            p = pNext(p) 
     2287 
     2288        if p_LmIsConstant(p, r): 
     2289            return si2sa( p_GetCoeff(p, r), r, (<NCPolynomialRing_plural>self._parent)._base ) 
     2290        else: 
     2291            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2292 
     2293    cpdef is_constant(self): 
     2294        """ 
     2295        Return ``True`` if this polynomial is constant. 
     2296 
     2297        EXAMPLES:: 
     2298 
     2299            sage: A.<x,z,y> = FreeAlgebra(GF(389), 3) 
     2300            sage: P = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2301            sage: P.inject_variables() 
     2302            Defining x, z, y 
     2303            sage: x.is_constant() 
     2304            False 
     2305            sage: P(1).is_constant() 
     2306            True 
     2307        """ 
     2308        return bool(p_IsConstant(self._poly, (<NCPolynomialRing_plural>self._parent)._ring)) 
     2309 
     2310    def lm(NCPolynomial_plural self): 
     2311        """ 
     2312        Returns the lead monomial of self with respect to the term 
     2313        order of ``self.parent()``. In Sage a monomial is a product of 
     2314        variables in some power without a coefficient. 
     2315 
     2316        EXAMPLES:: 
     2317 
     2318            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2319            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2320            sage: R.inject_variables() 
     2321            Defining x, y, z 
     2322            sage: f = x^1*y^2 + y^3*z^4 
     2323            sage: f.lm() 
     2324            x*y^2 
     2325            sage: f = x^3*y^2*z^4 + x^3*y^2*z^1  
     2326            sage: f.lm() 
     2327            x^3*y^2*z^4 
     2328 
     2329            sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2330            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='deglex') 
     2331            sage: R.inject_variables() 
     2332            Defining x, y, z 
     2333            sage: f = x^1*y^2*z^3 + x^3*y^2*z^0 
     2334            sage: f.lm() 
     2335            x*y^2*z^3 
     2336            sage: f = x^1*y^2*z^4 + x^1*y^1*z^5 
     2337            sage: f.lm() 
     2338            x*y^2*z^4 
     2339 
     2340            sage: A.<x,y,z> = FreeAlgebra(GF(127), 3) 
     2341            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='degrevlex') 
     2342            sage: R.inject_variables() 
     2343            Defining x, y, z 
     2344            sage: f = x^1*y^5*z^2 + x^4*y^1*z^3 
     2345            sage: f.lm() 
     2346            x*y^5*z^2 
     2347            sage: f = x^4*y^7*z^1 + x^4*y^2*z^3 
     2348            sage: f.lm() 
     2349            x^4*y^7*z 
     2350 
     2351        """ 
     2352        cdef poly *_p 
     2353        cdef ring *_ring 
     2354        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2355        if self._poly == NULL: 
     2356            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     2357        _p = p_Head(self._poly, _ring) 
     2358        p_SetCoeff(_p, n_Init(1,_ring), _ring) 
     2359        p_Setm(_p,_ring) 
     2360        return new_NCP((<NCPolynomialRing_plural>self._parent), _p) 
     2361 
     2362    def lc(NCPolynomial_plural self): 
     2363        """ 
     2364        Leading coefficient of this polynomial with respect to the 
     2365        term order of ``self.parent()``. 
     2366 
     2367        EXAMPLES:: 
     2368 
     2369            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2370            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2371            sage: R.inject_variables() 
     2372            Defining x, y, z 
     2373 
     2374            sage: f = 3*x^1*y^2 + 2*y^3*z^4 
     2375            sage: f.lc() 
     2376            3 
     2377 
     2378            sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1  
     2379            sage: f.lc() 
     2380            5 
     2381        """ 
     2382 
     2383        cdef poly *_p 
     2384        cdef ring *_ring 
     2385        cdef number *_n 
     2386        _ring = (<NCPolynomialRing_plural>self._parent)._ring 
     2387 
     2388        if self._poly == NULL: 
     2389            return (<NCPolynomialRing_plural>self._parent)._base._zero_element 
     2390         
     2391        if(_ring != currRing): rChangeCurrRing(_ring) 
     2392         
     2393        _p = p_Head(self._poly, _ring)  
     2394        _n = p_GetCoeff(_p, _ring) 
     2395 
     2396        ret =  si2sa(_n, _ring, (<NCPolynomialRing_plural>self._parent)._base) 
     2397        p_Delete(&_p, _ring) 
     2398        return ret 
     2399 
     2400    def lt(NCPolynomial_plural self): 
     2401        """ 
     2402        Leading term of this polynomial. In Sage a term is a product 
     2403        of variables in some power and a coefficient. 
     2404 
     2405        EXAMPLES:: 
     2406 
     2407            sage: A.<x,y,z> = FreeAlgebra(GF(7), 3) 
     2408            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2409            sage: R.inject_variables() 
     2410            Defining x, y, z 
     2411 
     2412            sage: f = 3*x^1*y^2 + 2*y^3*z^4 
     2413            sage: f.lt() 
     2414            3*x*y^2 
     2415             
     2416            sage: f = 5*x^3*y^2*z^4 + 4*x^3*y^2*z^1  
     2417            sage: f.lt() 
     2418            -2*x^3*y^2*z^4 
     2419        """ 
     2420        if self._poly == NULL: 
     2421            return (<NCPolynomialRing_plural>self._parent)._zero_element 
     2422 
     2423        return new_NCP((<NCPolynomialRing_plural>self._parent), 
     2424                                           p_Head(self._poly,(<NCPolynomialRing_plural>self._parent)._ring)) 
     2425 
     2426    def is_zero(self): 
     2427        """ 
     2428        Return ``True`` if this polynomial is zero. 
     2429 
     2430        EXAMPLES:: 
     2431 
     2432            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     2433            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2434            sage: R.inject_variables() 
     2435            Defining x, z, y 
     2436 
     2437            sage: x.is_zero() 
     2438            False 
     2439            sage: (x-x).is_zero() 
     2440            True 
     2441        """ 
     2442        if self._poly is NULL: 
     2443            return True 
     2444        else: 
     2445            return False 
     2446 
     2447    def __nonzero__(self): 
     2448        """ 
     2449        EXAMPLES:: 
     2450 
     2451            sage: A.<x,z,y> = FreeAlgebra(QQ, 3) 
     2452            sage: R = A.g_algebra(relations={y*x:-x*y + z},  order='lex') 
     2453            sage: R.inject_variables() 
     2454            Defining x, z, y 
     2455 
     2456            sage: bool(x) # indirect doctest 
     2457            True 
     2458            sage: bool(x-x) 
     2459            False 
     2460        """ 
     2461        if self._poly: 
     2462            return True 
     2463        else: 
     2464            return False 
     2465 
     2466 
     2467##################################################################### 
     2468 
     2469 
     2470cdef inline NCPolynomial_plural new_NCP(NCPolynomialRing_plural parent, 
     2471        poly *juice): 
     2472    """ 
     2473    Construct NCPolynomial_plural from parent and SINGULAR poly. 
     2474 
     2475    EXAMPLES:: 
     2476 
     2477     
     2478    """ 
     2479    cdef NCPolynomial_plural p = PY_NEW(NCPolynomial_plural) 
     2480    p._parent = <ParentWithBase>parent 
     2481    p._poly = juice 
     2482    p_Normalize(p._poly, parent._ring) 
     2483    return p 
     2484 
     2485 
     2486 
     2487 
     2488cpdef MPolynomialRing_libsingular new_CRing(RingWrap rw, base_ring): 
     2489    """ 
     2490    Construct MPolynomialRing_libsingular from ringWrap, assumming the ground field to be base_ring 
     2491 
     2492    EXAMPLES:: 
     2493        sage: H.<x,y,z> = PolynomialRing(QQ, 3) 
     2494        sage: from sage.libs.singular.function import singular_function 
     2495 
     2496        sage: ringlist = singular_function('ringlist') 
     2497        sage: ring = singular_function("ring")  
     2498 
     2499        sage: L = ringlist(H, ring=H); L 
     2500        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0]] 
     2501 
     2502        sage: len(L) 
     2503        4 
     2504         
     2505        sage: W = ring(L, ring=H); W 
     2506        <RingWrap> 
     2507 
     2508        sage: from sage.rings.polynomial.plural import new_CRing 
     2509        sage: R = new_CRing(W, H.base_ring()) 
     2510        sage: R # indirect doctest 
     2511        Multivariate Polynomial Ring in x, y, z over Rational Field 
     2512    """ 
     2513    assert( rw.is_commutative() ) 
     2514        
     2515    cdef MPolynomialRing_libsingular self = <MPolynomialRing_libsingular>PY_NEW(MPolynomialRing_libsingular) 
     2516         
     2517    self._ring = rw._ring 
     2518    self._ring.ShortOut = 0 
     2519         
     2520    self.__ngens = rw.ngens() 
     2521    self.__term_order =  TermOrder(rw.ordering_string(), force=True) 
     2522         
     2523    ParentWithGens.__init__(self, base_ring, rw.var_names()) 
     2524#    self._populate_coercion_lists_()  # ??? 
     2525          
     2526    #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     2527    self._has_singular = True 
     2528#    self._relations = self.relations() 
     2529         
     2530    return self 
     2531     
     2532cpdef NCPolynomialRing_plural new_NRing(RingWrap rw, base_ring): 
     2533    """ 
     2534    Construct NCPolynomialRing_plural from ringWrap, assumming the ground field to be base_ring 
     2535 
     2536    EXAMPLES:: 
     2537    EXAMPLES:: 
     2538         
     2539        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2540        sage: H = A.g_algebra({y*x:x*y-1}) 
     2541        sage: H.inject_variables() 
     2542        Defining x, y, z 
     2543        sage: z*x 
     2544        x*z 
     2545        sage: z*y 
     2546        y*z 
     2547        sage: y*x 
     2548        x*y - 1 
     2549        sage: I = H.ideal([y^2, x^2, z^2-1]) 
     2550        sage: I._groebner_basis_libsingular()  
     2551        [1] 
     2552 
     2553        sage: from sage.libs.singular.function import singular_function 
     2554 
     2555        sage: ringlist = singular_function('ringlist') 
     2556        sage: ring = singular_function("ring")  
     2557 
     2558        sage: L = ringlist(H, ring=H); L 
     2559        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 1 1] 
     2560        [0 0 1] 
     2561        [0 0 0], [ 0 -1  0] 
     2562        [ 0  0  0] 
     2563        [ 0  0  0]] 
     2564 
     2565        sage: len(L) 
     2566        6       
     2567 
     2568        sage: W = ring(L, ring=H); W 
     2569        <noncommutative RingWrap> 
     2570 
     2571        sage: from sage.rings.polynomial.plural import new_NRing 
     2572        sage: R = new_NRing(W, H.base_ring()) 
     2573        sage: R # indirect doctest 
     2574        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1} 
     2575    """ 
     2576 
     2577    assert( not rw.is_commutative() ) 
     2578     
     2579    cdef NCPolynomialRing_plural self = <NCPolynomialRing_plural>PY_NEW(NCPolynomialRing_plural) 
     2580    self._ring = rw._ring 
     2581    self._ring.ShortOut = 0 
     2582         
     2583    self.__ngens = rw.ngens() 
     2584    self.__term_order =  TermOrder(rw.ordering_string(), force=True) 
     2585         
     2586    ParentWithGens.__init__(self, base_ring, rw.var_names()) 
     2587#    self._populate_coercion_lists_()  # ??? 
     2588     
     2589    #MPolynomialRing_generic.__init__(self, base_ring, n, names, order) 
     2590    self._has_singular = True 
     2591    self._relations = self.relations() 
     2592         
     2593    return self 
     2594 
     2595 
     2596def new_Ring(RingWrap rw, base_ring): 
     2597    """ 
     2598    Constructs a Sage ring out of low level RingWrap, which wraps a pointer to a Singular ring. 
     2599    The constructed ring is either commutative or noncommutative depending on the Singular ring. 
     2600 
     2601    EXAMPLES:: 
     2602         
     2603        sage: A.<x,y,z> = FreeAlgebra(QQ, 3) 
     2604        sage: H = A.g_algebra({y*x:x*y-1}) 
     2605        sage: H.inject_variables() 
     2606        Defining x, y, z 
     2607        sage: z*x 
     2608        x*z 
     2609        sage: z*y 
     2610        y*z 
     2611        sage: y*x 
     2612        x*y - 1 
     2613        sage: I = H.ideal([y^2, x^2, z^2-1]) 
     2614        sage: I._groebner_basis_libsingular()  
     2615        [1] 
     2616 
     2617        sage: from sage.libs.singular.function import singular_function 
     2618 
     2619        sage: ringlist = singular_function('ringlist') 
     2620        sage: ring = singular_function("ring")  
     2621 
     2622        sage: L = ringlist(H, ring=H); L 
     2623        [0, ['x', 'y', 'z'], [['dp', (1, 1, 1)], ['C', (0,)]], [0], [0 1 1] 
     2624        [0 0 1] 
     2625        [0 0 0], [ 0 -1  0] 
     2626        [ 0  0  0] 
     2627        [ 0  0  0]] 
     2628 
     2629        sage: len(L) 
     2630        6       
     2631 
     2632        sage: W = ring(L, ring=H); W 
     2633        <noncommutative RingWrap> 
     2634 
     2635        sage: from sage.rings.polynomial.plural import new_Ring 
     2636        sage: R = new_Ring(W, H.base_ring()); R 
     2637        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - 1} 
     2638 
     2639    """ 
     2640    import warnings 
     2641#    warnings.warn("This is a hack. Please, use it on your own risk...") 
     2642    if rw.is_commutative(): 
     2643        return new_CRing(rw, base_ring) 
     2644    return new_NRing(rw, base_ring) 
     2645         
     2646 
     2647def SCA(base_ring, names, alt_vars, order='degrevlex'): 
     2648    """ 
     2649    Shortcut to construct a graded commutative algebra out of the following data:  
     2650 
     2651    Input:  
     2652         
     2653    - ``base_ring``: the ground field 
     2654    - ``names``: a list of variable names  
     2655    - ``alt_vars``: a list of indices of to be anti-commutative variables 
     2656    - ``order``: orderig to be used for the constructed algebra 
     2657 
     2658    EXAMPLES:: 
     2659 
     2660        sage: from sage.rings.polynomial.plural import SCA 
     2661        sage: E = SCA(QQ, ['x', 'y', 'z'], [0, 1], order = 'degrevlex') 
     2662        sage: E 
     2663        Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: -x*y} 
     2664        sage: E.inject_variables() 
     2665        Defining x, y, z 
     2666        sage: y*x 
     2667        -x*y 
     2668        sage: x^2 
     2669        0 
     2670        sage: y^2 
     2671        0 
     2672        sage: z^2 
     2673        z^2 
     2674    """ 
     2675    n = len(names) 
     2676    alt_start = min(alt_vars) 
     2677    alt_end = max(alt_vars) 
     2678    assert( alt_start >= 0 ) 
     2679    assert( (alt_end >= alt_start) and (alt_end < n) ) 
     2680     
     2681    relations = {} # {y*x:-x*y} 
     2682    from sage.algebras.free_algebra import FreeAlgebra 
     2683    A = FreeAlgebra(base_ring, n, names) 
     2684    for r in range(0, n-1, 1): 
     2685        for c in range(r+1, n, 1): 
     2686            if (r in alt_vars) and (c in alt_vars): 
     2687                relations[ A.gen(c) * A.gen(r) ] = - A.gen(r) * A.gen(c) 
     2688     
     2689    H = A.g_algebra(relations=relations, order=order) 
     2690    I = H.ideal([H.gen(i) *H.gen(i) for i in alt_vars]).twostd() 
     2691    return H.quotient(I) 
     2692 
     2693cdef poly *addwithcarry(poly *tempvector, poly *maxvector, int pos, ring *_ring): 
     2694    if p_GetExp(tempvector, pos, _ring) < p_GetExp(maxvector, pos, _ring): 
     2695      p_SetExp(tempvector, pos, p_GetExp(tempvector, pos, _ring)+1, _ring) 
     2696    else: 
     2697      p_SetExp(tempvector, pos, 0, _ring) 
     2698      tempvector = addwithcarry(tempvector, maxvector, pos + 1, _ring) 
     2699    p_Setm(tempvector, _ring) 
     2700    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  
    686686                    singular_str = [] 
    687687                    macaulay2_str = [] 
    688688 
     689                    length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end 
    689690                    for block in block_names: 
    690691                        try: 
    691                             length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end                   
    692                             block_name, block_length, _ = re.split(length_pattern,block) 
     692                            block_name, block_length, _ = re.split(length_pattern,block.strip()) 
    693693                            block_length = int(block_length) 
    694                             blocks.append( TermOrder(block_name,block_length,force=force) ) 
    695                         except: 
    696                             raise TypeError, "%s is not a valid term order"%(name,) 
    697                         length += block_length 
     694                            assert( block_length > 0) 
     695 
     696                            blocks.append( TermOrder(block_name, block_length, force=force) ) 
     697                            name_str.append("%s(%d)"%(block_name, block_length)) 
     698                            singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length)) 
     699                            macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length)) 
     700                            length += block_length 
     701                        except ValueError: 
     702                            block_name = block.strip() 
     703                            if block_name.lower() != "c": 
     704                                raise TypeError, "%s is not a valid term ordering (wrong part: '%s')"%(name, block) 
    698705 
    699706                    if n != 0 and length != n: 
    700707                        raise TypeError, "Term order length does not match the number of generators"  
  • 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) 
    9     cdef public object __ideal_monoid 
    1010 
    1111cdef class CommutativeRing(Ring): 
    1212    cdef public object __fraction_field 
  • sage/rings/ring.pyx

    diff --git a/sage/rings/ring.pyx b/sage/rings/ring.pyx
    a b  
    13001300            if not x.is_zero(): 
    13011301                return x 
    13021302 
     1303    def ideal_monoid(self): 
     1304        """ 
     1305        Return the monoid of ideals of this ring. 
     1306 
     1307        EXAMPLES:: 
     1308 
     1309            sage: ZZ.ideal_monoid() 
     1310            Monoid of ideals of Integer Ring 
     1311            sage: R.<x>=QQ[]; R.ideal_monoid() 
     1312            Monoid of ideals of Univariate Polynomial Ring in x over Rational Field 
     1313        """ 
     1314        if self.__ideal_monoid is not None: 
     1315            return self.__ideal_monoid 
     1316        else: 
     1317            from sage.rings.ideal_monoid import IdealMonoid 
     1318            M = IdealMonoid(self) 
     1319            self.__ideal_monoid = M 
     1320            return M 
     1321 
    13031322cdef class CommutativeRing(Ring): 
    13041323    """ 
    13051324    Generic commutative ring.