Ticket #4539: trac4539_libplural_todo.patch

File trac4539_libplural_todo.patch, 160.1 KB (added by SimonKing, 5 years ago)

Experimental rebasement wrt sage-4.7.2.alpha3 plus #7797 plus #11856

  • module_list.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1300026255 -3600
    # Node ID 756615e11cc63bde48a25ffde67f51bae74159c8
    # Parent  e453d3f57e7ecfe74cdd311abb1354203b06ef5a
    Initial wrapper for Singular/Plural - Sage-Trac #4539.
    * * *
    MPolynomialRing_plural now accepts matrix parameters to specify commutativity
    relations. Added ExteriorAlgebra.
    * * *
    [mq]: plural_3.patch
    
    diff --git a/module_list.py b/module_list.py
    a b  
    14901490              include_dirs = [SAGE_INC + 'singular'],
    14911491              depends = singular_depends),
    14921492
     1493    Extension('sage.rings.polynomial.plural',
     1494              sources = ['sage/rings/polynomial/plural.pyx'],
     1495              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
     1496              language="c++",
     1497              include_dirs = [SAGE_ROOT +'/local/include/singular'],
     1498              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
     1499
    14931500    Extension('sage.rings.polynomial.multi_polynomial_libsingular',
    14941501              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'],
    14951502              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
  • sage/algebras/free_algebra.py

    diff --git a/sage/algebras/free_algebra.py b/sage/algebras/free_algebra.py
    a b  
    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`
     
    166165    Element = FreeAlgebraElement
    167166    def __init__(self, R, n, names):
    168167        """
     168        The free algebra on `n` generators over a base ring.
    169169        INPUT:
    170170       
    171        
    172171        -  ``R`` - ring
    173172       
    174173        -  ``n`` - an integer
    175174       
    176175        -  ``names`` - generator names
     176   
     177        EXAMPLES::
     178   
     179        sage: F.<x,y,z> = FreeAlgebra(QQ, 3); F # indirect doctet
     180        Free Algebra on 3 generators (x, y, z) over Rational Field
    177181        """
    178182        if not isinstance(R, Ring):
    179183            raise TypeError, "Argument R must be a ring."
     
    254258            sage: print F  # indirect doctest
    255259            Free Algebra on 3 generators (x0, x1, x2) over Rational Field
    256260            sage: F.rename('QQ<<x0,x1,x2>>')
    257             sage: print F
     261            sage: print F #indirect doctest
    258262            QQ<<x0,x1,x2>>
    259263            sage: FreeAlgebra(ZZ,1,['a'])
    260264            Free Algebra on 1 generators (a,) over Integer Ring
     
    315319       
    316320        ::
    317321       
    318             sage: F._coerce_(x*y)
     322            sage: F._coerce_(x*y) # indirect doctest
    319323            x*y
    320324       
    321325        Elements of the integers coerce in, since there is a coerce map
     
    427431        which form a free basis for the module of A, and a list of
    428432        matrices, which give the action of the free generators of A on this
    429433        monomial basis.
     434        Quaternion algebra defined in terms of three generators::
     435       
     436        sage: n = 3
     437        sage: A = FreeAlgebra(QQ,n,'i')
     438        sage: F = A.monoid()
     439        sage: i, j, k = F.gens()
     440        sage: mons = [ F(1), i, j, k ]
     441        sage: M = MatrixSpace(QQ,4)
     442        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]) ]
     443        sage: H.<i,j,k> = A.quotient(mons, mats); H
     444        Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field
    430445        """
    431446        import free_algebra_quotient
    432447        return free_algebra_quotient.FreeAlgebraQuotient(self, mons, mats, names)
     
    456471        """
    457472        return self.__monoid
    458473   
    459                    
     474    def g_algebra(self, relations, order='degrevlex', check = True):
     475        """
     476           
     477            The G-Algebra derrived from this algebra by relations.
     478            By default is assumed, that two variables commute.
     479
     480           
     481            TODO:
     482            * Coercion doesn't work yet, there is some cheating about assumptions
     483            * The optional argument check controlls checking the degeneracy conditions
     484            Furthermore, the default values interfere with non degeneracy conditions...
     485           
     486            EXAMPLES:
     487            sage: A.<x,y,z>=FreeAlgebra(QQ,3)
     488            sage: G=A.g_algebra({y*x:-x*y})
     489            sage: (x,y,z)=G.gens()
     490            sage: x*y
     491            x*y
     492            sage: y*x
     493            -x*y
     494            sage: z*x
     495            x*z
     496            sage: (x,y,z)=A.gens()
     497            sage: G=A.g_algebra({y*x:-x*y+1})
     498            sage: (x,y,z)=G.gens()
     499            sage: y*x
     500            -x*y + 1
     501            sage: (x,y,z)=A.gens()
     502            sage: G=A.g_algebra({y*x:-x*y+z})
     503            sage: (x,y,z)=G.gens()
     504            sage: y*x
     505            -x*y + z
     506        """
     507        from sage.matrix.constructor  import Matrix
     508        from sage.rings.polynomial.plural import NCPolynomialRing_plural
     509       
     510        base_ring=self.base_ring()
     511        n=self.ngens()
     512        cmat=Matrix(base_ring,n)
     513        dmat=Matrix(self,n)
     514        for i in xrange(n):
     515            for j in xrange(i+1,n):
     516                cmat[i,j]=1
     517        for (to_commute,commuted) in relations.iteritems():
     518            #This is dirty, coercion is broken
     519            assert isinstance(to_commute,FreeAlgebraElement), to_commute.__class__
     520            assert isinstance(commuted,FreeAlgebraElement), commuted
     521            ((v1,e1),(v2,e2))=list(list(to_commute)[0][1])
     522            assert e1==1
     523            assert e2==1
     524            assert v1>v2
     525            c_coef=None
     526            d_poly=None
     527            for (c,m) in commuted:
     528                if list(m)==[(v2,1),(v1,1)]:
     529                    c_coef=c
     530                    #buggy coercion workaround
     531                    d_poly=commuted-self(c)*self(m)
     532                    break
     533            assert not c_coef is None,list(m)
     534            v2_ind = self.gens().index(v2)
     535            v1_ind = self.gens().index(v1)
     536            cmat[v2_ind,v1_ind]=c_coef
     537            if d_poly:
     538                dmat[v2_ind,v1_ind]=d_poly
     539       
     540        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat, order=order, check=check)
     541           
     542           
    460543from sage.misc.cache import Cache
    461544cache = 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 name 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): # , debug = False
     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#        if debug:
     294#        rDebugPrint(self._ring)
     295           
    158296cdef class Resolution:
    159297    """
    160298    A simple wrapper around Singular's resolutions.
     
    171309           sage: M = syz(I)
    172310           sage: resolution = mres(M, 0)
    173311        """
    174         assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular)
    175         self.base_ring = <MPolynomialRing_libsingular> base_ring
     312        #FIXME: still not working noncommutative
     313        assert is_sage_wrapper_for_singular_ring(base_ring)
     314        self.base_ring = base_ring
    176315    def __repr__(self):
    177316        """
    178317        EXAMPLE::
     
    230369    args.CleanUp()
    231370    omFreeBin(args, sleftv_bin)
    232371
     372# =====================================
     373# = Singular/Plural Abstraction Layer =
     374# =====================================
    233375
    234 def all_polynomials(s):
     376def is_sage_wrapper_for_singular_ring(ring):
     377    """
     378    Check whether wrapped ring arises from Singular or Singular/Plural
     379
     380    EXAMPLE::
     381
     382    sage: from sage.libs.singular.function import is_sage_wrapper_for_singular_ring
     383    sage: P.<x,y,z> = QQ[]
     384    sage: is_sage_wrapper_for_singular_ring(P)
     385    True
     386
     387    sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     388    sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
     389    sage: is_sage_wrapper_for_singular_ring(P)
     390    True
     391
     392    """
     393    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     394        return True
     395    if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     396        return True
     397    return False
     398
     399cdef new_sage_polynomial(ring,  poly *p):
     400    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     401        return new_MP(ring, p)
     402    else:
     403        if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     404            return new_NCP(ring, p)
     405    raise ValueError("not a singular or plural ring")
     406
     407def is_singular_poly_wrapper(p):
     408    """
     409        checks if p is some data type corresponding to some singular ``poly```.
     410       
     411        EXAMPLE::
     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        EXAMPLE::
     448            # sage: P.<a,b,c> = PolynomialRing(QQ)
     449            #  sage: p=a+b
     450            #  sage: from sage.libs.singular.function import access_singular_poly
     451            #  sage: access_singular_poly(p)
     452    """
     453    if PY_TYPE_CHECK(p, MPolynomial_libsingular):
     454        return (<MPolynomial_libsingular> p)._poly
     455    else:
     456        if PY_TYPE_CHECK(p, NCPolynomial_plural):
     457            return (<NCPolynomial_plural> p)._poly
     458    raise ValueError("not a singular polynomial wrapper")
     459
     460cdef ring* access_singular_ring(r) except <ring*> -1:
     461    """
     462        Get the singular ``ring`` pointer from a
     463        wrapper object.
     464       
     465        EXAMPLE::
     466            # sage: P.<x,y,z> = QQ[]
     467            # sage: from sage.libs.singular.function import access_singular_ring
     468            # sage: access_singular_ring(P)
     469
     470    """
     471    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular):
     472        return (<MPolynomialRing_libsingular> r )._ring
     473    if PY_TYPE_CHECK(r, NCPolynomialRing_plural):
     474        return (<NCPolynomialRing_plural> r )._ring
     475    raise ValueError("not a singular polynomial ring wrapper")
     476 
     477cdef poly* copy_sage_polynomial_into_singular_poly(p):
     478    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent()))
     479
    253480def all_vectors(s):
    254481    """
    255482    Checks if a sequence ``s`` consists of free module
     
    270497        False
    271498    """
    272499    for p in s:
    273         if not (isinstance(p, FreeModuleElement_generic_dense)\
    274             and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)):
     500        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\
     501            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())):
    275502            return False
    276503    return True
    277504
    278505
    279506
     507
     508
     509
     510
    280511cdef class Converter(SageObject):
    281512    """
    282513    A :class:`Converter` interfaces between Sage objects and Singular
     
    305536        """
    306537        cdef leftv *v
    307538        self.args = NULL
    308         self._ring = ring
     539        self._sage_ring = ring
     540        if ring is not None:
     541            self._singular_ring = access_singular_ring(ring)
     542       
    309543        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    310544        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
     545        from sage.matrix.matrix_generic_dense import Matrix_generic_dense
    311546        for a in args:
    312             if PY_TYPE_CHECK(a, MPolynomial_libsingular):
    313                 v = self.append_polynomial(<MPolynomial_libsingular> a)
     547            if is_singular_poly_wrapper(a):
     548                v = self.append_polynomial(a)
    314549
    315             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
    316                 v = self.append_ring(<MPolynomialRing_libsingular> a)
     550            elif is_sage_wrapper_for_singular_ring(a):
     551                v = self.append_ring(a)
    317552
    318             elif PY_TYPE_CHECK(a, MPolynomialIdeal):
     553            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     554                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    319555                v = self.append_ideal(a)
    320556
    321557            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long):
     
    329565
    330566            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    331567                v = self.append_intmat(a)
    332 
     568           
     569            elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\
     570                is_sage_wrapper_for_singular_ring(a.parent().base_ring()):
     571                self.append_matrix(a)
     572           
    333573            elif PY_TYPE_CHECK(a, Resolution):
    334574                v = self.append_resolution(a)
    335575
    336576            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    337                 and isinstance(
    338                     a.parent().base_ring(),
    339                     MPolynomialRing_libsingular):
     577                and is_sage_wrapper_for_singular_ring(
     578                    a.parent().base_ring()):
    340579                v = self.append_vector(a)
    341580               
    342581            # as output ideals get converted to sequences
     
    344583            # this means, that Singular lists should not be converted to Sequences,
    345584            # as we do not want ambiguities
    346585            elif PY_TYPE_CHECK(a, Sequence_generic)\
    347                 and all_polynomials(a):
     586                and all_singular_poly_wrapper(a):
    348587                v = self.append_ideal(ring.ideal(a))
    349588            elif PY_TYPE_CHECK(a, PolynomialSequence):
    350589                v = self.append_ideal(ring.ideal(a))
     
    365604                    v = self.append_intvec(a)
    366605                else:
    367606                    v = self.append_list(a)
    368             elif a.parent() is self._ring.base_ring():
     607            elif a.parent() is self._sage_ring.base_ring():
    369608                v = self.append_number(a)
    370609
    371610            elif PY_TYPE_CHECK(a, Integer):
     
    394633            sage: Converter([a,b,c],ring=P).ring()
    395634            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    396635        """
    397         return self._ring
     636        return self._sage_ring
    398637
    399638    def _repr_(self):
    400639        """
     
    405644            sage: Converter([a,b,c],ring=P) # indirect doctest
    406645            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    407646        """
    408         return "Singular Converter in %s"%(self._ring)
     647        return "Singular Converter in %s"%(self._sage_ring)
    409648
    410649    def __dealloc__(self):
    411650        if self.args:
     
    470709        Convert singular matrix to matrix over the polynomial ring.
    471710        """
    472711        from sage.matrix.constructor import Matrix
    473         sage_ring = self._ring
    474         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
    475             sage_ring)._ring
     712        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
     713        #    self._sage_ring)._ring
    476714        ncols = mat.ncols
    477715        nrows = mat.nrows
    478         result = Matrix(sage_ring, nrows, ncols)
    479         cdef MPolynomial_libsingular p
     716        result = Matrix(self._sage_ring, nrows, ncols)
    480717        for i in xrange(nrows):
    481718            for j in xrange(ncols):
    482                 p = MPolynomial_libsingular(sage_ring)
    483                 p._poly = mat.m[i*ncols+j]
     719                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j])
    484720                mat.m[i*ncols+j]=NULL
    485721                result[i,j] = p
    486722        return result
    487723   
    488724    cdef to_sage_vector_destructive(self, poly *p, free_module = None):
    489         cdef ring *r=self._ring._ring
     725        #cdef ring *r=self._ring._ring
    490726        cdef int rank
    491727        if free_module:
    492728            rank = free_module.rank()
    493729        else:
    494             rank = singular_vector_maximal_component(p, r)
    495             free_module = self._ring**rank
     730            rank = singular_vector_maximal_component(p, self._singular_ring)
     731            free_module = self._sage_ring**rank
    496732        cdef poly *acc
    497733        cdef poly *p_iter
    498734        cdef poly *first
     
    505741            first = NULL
    506742            p_iter=p
    507743            while p_iter != NULL:
    508                 if p_GetComp(p_iter, r) == i:
    509                     p_SetComp(p_iter,0, r)
    510                     p_Setm(p_iter, r)
     744                if p_GetComp(p_iter, self._singular_ring) == i:
     745                    p_SetComp(p_iter,0, self._singular_ring)
     746                    p_Setm(p_iter, self._singular_ring)
    511747                    if acc == NULL:
    512748                        first = p_iter
    513749                    else:
     
    522758                else:
    523759                    previous = p_iter
    524760                    p_iter = pNext(p_iter)
    525             result.append(new_MP(self._ring, first))
     761           
     762            result.append(new_sage_polynomial(self._sage_ring, first))
    526763        return free_module(result)
    527764         
    528765    cdef object to_sage_module_element_sequence_destructive( self, ideal *i):
     
    536773        - ``r`` -- a SINGULAR ring
    537774        - ``sage_ring`` -- a Sage ring matching r
    538775        """
    539         cdef MPolynomialRing_libsingular sage_ring = self._ring
     776        #cdef MPolynomialRing_libsingular sage_ring = self._ring
    540777        cdef int j
    541778        cdef int rank=i.rank
    542         free_module = sage_ring**rank       
     779        free_module = self._sage_ring ** rank       
    543780        l = []
    544781
    545782        for j from 0 <= j < IDELEMS(i):
     
    568805        return result
    569806   
    570807   
    571     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL:
     808    cdef leftv *append_polynomial(self, p) except NULL:
    572809        """
    573810        Append the polynomial ``p`` to the list.
    574811        """
    575         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring)
     812        cdef poly* _p
     813        _p = copy_sage_polynomial_into_singular_poly(p)
     814               
    576815        return self._append(_p, POLY_CMD)
    577816
    578817    cdef leftv *append_ideal(self,  i) except NULL:
     
    589828        """
    590829        rank = max([v.parent().rank() for v in m])
    591830        cdef ideal *result
    592         cdef ring *r = self._ring._ring
     831        cdef ring *r = self._singular_ring
    593832        cdef ideal *i
    594833        cdef int j = 0
    595834
     
    605844        """
    606845        Append the number ``n`` to the list.
    607846        """
    608         cdef number *_n =  sa2si(n, self._ring._ring)
     847        cdef number *_n =  sa2si(n, self._singular_ring)
    609848        return self._append(<void *>_n, NUMBER_CMD)
    610849
    611     cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL:
     850    cdef leftv *append_ring(self, r) except NULL:
    612851        """
    613852        Append the ring ``r`` to the list.
    614853        """
    615         cdef ring *_r =  <ring*> r._ring
     854        cdef ring *_r =  access_singular_ring(r)
    616855        _r.ref+=1
    617856        return self._append(<void *>_r, RING_CMD)
    618857
    619858    cdef leftv *append_matrix(self, mat) except NULL:
    620859       
    621860        sage_ring = mat.base_ring()
    622         cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring
     861        cdef ring *r=<ring*> access_singular_ring(sage_ring)
    623862
    624863        cdef poly *p
    625864        ncols = mat.ncols()
     
    627866        cdef matrix* _m=mpNew(nrows,ncols)
    628867        for i in xrange(nrows):
    629868            for j in xrange(ncols):
    630                 p = p_Copy(
    631                     (<MPolynomial_libsingular> mat[i,j])._poly, r)
     869                #FIXME
     870                p = copy_sage_polynomial_into_singular_poly(mat[i,j])
    632871                _m.m[ncols*i+j]=p
    633872        return self._append(_m, MATRIX_CMD)
    634873
     
    646885        Append the list ``l`` to the list.
    647886        """
    648887       
    649         cdef Converter c = Converter(l, self._ring)
     888        cdef Converter c = Converter(l, self._sage_ring)
    650889        n = len(c)
    651890
    652891        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin)
     
    677916        Append vector ``v`` from free
    678917        module over polynomial ring.
    679918        """
    680         cdef ring *r = self._ring._ring
     919        cdef ring *r = self._singular_ring
    681920        cdef poly *p = sage_vector_to_poly(v, r)
    682921        return self._append(<void*> p, VECTOR_CMD)
    683922   
     
    717956
    718957        - ``to_convert`` - a Singular ``leftv``
    719958        """
     959        #FIXME
    720960        cdef MPolynomial_libsingular res_poly
    721961        cdef int rtyp = to_convert.rtyp
    722962        cdef lists *singular_list
    723963        cdef Resolution res_resolution
    724964        if rtyp == IDEAL_CMD:
    725             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring)
     965            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring)
    726966
    727967        elif rtyp == POLY_CMD:
    728             res_poly = MPolynomial_libsingular(self._ring)
     968            #FIXME
     969            res_poly = MPolynomial_libsingular(self._sage_ring)
    729970            res_poly._poly = <poly*>to_convert.data
    730971            to_convert.data = NULL
    731972            #prevent it getting free, when cleaning the leftv
     
    735976            return <long>to_convert.data
    736977       
    737978        elif rtyp == NUMBER_CMD:
    738             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring())
     979            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring())
    739980
    740981        elif rtyp == INTVEC_CMD:
    741982            return si2sa_intvec(<intvec *>to_convert.data)
     
    751992           
    752993
    753994        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
     995            return new_RingWrap( <ring*> to_convert.data )
    758996
    759997        elif rtyp == MATRIX_CMD:
    760998            return self.to_sage_matrix(<matrix*>  to_convert.data )
     
    7771015            return self.to_sage_integer_matrix(
    7781016                <intvec*> to_convert.data)
    7791017        elif rtyp == RESOLUTION_CMD:
    780             res_resolution = Resolution(self._ring)
     1018            res_resolution = Resolution(self._sage_ring)
    7811019            res_resolution._resolution = <syStrategy*> to_convert.data
    7821020            res_resolution._resolution.references += 1
    7831021            return res_resolution
     
    9461184        """
    9471185        return "%s (singular function)" %(self._name)
    9481186
    949     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None):
     1187    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None):
    9501188        """
    9511189        Call this function with the provided arguments ``args`` in the
    9521190        ring ``R``.
     
    10261264        """
    10271265        if ring is None:
    10281266            ring = self.common_ring(args, ring)
    1029         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     1267        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \
     1268                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)):
    10301269            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring)))
    10311270        return call_function(self, args, ring, interruptible, attributes)
    10321271   
     
    10851324        singular_doc = get_docstring(self._name).split('\n')
    10861325        return prefix + "\n::\n\n"+'\n'.join(["    "+L for L in singular_doc])
    10871326
    1088     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None):
     1327    cdef common_ring(self, tuple args, ring=None):
    10891328        """
    10901329        Return the common ring for the argument list ``args``.
    10911330
     
    11031342        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    11041343        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
    11051344        for a in args:
    1106             if PY_TYPE_CHECK(a, MPolynomialIdeal):
     1345            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     1346                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    11071347                ring2 = a.ring()
    1108             elif PY_TYPE_CHECK(a, MPolynomial_libsingular):
     1348            elif is_singular_poly_wrapper(a):
    11091349                ring2 = a.parent()
    1110             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
     1350            elif is_sage_wrapper_for_singular_ring(a):
    11111351                ring2 = a
    1112             elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring):
     1352            elif PY_TYPE_CHECK(a, int) or\
     1353                PY_TYPE_CHECK(a, long) or\
     1354                PY_TYPE_CHECK(a, basestring):
    11131355                continue
    11141356            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    11151357                continue
     
    11221364            elif PY_TYPE_CHECK(a, Resolution):
    11231365                ring2 = (<Resolution> a).base_ring
    11241366            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    1125                 and PY_TYPE_CHECK(
    1126                     a.parent().base_ring(),
    1127                      MPolynomialRing_libsingular):
     1367                and is_sage_wrapper_for_singular_ring(
     1368                    a.parent().base_ring()):
    11281369                ring2 = a.parent().base_ring()
    11291370            elif ring is not None:
    11301371                a.parent() is ring
     
    11361377                raise ValueError("Rings do not match up.")
    11371378        if ring is None:
    11381379            raise ValueError("Could not detect ring.")
    1139         return <MPolynomialRing_libsingular>ring
     1380        return ring
    11401381
    11411382    def __reduce__(self):
    11421383        """
     
    11671408        else:
    11681409            return cmp(self._name, (<SingularFunction>other)._name)
    11691410
    1170 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None):
     1411cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None):
    11711412    global currRingHdl
    11721413    global errorreported
    11731414    global currentVoice
     
    11751416    global error_messages
    11761417
    11771418
    1178     cdef ring *si_ring = R._ring
    1179 
     1419    cdef ring *si_ring
     1420    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular):
     1421        si_ring = (<MPolynomialRing_libsingular>R)._ring
     1422    else:
     1423        si_ring = (<NCPolynomialRing_plural>R)._ring
     1424 
    11801425    if si_ring != currRing:
    11811426        rChangeCurrRing(si_ring)
    11821427
     
    14181663        <Resolution>
    14191664        sage: singular_list(resolution)
    14201665        [[(-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)]]
    1421 
     1666        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
     1667        sage: from sage.matrix.constructor  import Matrix
     1668        sage: c=Matrix(2)
     1669        sage: c[0,1]=-1
     1670        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
     1671        sage: (x,y)=P.gens()
     1672        sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y)
     1673        sage: twostd = singular_function("twostd")
     1674        sage: twostd(I)
     1675        [x + y, y^2]
     1676        sage: M=syz(I)
     1677        doctest...
     1678        sage: M
     1679        [(x + y, x*y)]
     1680        sage: syz(M, ring=P)
     1681        [(0)]
     1682        sage: mres(I, 0)
     1683        <Resolution>
     1684        sage: M=P**3
     1685        sage: v=M((100*x,5*y,10*y*x*y))
     1686        sage: leadcoef(v)
     1687        -10
     1688        sage: v = M([x+y,x*y+y**3,x])
     1689        sage: lead(v)
     1690        (0, y^3)
     1691        sage: jet(v, 2)
     1692        (x + y, x*y, x)
     1693        sage: l = ringlist(P)
     1694        sage: len(l)
     1695        6
     1696        sage: ring(l, ring=P)
     1697        <noncommutative RingWrap>
     1698        sage: I=twostd(I)
     1699        sage: l[3]=I
     1700        sage: ring(l, ring=P)
     1701        <noncommutative RingWrap>
    14221702       
    14231703    """
    14241704
     
    14901770                    ph = IDNEXT(ph)
    14911771        h = IDNEXT(h)
    14921772    return l
     1773
     1774
     1775#cdef ring*?
     1776cdef inline RingWrap new_RingWrap(ring* r):
     1777    cdef RingWrap ring_wrap_result = PY_NEW(RingWrap)
     1778    ring_wrap_result._ring = r
     1779    ring_wrap_result._ring.ref += 1
     1780   
     1781    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   
     
    9861002
    9871003    cdef int LANG_TOP
    9881004
     1005# Non-commutative functions
     1006    ctypedef enum nc_type:
     1007      nc_error # Something's gone wrong!
     1008      nc_general # yx=q xy+...
     1009      nc_skew # yx=q xy
     1010      nc_comm # yx= xy
     1011      nc_lie,  # yx=xy+...
     1012      nc_undef, # for internal reasons */
     1013      nc_exterior #
     1014
     1015 
     1016cdef extern from "gring.h":
     1017    void ncRingType(ring *, nc_type)
     1018    nc_type ncRingType_get "ncRingType" (ring *)
     1019    int nc_CallPlural(matrix* CC, matrix* DD, poly* CN, poly* DN, ring* r)
     1020    bint nc_SetupQuotient(ring *, ring *, bint)
     1021   
     1022cdef extern from "sca.h":
     1023    void sca_p_ProcsSet(ring *, p_Procs_s *)
     1024    void scaFirstAltVar(ring *, int)
     1025    void scaLastAltVar(ring *, int)
     1026
     1027cdef extern from "ring.h":
     1028    bint rIsPluralRing(ring* r)
     1029    void rPrint "rWrite"(ring* r)
     1030    char* rOrderingString "rOrdStr"(ring* r)
     1031#    void rDebugPrint(ring* r)
     1032    void pDebugPrint "p_DebugPrint" (poly*p, ring* r)
     1033   
    9891034cdef extern from "stairc.h":
    9901035    # Computes the monomial basis for R[x]/I
    9911036    ideal *scKBase(int deg, ideal *s, ideal *Q)
  • sage/modules/free_module.py

    diff --git a/sage/modules/free_module.py b/sage/modules/free_module.py
    a b  
    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        """
     
    350356        if not isinstance(sparse,bool):
    351357            raise TypeError, "Argument sparse (= %s) must be True or False" % sparse
    352358
     359
     360        # We should have two sided, left sided and right sided ideals,
     361        # but that's another story ....
     362        #
    353363        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:
     364            warn("""You are constructing a free module   over a noncommutative ring. Sage does
     365             not have a concept of left/right and both sided modules, so be careful. It's also
     366             not guaranteed that all multiplications are done from the right side.""")
     367
     368        #            raise TypeError, "The base_ring must be a commutative ring."
     369
     370        try:
     371            if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class):
     372                return RealDoubleVectorSpace_class(rank)
     373
     374            elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class):
     375                return ComplexDoubleVectorSpace_class(rank)
     376
     377            elif base_ring.is_field():
     378                return FreeModule_ambient_field(base_ring, rank, sparse=sparse)
     379
     380            elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain):
    370381                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:
     382
     383            elif isinstance(base_ring, sage.rings.number_field.order.Order) \
     384                and base_ring.is_maximal() and base_ring.class_number() == 1:
     385                return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
     386
     387            elif isinstance(base_ring, integral_domain.IntegralDomain) or base_ring.is_integral_domain():
     388                return FreeModule_ambient_domain(base_ring, rank, sparse=sparse)
     389
     390            else:
     391                return FreeModule_ambient(base_ring, rank, sparse=sparse)
     392        except NotImplementedError:
    376393            return FreeModule_ambient(base_ring, rank, sparse=sparse)
    377394
    378395
     
    563580            Category of modules with basis over Integer Ring
    564581
    565582        """
    566         if not isinstance(base_ring, commutative_ring.CommutativeRing):
    567             raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
     583        if not base_ring.is_commutative():
     584            warn("""You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules be careful. It's also not guarantied that all multiplications are done from the right side.""")
     585            #raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
     586           
    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  
    431431        sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
    432432        sage: J = sage.rings.ideal.Cyclic(P).homogenize()
    433433        sage: from sage.misc.sageinspect import sage_getsource
    434         sage: "buchberger" in sage_getsource(J.interreduced_basis)
     434        sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest
    435435        True
    436436
    437437    The following tests against a bug that was fixed in trac ticket #11298::
     
    647647        EXAMPLES::
    648648       
    649649            sage: R.<a,b,c,d,e,f,g,h,i,j> = PolynomialRing(GF(127),10)
    650             sage: I = sage.rings.ideal.Cyclic(R,4)
    651             sage: magma(I)                                          # optional - magma
     650            sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest
     651            sage: magma(I)    # optional - magma
    652652            Ideal of Polynomial ring of rank 10 over GF(127)
    653653            Order: Graded Reverse Lexicographical
    654654            Variables: a, b, c, d, e, f, g, h, i, j
     
    730730        B = PolynomialSequence([R(e) for e in mgb], R, immutable=True)
    731731        return B
    732732
    733 class MPolynomialIdeal_singular_repr:
     733class MPolynomialIdeal_singular_base_repr:
     734    @require_field
     735    def syzygy_module(self):
     736        r"""
     737        Computes the first syzygy (i.e., the module of relations of the
     738        given generators) of the ideal.
     739       
     740        EXAMPLE::
     741       
     742            sage: R.<x,y> = PolynomialRing(QQ)
     743            sage: f = 2*x^2 + y
     744            sage: g = y
     745            sage: h = 2*f + g
     746            sage: I = Ideal([f,g,h])
     747            sage: M = I.syzygy_module(); M
     748            [       -2        -1         1]
     749            [       -y 2*x^2 + y         0]
     750            sage: G = vector(I.gens())
     751            sage: M*G
     752            (0, 0)
     753       
     754        ALGORITHM: Uses Singular's syz command
     755        """
     756        import sage.libs.singular
     757        syz = sage.libs.singular.ff.syz
     758        from sage.matrix.constructor import matrix
     759
     760        #return self._singular_().syz().transpose().sage_matrix(self.ring())
     761        S = syz(self)
     762        return matrix(self.ring(), S)
     763
     764    @libsingular_standard_options
     765    def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
     766        """
     767        Return the reduced Groebner basis of this ideal. If the
     768        Groebner basis for this ideal has been calculated before the
     769        cached Groebner basis is returned regardless of the requested
     770        algorithm.
     771       
     772        INPUT:
     773       
     774        -  ``algorithm`` - see below for available algorithms
     775        - ``redsb`` - return a reduced Groebner basis (default: ``True``)
     776        - ``red_tail`` - perform tail reduction (default: ``True``)
     777
     778        ALGORITHMS:
     779       
     780        'groebner'
     781            Singular's heuristic script (default)
     782
     783        'std'
     784            Buchberger's algorithm
     785       
     786        'slimgb'
     787            the *SlimGB* algorithm
     788
     789        'stdhilb'
     790            Hilbert Basis driven Groebner basis
     791       
     792        'stdfglm'
     793            Buchberger and FGLM
     794       
     795        EXAMPLES:
     796       
     797        We compute a Groebner basis of 'cyclic 4' relative to
     798        lexicographic ordering. ::
     799       
     800            sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
     801            sage: I = sage.rings.ideal.Cyclic(R,4); I
     802            Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
     803            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
     804            Ring in a, b, c, d over Rational Field
     805       
     806        ::
     807       
     808            sage: I._groebner_basis_libsingular()
     809            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
     810            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
     811            b^2 + 2*b*d + d^2, a + b + c + d]
     812       
     813        ALGORITHM:
     814
     815        Uses libSINGULAR.
     816        """
     817        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular
     818        from sage.libs.singular import singular_function
     819        from sage.libs.singular.option import opt
     820
     821        import sage.libs.singular
     822        groebner = sage.libs.singular.ff.groebner
     823
     824        if get_verbose()>=2:
     825            opt['prot'] = True
     826        for name,value in kwds.iteritems():
     827            if value is not None:
     828                opt[name] = value
     829
     830        T = self.ring().term_order()
     831       
     832        if algorithm == "std":
     833            S = std_libsingular(self)
     834        elif algorithm == "slimgb":
     835            S = slimgb_libsingular(self)
     836        elif algorithm == "groebner":
     837            S = groebner(self)
     838        else:
     839            try:
     840                fnc = singular_function(algorithm)
     841                S = fnc(self)
     842            except NameError:
     843                raise NameError("Algorithm '%s' unknown"%algorithm)
     844        return S
     845
     846
     847class MPolynomialIdeal_singular_repr(
     848        MPolynomialIdeal_singular_base_repr):
    734849    """
    735850    An ideal in a multivariate polynomial ring, which has an
    736851    underlying Singular ring associated to it.
     
    15231638            print "Highest degree reached during computation: %2d."%log_parser.max_deg
    15241639        return S
    15251640
    1526     @libsingular_standard_options
    1527     def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
    1528         """
    1529         Return the reduced Groebner basis of this ideal. If the
    1530         Groebner basis for this ideal has been calculated before the
    1531         cached Groebner basis is returned regardless of the requested
    1532         algorithm.
    1533        
    1534         INPUT:
    1535        
    1536         -  ``algorithm`` - see below for available algorithms
    1537         - ``redsb`` - return a reduced Groebner basis (default: ``True``)
    1538         - ``red_tail`` - perform tail reduction (default: ``True``)
    1539 
    1540         ALGORITHMS:
    1541        
    1542         'groebner'
    1543             Singular's heuristic script (default)
    1544 
    1545         'std'
    1546             Buchberger's algorithm
    1547        
    1548         'slimgb'
    1549             the *SlimGB* algorithm
    1550 
    1551         'stdhilb'
    1552             Hilbert Basis driven Groebner basis
    1553        
    1554         'stdfglm'
    1555             Buchberger and FGLM
    1556        
    1557         EXAMPLES:
    1558        
    1559         We compute a Groebner basis of 'cyclic 4' relative to
    1560         lexicographic ordering. ::
    1561        
    1562             sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
    1563             sage: I = sage.rings.ideal.Cyclic(R,4); I
    1564             Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
    1565             + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
    1566             Ring in a, b, c, d over Rational Field
    1567        
    1568         ::
    1569        
    1570             sage: I._groebner_basis_libsingular()
    1571             [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
    1572             b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
    1573             b^2 + 2*b*d + d^2, a + b + c + d]
    1574        
    1575         ALGORITHM:
    1576 
    1577         Uses libSINGULAR.
    1578         """
    1579         from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular
    1580         from sage.libs.singular import singular_function
    1581         from sage.libs.singular.option import opt
    1582 
    1583         import sage.libs.singular
    1584         groebner = sage.libs.singular.ff.groebner
    1585 
    1586         if get_verbose()>=2:
    1587             opt['prot'] = True
    1588         for name,value in kwds.iteritems():
    1589             if value is not None:
    1590                 opt[name] = value
    1591 
    1592         T = self.ring().term_order()
    1593        
    1594         if algorithm == "std":
    1595             S = std_libsingular(self)
    1596         elif algorithm == "slimgb":
    1597             S = slimgb_libsingular(self)
    1598         elif algorithm == "groebner":
    1599             S = groebner(self)
    1600         else:
    1601             try:
    1602                 fnc = singular_function(algorithm)
    1603                 S = fnc(self)
    1604             except NameError:
    1605                 raise NameError("Algorithm '%s' unknown"%algorithm)
    1606         return S
    1607    
    16081641    @require_field
    16091642    def genus(self):
    16101643        """
     
    16651698            False
    16661699        """
    16671700        R = self.ring()
     1701
    16681702        if not isinstance(other, MPolynomialIdeal_singular_repr) or other.ring() != R:
    16691703            raise ValueError, "other must be an ideal in the ring of self, but it isn't."
    16701704
     
    25712605       
    25722606            sage: R.<x,y,z> = PolynomialRing(QQ)
    25732607            sage: I = R.ideal(x^2-2*x*z+5, x*y^2+y*z+1, 3*y^2-8*x*z)
    2574             sage: I.normal_basis()
     2608            sage: I.normal_basis() #indirect doctest
    25752609            [z^2, y*z, x*z, z, x*y, y, x, 1]
    25762610        """
    25772611        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular
     
    26272661    def _macaulay2_(self, macaulay2=None):
    26282662        """
    26292663        Return Macaulay2 ideal corresponding to this ideal.
     2664    EXAMPLES::
     2665   
     2666        sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
     2667        sage: I = ideal(x*y-z^2, y^2-w^2)  #indirect doctest
     2668        sage: macaulay2(I) # optional - macaulay2
     2669        Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring
    26302670        """
    26312671        if macaulay2 is None: macaulay2 = macaulay2_default
    26322672        try:
     
    27082748        R = self.ring()
    27092749        return R(k)
    27102750
     2751class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_generic):
     2752    def __init__(self, ring, gens, coerce=True):
     2753        r"""
     2754        Computes a non-commutative ideal.
     2755       
     2756        EXAMPLES::
     2757       
     2758            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2759            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2760            sage: H.inject_variables()
     2761            Defining x, y, z
     2762
     2763            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) # indirect doctest
     2764        """
     2765        Ideal_generic.__init__(self, ring, gens, coerce=coerce)
     2766
     2767    def __call_singular(self, cmd, arg = None):
     2768        """
     2769        Internal function for calling a Singular function
     2770
     2771        INPUTS:
     2772
     2773        - ``cmd`` - string, representing a Singular function
     2774
     2775        - ``arg`` (Default: None) - arguments for which cmd is called
     2776
     2777        OUTPUTS:
     2778
     2779        - result of the Singular function call
     2780
     2781        EXAMPLES::
     2782
     2783            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2784            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2785            sage: H.inject_variables()
     2786            Defining x, y, z
     2787            sage: id = H.ideal(x + y, y + z)
     2788            sage: id.std()  # indirect doctest
     2789            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}
     2790        """
     2791        from sage.libs.singular.function import singular_function
     2792        fun = singular_function(cmd)
     2793        if arg is None:
     2794             return fun(self, ring=self.ring())
     2795       
     2796        return fun(self, arg, ring=self.ring())
     2797
     2798    def std(self):
     2799        r"""
     2800        Computes a left GB of the ideal.
     2801       
     2802        EXAMPLES::
     2803       
     2804            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2805            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2806            sage: H.inject_variables()
     2807            Defining x, y, z
     2808            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2809            sage: I.std()
     2810            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...
     2811       
     2812        ALGORITHM: Uses Singular's std command
     2813        """
     2814        return self.ring().ideal( self.__call_singular('std') )
     2815#        return self.__call_singular('std')
     2816
     2817    def twostd(self):
     2818        r"""
     2819        Computes a two-sided GB of the ideal.
     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.twostd()
     2829            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...
     2830       
     2831        ALGORITHM: Uses Singular's twostd command
     2832        """
     2833        return self.ring().ideal( self.__call_singular('twostd') )
     2834#        return self.__call_singular('twostd')
     2835
     2836#    def syz(self):
     2837#        return self.__call_singular('syz')
     2838
     2839    @require_field
     2840    def syzygy_module(self):
     2841        r"""
     2842        Computes the first syzygy (i.e., the module of relations of the
     2843        given generators) of the ideal.
     2844       
     2845        EXAMPLE::
     2846       
     2847            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2848            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2849            sage: H.inject_variables()
     2850            Defining x, y, z
     2851            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2852            sage: G = vector(I.gens()); G
     2853            doctest:357: UserWarning: You are constructing a free module   over a noncommutative ring. Sage does
     2854                         not have a concept of left/right and both sided modules be careful. It's also
     2855                         not guarantied that all multiplications are done from the right side.
     2856            doctest:573: UserWarning: You are constructing a free module over a noncommutative ring. Sage does not have a concept of left/right and both sided modules be careful. It's also not guarantied that all multiplications are done from the right side.
     2857            (y^2, x^2, z^2 - 1)
     2858            sage: M = I.syzygy_module(); M
     2859            [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2]
     2860            [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2]
     2861            [                                                              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]
     2862            [                 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]
     2863            [                                                              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]
     2864            [  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]
     2865            [                                                  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]
     2866            [                                                  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]
     2867            [                                                                           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]
     2868            [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]
     2869
     2870            sage: M*G
     2871            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
     2872       
     2873        ALGORITHM: Uses Singular's syz command
     2874        """
     2875        import sage.libs.singular
     2876        syz = sage.libs.singular.ff.syz
     2877        from sage.matrix.constructor import matrix
     2878
     2879        #return self._singular_().syz().transpose().sage_matrix(self.ring())
     2880        S = syz(self)
     2881        return matrix(self.ring(), S)
     2882
     2883
     2884    def res(self, length):
     2885        r"""
     2886        Computes the first syzygy (i.e., the module of relations of the
     2887        given generators) of the ideal.
     2888       
     2889        EXAMPLE::
     2890       
     2891            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2892            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2893            sage: H.inject_variables()
     2894            Defining x, y, z
     2895            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2896            sage: I.res(3)
     2897            <Resolution>
     2898        """
     2899        return self.__call_singular('res', length)
     2900
    27112901
    27122902class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \
    27132903                        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 nInvers, pp_Mult_nn, p_Delete, n_Delete
     68from sage.libs.singular.decl cimport rIsPluralRing
    6869
    6970from sage.structure.parent_base cimport ParentWithBase
    7071
    7172from sage.rings.polynomial.multi_polynomial_libsingular cimport new_MP
     73from sage.rings.polynomial.plural cimport new_NCP
    7274
    7375from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
    7476from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular
    7577from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
    7678from sage.structure.sequence import Sequence
    7779
     80from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_plural
     81
    7882cdef object singular_ideal_to_sage_sequence(ideal *i, ring *r, object parent):
    7983    """
    8084    convert a SINGULAR ideal to a Sage Sequence (the format Sage
     
    8892    """
    8993    cdef int j
    9094    cdef MPolynomial_libsingular p
     95    cdef NCPolynomial_plural p_nc
    9196               
    9297    l = []
    9398
    94     for j from 0 <= j < IDELEMS(i):
    95         p = new_MP(parent, p_Copy(i.m[j], r))
    96         l.append( p )
     99    if rIsPluralRing(r):
     100        for j from 0 <= j < IDELEMS(i):
     101            p_nc = new_NCP(parent, p_Copy(i.m[j], r))
     102            l.append( p_nc )
     103    else:
     104        for j from 0 <= j < IDELEMS(i):
     105            p = new_MP(parent, p_Copy(i.m[j], r))
     106            l.append( p )
    97107
    98108    return Sequence(l, check=False, immutable=True)
    99109
     
    113123    cdef ideal *i
    114124    cdef int j = 0
    115125
    116     if not PY_TYPE_CHECK(R,MPolynomialRing_libsingular):
     126    if PY_TYPE_CHECK(R,MPolynomialRing_libsingular):
     127        r = (<MPolynomialRing_libsingular>R)._ring
     128    elif PY_TYPE_CHECK(R, NCPolynomialRing_plural):
     129        r = (<NCPolynomialRing_plural>R)._ring
     130    else:
    117131        raise TypeError("Ring must be of type 'MPolynomialRing_libsingular'")
    118 
    119     r = (<MPolynomialRing_libsingular>R)._ring
     132       
     133    #r = (<MPolynomialRing_libsingular>R)._ring
    120134    rChangeCurrRing(r);
    121135
    122136    i = idInit(len(gens),1)
    123137    for f in gens:
    124         if not PY_TYPE_CHECK(f,MPolynomial_libsingular):
     138        if PY_TYPE_CHECK(f,MPolynomial_libsingular):
     139            i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r)
     140        elif PY_TYPE_CHECK(f, NCPolynomial_plural):
     141            i.m[j] = p_Copy((<NCPolynomial_plural>f)._poly, r)
     142        else:
    125143            id_Delete(&i, r)
    126144            raise TypeError("All generators must be of type MPolynomial_libsingular.")
    127         i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r)
     145        #i.m[j] = p_Copy((<MPolynomial_libsingular>f)._poly, r)
    128146        j+=1
    129147    return i
    130148
  • sage/rings/polynomial/multi_polynomial_libsingular.pyx

    diff --git a/sage/rings/polynomial/multi_polynomial_libsingular.pyx b/sage/rings/polynomial/multi_polynomial_libsingular.pyx
    a b  
    20172017        EXAMPLES::
    20182018
    20192019            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2020             sage: 3/2*x + 1/2*y + 1
     2020            sage: 3/2*x + 1/2*y + 1 #indirect doctest
    20212021            3/2*x + 1/2*y + 1
    20222022
    20232023        """
     
    20342034        EXAMPLES::
    20352035
    20362036            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2037             sage: 3/2*x - 1/2*y - 1
     2037            sage: 3/2*x - 1/2*y - 1 #indirect doctest
    20382038            3/2*x - 1/2*y - 1
    20392039
    20402040        """
     
    20532053        EXAMPLES::
    20542054
    20552055            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2056             sage: 3/2*x
     2056            sage: 3/2*x # indirect doctest
    20572057            3/2*x
    20582058        """
    20592059
     
    20652065        return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
    20662066       
    20672067    cpdef ModuleElement _lmul_(self, RingElement right):
    2068         # all currently implemented rings are commutative
    2069         return self._rmul_(right)
     2068        """
     2069        Multiply left and right.
     2070
     2071        EXAMPLES::
     2072
     2073            sage: P.<x,y,z>=PolynomialRing(QQ,3)
     2074            sage: (3/2*x - 1/2*y - 1) * (3/2) # indirect doctest
     2075            9/4*x - 3/4*y - 3/2
     2076        """
     2077        # all currently implemented baser rings are commutative
     2078        return right._rmul_(self)
    20702079       
    20712080    cpdef RingElement  _mul_(left, RingElement right):
    20722081        """
     
    20752084        EXAMPLES::
    20762085
    20772086            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2078             sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1)
     2087            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest
    20792088            9/4*x^2 - 1/4*y^2 - y - 1
    20802089
    20812090            sage: P.<x,y> = PolynomialRing(QQ,order='lex')
     
    20982107        EXAMPLES::
    20992108
    21002109            sage: R.<x,y>=PolynomialRing(QQ,2)
    2101             sage: f = (x + y)/3
     2110            sage: f = (x + y)/3 # indirect doctest
    21022111            sage: f.parent()
    21032112            Multivariate Polynomial Ring in x, y over Rational Field
    21042113
     
    22742283
    22752284            sage: P.<x,y,z> = QQ[]
    22762285            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
    2277             sage: latex(f)
     2286            sage: latex(f)  # indirect doctest
    22782287            - x^{2} y - \frac{25}{27} y^{3} - z^{2}
    22792288        """
    22802289        cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     
    42484257        EXAMPLES::
    42494258
    42504259            sage: R.<x,y> = PolynomialRing(GF(7), 2)
    4251             sage: f = (x^3 + 2*y^2*x)^7; f
     4260            sage: f = (x^3 + 2*y^2*x)^7; f          # indirect doctest
    42524261            x^21 + 2*x^7*y^14
    42534262
    42544263            sage: h = macaulay2(f); h               # optional
  • new file sage/rings/polynomial/plural.pxd

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

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

    diff --git a/sage/rings/polynomial/term_order.py b/sage/rings/polynomial/term_order.py
    a b  
    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)
    910
    1011cdef class CommutativeRing(Ring):
    1112    cdef public object __fraction_field
    12     cdef public object __ideal_monoid
    1313
    1414cdef class IntegralDomain(CommutativeRing):
    1515    pass
  • sage/rings/ring.pyx

    diff --git a/sage/rings/ring.pyx b/sage/rings/ring.pyx
    a b  
    11171117            if not x.is_zero():
    11181118                return x
    11191119
     1120    def ideal_monoid(self):
     1121        """
     1122        Return the monoid of ideals of this ring.
     1123
     1124        EXAMPLES::
     1125
     1126            sage: ZZ.ideal_monoid()
     1127            Monoid of ideals of Integer Ring
     1128            sage: R.<x>=QQ[]; R.ideal_monoid()
     1129            Monoid of ideals of Univariate Polynomial Ring in x over Rational Field
     1130        """
     1131        if self.__ideal_monoid is not None:
     1132            return self.__ideal_monoid
     1133        else:
     1134            from sage.rings.ideal_monoid import IdealMonoid
     1135            M = IdealMonoid(self)
     1136            self.__ideal_monoid = M
     1137            return M
     1138
    11201139cdef class CommutativeRing(Ring):
    11211140    """
    11221141    Generic commutative ring.
     
    12561275        """
    12571276        raise NotImplementedError
    12581277
    1259     def ideal_monoid(self):
    1260         """
    1261         Return the monoid of ideals of this ring.
    1262 
    1263         EXAMPLES::
    1264 
    1265             sage: ZZ.ideal_monoid()
    1266             Monoid of ideals of Integer Ring
    1267             sage: R.<x>=QQ[]; R.ideal_monoid()
    1268             Monoid of ideals of Univariate Polynomial Ring in x over Rational Field
    1269         """
    1270         if self.__ideal_monoid is not None:
    1271             return self.__ideal_monoid
    1272         else:
    1273             from sage.rings.ideal_monoid import IdealMonoid
    1274             M = IdealMonoid(self)
    1275             self.__ideal_monoid = M
    1276             return M
    1277 
    12781278    def quotient(self, I, names=None):
    12791279        """
    12801280        Create the quotient of R by the ideal I.