Ticket #4539: trac4539_libplural.patch

File trac4539_libplural.patch, 165.3 KB (added by SimonKing, 5 years ago)

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

  • module_list.py

    # HG changeset patch
    # User Simon King <simon.king@uni-jena.de>
    # Date 1300026255 -3600
    # Node ID 0e1053cf125248cb2022db53fec32f59853f3c28
    # Parent  11292a29b438b5a72776d0f5d80f799c3c4ac531
    Wrapper for Singular/Plural - Sage-Trac #4539.
    * * *
    MPolynomialRing_plural now accepts matrix parameters to specify commutativity
    relations. Added ExteriorAlgebra. Ideals of g-algebras can be left- and twosided
    (cf. #11068).
    
    diff --git a/module_list.py b/module_list.py
    a b  
    14931493              include_dirs = [SAGE_INC + 'singular'],
    14941494              depends = singular_depends),
    14951495
     1496    Extension('sage.rings.polynomial.plural',
     1497              sources = ['sage/rings/polynomial/plural.pyx'],
     1498              libraries = ['m', 'readline', 'singular', 'givaro', 'gmpxx', 'gmp'],
     1499              language="c++",
     1500              include_dirs = [SAGE_ROOT +'/local/include/singular'],
     1501              depends = [SAGE_ROOT + "/local/include/libsingular.h"]),
     1502
    14961503    Extension('sage.rings.polynomial.multi_polynomial_libsingular',
    14971504              sources = ['sage/rings/polynomial/multi_polynomial_libsingular.pyx'],
    14981505              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`
     
    7473   
    7574    INPUT:
    7675   
    77    
    7876    -  ``R`` - ring
    79    
    8077    -  ``n`` - integer
    81    
    8278    -  ``names`` - string or list/tuple of n strings
    8379   
    84    
    85     OUTPUT: a free algebra
     80    OUTPUT:
     81       
     82    A free algebra.
    8683   
    8784    EXAMPLES::
    8885   
     
    110107        True
    111108   
    112109    Free algebras commute with their base ring.
    113    
    114110    ::
    115111   
    116112        sage: K.<a,b> = FreeAlgebra(QQ,2)
     
    166162    Element = FreeAlgebraElement
    167163    def __init__(self, R, n, names):
    168164        """
     165        The free algebra on `n` generators over a base ring.
     166
    169167        INPUT:
    170168       
    171        
    172169        -  ``R`` - ring
    173        
    174170        -  ``n`` - an integer
    175        
    176171        -  ``names`` - generator names
     172   
     173        EXAMPLES::
     174   
     175            sage: F.<x,y,z> = FreeAlgebra(QQ, 3); F # indirect doctet
     176            Free Algebra on 3 generators (x, y, z) over Rational Field
    177177        """
    178178        if not isinstance(R, Ring):
    179179            raise TypeError, "Argument R must be a ring."
     
    254254            sage: print F  # indirect doctest
    255255            Free Algebra on 3 generators (x0, x1, x2) over Rational Field
    256256            sage: F.rename('QQ<<x0,x1,x2>>')
    257             sage: print F
     257            sage: print F #indirect doctest
    258258            QQ<<x0,x1,x2>>
    259259            sage: FreeAlgebra(ZZ,1,['a'])
    260260            Free Algebra on 1 generators (a,) over Integer Ring
     
    315315       
    316316        ::
    317317       
    318             sage: F._coerce_(x*y)
     318            sage: F._coerce_(x*y) # indirect doctest
    319319            x*y
    320320       
    321321        Elements of the integers coerce in, since there is a coerce map
     
    421421
    422422    def quotient(self, mons, mats, names):
    423423        """
    424         Returns a quotient algebra defined via the action of a free algebra
     424        Returns a quotient algebra.
     425       
     426        The quotient algebra is defined via the action of a free algebra
    425427        A on a (finitely generated) free module. The input for the quotient
    426428        algebra is a list of monomials (in the underlying monoid for A)
    427429        which form a free basis for the module of A, and a list of
    428430        matrices, which give the action of the free generators of A on this
    429431        monomial basis.
     432
     433        EXAMPLE:
     434
     435        Here is the quaternion algebra defined in terms of three generators::
     436       
     437            sage: n = 3
     438            sage: A = FreeAlgebra(QQ,n,'i')
     439            sage: F = A.monoid()
     440            sage: i, j, k = F.gens()
     441            sage: mons = [ F(1), i, j, k ]
     442            sage: M = MatrixSpace(QQ,4)
     443            sage: mats = [M([0,1,0,0, -1,0,0,0, 0,0,0,-1, 0,0,1,0]),  M([0,0,1,0, 0,0,0,1, -1,0,0,0, 0,-1,0,0]),  M([0,0,0,1, 0,0,-1,0, 0,1,0,0, -1,0,0,0]) ]
     444            sage: H.<i,j,k> = A.quotient(mons, mats); H
     445            Free algebra quotient on 3 generators ('i', 'j', 'k') and dimension 4 over Rational Field
    430446        """
    431447        import free_algebra_quotient
    432448        return free_algebra_quotient.FreeAlgebraQuotient(self, mons, mats, names)
     
    456472        """
    457473        return self.__monoid
    458474   
    459                    
     475    def g_algebra(self, relations, order='degrevlex', check = True):
     476        """
     477        The G-Algebra derived from this algebra by relations.
     478        By default is assumed, that two variables commute.
     479
     480        TODO:
     481
     482        - Coercion doesn't work yet, there is some cheating about assumptions
     483        - The optional argument ``check`` controls checking the degeneracy
     484          conditions. Furthermore, the default values interfere with
     485          non-degeneracy conditions.
     486           
     487        EXAMPLES::
     488
     489            sage: A.<x,y,z>=FreeAlgebra(QQ,3)
     490            sage: G=A.g_algebra({y*x:-x*y})
     491            sage: (x,y,z)=G.gens()
     492            sage: x*y
     493            x*y
     494            sage: y*x
     495            -x*y
     496            sage: z*x
     497            x*z
     498            sage: (x,y,z)=A.gens()
     499            sage: G=A.g_algebra({y*x:-x*y+1})
     500            sage: (x,y,z)=G.gens()
     501            sage: y*x
     502            -x*y + 1
     503            sage: (x,y,z)=A.gens()
     504            sage: G=A.g_algebra({y*x:-x*y+z})
     505            sage: (x,y,z)=G.gens()
     506            sage: y*x
     507            -x*y + z
     508        """
     509        from sage.matrix.constructor  import Matrix
     510        from sage.rings.polynomial.plural import NCPolynomialRing_plural
     511       
     512        base_ring=self.base_ring()
     513        n=self.ngens()
     514        cmat=Matrix(base_ring,n)
     515        dmat=Matrix(self,n)
     516        for i in xrange(n):
     517            for j in xrange(i+1,n):
     518                cmat[i,j]=1
     519        for (to_commute,commuted) in relations.iteritems():
     520            #This is dirty, coercion is broken
     521            assert isinstance(to_commute,FreeAlgebraElement), to_commute.__class__
     522            assert isinstance(commuted,FreeAlgebraElement), commuted
     523            ((v1,e1),(v2,e2))=list(list(to_commute)[0][1])
     524            assert e1==1
     525            assert e2==1
     526            assert v1>v2
     527            c_coef=None
     528            d_poly=None
     529            for (c,m) in commuted:
     530                if list(m)==[(v2,1),(v1,1)]:
     531                    c_coef=c
     532                    #buggy coercion workaround
     533                    d_poly=commuted-self(c)*self(m)
     534                    break
     535            assert not c_coef is None,list(m)
     536            v2_ind = self.gens().index(v2)
     537            v1_ind = self.gens().index(v1)
     538            cmat[v2_ind,v1_ind]=c_coef
     539            if d_poly:
     540                dmat[v2_ind,v1_ind]=d_poly
     541       
     542        return NCPolynomialRing_plural(base_ring, n, ",".join([str(g) for g in self.gens()]), c=cmat, d=dmat, order=order, check=check)
     543           
     544           
    460545from sage.misc.cache import Cache
    461546cache = Cache(FreeAlgebra_generic)
  • sage/libs/singular/function.pxd

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

    diff --git a/sage/libs/singular/function.pyx b/sage/libs/singular/function.pyx
    a b  
    1414- Michael Brickenstein (2009-10): extension to more Singular types
    1515- Martin Albrecht (2010-01): clean up, support for attributes
    1616- Simon King (2011-04): include the documentation provided by Singular as a code block.
     17- Burcin Erocal, Michael Brickenstein, Oleksandr Motsak, Alexander Dreyer, Simon King
     18  (2011-09) plural support
    1719
    1820EXAMPLES:
    1921
     
    8183from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomial_libsingular, new_MP
    8284from sage.rings.polynomial.multi_polynomial_libsingular cimport MPolynomialRing_libsingular
    8385
     86from sage.rings.polynomial.plural cimport NCPolynomialRing_plural, NCPolynomial_plural, new_NCP
     87from sage.rings.polynomial.multi_polynomial_ideal import NCPolynomialIdeal
     88
    8489from sage.rings.polynomial.multi_polynomial_ideal import MPolynomialIdeal
    8590
    8691from sage.rings.polynomial.multi_polynomial_ideal_libsingular cimport sage_ideal_to_singular_ideal, singular_ideal_to_sage_sequence
     
    9095from sage.libs.singular.decl cimport iiMake_proc, iiExprArith1, iiExprArith2, iiExprArith3, iiExprArithM, iiLibCmd
    9196from sage.libs.singular.decl cimport ggetid, IDEAL_CMD, CMD_M, POLY_CMD, PROC_CMD, RING_CMD, QRING_CMD, NUMBER_CMD, INT_CMD, INTVEC_CMD, RESOLUTION_CMD
    9297from sage.libs.singular.decl cimport MODUL_CMD, LIST_CMD, MATRIX_CMD, VECTOR_CMD, STRING_CMD, V_LOAD_LIB, V_REDEFINE, INTMAT_CMD, NONE, PACKAGE_CMD
    93 from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy
     98from sage.libs.singular.decl cimport IsCmd, rChangeCurrRing, currRing, p_Copy, rIsPluralRing, rPrint, rOrderingString
    9499from sage.libs.singular.decl cimport IDROOT, enterid, currRingHdl, memcpy, IDNEXT, IDTYP, IDPACKAGE
    95100from sage.libs.singular.decl cimport errorreported, verbose, Sy_bit, currentVoice, myynest
    96101from sage.libs.singular.decl cimport intvec_new_int3, intvec_new, matrix, mpNew
     
    123128   
    124129    for (i, p) in enumerate(v):
    125130        component = <int>i+1
    126         poly_component = p_Copy(
    127             (<MPolynomial_libsingular>p)._poly, r)
     131        poly_component = copy_sage_polynomial_into_singular_poly(p)
    128132        p_iter = poly_component
    129133        while p_iter!=NULL:
    130134            p_SetComp(p_iter, component, r)
     
    133137        res=p_Add_q(res, poly_component, r)
    134138    return res
    135139
     140
    136141cdef class RingWrap:
    137142    """
    138143    A simple wrapper around Singular's rings.
     
    149154            sage: ring(l, ring=P)
    150155            <RingWrap>
    151156        """
     157        if not self.is_commutative():
     158            return "<noncommutative RingWrap>"
    152159        return "<RingWrap>"
    153160   
    154161    def __dealloc__(self):
    155162        if self._ring!=NULL:
    156163            self._ring.ref -= 1
    157164
     165    def ngens(self):
     166        """
     167        Get number of generators.
     168
     169        EXAMPLE::
     170
     171            sage: from sage.libs.singular.function import singular_function
     172            sage: P.<x,y,z> = PolynomialRing(QQ)
     173            sage: ringlist = singular_function("ringlist")
     174            sage: l = ringlist(P)
     175            sage: ring = singular_function("ring")
     176            sage: ring(l, ring=P).ngens()
     177            3
     178        """
     179        return self._ring.N
     180
     181    def var_names(self):
     182        """
     183        Get names of variables.
     184
     185        EXAMPLE::
     186
     187            sage: from sage.libs.singular.function import singular_function
     188            sage: P.<x,y,z> = PolynomialRing(QQ)
     189            sage: ringlist = singular_function("ringlist")
     190            sage: l = ringlist(P)
     191            sage: ring = singular_function("ring")
     192            sage: ring(l, ring=P).var_names()
     193            ['x', 'y', 'z']
     194        """
     195        return [self._ring.names[i] for i in range(self.ngens())]
     196
     197    def npars(self):
     198        """
     199        Get number of parameters.
     200
     201        EXAMPLE::
     202
     203            sage: from sage.libs.singular.function import singular_function
     204            sage: P.<x,y,z> = PolynomialRing(QQ)
     205            sage: ringlist = singular_function("ringlist")
     206            sage: l = ringlist(P)
     207            sage: ring = singular_function("ring")
     208            sage: ring(l, ring=P).npars()
     209            0
     210        """
     211        return self._ring.P
     212
     213    def ordering_string(self):
     214        """
     215        Get Singular string defining monomial ordering.
     216
     217        EXAMPLE::
     218
     219            sage: from sage.libs.singular.function import singular_function
     220            sage: P.<x,y,z> = PolynomialRing(QQ)
     221            sage: ringlist = singular_function("ringlist")
     222            sage: l = ringlist(P)
     223            sage: ring = singular_function("ring")
     224            sage: ring(l, ring=P).ordering_string()
     225            'dp(3),C'
     226        """
     227        return rOrderingString(self._ring)
     228   
     229   
     230
     231    def par_names(self):
     232        """
     233        Get parameter names.
     234
     235        EXAMPLE::
     236
     237            sage: from sage.libs.singular.function import singular_function
     238            sage: P.<x,y,z> = PolynomialRing(QQ)
     239            sage: ringlist = singular_function("ringlist")
     240            sage: l = ringlist(P)
     241            sage: ring = singular_function("ring")
     242            sage: ring(l, ring=P).par_names()
     243            []
     244        """
     245        return [self._ring.parameter[i] for i in range(self.npars())]
     246
     247    def characteristic(self):
     248        """
     249        Get characteristic.
     250
     251        EXAMPLE::
     252
     253            sage: from sage.libs.singular.function import singular_function
     254            sage: P.<x,y,z> = PolynomialRing(QQ)
     255            sage: ringlist = singular_function("ringlist")
     256            sage: l = ringlist(P)
     257            sage: ring = singular_function("ring")
     258            sage: ring(l, ring=P).characteristic()
     259            0
     260        """
     261        return self._ring.ch
     262
     263    def is_commutative(self):
     264        """
     265        Determine whether a given ring is commutative.
     266
     267        EXAMPLE::
     268
     269            sage: from sage.libs.singular.function import singular_function
     270            sage: P.<x,y,z> = PolynomialRing(QQ)
     271            sage: ringlist = singular_function("ringlist")
     272            sage: l = ringlist(P)
     273            sage: ring = singular_function("ring")
     274            sage: ring(l, ring=P).is_commutative()
     275            True
     276        """
     277        return not rIsPluralRing(self._ring)
     278   
     279    def _output(self):
     280        """
     281        Use Singular output.
     282
     283        EXAMPLE::
     284
     285            sage: from sage.libs.singular.function import singular_function
     286            sage: P.<x,y,z> = PolynomialRing(QQ)
     287            sage: ringlist = singular_function("ringlist")
     288            sage: l = ringlist(P)
     289            sage: ring = singular_function("ring")
     290            sage: ring(l, ring=P)._output()
     291        """
     292        rPrint(self._ring)
     293
    158294cdef class Resolution:
    159295    """
    160296    A simple wrapper around Singular's resolutions.
     
    171307           sage: M = syz(I)
    172308           sage: resolution = mres(M, 0)
    173309        """
    174         assert PY_TYPE_CHECK(base_ring, MPolynomialRing_libsingular)
    175         self.base_ring = <MPolynomialRing_libsingular> base_ring
     310        #FIXME: still not working noncommutative
     311        assert is_sage_wrapper_for_singular_ring(base_ring)
     312        self.base_ring = base_ring
    176313    def __repr__(self):
    177314        """
    178315        EXAMPLE::
     
    209346    INPUT:
    210347
    211348    - ``data`` - some Singular data this interpreter object points to
    212 
    213349    - ``res_type`` - the type of that data
    214350    """
    215351    cdef leftv* res
     
    230366    args.CleanUp()
    231367    omFreeBin(args, sleftv_bin)
    232368
     369# =====================================
     370# = Singular/Plural Abstraction Layer =
     371# =====================================
    233372
    234 def all_polynomials(s):
     373def is_sage_wrapper_for_singular_ring(ring):
     374    """
     375    Check whether wrapped ring arises from Singular or Singular/Plural.
     376
     377    EXAMPLE::
     378
     379        sage: from sage.libs.singular.function import is_sage_wrapper_for_singular_ring
     380        sage: P.<x,y,z> = QQ[]
     381        sage: is_sage_wrapper_for_singular_ring(P)
     382        True
     383
     384    ::
     385
     386        sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     387        sage: P = A.g_algebra(relations={y*x:-x*y}, order = 'lex')
     388        sage: is_sage_wrapper_for_singular_ring(P)
     389        True
     390
     391    """
     392    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     393        return True
     394    if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     395        return True
     396    return False
     397
     398cdef new_sage_polynomial(ring,  poly *p):
     399    if PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     400        return new_MP(ring, p)
     401    else:
     402        if PY_TYPE_CHECK(ring, NCPolynomialRing_plural):
     403            return new_NCP(ring, p)
     404    raise ValueError("not a singular or plural ring")
     405
     406def is_singular_poly_wrapper(p):
     407    """
     408    Checks if p is some data type corresponding to some singular ``poly```.
     409       
     410    EXAMPLE::
     411
     412        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
     413        sage: from sage.matrix.constructor  import Matrix
     414        sage: from sage.libs.singular.function import is_singular_poly_wrapper
     415        sage: c=Matrix(2)
     416        sage: c[0,1]=-1
     417        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
     418        sage: (x,y)=P.gens()
     419        sage: is_singular_poly_wrapper(x+y)
     420        True
     421       
     422    """
     423    return PY_TYPE_CHECK(p, MPolynomial_libsingular) or PY_TYPE_CHECK(p,  NCPolynomial_plural)
     424
     425def all_singular_poly_wrapper(s):
    235426    """
    236427    Tests for a sequence ``s``, whether it consists of
    237428    singular polynomials.
    238429   
    239430    EXAMPLE::
    240431       
    241         sage: from sage.libs.singular.function import all_polynomials
     432        sage: from sage.libs.singular.function import all_singular_poly_wrapper
    242433        sage: P.<x,y,z> = QQ[]
    243         sage: all_polynomials([x+1, y])
     434        sage: all_singular_poly_wrapper([x+1, y])
    244435        True
    245         sage: all_polynomials([x+1, y, 1])
     436        sage: all_singular_poly_wrapper([x+1, y, 1])
    246437        False
    247438    """
    248439    for p in s:
    249         if not isinstance(p, MPolynomial_libsingular):
     440        if not is_singular_poly_wrapper(p):
    250441            return False
    251442    return True
    252443
     444cdef poly* access_singular_poly(p) except <poly*> -1:
     445    """
     446    Get the raw ``poly`` pointer from a wrapper object.
     447    """
     448    if PY_TYPE_CHECK(p, MPolynomial_libsingular):
     449        return (<MPolynomial_libsingular> p)._poly
     450    else:
     451        if PY_TYPE_CHECK(p, NCPolynomial_plural):
     452            return (<NCPolynomial_plural> p)._poly
     453    raise ValueError("not a singular polynomial wrapper")
     454
     455cdef ring* access_singular_ring(r) except <ring*> -1:
     456    """
     457    Get the singular ``ring`` pointer from a wrapper object.
     458    """
     459    if PY_TYPE_CHECK(r, MPolynomialRing_libsingular):
     460        return (<MPolynomialRing_libsingular> r )._ring
     461    if PY_TYPE_CHECK(r, NCPolynomialRing_plural):
     462        return (<NCPolynomialRing_plural> r )._ring
     463    raise ValueError("not a singular polynomial ring wrapper")
     464 
     465cdef poly* copy_sage_polynomial_into_singular_poly(p):
     466    return p_Copy(access_singular_poly(p), access_singular_ring(p.parent()))
     467
    253468def all_vectors(s):
    254469    """
    255470    Checks if a sequence ``s`` consists of free module
     
    270485        False
    271486    """
    272487    for p in s:
    273         if not (isinstance(p, FreeModuleElement_generic_dense)\
    274             and isinstance(p.parent().base_ring(), MPolynomialRing_libsingular)):
     488        if not (PY_TYPE_CHECK(p, FreeModuleElement_generic_dense)\
     489            and is_sage_wrapper_for_singular_ring(p.parent().base_ring())):
    275490            return False
    276491    return True
    277492
    278493
    279 
    280494cdef class Converter(SageObject):
    281495    """
    282496    A :class:`Converter` interfaces between Sage objects and Singular
     
    290504        INPUT:
    291505
    292506        - ``args`` - a list of Python objects
    293 
    294507        - ``ring`` - a multivariate polynomial ring
    295 
    296508        - ``attributes`` - an optional dictionary of Singular
    297                            attributes (default: ``None``)
     509          attributes (default: ``None``)
    298510
    299511        EXAMPLE::
    300512
     
    305517        """
    306518        cdef leftv *v
    307519        self.args = NULL
    308         self._ring = ring
     520        self._sage_ring = ring
     521        if ring is not None:
     522            self._singular_ring = access_singular_ring(ring)
     523       
    309524        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    310525        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
     526        from sage.matrix.matrix_generic_dense import Matrix_generic_dense
    311527        for a in args:
    312             if PY_TYPE_CHECK(a, MPolynomial_libsingular):
    313                 v = self.append_polynomial(<MPolynomial_libsingular> a)
     528            if is_singular_poly_wrapper(a):
     529                v = self.append_polynomial(a)
    314530
    315             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
    316                 v = self.append_ring(<MPolynomialRing_libsingular> a)
     531            elif is_sage_wrapper_for_singular_ring(a):
     532                v = self.append_ring(a)
    317533
    318             elif PY_TYPE_CHECK(a, MPolynomialIdeal):
     534            elif PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     535                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    319536                v = self.append_ideal(a)
    320537
    321538            elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long):
     
    329546
    330547            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    331548                v = self.append_intmat(a)
    332 
     549           
     550            elif PY_TYPE_CHECK(a, Matrix_generic_dense) and\
     551                is_sage_wrapper_for_singular_ring(a.parent().base_ring()):
     552                self.append_matrix(a)
     553           
    333554            elif PY_TYPE_CHECK(a, Resolution):
    334555                v = self.append_resolution(a)
    335556
    336557            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    337                 and isinstance(
    338                     a.parent().base_ring(),
    339                     MPolynomialRing_libsingular):
     558                and is_sage_wrapper_for_singular_ring(
     559                    a.parent().base_ring()):
    340560                v = self.append_vector(a)
    341561               
    342562            # as output ideals get converted to sequences
     
    344564            # this means, that Singular lists should not be converted to Sequences,
    345565            # as we do not want ambiguities
    346566            elif PY_TYPE_CHECK(a, Sequence_generic)\
    347                 and all_polynomials(a):
     567                and all_singular_poly_wrapper(a):
    348568                v = self.append_ideal(ring.ideal(a))
    349569            elif PY_TYPE_CHECK(a, PolynomialSequence):
    350570                v = self.append_ideal(ring.ideal(a))
     
    365585                    v = self.append_intvec(a)
    366586                else:
    367587                    v = self.append_list(a)
    368             elif a.parent() is self._ring.base_ring():
     588            elif a.parent() is self._sage_ring.base_ring():
    369589                v = self.append_number(a)
    370590
    371591            elif PY_TYPE_CHECK(a, Integer):
     
    394614            sage: Converter([a,b,c],ring=P).ring()
    395615            Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    396616        """
    397         return self._ring
     617        return self._sage_ring
    398618
    399619    def _repr_(self):
    400620        """
     
    405625            sage: Converter([a,b,c],ring=P) # indirect doctest
    406626            Singular Converter in Multivariate Polynomial Ring in a, b, c over Finite Field of size 127
    407627        """
    408         return "Singular Converter in %s"%(self._ring)
     628        return "Singular Converter in %s"%(self._sage_ring)
    409629
    410630    def __dealloc__(self):
    411631        if self.args:
     
    460680        INPUT:
    461681
    462682        - ``data`` - the raw data
    463 
    464683        - ``res_type`` - the type of the data
    465684        """
    466685        return self._append_leftv( new_leftv(data, res_type) )
     
    470689        Convert singular matrix to matrix over the polynomial ring.
    471690        """
    472691        from sage.matrix.constructor import Matrix
    473         sage_ring = self._ring
    474         cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
    475             sage_ring)._ring
     692        #cdef ring *singular_ring = (<MPolynomialRing_libsingular>\
     693        #    self._sage_ring)._ring
    476694        ncols = mat.ncols
    477695        nrows = mat.nrows
    478         result = Matrix(sage_ring, nrows, ncols)
    479         cdef MPolynomial_libsingular p
     696        result = Matrix(self._sage_ring, nrows, ncols)
    480697        for i in xrange(nrows):
    481698            for j in xrange(ncols):
    482                 p = MPolynomial_libsingular(sage_ring)
    483                 p._poly = mat.m[i*ncols+j]
     699                p = new_sage_polynomial(self._sage_ring, mat.m[i*ncols+j])
    484700                mat.m[i*ncols+j]=NULL
    485701                result[i,j] = p
    486702        return result
    487703   
    488704    cdef to_sage_vector_destructive(self, poly *p, free_module = None):
    489         cdef ring *r=self._ring._ring
     705        #cdef ring *r=self._ring._ring
    490706        cdef int rank
    491707        if free_module:
    492708            rank = free_module.rank()
    493709        else:
    494             rank = singular_vector_maximal_component(p, r)
    495             free_module = self._ring**rank
     710            rank = singular_vector_maximal_component(p, self._singular_ring)
     711            free_module = self._sage_ring**rank
    496712        cdef poly *acc
    497713        cdef poly *p_iter
    498714        cdef poly *first
     
    505721            first = NULL
    506722            p_iter=p
    507723            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)
     724                if p_GetComp(p_iter, self._singular_ring) == i:
     725                    p_SetComp(p_iter,0, self._singular_ring)
     726                    p_Setm(p_iter, self._singular_ring)
    511727                    if acc == NULL:
    512728                        first = p_iter
    513729                    else:
     
    522738                else:
    523739                    previous = p_iter
    524740                    p_iter = pNext(p_iter)
    525             result.append(new_MP(self._ring, first))
     741           
     742            result.append(new_sage_polynomial(self._sage_ring, first))
    526743        return free_module(result)
    527744         
    528745    cdef object to_sage_module_element_sequence_destructive( self, ideal *i):
     
    536753        - ``r`` -- a SINGULAR ring
    537754        - ``sage_ring`` -- a Sage ring matching r
    538755        """
    539         cdef MPolynomialRing_libsingular sage_ring = self._ring
     756        #cdef MPolynomialRing_libsingular sage_ring = self._ring
    540757        cdef int j
    541758        cdef int rank=i.rank
    542         free_module = sage_ring**rank       
     759        free_module = self._sage_ring ** rank       
    543760        l = []
    544761
    545762        for j from 0 <= j < IDELEMS(i):
     
    568785        return result
    569786   
    570787   
    571     cdef leftv *append_polynomial(self, MPolynomial_libsingular p) except NULL:
     788    cdef leftv *append_polynomial(self, p) except NULL:
    572789        """
    573790        Append the polynomial ``p`` to the list.
    574791        """
    575         cdef poly* _p = p_Copy(p._poly, <ring*>(<MPolynomialRing_libsingular>p._parent)._ring)
     792        cdef poly* _p
     793        _p = copy_sage_polynomial_into_singular_poly(p)
     794               
    576795        return self._append(_p, POLY_CMD)
    577796
    578797    cdef leftv *append_ideal(self,  i) except NULL:
     
    589808        """
    590809        rank = max([v.parent().rank() for v in m])
    591810        cdef ideal *result
    592         cdef ring *r = self._ring._ring
     811        cdef ring *r = self._singular_ring
    593812        cdef ideal *i
    594813        cdef int j = 0
    595814
     
    605824        """
    606825        Append the number ``n`` to the list.
    607826        """
    608         cdef number *_n =  sa2si(n, self._ring._ring)
     827        cdef number *_n =  sa2si(n, self._singular_ring)
    609828        return self._append(<void *>_n, NUMBER_CMD)
    610829
    611     cdef leftv *append_ring(self, MPolynomialRing_libsingular r) except NULL:
     830    cdef leftv *append_ring(self, r) except NULL:
    612831        """
    613832        Append the ring ``r`` to the list.
    614833        """
    615         cdef ring *_r =  <ring*> r._ring
     834        cdef ring *_r =  access_singular_ring(r)
    616835        _r.ref+=1
    617836        return self._append(<void *>_r, RING_CMD)
    618837
    619838    cdef leftv *append_matrix(self, mat) except NULL:
    620839       
    621840        sage_ring = mat.base_ring()
    622         cdef ring *r=<ring*> (<MPolynomialRing_libsingular> sage_ring)._ring
     841        cdef ring *r=<ring*> access_singular_ring(sage_ring)
    623842
    624843        cdef poly *p
    625844        ncols = mat.ncols()
     
    627846        cdef matrix* _m=mpNew(nrows,ncols)
    628847        for i in xrange(nrows):
    629848            for j in xrange(ncols):
    630                 p = p_Copy(
    631                     (<MPolynomial_libsingular> mat[i,j])._poly, r)
     849                #FIXME
     850                p = copy_sage_polynomial_into_singular_poly(mat[i,j])
    632851                _m.m[ncols*i+j]=p
    633852        return self._append(_m, MATRIX_CMD)
    634853
     
    646865        Append the list ``l`` to the list.
    647866        """
    648867       
    649         cdef Converter c = Converter(l, self._ring)
     868        cdef Converter c = Converter(l, self._sage_ring)
    650869        n = len(c)
    651870
    652871        cdef lists *singular_list=<lists*>omAlloc0Bin(slists_bin)
     
    677896        Append vector ``v`` from free
    678897        module over polynomial ring.
    679898        """
    680         cdef ring *r = self._ring._ring
     899        cdef ring *r = self._singular_ring
    681900        cdef poly *p = sage_vector_to_poly(v, r)
    682901        return self._append(<void*> p, VECTOR_CMD)
    683902   
     
    717936
    718937        - ``to_convert`` - a Singular ``leftv``
    719938        """
     939        #FIXME
    720940        cdef MPolynomial_libsingular res_poly
    721941        cdef int rtyp = to_convert.rtyp
    722942        cdef lists *singular_list
    723943        cdef Resolution res_resolution
    724944        if rtyp == IDEAL_CMD:
    725             return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._ring._ring, self._ring)
     945            return singular_ideal_to_sage_sequence(<ideal*>to_convert.data, self._singular_ring, self._sage_ring)
    726946
    727947        elif rtyp == POLY_CMD:
    728             res_poly = MPolynomial_libsingular(self._ring)
     948            #FIXME
     949            res_poly = MPolynomial_libsingular(self._sage_ring)
    729950            res_poly._poly = <poly*>to_convert.data
    730951            to_convert.data = NULL
    731952            #prevent it getting free, when cleaning the leftv
     
    735956            return <long>to_convert.data
    736957       
    737958        elif rtyp == NUMBER_CMD:
    738             return si2sa(<number *>to_convert.data, self._ring._ring, self._ring.base_ring())
     959            return si2sa(<number *>to_convert.data, self._singular_ring, self._sage_ring.base_ring())
    739960
    740961        elif rtyp == INTVEC_CMD:
    741962            return si2sa_intvec(<intvec *>to_convert.data)
     
    751972           
    752973
    753974        elif rtyp == RING_CMD or rtyp==QRING_CMD:
    754             ring_wrap_result=RingWrap()
    755             (<RingWrap> ring_wrap_result)._ring=<ring*> to_convert.data
    756             (<RingWrap> ring_wrap_result)._ring.ref+=1
    757             return ring_wrap_result
     975            return new_RingWrap( <ring*> to_convert.data )
    758976
    759977        elif rtyp == MATRIX_CMD:
    760978            return self.to_sage_matrix(<matrix*>  to_convert.data )
     
    777995            return self.to_sage_integer_matrix(
    778996                <intvec*> to_convert.data)
    779997        elif rtyp == RESOLUTION_CMD:
    780             res_resolution = Resolution(self._ring)
     998            res_resolution = Resolution(self._sage_ring)
    781999            res_resolution._resolution = <syStrategy*> to_convert.data
    7821000            res_resolution._resolution.references += 1
    7831001            return res_resolution
     
    9461164        """
    9471165        return "%s (singular function)" %(self._name)
    9481166
    949     def __call__(self, *args, MPolynomialRing_libsingular ring=None, bint interruptible=True, attributes=None):
     1167    def __call__(self, *args, ring=None, bint interruptible=True, attributes=None):
    9501168        """
    9511169        Call this function with the provided arguments ``args`` in the
    9521170        ring ``R``.
     
    9541172        INPUT:
    9551173
    9561174        - ``args`` - a list of arguments
    957 
    9581175        - ``ring`` - a multivariate polynomial ring
    959 
    9601176        - ``interruptible`` - if ``True`` pressing Ctrl-C during the
    961                               execution of this function will
    962                               interrupt the computation (default: ``True``)
     1177          execution of this function will interrupt the computation
     1178          (default: ``True``)
    9631179
    9641180        - ``attributes`` - a dictionary of optional Singular
    965                            attributes assigned to Singular objects (default: ``None``)
     1181          attributes assigned to Singular objects (default: ``None``)
    9661182
    9671183        EXAMPLE::
    9681184
     
    10261242        """
    10271243        if ring is None:
    10281244            ring = self.common_ring(args, ring)
    1029         if not PY_TYPE_CHECK(ring, MPolynomialRing_libsingular):
     1245        if not (PY_TYPE_CHECK(ring, MPolynomialRing_libsingular) or \
     1246                PY_TYPE_CHECK(ring, NCPolynomialRing_plural)):
    10301247            raise TypeError("Cannot call Singular function '%s' with ring parameter of type '%s'"%(self._name,type(ring)))
    10311248        return call_function(self, args, ring, interruptible, attributes)
    10321249   
     
    10851302        singular_doc = get_docstring(self._name).split('\n')
    10861303        return prefix + "\n::\n\n"+'\n'.join(["    "+L for L in singular_doc])
    10871304
    1088     cdef MPolynomialRing_libsingular common_ring(self, tuple args, ring=None):
     1305    cdef common_ring(self, tuple args, ring=None):
    10891306        """
    10901307        Return the common ring for the argument list ``args``.
    10911308
     
    10971314        INPUT:
    10981315
    10991316        - ``args`` - a list of Python objects
    1100 
    11011317        - ``ring`` - an optional ring to check
    11021318        """
    11031319        from  sage.matrix.matrix_mpolynomial_dense import Matrix_mpolynomial_dense
    11041320        from sage.matrix.matrix_integer_dense import Matrix_integer_dense
    11051321        for a in args:
    1106             if PY_TYPE_CHECK(a, MPolynomialIdeal):
     1322            if PY_TYPE_CHECK(a, MPolynomialIdeal) or \
     1323                    PY_TYPE_CHECK(a, NCPolynomialIdeal):
    11071324                ring2 = a.ring()
    1108             elif PY_TYPE_CHECK(a, MPolynomial_libsingular):
     1325            elif is_singular_poly_wrapper(a):
    11091326                ring2 = a.parent()
    1110             elif PY_TYPE_CHECK(a, MPolynomialRing_libsingular):
     1327            elif is_sage_wrapper_for_singular_ring(a):
    11111328                ring2 = a
    1112             elif PY_TYPE_CHECK(a, int) or PY_TYPE_CHECK(a, long) or PY_TYPE_CHECK(a, basestring):
     1329            elif PY_TYPE_CHECK(a, int) or\
     1330                PY_TYPE_CHECK(a, long) or\
     1331                PY_TYPE_CHECK(a, basestring):
    11131332                continue
    11141333            elif PY_TYPE_CHECK(a, Matrix_integer_dense):
    11151334                continue
     
    11221341            elif PY_TYPE_CHECK(a, Resolution):
    11231342                ring2 = (<Resolution> a).base_ring
    11241343            elif PY_TYPE_CHECK(a, FreeModuleElement_generic_dense)\
    1125                 and PY_TYPE_CHECK(
    1126                     a.parent().base_ring(),
    1127                      MPolynomialRing_libsingular):
     1344                and is_sage_wrapper_for_singular_ring(
     1345                    a.parent().base_ring()):
    11281346                ring2 = a.parent().base_ring()
    11291347            elif ring is not None:
    11301348                a.parent() is ring
     
    11361354                raise ValueError("Rings do not match up.")
    11371355        if ring is None:
    11381356            raise ValueError("Could not detect ring.")
    1139         return <MPolynomialRing_libsingular>ring
     1357        return ring
    11401358
    11411359    def __reduce__(self):
    11421360        """
     
    11671385        else:
    11681386            return cmp(self._name, (<SingularFunction>other)._name)
    11691387
    1170 cdef inline call_function(SingularFunction self, tuple args, MPolynomialRing_libsingular R, bint signal_handler=True, attributes=None):
     1388cdef inline call_function(SingularFunction self, tuple args, object R, bint signal_handler=True, attributes=None):
    11711389    global currRingHdl
    11721390    global errorreported
    11731391    global currentVoice
     
    11751393    global error_messages
    11761394
    11771395
    1178     cdef ring *si_ring = R._ring
    1179 
     1396    cdef ring *si_ring
     1397    if PY_TYPE_CHECK(R, MPolynomialRing_libsingular):
     1398        si_ring = (<MPolynomialRing_libsingular>R)._ring
     1399    else:
     1400        si_ring = (<NCPolynomialRing_plural>R)._ring
     1401 
    11801402    if si_ring != currRing:
    11811403        rChangeCurrRing(si_ring)
    11821404
     
    14181640        <Resolution>
    14191641        sage: singular_list(resolution)
    14201642        [[(-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 
     1643        sage: from sage.rings.polynomial.plural import NCPolynomialRing_plural
     1644        sage: from sage.matrix.constructor  import Matrix
     1645        sage: c=Matrix(2)
     1646        sage: c[0,1]=-1
     1647        sage: P = NCPolynomialRing_plural(QQ, 2, 'x,y', c=c, d=Matrix(2))
     1648        sage: (x,y)=P.gens()
     1649        sage: I= Sequence([x*y,x+y], check=False, immutable=True)#P.ideal(x*y,x+y)
     1650        sage: twostd = singular_function("twostd")
     1651        sage: twostd(I)
     1652        [x + y, y^2]
     1653        sage: M=syz(I)
     1654        doctest...
     1655        sage: M
     1656        [(x + y, x*y)]
     1657        sage: syz(M, ring=P)
     1658        [(0)]
     1659        sage: mres(I, 0)
     1660        <Resolution>
     1661        sage: M=P**3
     1662        sage: v=M((100*x,5*y,10*y*x*y))
     1663        sage: leadcoef(v)
     1664        -10
     1665        sage: v = M([x+y,x*y+y**3,x])
     1666        sage: lead(v)
     1667        (0, y^3)
     1668        sage: jet(v, 2)
     1669        (x + y, x*y, x)
     1670        sage: l = ringlist(P)
     1671        sage: len(l)
     1672        6
     1673        sage: ring(l, ring=P)
     1674        <noncommutative RingWrap>
     1675        sage: I=twostd(I)
     1676        sage: l[3]=I
     1677        sage: ring(l, ring=P)
     1678        <noncommutative RingWrap>
    14221679       
    14231680    """
    14241681
     
    14901747                    ph = IDNEXT(ph)
    14911748        h = IDNEXT(h)
    14921749    return l
     1750
     1751
     1752#cdef ring*?
     1753cdef inline RingWrap new_RingWrap(ring* r):
     1754    cdef RingWrap ring_wrap_result = PY_NEW(RingWrap)
     1755    ring_wrap_result._ring = r
     1756    ring_wrap_result._ring.ref += 1
     1757   
     1758    return ring_wrap_result
  • sage/libs/singular/singular-cdefs.pxi

    diff --git a/sage/libs/singular/singular-cdefs.pxi b/sage/libs/singular/singular-cdefs.pxi
    a b  
    148148        bint (*nGreaterZero)(number* a)
    149149        void (*nPower)(number* a, int i, number* * result)
    150150
     151    # polynomials
     152
     153    ctypedef struct poly "polyrec":
     154        poly *next
     155
     156    # ideals
     157
     158    ctypedef struct ideal "sip_sideal":
     159        poly **m # gens array
     160        long rank # rank of module, 1 for ideals
     161        int nrows # always 1
     162        int ncols # number of gens
     163
     164    # polynomial procs
     165    ctypedef struct p_Procs_s "p_Procs_s":
     166        pass
    151167    # rings
    152168
    153169    ctypedef struct ring "ip_sring":
     
    160176        int  CanShortOut # control printing capabilities
    161177        number *minpoly # minpoly for base extension field
    162178        char **names # variable names
     179        p_Procs_s *p_Procs #polxnomial procs
     180        ideal *qideal #quotient ideal
     181       
    163182        char **parameter # parameter names
    164183        ring *algring # base extension field
    165184        short N # number of variables
     
    198217        ringorder_Ws
    199218        ringorder_L
    200219
    201     # polynomials
    202220
    203     ctypedef struct poly "polyrec":
    204         poly *next
    205221
    206222    # groebner basis options
    207223   
     
    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        """
     
    351357            raise TypeError, "Argument sparse (= %s) must be True or False" % sparse
    352358
    353359        if not (hasattr(base_ring,'is_commutative') and base_ring.is_commutative()):
    354             raise TypeError, "The base_ring must be a commutative ring."
    355 
    356         if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class):
    357             return RealDoubleVectorSpace_class(rank)
    358 
    359         elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class):
    360             return ComplexDoubleVectorSpace_class(rank)
    361 
    362         elif base_ring.is_field():
    363             return FreeModule_ambient_field(base_ring, rank, sparse=sparse)
    364 
    365         elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain):
    366             return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
    367 
    368         elif isinstance(base_ring, sage.rings.number_field.order.Order) \
    369             and base_ring.is_maximal() and base_ring.class_number() == 1:
     360            warn("""You are constructing a free module
     361over a noncommutative ring. Sage does not have a concept
     362of left/right and both sided modules, so be careful.
     363It's also not guaranteed that all multiplications are
     364done from the right side.""")
     365
     366        #            raise TypeError, "The base_ring must be a commutative ring."
     367
     368        try:
     369            if not sparse and isinstance(base_ring,sage.rings.real_double.RealDoubleField_class):
     370                return RealDoubleVectorSpace_class(rank)
     371
     372            elif not sparse and isinstance(base_ring,sage.rings.complex_double.ComplexDoubleField_class):
     373                return ComplexDoubleVectorSpace_class(rank)
     374
     375            elif base_ring.is_field():
     376                return FreeModule_ambient_field(base_ring, rank, sparse=sparse)
     377
     378            elif isinstance(base_ring, principal_ideal_domain.PrincipalIdealDomain):
    370379                return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
    371        
    372         elif isinstance(base_ring, integral_domain.IntegralDomain) or base_ring.is_integral_domain():
    373             return FreeModule_ambient_domain(base_ring, rank, sparse=sparse)
    374            
    375         else:
     380
     381            elif isinstance(base_ring, sage.rings.number_field.order.Order) \
     382                and base_ring.is_maximal() and base_ring.class_number() == 1:
     383                return FreeModule_ambient_pid(base_ring, rank, sparse=sparse)
     384
     385            elif isinstance(base_ring, integral_domain.IntegralDomain) or base_ring.is_integral_domain():
     386                return FreeModule_ambient_domain(base_ring, rank, sparse=sparse)
     387
     388            else:
     389                return FreeModule_ambient(base_ring, rank, sparse=sparse)
     390        except NotImplementedError:
    376391            return FreeModule_ambient(base_ring, rank, sparse=sparse)
    377392
    378393
     
    563578            Category of modules with basis over Integer Ring
    564579
    565580        """
    566         if not isinstance(base_ring, commutative_ring.CommutativeRing):
    567             raise TypeError, "base_ring (=%s) must be a commutative ring"%base_ring
     581        if not base_ring.is_commutative():
     582            warn("""You are constructing a free module
     583over a noncommutative ring. Sage does not have a concept
     584of left/right and both sided modules, so be careful.
     585It's also not guaranteed that all multiplications are
     586done from the right side.""")
    568587        rank = sage.rings.integer.Integer(rank)
    569588        if rank < 0:
    570589            raise ValueError, "rank (=%s) must be nonnegative"%rank
  • sage/rings/ideal_monoid.py

    diff --git a/sage/rings/ideal_monoid.py b/sage/rings/ideal_monoid.py
    a b  
    4747            sage: M = sage.rings.ideal_monoid.IdealMonoid(R); M # indirect doctest
    4848            Monoid of ideals of Number Field in a with defining polynomial x^2 + 23
    4949        """
    50         if not is_CommutativeRing(R):
    51             raise TypeError, "R must be a commutative ring"
    5250        self.__R = R
    5351        Parent.__init__(self, base = sage.rings.integer_ring.ZZ, category = Monoids())
    5452        self._populate_coercion_lists_()
  • sage/rings/polynomial/multi_polynomial_ideal.py

    diff --git a/sage/rings/polynomial/multi_polynomial_ideal.py b/sage/rings/polynomial/multi_polynomial_ideal.py
    a b  
    241241from sage.interfaces.expect import StdOutContext
    242242
    243243from sage.rings.ideal import Ideal_generic
     244from sage.rings.noncommutative_ideals import Ideal_nc
    244245from sage.rings.integer import Integer
    245246from sage.structure.sequence import Sequence
    246247
     
    431432        sage: P.<a,b,c,d,e> = PolynomialRing(GF(127))
    432433        sage: J = sage.rings.ideal.Cyclic(P).homogenize()
    433434        sage: from sage.misc.sageinspect import sage_getsource
    434         sage: "buchberger" in sage_getsource(J.interreduced_basis)
     435        sage: "buchberger" in sage_getsource(J.interreduced_basis) #indirect doctest
    435436        True
    436437
    437438    The following tests against a bug that was fixed in trac ticket #11298::
     
    647648        EXAMPLES::
    648649       
    649650            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
     651            sage: I = sage.rings.ideal.Cyclic(R,4) # indirect doctest
     652            sage: magma(I)    # optional - magma
    652653            Ideal of Polynomial ring of rank 10 over GF(127)
    653654            Order: Graded Reverse Lexicographical
    654655            Variables: a, b, c, d, e, f, g, h, i, j
     
    730731        B = PolynomialSequence([R(e) for e in mgb], R, immutable=True)
    731732        return B
    732733
    733 class MPolynomialIdeal_singular_repr:
     734class MPolynomialIdeal_singular_base_repr:
     735    @require_field
     736    def syzygy_module(self):
     737        r"""
     738        Computes the first syzygy (i.e., the module of relations of the
     739        given generators) of the ideal.
     740       
     741        EXAMPLE::
     742       
     743            sage: R.<x,y> = PolynomialRing(QQ)
     744            sage: f = 2*x^2 + y
     745            sage: g = y
     746            sage: h = 2*f + g
     747            sage: I = Ideal([f,g,h])
     748            sage: M = I.syzygy_module(); M
     749            [       -2        -1         1]
     750            [       -y 2*x^2 + y         0]
     751            sage: G = vector(I.gens())
     752            sage: M*G
     753            (0, 0)
     754       
     755        ALGORITHM: Uses Singular's syz command
     756        """
     757        import sage.libs.singular
     758        syz = sage.libs.singular.ff.syz
     759        from sage.matrix.constructor import matrix
     760
     761        #return self._singular_().syz().transpose().sage_matrix(self.ring())
     762        S = syz(self)
     763        return matrix(self.ring(), S)
     764
     765    @libsingular_standard_options
     766    def _groebner_basis_libsingular(self, algorithm="groebner", *args, **kwds):
     767        """
     768        Return the reduced Groebner basis of this ideal. If the
     769        Groebner basis for this ideal has been calculated before the
     770        cached Groebner basis is returned regardless of the requested
     771        algorithm.
     772       
     773        INPUT:
     774       
     775        -  ``algorithm`` - see below for available algorithms
     776        - ``redsb`` - return a reduced Groebner basis (default: ``True``)
     777        - ``red_tail`` - perform tail reduction (default: ``True``)
     778
     779        ALGORITHMS:
     780       
     781        'groebner'
     782            Singular's heuristic script (default)
     783
     784        'std'
     785            Buchberger's algorithm
     786       
     787        'slimgb'
     788            the *SlimGB* algorithm
     789
     790        'stdhilb'
     791            Hilbert Basis driven Groebner basis
     792       
     793        'stdfglm'
     794            Buchberger and FGLM
     795       
     796        EXAMPLES:
     797       
     798        We compute a Groebner basis of 'cyclic 4' relative to
     799        lexicographic ordering. ::
     800       
     801            sage: R.<a,b,c,d> = PolynomialRing(QQ, 4, order='lex')
     802            sage: I = sage.rings.ideal.Cyclic(R,4); I
     803            Ideal (a + b + c + d, a*b + a*d + b*c + c*d, a*b*c + a*b*d
     804            + a*c*d + b*c*d, a*b*c*d - 1) of Multivariate Polynomial
     805            Ring in a, b, c, d over Rational Field
     806       
     807        ::
     808       
     809            sage: I._groebner_basis_libsingular()
     810            [c^2*d^6 - c^2*d^2 - d^4 + 1, c^3*d^2 + c^2*d^3 - c - d,
     811            b*d^4 - b + d^5 - d, b*c - b*d + c^2*d^4 + c*d - 2*d^2,
     812            b^2 + 2*b*d + d^2, a + b + c + d]
     813       
     814        ALGORITHM:
     815
     816        Uses libSINGULAR.
     817        """
     818        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import std_libsingular, slimgb_libsingular
     819        from sage.libs.singular import singular_function
     820        from sage.libs.singular.option import opt
     821
     822        import sage.libs.singular
     823        groebner = sage.libs.singular.ff.groebner
     824
     825        if get_verbose()>=2:
     826            opt['prot'] = True
     827        for name,value in kwds.iteritems():
     828            if value is not None:
     829                opt[name] = value
     830
     831        T = self.ring().term_order()
     832       
     833        if algorithm == "std":
     834            S = std_libsingular(self)
     835        elif algorithm == "slimgb":
     836            S = slimgb_libsingular(self)
     837        elif algorithm == "groebner":
     838            S = groebner(self)
     839        else:
     840            try:
     841                fnc = singular_function(algorithm)
     842                S = fnc(self)
     843            except NameError:
     844                raise NameError("Algorithm '%s' unknown"%algorithm)
     845        return S
     846
     847
     848class MPolynomialIdeal_singular_repr(
     849        MPolynomialIdeal_singular_base_repr):
    734850    """
    735851    An ideal in a multivariate polynomial ring, which has an
    736852    underlying Singular ring associated to it.
     
    15231639            print "Highest degree reached during computation: %2d."%log_parser.max_deg
    15241640        return S
    15251641
    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    
    16081642    @require_field
    16091643    def genus(self):
    16101644        """
     
    16651699            False
    16661700        """
    16671701        R = self.ring()
     1702
    16681703        if not isinstance(other, MPolynomialIdeal_singular_repr) or other.ring() != R:
    16691704            raise ValueError, "other must be an ideal in the ring of self, but it isn't."
    16701705
     
    25712606       
    25722607            sage: R.<x,y,z> = PolynomialRing(QQ)
    25732608            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()
     2609            sage: I.normal_basis() #indirect doctest
    25752610            [z^2, y*z, x*z, z, x*y, y, x, 1]
    25762611        """
    25772612        from sage.rings.polynomial.multi_polynomial_ideal_libsingular import kbase_libsingular
     
    26272662    def _macaulay2_(self, macaulay2=None):
    26282663        """
    26292664        Return Macaulay2 ideal corresponding to this ideal.
     2665    EXAMPLES::
     2666   
     2667        sage: R.<x,y,z,w> = PolynomialRing(ZZ, 4)
     2668        sage: I = ideal(x*y-z^2, y^2-w^2)  #indirect doctest
     2669        sage: macaulay2(I) # optional - macaulay2
     2670        Ideal (x*y - z^2, y^2 - w^2) of Multivariate Polynomial Ring in x, y, z, w over Integer Ring
    26302671        """
    26312672        if macaulay2 is None: macaulay2 = macaulay2_default
    26322673        try:
     
    27082749        R = self.ring()
    27092750        return R(k)
    27102751
     2752class NCPolynomialIdeal(MPolynomialIdeal_singular_repr, Ideal_nc):
     2753    def __init__(self, ring, gens, coerce=True, side = "left"):
     2754        r"""
     2755        Creates a non-commutative polynomial ideal.
     2756
     2757        INPUT:
     2758
     2759        - ``ring`` - the g-algebra to which this ideal belongs
     2760        - ``gens`` - the generators of this ideal
     2761        - ``coerce`` (optional - default True) - generators are
     2762          coerced into the ring before creating the ideal
     2763        - ``side`` - optional string, either "left" (default)
     2764          or "twosided"; defines whether this ideal is left
     2765          of two-sided.
     2766       
     2767        EXAMPLES::
     2768       
     2769            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2770            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2771            sage: H.inject_variables()
     2772            Defining x, y, z
     2773            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False) # indirect doctest
     2774            sage: I
     2775            Left Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2776            sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="twosided")
     2777            Twosided Ideal (y^2, x^2, z^2 - 1) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2778            sage: H.ideal([y^2, x^2, z^2-H.one_element()], side="right")
     2779            Traceback (most recent call last):
     2780            ...
     2781            ValueError: Only left and two-sided ideals are allowed.
     2782
     2783        """
     2784        if side == "right":
     2785            raise ValueError, "Only left and two-sided ideals are allowed."
     2786        Ideal_nc.__init__(self, ring, gens, coerce=coerce, side=side)
     2787
     2788    def __call_singular(self, cmd, arg = None):
     2789        """
     2790        Internal function for calling a Singular function.
     2791
     2792        INPUT:
     2793
     2794        - ``cmd`` - string, representing a Singular function
     2795        - ``arg`` (Default: None) - arguments for which cmd is called
     2796
     2797        OUTPUT:
     2798
     2799        - result of the Singular function call
     2800
     2801        EXAMPLES::
     2802
     2803            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2804            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2805            sage: H.inject_variables()
     2806            Defining x, y, z
     2807            sage: id = H.ideal(x + y, y + z)
     2808            sage: id.std()  # indirect doctest
     2809            Left Ideal (z, y, x) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2810        """
     2811        from sage.libs.singular.function import singular_function
     2812        fun = singular_function(cmd)
     2813        if arg is None:
     2814             return fun(self, ring=self.ring())
     2815       
     2816        return fun(self, arg, ring=self.ring())
     2817
     2818    @cached_method
     2819    def std(self):
     2820        r"""
     2821        Computes a GB of the ideal. It is two-sided if and only if the ideal is two-sided.
     2822       
     2823        EXAMPLES::
     2824       
     2825            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2826            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2827            sage: H.inject_variables()
     2828            Defining x, y, z
     2829            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2830            sage: I.std()
     2831            Left Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2832
     2833        If the ideal is a left ideal, then std returns a left
     2834        Groebner basis. But if it is a two-sided ideal, then
     2835        the output of std and :meth:`twostd` coincide::
     2836
     2837            sage: JL = H.ideal([x^3, y^3, z^3 - 4*z])
     2838            sage: JL
     2839            Left Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2840            sage: JL.std()
     2841            Left Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, 2*x*y*z - z^2 - 2*z, y^3, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2842            sage: JT = H.ideal([x^3, y^3, z^3 - 4*z], side='twosided')
     2843            sage: JT
     2844            Twosided Ideal (x^3, y^3, z^3 - 4*z) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2845            sage: JT.std()
     2846            Twosided Ideal (z^3 - 4*z, y*z^2 - 2*y*z, x*z^2 + 2*x*z, y^2*z - 2*y^2, 2*x*y*z - z^2 - 2*z, x^2*z + 2*x^2, y^3, x*y^2 - y*z, x^2*y - x*z - 2*x, x^3) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field, nc-relations: {y*x: x*y - z, z*y: y*z - 2*y, z*x: x*z + 2*x}
     2847            sage: JT.std() == JL.twostd()
     2848            True
     2849
     2850        ALGORITHM: Uses Singular's std command
     2851        """
     2852        if self.side()  == 'twosided':
     2853            return self.twostd()
     2854        return self.ring().ideal( self.__call_singular('std'), side=self.side())
     2855#        return self.__call_singular('std')
     2856
     2857    @cached_method
     2858    def twostd(self):
     2859        r"""
     2860        Computes a two-sided GB of the ideal (even if it is a left ideal).
     2861       
     2862        EXAMPLES::
     2863       
     2864            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2865            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2866            sage: H.inject_variables()
     2867            Defining x, y, z
     2868            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2869            sage: I.twostd()
     2870            Twosided Ideal (z^2 - 1, y*z - y, x*z + x, y^2, 2*x*y - z - 1, x^2) of Noncommutative Multivariate Polynomial Ring in x, y, z over Rational Field...
     2871       
     2872        ALGORITHM: Uses Singular's twostd command
     2873        """
     2874        return self.ring().ideal( self.__call_singular('twostd'), side='twosided')
     2875#        return self.__call_singular('twostd')
     2876
     2877#    def syz(self):
     2878#        return self.__call_singular('syz')
     2879
     2880    @require_field
     2881    def syzygy_module(self):
     2882        r"""
     2883        Computes the first syzygy (i.e., the module of relations of the
     2884        given generators) of the ideal.
     2885
     2886        NOTE:
     2887
     2888        Only left syzygies can be computed. So, even if the ideal is
     2889        two-sided, then the syzygies are only one-sided. In that case,
     2890        a warning is printed.
     2891
     2892        EXAMPLE::
     2893       
     2894            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2895            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2896            sage: H.inject_variables()
     2897            Defining x, y, z
     2898            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2899            sage: G = vector(I.gens()); G
     2900            d...: UserWarning: You are constructing a free module
     2901            over a noncommutative ring. Sage does not have a concept
     2902            of left/right and both sided modules, so be careful.
     2903            It's also not guaranteed that all multiplications are
     2904            done from the right side.
     2905            d...: UserWarning: You are constructing a free module
     2906            over a noncommutative ring. Sage does not have a concept
     2907            of left/right and both sided modules, so be careful.
     2908            It's also not guaranteed that all multiplications are
     2909            done from the right side.
     2910            (y^2, x^2, z^2 - 1)
     2911            sage: M = I.syzygy_module(); M
     2912            [                                                                         -z^2 - 8*z - 15                                                                                        0                                                                                      y^2]
     2913            [                                                                                       0                                                                          -z^2 + 8*z - 15                                                                                      x^2]
     2914            [                                                              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]
     2915            [                 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]
     2916            [                                                              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]
     2917            [  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]
     2918            [                                                  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]
     2919            [                                                  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]
     2920            [                                                                           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]
     2921            [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]
     2922
     2923            sage: M*G
     2924            (0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
     2925       
     2926        ALGORITHM: Uses Singular's syz command
     2927        """
     2928        if self.side() == 'twosided':
     2929            warn("The result of this Syzygy computation is one-sided (left)!")
     2930        import sage.libs.singular
     2931        syz = sage.libs.singular.ff.syz
     2932        from sage.matrix.constructor import matrix
     2933
     2934        #return self._singular_().syz().transpose().sage_matrix(self.ring())
     2935        S = syz(self)
     2936        return matrix(self.ring(), S)
     2937
     2938
     2939    def res(self, length):
     2940        r"""
     2941        Computes the resoltuion up to a given length of the ideal.
     2942       
     2943        NOTE:
     2944
     2945        Only left syzygies can be computed. So, even if the ideal is
     2946        two-sided, then the resolution is only one-sided. In that case,
     2947        a warning is printed.
     2948
     2949        EXAMPLE::
     2950       
     2951            sage: A.<x,y,z> = FreeAlgebra(QQ, 3)
     2952            sage: H = A.g_algebra({y*x:x*y-z, z*x:x*z+2*x, z*y:y*z-2*y})
     2953            sage: H.inject_variables()
     2954            Defining x, y, z
     2955            sage: I = H.ideal([y^2, x^2, z^2-H.one_element()],coerce=False)
     2956            sage: I.res(3)
     2957            <Resolution>
     2958        """
     2959        if self.side() == 'twosided':
     2960            warn("The resulting resolution is one-sided (left)!")
     2961        return self.__call_singular('res', length)
     2962
    27112963
    27122964class MPolynomialIdeal( MPolynomialIdeal_singular_repr, \
    27132965                        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  
    20182018        EXAMPLES::
    20192019
    20202020            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2021             sage: 3/2*x + 1/2*y + 1
     2021            sage: 3/2*x + 1/2*y + 1 #indirect doctest
    20222022            3/2*x + 1/2*y + 1
    20232023
    20242024        """
     
    20352035        EXAMPLES::
    20362036
    20372037            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2038             sage: 3/2*x - 1/2*y - 1
     2038            sage: 3/2*x - 1/2*y - 1 #indirect doctest
    20392039            3/2*x - 1/2*y - 1
    20402040
    20412041        """
     
    20542054        EXAMPLES::
    20552055
    20562056            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2057             sage: 3/2*x
     2057            sage: 3/2*x # indirect doctest
    20582058            3/2*x
    20592059        """
    20602060
     
    20662066        return new_MP((<MPolynomialRing_libsingular>self._parent),_p)
    20672067       
    20682068    cpdef ModuleElement _lmul_(self, RingElement right):
    2069         # all currently implemented rings are commutative
     2069        """
     2070        Multiply left and right.
     2071
     2072        EXAMPLES::
     2073
     2074            sage: P.<x,y,z>=PolynomialRing(QQ,3)
     2075            sage: (3/2*x - 1/2*y - 1) * (3/2) # indirect doctest
     2076            9/4*x - 3/4*y - 3/2
     2077        """
     2078        # Note that the argument to _rmul_ and _lmul_ is an
     2079        # element of the base ring.
     2080        # All currently implemented base rings are commutative,
     2081        # So, calling _rmul_ is the correct thing to do.
    20702082        return self._rmul_(right)
    20712083       
    20722084    cpdef RingElement  _mul_(left, RingElement right):
     
    20762088        EXAMPLES::
    20772089
    20782090            sage: P.<x,y,z>=PolynomialRing(QQ,3)
    2079             sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1)
     2091            sage: (3/2*x - 1/2*y - 1) * (3/2*x + 1/2*y + 1) # indirect doctest
    20802092            9/4*x^2 - 1/4*y^2 - y - 1
    20812093
    20822094            sage: P.<x,y> = PolynomialRing(QQ,order='lex')
     
    20992111        EXAMPLES::
    21002112
    21012113            sage: R.<x,y>=PolynomialRing(QQ,2)
    2102             sage: f = (x + y)/3
     2114            sage: f = (x + y)/3 # indirect doctest
    21032115            sage: f.parent()
    21042116            Multivariate Polynomial Ring in x, y over Rational Field
    21052117
     
    22752287
    22762288            sage: P.<x,y,z> = QQ[]
    22772289            sage: f = - 1*x^2*y - 25/27 * y^3 - z^2
    2278             sage: latex(f)
     2290            sage: latex(f)  # indirect doctest
    22792291            - x^{2} y - \frac{25}{27} y^{3} - z^{2}
    22802292        """
    22812293        cdef ring *_ring = (<MPolynomialRing_libsingular>self._parent)._ring
     
    42494261        EXAMPLES::
    42504262
    42514263            sage: R.<x,y> = PolynomialRing(GF(7), 2)
    4252             sage: f = (x^3 + 2*y^2*x)^7; f
     4264            sage: f = (x^3 + 2*y^2*x)^7; f          # indirect doctest
    42534265            x^21 + 2*x^7*y^14
    42544266
    42554267            sage: h = macaulay2(f); h               # optional
  • new file sage/rings/polynomial/plural.pxd

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

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

    diff --git a/sage/rings/polynomial/term_order.py b/sage/rings/polynomial/term_order.py
    a b  
    686686                    singular_str = []
    687687                    macaulay2_str = []
    688688
     689                    length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end
    689690                    for block in block_names:
    690691                        try:
    691                             length_pattern  = re.compile("\(([0-9]+)\)$") # match with parenthesized block length at end                 
    692                             block_name, block_length, _ = re.split(length_pattern,block)
     692                            block_name, block_length, _ = re.split(length_pattern,block.strip())
    693693                            block_length = int(block_length)
    694                             blocks.append( TermOrder(block_name,block_length,force=force) )
    695                         except:
    696                             raise TypeError, "%s is not a valid term order"%(name,)
    697                         length += block_length
     694                            assert( block_length > 0)
     695
     696                            blocks.append( TermOrder(block_name, block_length, force=force) )
     697                            name_str.append("%s(%d)"%(block_name, block_length))
     698                            singular_str.append("%s(%d)"%(singular_name_mapping.get(block_name, block_name), block_length))
     699                            macaulay2_str.append("%s => %d"%(macaulay2_name_mapping.get(block_name, block_name), block_length))
     700                            length += block_length
     701                        except ValueError:
     702                            block_name = block.strip()
     703                            if block_name.lower() != "c":
     704                                raise TypeError, "%s is not a valid term ordering (wrong part: '%s')"%(name, block)
    698705
    699706                    if n != 0 and length != n:
    700707                        raise TypeError, "Term order length does not match the number of generators"
  • sage/rings/ring.pxd

    diff --git a/sage/rings/ring.pxd b/sage/rings/ring.pxd
    a b  
    55    cdef public object _one_element
    66    cdef public object _zero_ideal
    77    cdef public object _unit_ideal
     8    cdef public object __ideal_monoid
    89    cdef _an_element_c_impl(self)
    9     cdef public object __ideal_monoid
    1010
    1111cdef class CommutativeRing(Ring):
    1212    cdef public object __fraction_field
  • sage/rings/ring.pyx

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