B
    [M                @   s  d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZmZ ddlmZmZ ddlmZmZ dd	lmZmZmZmZ dd
lmZ ddl m!Z! ddl"m#Z# ddl$m%Z% ddl&m'Z' ddl(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2 ddl3m4Z4 ddl5m6Z7m8Z9m:Z: ddl;m<Z<m=Z= ddl>m?Z? ddl@mAZA ddlBmCZC ddlDmEZE eCe#fddZFeCe#fddZGeCe#fddZHeCdd  ZId!d" ZJi ZKG d#d$ d$eAe'ZLG d%d& d&e2eAeeMZNd'S )(zSparse polynomial rings.     )print_functiondivision)addmulltlegtge)GeneratorType)Expr)Symbolsymbols)igcdoo)CantSympifysympify)is_sequencereducestring_typesrange)multinomial_coefficients)MonomialOps)lex)heugcd)IPolys)expr_from_dict_dict_reorder_parallel_dict_from_expr)CoercionFailedGeneratorsErrorExactQuotientFailedMultivariatePolynomialError)DomainElement)PolynomialRing)DomainOrderbuild_options)dmp_to_dictdmp_from_dict)construct_domain)DefaultPrinting)public)pollutec             C   s   t | ||}|f|j S )a  Construct a polynomial ring returning ``(ring, x_1, ..., x_n)``.

    Parameters
    ----------
    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
    domain : :class:`Domain` or coercible
    order : :class:`Order` or coercible, optional, defaults to ``lex``

    Examples
    ========

    >>> from sympy.polys.rings import ring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.orderings import lex

    >>> R, x, y, z = ring("x,y,z", ZZ, lex)
    >>> R
    Polynomial ring in x, y, z over ZZ with lex order
    >>> x + y + z
    x + y + z
    >>> type(_)
    <class 'sympy.polys.rings.PolyElement'>

    )PolyRinggens)r   domainorder_ring r2   0lib/python3.7/site-packages/sympy/polys/rings.pyring!   s    r4   c             C   s   t | ||}||jfS )a  Construct a polynomial ring returning ``(ring, (x_1, ..., x_n))``.

    Parameters
    ----------
    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
    domain : :class:`Domain` or coercible
    order : :class:`Order` or coercible, optional, defaults to ``lex``

    Examples
    ========

    >>> from sympy.polys.rings import xring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.orderings import lex

    >>> R, (x, y, z) = xring("x,y,z", ZZ, lex)
    >>> R
    Polynomial ring in x, y, z over ZZ with lex order
    >>> x + y + z
    x + y + z
    >>> type(_)
    <class 'sympy.polys.rings.PolyElement'>

    )r-   r.   )r   r/   r0   r1   r2   r2   r3   xring>   s    r5   c             C   s(   t | ||}tdd |jD |j |S )a  Construct a polynomial ring and inject ``x_1, ..., x_n`` into the global namespace.

    Parameters
    ----------
    symbols : str, Symbol/Expr or sequence of str, Symbol/Expr (non-empty)
    domain : :class:`Domain` or coercible
    order : :class:`Order` or coercible, optional, defaults to ``lex``

    Examples
    ========

    >>> from sympy.polys.rings import vring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.orderings import lex

    >>> vring("x,y,z", ZZ, lex)
    Polynomial ring in x, y, z over ZZ with lex order
    >>> x + y + z
    x + y + z
    >>> type(_)
    <class 'sympy.polys.rings.PolyElement'>

    c             S   s   g | ]
}|j qS r2   )name).0Zsymr2   r2   r3   
<listcomp>u   s    zvring.<locals>.<listcomp>)r-   r,   r   r.   )r   r/   r0   r1   r2   r2   r3   vring[   s    r9   c       
      O   s   d}t | s| gd } }ttt| } t||}t| |\}}|jdkrntdd |D g }t||d\|_}t	|j
|j|j}tt|j|}	|r||	d fS ||	fS dS )a  Construct a ring deriving generators and domain from options and input expressions.

    Parameters
    ----------
    exprs : :class:`Expr` or sequence of :class:`Expr` (sympifiable)
    symbols : sequence of :class:`Symbol`/:class:`Expr`
    options : keyword arguments understood by :class:`Options`

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.polys.rings import sring
    >>> from sympy.polys.domains import ZZ
    >>> from sympy.polys.orderings import lex

    >>> x, y, z = symbols("x,y,z")
    >>> R, f = sring(x + 2*y + 3*z)
    >>> R
    Polynomial ring in x, y, z over ZZ with lex order
    >>> f
    x + 2*y + 3*z
    >>> type(_)
    <class 'sympy.polys.rings.PolyElement'>

    FTNc             S   s   g | ]}t | qS r2   )listvalues)r7   Zrepr2   r2   r3   r8      s    zsring.<locals>.<listcomp>)optr   )r   r:   mapr   r&   r   r/   sumr)   r-   r.   r0   	from_dict)
Zexprsr   ZoptionsZsingler<   Zrepscoeffs_r1   polysr2   r2   r3   sringx   s    

rC   c             C   sr   t | tr| rt| ddS dS t | tr.| fS t| rftdd | D rPt| S tdd | D rf| S tdd S )NT)seqr2   c             s   s   | ]}t |tV  qd S )N)
isinstancer   )r7   sr2   r2   r3   	<genexpr>   s    z!_parse_symbols.<locals>.<genexpr>c             s   s   | ]}t |tV  qd S )N)rE   r   )r7   rF   r2   r2   r3   rG      s    zbexpected a string, Symbol or expression or a non-empty sequence of strings, Symbols or expressions)rE   r   _symbolsr   r   allr   )r   r2   r2   r3   _parse_symbols   s    

rJ   c               @   s4  e Zd ZdZefddZdd Zdd Zdd	 Zd
d Z	dd Z
dd ZdEddZdd Zedd Zedd ZdFddZdd Zdd Zdd  ZeZd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Z ed7d8 Z!ed9d: Z"d;d< Z#d=d> Z$d?d@ Z%dAdB Z&dCdD Z'dS )Gr-   z*Multivariate distributed polynomial ring. c                s  t t|}t|}t|}t  | j||| f}t|}|d kr|j	rlt
|t
|j@ rltdt| }||_t||_tdtfd|i|_||_||_||_ |_d| |_| |_t
|j|_|j|jfg|_|r8t|}| |_ |! |_"|# |_$|% |_&|' |_(|) |_*|+ |_,n6dd }||_ ||_"dd |_$||_&||_(||_*||_, t-krdd |_.n fd	d|_.xFt/|j|jD ]4\}	}
t0|	t1r|	j2}t3||st4|||
 qW |t|< |S )
Nz7polynomial ring and it's ground domain share generatorsPolyElementr4   )r   c             S   s   dS )Nr2   r2   )abr2   r2   r3   <lambda>   s    z"PolyRing.__new__.<locals>.<lambda>c             S   s   dS )Nr2   r2   )rL   rM   cr2   r2   r3   rN      s    c             S   s   t | S )N)max)fr2   r2   r3   rN      s    c                s   t |  dS )N)key)rP   )rQ   )r0   r2   r3   rN      s    )5tuplerJ   len	DomainOpt
preprocessOrderOpt__name___ring_cachegetis_Compositesetr   r   object__new___hash_tuplehash_hashtyperK   dtypengensr/   r0   
zero_monom_gensr.   	_gens_setone_oner   r   monomial_mulpowmonomial_powZmulpowmonomial_mulpowZldivmonomial_ldivdivmonomial_divlcmZmonomial_lcmgcdmonomial_gcdr   leading_expvziprE   r   r6   hasattrsetattr)clsr   r/   r0   rd   r_   objZcodegenZmonunitsymbol	generatorr6   r2   )r0   r3   r^      s`    















zPolyRing.__new__c             C   sJ   | j j}g }x4t| jD ]&}| |}| j}|||< || qW t|S )z(Return a list of polynomial generators. )r/   rh   r   rd   monomial_basiszeroappendrS   )selfrh   rf   iexpvpolyr2   r2   r3   rf      s    
zPolyRing._gensc             C   s   | j | j| jfS )N)r   r/   r0   )r   r2   r2   r3   __getnewargs__  s    zPolyRing.__getnewargs__c             C   s:   | j  }|d= x$| D ]\}}|dr||= qW |S )Nrt   Z	monomial_)__dict__copyitems
startswith)r   staterR   valuer2   r2   r3   __getstate__  s    


zPolyRing.__getstate__c             C   s   | j S )N)ra   )r   r2   r2   r3   __hash__  s    zPolyRing.__hash__c             C   s2   t |to0| j| j| j| jf|j|j|j|jfkS )N)rE   r-   r   r/   rd   r0   )r   otherr2   r2   r3   __eq__  s    
zPolyRing.__eq__c             C   s
   | |k S )Nr2   )r   r   r2   r2   r3   __ne__   s    zPolyRing.__ne__Nc             C   s    |  |p| j|p| j|p| jS )N)	__class__r   r/   r0   )r   r   r/   r0   r2   r2   r3   clone#  s    zPolyRing.clonec             C   s   dg| j  }d||< t|S )zReturn the ith-basis element. r      )rd   rS   )r   r   Zbasisr2   r2   r3   r|   &  s    zPolyRing.monomial_basisc             C   s   |   S )N)rc   )r   r2   r2   r3   r}   ,  s    zPolyRing.zeroc             C   s   |  | jS )N)rc   ri   )r   r2   r2   r3   rh   0  s    zPolyRing.onec             C   s   | j ||S )N)r/   convert)r   elementZorig_domainr2   r2   r3   
domain_new4  s    zPolyRing.domain_newc             C   s   |  | j|S )N)term_newre   )r   coeffr2   r2   r3   
ground_new7  s    zPolyRing.ground_newc             C   s    |  |}| j}|r|||< |S )N)r   r}   )r   monomr   r   r2   r2   r3   r   :  s
    
zPolyRing.term_newc             C   s   t |trF| |jkr|S t | jtr<| jj|jkr<| |S tdnxt |trZtdndt |trn| 	|S t |t
ry
| |S  tk
r   | |S X nt |tr| |S | |S d S )NZ
conversionZparsing)rE   rK   r4   r/   r#   r   NotImplementedErrorr   dictr?   r:   
from_terms
ValueError	from_listr   	from_expr)r   r   r2   r2   r3   ring_newA  s$    











zPolyRing.ring_newc             C   s:   | j }| j}x(| D ]\}}||}|r|||< qW |S )N)r   r}   r   )r   r   r   r   r   r   r2   r2   r3   r?   Y  s    zPolyRing.from_dictc             C   s   |  t|S )N)r?   r   )r   r   r2   r2   r3   r   d  s    zPolyRing.from_termsc             C   s   |  t|| jd | jS )Nr   )r?   r'   rd   r/   )r   r   r2   r2   r3   r   g  s    zPolyRing.from_listc                s"   | j  fdd  t|S )Nc                s    | }|d k	r|S | jr2tttt | jS | jrNtttt | jS | j	rz| j
jrz| j
dkrz | jt| j
 S | S d S )Nr   )rZ   Zis_Addr   r   r:   r=   argsZis_Mulr   Zis_PowexpZ
is_Integerbaseintr   )exprr{   )_rebuildr/   mappingr2   r3   r   m  s    
z(PolyRing._rebuild_expr.<locals>._rebuild)r/   r   )r   r   r   r2   )r   r/   r   r3   _rebuild_exprj  s    zPolyRing._rebuild_exprc             C   sZ   t tt| j| j}y| ||}W n$ tk
rJ   td| |f Y nX | |S d S )Nz@expected an expression convertible to a polynomial in %s, got %s)	r   r:   ru   r   r.   r   r   r   r   )r   r   r   r   r2   r2   r3   r   }  s    zPolyRing.from_exprc             C   s   |dkr| j rd}qd}nt|trj|}d|kr<|| j k r<q| j  |kr\|dkr\| d }qtd| nt|| jry| j|}W q tk
r   td| Y qX nJt|try| j|}W q tk
r   td| Y qX ntd| |S )z+Compute index of ``gen`` in ``self.gens``. Nr   r   zinvalid generator index: %szinvalid generator: %szEexpected a polynomial generator, an integer, a string or None, got %s)	rd   rE   r   r   rc   r.   indexr   r   )r   genr   r2   r2   r3   r     s.    

zPolyRing.indexc                sB   t t| j|  fddt| jD }|s2| jS | j|dS dS )z,Remove specified generators from this ring. c                s   g | ]\}}| kr|qS r2   r2   )r7   r   rF   )indicesr2   r3   r8     s    z!PolyRing.drop.<locals>.<listcomp>)r   N)r\   r=   r   	enumerater   r/   r   )r   r.   r   r2   )r   r3   drop  s
    zPolyRing.dropc             C   s$   | j | }|s| jS | j|dS d S )N)r   )r   r/   r   )r   rR   r   r2   r2   r3   __getitem__  s    
zPolyRing.__getitem__c             C   s6   | j jst| j dr$| j| j j dS td| j  d S )Nr/   )r/   z%s is not a composite domain)r/   r[   rv   r   r   )r   r2   r2   r3   	to_ground  s    zPolyRing.to_groundc             C   s   t | S )N)r#   )r   r2   r2   r3   	to_domain  s    zPolyRing.to_domainc             C   s   ddl m} || j| j| jS )Nr   )	FracField)Zsympy.polys.fieldsr   r   r/   r0   )r   r   r2   r2   r3   to_field  s    zPolyRing.to_fieldc             C   s   t | jdkS )Nr   )rT   r.   )r   r2   r2   r3   is_univariate  s    zPolyRing.is_univariatec             C   s   t | jdkS )Nr   )rT   r.   )r   r2   r2   r3   is_multivariate  s    zPolyRing.is_multivariatec             G   s<   | j }x0|D ](}t|tdr,|| j| 7 }q||7 }qW |S )aw  
        Add a sequence of polynomials or containers of polynomials.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> R, x = ring("x", ZZ)
        >>> R.add([ x**2 + 2*i + 3 for i in range(4) ])
        4*x**2 + 24
        >>> _.factor_list()
        (4, [(x**2 + 6, 1)])

        )include)r}   r   r
   r   )r   objspry   r2   r2   r3   r     s    
zPolyRing.addc             G   s<   | j }x0|D ](}t|tdr,|| j| 9 }q||9 }qW |S )a  
        Multiply a sequence of polynomials or containers of polynomials.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> R, x = ring("x", ZZ)
        >>> R.mul([ x**2 + 2*i + 3 for i in range(4) ])
        x**8 + 24*x**6 + 206*x**4 + 744*x**2 + 945
        >>> _.factor_list()
        (1, [(x**2 + 3, 1), (x**2 + 5, 1), (x**2 + 7, 1), (x**2 + 9, 1)])

        )r   )rh   r   r
   r   )r   r   r   ry   r2   r2   r3   r     s    
zPolyRing.mulc                s`   t t| j|  fddt| jD } fddt| jD }|sH| S | j|| j| dS dS )zd
        Remove specified generators from the ring and inject them into
        its domain.
        c                s   g | ]\}}| kr|qS r2   r2   )r7   r   rF   )r   r2   r3   r8   
  s    z+PolyRing.drop_to_ground.<locals>.<listcomp>c                s   g | ]\}}| kr|qS r2   r2   )r7   r   r   )r   r2   r3   r8     s    )r   r/   N)r\   r=   r   r   r   r.   r   r   )r   r.   r   r2   )r   r3   drop_to_ground  s    zPolyRing.drop_to_groundc             C   s6   | |kr.t | jt |j}| jt|dS | S dS )z+Add the generators of ``other`` to ``self``)r   N)r\   r   unionr   r:   )r   r   symsr2   r2   r3   compose  s    zPolyRing.composec             C   s$   t | jt |}| jt|dS )z9Add the elements of ``symbols`` as generators to ``self``)r   )r\   r   r   r   r:   )r   r   r   r2   r2   r3   add_gens  s    zPolyRing.add_gens)NNN)N)(rX   
__module____qualname____doc__r   r^   rf   r   r   r   r   r   r   r|   propertyr}   rh   r   r   r   r   __call__r?   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r2   r2   r2   r3   r-      sF   A




r-   c               @   s  e Zd ZdZdd Zdd Zdd ZdZd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd ZdddZdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Zed7d8 Z ed9d: Z!ed;d< Z"ed=d> Z#ed?d@ Z$edAdB Z%edCdD Z&edEdF Z'edGdH Z(edIdJ Z)edKdL Z*edMdN Z+edOdP Z,edQdR Z-edSdT Z.edUdV Z/edWdX Z0dYdZ Z1d[d\ Z2d]d^ Z3d_d` Z4dadb Z5dcdd Z6dedf Z7dgdh Z8didj Z9dkdl Z:dmdn Z;dodp Z<dqdr Z=dsdt Z>dudv Z?dwdx Z@dydz ZAd{d| ZBeA ZCZDeB ZEZFd}d~ ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdddZNdd ZOdddZPdd ZQdd ZRdd ZSdd ZTdd ZUedd ZVedd ZWdd ZXedd ZYdd ZZdd Z[dddZ\dddZ]dddZ^dd Z_dd Z`dd Zadd Zbdd Zcdd Zddd Zedd Zfdd Zgdd Zhdd ZiddĄ ZjddƄ ZkddȄ Zlddʄ Zmdd̄ ZnenZodd΄ ZpddЄ Zqdd҄ ZrddԄ Zsddք Ztdd؄ Zuddڄ Zvdd܄ Zwddބ Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zdd ZdddZdddZd ddZdd Zdd Zdd Zdd Zdd Zdd  Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Zdd Zdd Zd!ddZdd ZdS ("  rK   z5Element of multivariate distributed polynomial ring. c             C   s
   |  |S )N)r   )r   Zinitr2   r2   r3   new#  s    zPolyElement.newc             C   s
   | j  S )N)r4   r   )r   r2   r2   r3   parent&  s    zPolyElement.parentc             C   s   | j t|  fS )N)r4   r:   	iterterms)r   r2   r2   r3   r   )  s    zPolyElement.__getnewargs__Nc             C   s.   | j }|d kr*t| jt|  f | _ }|S )N)ra   r`   r4   	frozensetr   )r   ra   r2   r2   r3   r   .  s    zPolyElement.__hash__c             C   s
   |  | S )a  Return a copy of polynomial self.

        Polynomials are mutable; if one is interested in preserving
        a polynomial, and one plans to use inplace operations, one
        can copy the polynomial. This method makes a shallow copy.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> R, x, y = ring('x, y', ZZ)
        >>> p = (x + y)**2
        >>> p1 = p.copy()
        >>> p2 = p
        >>> p[R.zero_monom] = 3
        >>> p
        x**2 + 2*x*y + y**2 + 3
        >>> p1
        x**2 + 2*x*y + y**2
        >>> p2
        x**2 + 2*x*y + y**2 + 3

        )r   )r   r2   r2   r3   r   9  s    zPolyElement.copyc             C   sN   | j |kr| S | j j|jkr@ttt| | j j|j }||S || S d S )N)r4   r   r:   ru   r   r   r?   )r   new_ringtermsr2   r2   r3   set_ringU  s    

zPolyElement.set_ringc             G   sH   |r.t || jjkr.td| jjt |f n| jj}t|  f| S )Nz&not enough symbols, expected %s got %s)rT   r4   rd   r   r   r   as_expr_dict)r   r   r2   r2   r3   as_expr^  s    zPolyElement.as_exprc                s    | j jj  fdd|  D S )Nc                s   i | ]\}} ||qS r2   r2   )r7   r   r   )to_sympyr2   r3   
<dictcomp>h  s    z,PolyElement.as_expr_dict.<locals>.<dictcomp>)r4   r/   r   r   )r   r2   )r   r3   r   f  s    
zPolyElement.as_expr_dictc                s|   | j j}|jr|js|j| fS | }|j |j}|j}x|  D ]}| || qBW | 	 fdd| 
 D } |fS )Nc                s   g | ]\}}||  fqS r2   r2   )r7   kv)commonr2   r3   r8   x  s    z,PolyElement.clear_denoms.<locals>.<listcomp>)r4   r/   is_Fieldhas_assoc_Ringrh   get_ringrq   denomr;   r   r   )r   r/   Zground_ringrq   r   r   r   r2   )r   r3   clear_denomsj  s    
zPolyElement.clear_denomsc             C   s(   x"t |  D ]\}}|s| |= qW dS )z+Eliminate monomials with zero coefficient. N)r:   r   )r   r   r   r2   r2   r3   
strip_zero{  s    zPolyElement.strip_zeroc             C   sR   |s
|  S t |tr,|j| jkr,t| |S t| dkr<dS | | jj|kS dS )aP  Equality test for polynomials.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> p1 = (x + y)**2 + (x - y)**2
        >>> p1 == 4*x*y
        False
        >>> p1 == 2*(x**2 + y**2)
        True

        r   FN)rE   rK   r4   r   r   rT   rZ   re   )p1p2r2   r2   r3   r     s    zPolyElement.__eq__c             C   s
   | |k S )Nr2   )r   r   r2   r2   r3   r     s    zPolyElement.__ne__c             C   s   | j }t||jrft|  t| kr.dS |jj}xx|  D ]}|| | || |s@dS q@W dS nJt| dkrvdS y|j|}W n t	k
r   dS X |j| 
 ||S dS )z+Approximate equality test for polynomials. FTr   N)r4   rE   rc   r\   keysr/   almosteqrT   r   r   const)r   r   Z	tolerancer4   r   r   r2   r2   r3   r     s     zPolyElement.almosteqc             C   s   t | |  fS )N)rT   r   )r   r2   r2   r3   sort_key  s    zPolyElement.sort_keyc             C   s(   t || jjr ||  | S tS d S )N)rE   r4   rc   r   NotImplemented)r   r   opr2   r2   r3   _cmp  s    zPolyElement._cmpc             C   s   |  |tS )N)r   r   )r   r   r2   r2   r3   __lt__  s    zPolyElement.__lt__c             C   s   |  |tS )N)r   r   )r   r   r2   r2   r3   __le__  s    zPolyElement.__le__c             C   s   |  |tS )N)r   r   )r   r   r2   r2   r3   __gt__  s    zPolyElement.__gt__c             C   s   |  |tS )N)r   r	   )r   r   r2   r2   r3   __ge__  s    zPolyElement.__ge__c             C   sH   | j }||}|jdkr$||jfS t|j}||= ||j|dfS d S )Nr   )r   )r4   r   rd   r/   r:   r   r   )r   r   r4   r   r   r2   r2   r3   _drop  s    



zPolyElement._dropc             C   s   |  |\}}| jjdkr8| jr*| dS td| nT|j}xH|  D ]<\}}|| dkrxt|}||= ||t	|< qHtd| qHW |S d S )Nr   zcan't drop %sr   )
r   r4   rd   	is_groundr   r   r}   r   r:   rS   )r   r   r   r4   r   r   r   Kr2   r2   r3   r     s    
zPolyElement.dropc             C   s6   | j }||}t|j}||= ||j||| dfS )N)r   r/   )r4   r   r:   r   r   )r   r   r4   r   r   r2   r2   r3   _drop_to_ground  s
    

zPolyElement._drop_to_groundc             C   s   | j jdkrtd| |\}}|j}|jjd }xn|  D ]b\}}|d | ||d d   }||kr|||  |||< q>||  |||  |7  < q>W |S )Nr   z#can't drop only generator to groundr   )	r4   rd   r   r   r}   r/   r.   r   
mul_ground)r   r   r   r4   r   r   r   Zmonr2   r2   r3   r     s    "zPolyElement.drop_to_groundc             C   s   t | | jjd | jjS )Nr   )r(   r4   rd   r/   )r   r2   r2   r3   to_dense  s    zPolyElement.to_densec             C   s   t | S )N)r   )r   r2   r2   r3   to_dict  s    zPolyElement.to_dictc             C   s  | s| | jjjS |d }|d }|d }| j}|j}	|j}
|j}g }x<|  D ].\}}|j|}|rrdnd}|	| ||kr| |}|
dr|dd  }n(|s| }|dkr|j||dd	}nd
}g }xt|
D ]}|| }|sq|j|	| |dd	}|dkrR|t|ks(|dk r:|j||dd	}n|}|	|||f  q|	d|  qW |rt|g| }|	|| qTW |d dkr|d}|dkr|dd d
|S )NZAddZMulZAtomz + z - -r   T)strict r   Fz%s)z + z - )Z_printr4   r/   r}   r   rd   re   r   is_positiver~   r   Zparenthesizer   r   joinpopinsert)r   ZprinterZ
precedenceZexp_patternZ
mul_symbolZprec_addZprec_mulZ	prec_atomr4   r   rd   zmZsexpvsr   r   ZpositiveZsignZscoeffZsexpvr   r   rz   Zsexpheadr2   r2   r3   str  sV    






zPolyElement.strc             C   s   | | j jkS )N)r4   rg   )r   r2   r2   r3   is_generator9  s    zPolyElement.is_generatorc             C   s   |  pt | dko| jj| kS )Nr   )rT   r4   re   )r   r2   r2   r3   r   =  s    zPolyElement.is_groundc             C   s   |  pt | dko| jdkS )Nr   )rT   LC)r   r2   r2   r3   is_monomialA  s    zPolyElement.is_monomialc             C   s   t | dkS )Nr   )rT   )r   r2   r2   r3   is_termE  s    zPolyElement.is_termc             C   s   | j j| jS )N)r4   r/   is_negativer   )r   r2   r2   r3   r   I  s    zPolyElement.is_negativec             C   s   | j j| jS )N)r4   r/   r   r   )r   r2   r2   r3   r   M  s    zPolyElement.is_positivec             C   s   | j j| jS )N)r4   r/   is_nonnegativer   )r   r2   r2   r3   r   Q  s    zPolyElement.is_nonnegativec             C   s   | j j| jS )N)r4   r/   is_nonpositiver   )r   r2   r2   r3   r   U  s    zPolyElement.is_nonpositivec             C   s   |  S )Nr2   )rQ   r2   r2   r3   is_zeroY  s    zPolyElement.is_zeroc             C   s   | | j jkS )N)r4   rh   )rQ   r2   r2   r3   is_one]  s    zPolyElement.is_onec             C   s   | j j| jS )N)r4   r/   r   r   )rQ   r2   r2   r3   is_monica  s    zPolyElement.is_monicc             C   s   | j j|  S )N)r4   r/   r   content)rQ   r2   r2   r3   is_primitivee  s    zPolyElement.is_primitivec             C   s   t dd |  D S )Nc             s   s   | ]}t |d kV  qdS )r   N)r>   )r7   r   r2   r2   r3   rG   k  s    z(PolyElement.is_linear.<locals>.<genexpr>)rI   
itermonoms)rQ   r2   r2   r3   	is_lineari  s    zPolyElement.is_linearc             C   s   t dd |  D S )Nc             s   s   | ]}t |d kV  qdS )   N)r>   )r7   r   r2   r2   r3   rG   o  s    z+PolyElement.is_quadratic.<locals>.<genexpr>)rI   r   )rQ   r2   r2   r3   is_quadraticm  s    zPolyElement.is_quadraticc             C   s   | j jsdS | j | S )NT)r4   rd   Z	dmp_sqf_p)rQ   r2   r2   r3   is_squarefreeq  s    zPolyElement.is_squarefreec             C   s   | j jsdS | j | S )NT)r4   rd   Zdmp_irreducible_p)rQ   r2   r2   r3   is_irreduciblew  s    zPolyElement.is_irreduciblec             C   s    | j jr| j | S tdd S )Nzcyclotomic polynomial)r4   r   Zdup_cyclotomic_pr!   )rQ   r2   r2   r3   is_cyclotomic}  s    zPolyElement.is_cyclotomicc             C   s   |  dd |  D S )Nc             S   s   g | ]\}}|| fqS r2   r2   )r7   r   r   r2   r2   r3   r8     s    z'PolyElement.__neg__.<locals>.<listcomp>)r   r   )r   r2   r2   r3   __neg__  s    zPolyElement.__neg__c             C   s   | S )Nr2   )r   r2   r2   r3   __pos__  s    zPolyElement.__pos__c       
      C   sB  |s|   S | j}t||jrp|   }|j}|jj}x6| D ]*\}}|||| }|rb|||< q>||= q>W |S t|trt|jt	r|jj|jkrn*t|jjt	r|jjj|kr|
| S tS y||}W n tk
r   tS X |   }|s|S |j}	|	|  kr|||	< n(|||	  kr*||	= n||	  |7  < |S dS )a  Add two polynomials.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> (x + y)**2 + (x - y)**2
        2*x**2 + 2*y**2

        N)r   r4   rE   rc   rZ   r/   r}   r   rK   r#   __radd__r   r   r   re   r   )
r   r   r4   r   rZ   r}   r   r   Zcp2r   r2   r2   r3   __add__  sB    




zPolyElement.__add__c             C   s   |   }|s|S | j}y||}W n tk
r8   tS X |j}||  krV|||< n&|||  krl||= n||  |7  < |S d S )N)r   r4   r   r   r   re   r   )r   nr   r4   r   r2   r2   r3   r	    s    
zPolyElement.__radd__c       	      C   s:  |s|   S | j}t||jrp|   }|j}|jj}x6| D ]*\}}|||| }|rb|||< q>||= q>W |S t|trt|jt	r|jj|jkrn*t|jjt	r|jjj|kr|
| S tS y||}W n tk
r   tS X |   }|j}||  kr| ||< n&||| kr"||= n||  |8  < |S dS )a.  Subtract polynomial p2 from p1.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> p1 = x + y**2
        >>> p2 = x*y + y**2
        >>> p1 - p2
        -x*y + x

        N)r   r4   rE   rc   rZ   r/   r}   r   rK   r#   __rsub__r   r   r   re   r   )	r   r   r4   r   rZ   r}   r   r   r   r2   r2   r3   __sub__  s>    



zPolyElement.__sub__c             C   s\   | j }y||}W n tk
r(   tS X |j}x| D ]}| |  ||< q6W ||7 }|S dS )a#  n - p1 with n convertible to the coefficient domain.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x + y
        >>> 4 - p
        -x - y + 4

        N)r4   r   r   r   r}   )r   r  r4   r   r   r2   r2   r3   r  
  s    
zPolyElement.__rsub__c             C   sD  | j }|j}| r|s|S t||jr|j}|jj}|j}t| }xF|  D ]:\}}	x0|D ](\}
}|||
}||||	|  ||< q\W qNW |	  |S t|t
rt|jtr|jj |j krn*t|j jtr|j jj |kr|| S tS y||}W n tk
r   tS X x,|  D ] \}}	|	| }|r|||< qW |S dS )a!  Multiply two polynomials.

        Examples
        ========

        >>> from sympy.polys.domains import QQ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', QQ)
        >>> p1 = x + y
        >>> p2 = x - y
        >>> p1*p2
        x**2 - y**2

        N)r4   r}   rE   rc   rZ   r/   rj   r:   r   r   rK   r#   __rmul__r   r   r   )r   r   r4   r   rZ   r}   rj   Zp2itexp1v1Zexp2Zv2r   r   r2   r2   r3   __mul__%  s<    


zPolyElement.__mul__c             C   sh   | j j}|s|S y|j |}W n tk
r4   tS X x(|  D ]\}}|| }|r@|||< q@W |S dS )a  p2 * p1 with p2 in the coefficient domain of p1.

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x + y
        >>> 4 * p
        4*x + 4*y

        N)r4   r}   r   r   r   r   )r   r   r   r  r  r   r2   r2   r3   r  W  s    zPolyElement.__rmul__c             C   s   | j }|s| r|jS tdnXt| dkrvt|  d \}}|j}|dkr^|||||< n|| ||||< |S t|}|dk rtdnT|dkr| 	 S |dkr| 
 S |dkr| | 
  S t| dkr| |S | |S dS )	a(  raise polynomial to power `n`

        Examples
        ========

        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.rings import ring

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x + y**2
        >>> p**3
        x**3 + 3*x**2*y**2 + 3*x*y**4 + y**6

        z0**0r   r   zNegative exponentr        N)r4   rh   r   rT   r:   r   r}   rl   r   r   square_pow_multinomial_pow_generic)r   r  r4   r   r   r   r2   r2   r3   __pow__t  s0    


zPolyElement.__pow__c             C   sD   | j j}| }x2|d@ r,|| }|d8 }|s,P | }|d }qW |S )Nr   r  )r4   rh   r  )r   r  r   rO   r2   r2   r3   r    s    zPolyElement._pow_genericc             C   s   t tt| | }| jj}| jj}t |  }| jjj	}| jj	}x|D ]x\}}	|}
|	}x6t
||D ](\}\}}|rf||
||}
||| 9 }qfW t|
}|}|||| }|r|||< qJ||= qJW |S )N)r:   r   rT   r   r4   rm   re   r   r/   r}   ru   rS   rZ   )r   r  Zmultinomialsrm   re   r   r}   r   ZmultinomialZmultinomial_coeffZproduct_monomZproduct_coeffr   r   r   r2   r2   r3   r    s(    


zPolyElement._pow_multinomialc             C   s   | j }|j}|j}t|  }|jj}|j}xbtt|D ]R}|| }| | }	x<t|D ]0}
||
 }|||}||||	| |   ||< qXW q:W |	d}|j}x4| 
 D ](\}}|||}||||d  ||< qW |  |S )a  square of a polynomial

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x + y**2
        >>> p.square()
        x**2 + 2*x*y**2 + y**4

        r  )r4   r}   rZ   r:   r   r/   rj   r   rT   imul_numr   r   )r   r4   r   rZ   r   r}   rj   r   Zk1ZpkjZk2r   r   r   r2   r2   r3   r    s(    
"

zPolyElement.squarec             C   s   | j }|j}|stdnft||jr0| |S t|trt|jtrV|jj |j krVn*t|j jtr||j jj |kr||	| S t
S y||}W n tk
r   t
S X | || |fS d S )Nzpolynomial division)r4   r}   ZeroDivisionErrorrE   rc   ro   rK   r/   r#   __rdivmod__r   r   r   
quo_ground
rem_ground)r   r   r4   r   r2   r2   r3   
__divmod__  s"    



zPolyElement.__divmod__c             C   s   t S )N)r   )r   r   r2   r2   r3   r    s    zPolyElement.__rdivmod__c             C   s   | j }|j}|stdnft||jr0| |S t|trt|jtrV|jj |j krVn*t|j jtr||j jj |kr||	| S t
S y||}W n tk
r   t
S X | |S d S )Nzpolynomial division)r4   r}   r  rE   rc   remrK   r/   r#   __rmod__r   r   r   r  )r   r   r4   r   r2   r2   r3   __mod__  s"    



zPolyElement.__mod__c             C   s   t S )N)r   )r   r   r2   r2   r3   r   &  s    zPolyElement.__rmod__c             C   s   | j }|j}|stdnzt||jrD|jr8| |d  S | |S nPt|trt|jt	rj|jj |j krjn*t|j jt	r|j jj |kr|
| S tS y||}W n tk
r   tS X | |S d S )Nzpolynomial divisionr   )r4   r}   r  rE   rc   r   quorK   r/   r#   __rtruediv__r   r   r   r  )r   r   r4   r   r2   r2   r3   __truediv__)  s&    


zPolyElement.__truediv__c             C   s   t S )N)r   )r   r   r2   r2   r3   r#  C  s    zPolyElement.__rtruediv__c                sJ   | j j| j j}|j | j j|jr6 fdd}n fdd}|S )Nc                sF   | \}}|\}}|kr|}n
||}|d k	r>| ||fS d S d S )Nr2   )	a_lm_a_lc	b_lm_b_lca_lma_lcb_lmb_lcr   )
domain_quorp   r   r2   r3   term_divR  s    
z'PolyElement._term_div.<locals>.term_divc                sN   | \}}|\}}|kr|}n
||}|d ksF|| sF| ||fS d S d S )Nr2   )r%  r&  r'  r(  r)  r*  r   )r+  rp   r   r2   r3   r,  ^  s    
)r4   re   r/   r"  rp   r   )r   r/   r,  r2   )r+  rp   r   r3   	_term_divK  s    zPolyElement._term_divc                s  | j   j}d}t|tr$d}|g}tdd |D r>td| s\|rR j jfS g  jfS x|D ]}|j  krbtdqbW t|} fddt	|D }| 
 } j}|  }	d	d |D }
x|rd
}d
}x||k r`|d
kr`| }|	||| f|
| || |
|  f}|dk	rV|\}}|| ||f||< ||| || f}d}q|d7 }qW |s| }|||| f}||= qW | jkr||7 }|r|s j|fS |d
 |fS n||fS dS )aU  Division algorithm, see [CLO] p64.

        fv array of polynomials
           return qv, r such that
           self = sum(fv[i]*qv[i]) + r

        All polynomials are required not to be Laurent polynomials.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> f = x**3
        >>> f0 = x - y**2
        >>> f1 = x - y
        >>> qv, r = f.div((f0, f1))
        >>> qv[0]
        x**2 + x*y**2 + y**4
        >>> qv[1]
        0
        >>> r
        y**6

        FTc             s   s   | ]}| V  qd S )Nr2   )r7   rQ   r2   r2   r3   rG     s    z"PolyElement.div.<locals>.<genexpr>zpolynomial divisionz"self and f must have the same ringc                s   g | ]
} j qS r2   )r}   )r7   r   )r4   r2   r3   r8     s    z#PolyElement.div.<locals>.<listcomp>c             S   s   g | ]}|  qS r2   )rt   )r7   Zfxr2   r2   r3   r8     s    r   Nr   )r4   r/   rE   rK   anyr  r}   r   rT   r   r   r-  rt   _iadd_monom_iadd_poly_monomre   )r   Zfvr/   Z
ret_singlerQ   rF   Zqvr   rr,  Zexpvsr   Zdivoccurredr   termZexpv1rO   r2   )r4   r3   ro   l  sX    



&


zPolyElement.divc             C   s\  | }t |tr|g}tdd |D r.td|j}|j}|j}|j}|j}|j}|	 }	|j
}
| }|j}x|rVx|D ]}|	|
|j
}|d k	r||\}}xD| D ]8\}}|||}|||||  }|s||= q|||< qW | }|d k	r ||| f}
P q|W |
\}}||kr*||  |7  < n|||< ||= | }|d k	rp||| f}
qpW |S )Nc             s   s   | ]}| V  qd S )Nr2   )r7   gr2   r2   r3   rG     s    z"PolyElement.rem.<locals>.<genexpr>zpolynomial division)rE   rK   r.  r  r4   r/   r0   r}   rj   r-  LTr   rZ   r   rt   )r   GrQ   r4   r/   r0   r}   rj   r1  r,  ZltfrZ   r3  ZtqmrO   mgcgZm1Zc1ZltmZltcr2   r2   r3   r    sN    




zPolyElement.remc             C   s   |  |d S )Nr   )ro   )rQ   r5  r2   r2   r3   r"    s    zPolyElement.quoc             C   s$   |  |\}}|s|S t| |d S )N)ro   r    )rQ   r5  qr1  r2   r2   r3   exquo  s    zPolyElement.exquoc             C   s^   | | j jkr|  }n| }|\}}||}|dkr>|||< n||7 }|rT|||< n||= |S )a  add to self the monomial coeff*x0**i0*x1**i1*...
        unless self is a generator -- then just return the sum of the two.

        mc is a tuple, (monom, coeff), where monomial is (i0, i1, ...)

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x**4 + 2*y
        >>> m = (1, 2)
        >>> p1 = p._iadd_monom((m, 5))
        >>> p1
        x**4 + 5*x*y**2 + 2*y
        >>> p1 is p
        True
        >>> p = x
        >>> p1 = p._iadd_monom((m, 5))
        >>> p1
        5*x*y**2 + x
        >>> p1 is p
        False

        N)r4   rg   r   rZ   )r   mcZcpselfr   r   rO   r2   r2   r3   r/    s    



zPolyElement._iadd_monomc             C   s   | }||j jkr| }|\}}|j}|j jj}|j j}xD| D ]8\}	}
||	|}||||
|  }|rt|||< qB||= qBW |S )aE  add to self the product of (p)*(coeff*x0**i0*x1**i1*...)
        unless self is a generator -- then just return the sum of the two.

        mc is a tuple, (monom, coeff), where monomial is (i0, i1, ...)

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y, z = ring('x, y, z', ZZ)
        >>> p1 = x**4 + 2*y
        >>> p2 = y + z
        >>> m = (1, 2, 3)
        >>> p1 = p1._iadd_poly_monom(p2, (m, 3))
        >>> p1
        x**4 + 3*x*y**3*z**3 + 3*x*y**2*z**4 + 2*y

        )r4   rg   r   rZ   r/   r}   rj   r   )r   r   r;  r   r6  rO   rZ   r}   rj   r   r   Zkar   r2   r2   r3   r0    s    



zPolyElement._iadd_poly_monomc                s@   | j | | st S  dk r"dS t fdd|  D S dS )z
        The leading degree in ``x`` or the main variable.

        Note that the degree of 0 is negative infinity (the SymPy object -oo).

        r   c                s   g | ]}|  qS r2   r2   )r7   r   )r   r2   r3   r8   Q  s    z&PolyElement.degree.<locals>.<listcomp>N)r4   r   r   rP   r   )rQ   xr2   )r   r3   degreeC  s    zPolyElement.degreec             C   s2   | st  f| jj S ttttt|   S dS )z
        A tuple containing leading degrees in all variables.

        Note that the degree of 0 is negative infinity (the SymPy object -oo)

        N)	r   r4   rd   rS   r=   rP   r:   ru   r   )rQ   r2   r2   r3   degreesS  s    zPolyElement.degreesc                s@   | j | | st S  dk r"dS t fdd|  D S dS )z
        The tail degree in ``x`` or the main variable.

        Note that the degree of 0 is negative infinity (the SymPy object -oo)

        r   c                s   g | ]}|  qS r2   r2   )r7   r   )r   r2   r3   r8   m  s    z+PolyElement.tail_degree.<locals>.<listcomp>N)r4   r   r   minr   )rQ   r<  r2   )r   r3   tail_degree_  s    zPolyElement.tail_degreec             C   s2   | st  f| jj S ttttt|   S dS )z
        A tuple containing tail degrees in all variables.

        Note that the degree of 0 is negative infinity (the SymPy object -oo)

        N)	r   r4   rd   rS   r=   r?  r:   ru   r   )rQ   r2   r2   r3   tail_degreeso  s    zPolyElement.tail_degreesc             C   s   | r| j | S dS dS )aT  Leading monomial tuple according to the monomial ordering.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y, z = ring('x, y, z', ZZ)
        >>> p = x**4 + x**3*y + x**2*z**2 + z**7
        >>> p.leading_expv()
        (4, 0, 0)

        N)r4   rt   )r   r2   r2   r3   rt   {  s    zPolyElement.leading_expvc             C   s   |  || jjjS )N)rZ   r4   r/   r}   )r   r   r2   r2   r3   
_get_coeff  s    zPolyElement._get_coeffc             C   sp   |dkr|  | jjS t|| jjr`t| }t|dkr`|d \}}|| jjj	kr`|  |S t
d| dS )a  
        Returns the coefficient that stands next to the given monomial.

        Parameters
        ----------
        element : PolyElement (with ``is_monomial = True``) or 1

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y, z = ring("x,y,z", ZZ)
        >>> f = 3*x**2*y - x*y*z + 7*z**3 + 23

        >>> f.coeff(x**2*y)
        3
        >>> f.coeff(x*y)
        0
        >>> f.coeff(1)
        23

        r   r   zexpected a monomial, got %sN)rB  r4   re   rE   rc   r:   r   rT   r/   rh   r   )r   r   r   r   r   r2   r2   r3   r     s    
zPolyElement.coeffc             C   s   |  | jjS )z!Returns the constant coeffcient. )rB  r4   re   )r   r2   r2   r3   r     s    zPolyElement.constc             C   s   |  |  S )N)rB  rt   )r   r2   r2   r3   r     s    zPolyElement.LCc             C   s    |   }|d kr| jjS |S d S )N)rt   r4   re   )r   r   r2   r2   r3   LM  s    zPolyElement.LMc             C   s&   | j j}|  }|r"| j jj||< |S )a  
        Leading monomial as a polynomial element.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> (3*x*y + y**2).leading_monom()
        x*y

        )r4   r}   rt   r/   rh   )r   r   r   r2   r2   r3   leading_monom  s
    zPolyElement.leading_monomc             C   s4   |   }|d kr"| jj| jjjfS || |fS d S )N)rt   r4   re   r/   r}   rB  )r   r   r2   r2   r3   r4    s    zPolyElement.LTc             C   s(   | j j}|  }|dk	r$| | ||< |S )a  Leading term as a polynomial element.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> (3*x*y + y**2).leading_term()
        3*x*y

        N)r4   r}   rt   )r   r   r   r2   r2   r3   leading_term  s
    zPolyElement.leading_termc                sP    d kr| j j n
t   tkr6t|dd ddS t| fddddS d S )Nc             S   s   | d S )Nr   r2   )r   r2   r2   r3   rN     s    z%PolyElement._sorted.<locals>.<lambda>T)rR   reversec                s    | d S )Nr   r2   )r   )r0   r2   r3   rN      s    )r4   r0   rW   rV   r   sorted)r   rD   r0   r2   )r0   r3   _sorted  s    

zPolyElement._sortedc             C   s   dd |  |D S )a  Ordered list of polynomial coefficients.

        Parameters
        ----------
        order : :class:`Order` or coercible, optional

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.orderings import lex, grlex

        >>> _, x, y = ring("x, y", ZZ, lex)
        >>> f = x*y**7 + 2*x**2*y**3

        >>> f.coeffs()
        [2, 1]
        >>> f.coeffs(grlex)
        [1, 2]

        c             S   s   g | ]\}}|qS r2   r2   )r7   rA   r   r2   r2   r3   r8     s    z&PolyElement.coeffs.<locals>.<listcomp>)r   )r   r0   r2   r2   r3   r@     s    zPolyElement.coeffsc             C   s   dd |  |D S )a  Ordered list of polynomial monomials.

        Parameters
        ----------
        order : :class:`Order` or coercible, optional

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.orderings import lex, grlex

        >>> _, x, y = ring("x, y", ZZ, lex)
        >>> f = x*y**7 + 2*x**2*y**3

        >>> f.monoms()
        [(2, 3), (1, 7)]
        >>> f.monoms(grlex)
        [(1, 7), (2, 3)]

        c             S   s   g | ]\}}|qS r2   r2   )r7   r   rA   r2   r2   r3   r8   2  s    z&PolyElement.monoms.<locals>.<listcomp>)r   )r   r0   r2   r2   r3   monoms  s    zPolyElement.monomsc             C   s   |  t|  |S )a  Ordered list of polynomial terms.

        Parameters
        ----------
        order : :class:`Order` or coercible, optional

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ
        >>> from sympy.polys.orderings import lex, grlex

        >>> _, x, y = ring("x, y", ZZ, lex)
        >>> f = x*y**7 + 2*x**2*y**3

        >>> f.terms()
        [((2, 3), 2), ((1, 7), 1)]
        >>> f.terms(grlex)
        [((1, 7), 1), ((2, 3), 2)]

        )rH  r:   r   )r   r0   r2   r2   r3   r   4  s    zPolyElement.termsc             C   s   t |  S )z,Iterator over coefficients of a polynomial. )iterr;   )r   r2   r2   r3   
itercoeffsM  s    zPolyElement.itercoeffsc             C   s   t |  S )z)Iterator over monomials of a polynomial. )rJ  r   )r   r2   r2   r3   r   Q  s    zPolyElement.itermonomsc             C   s   t |  S )z%Iterator over terms of a polynomial. )rJ  r   )r   r2   r2   r3   r   U  s    zPolyElement.itertermsc             C   s   t |  S )z+Unordered list of polynomial coefficients. )r:   r;   )r   r2   r2   r3   
listcoeffsY  s    zPolyElement.listcoeffsc             C   s   t |  S )z(Unordered list of polynomial monomials. )r:   r   )r   r2   r2   r3   
listmonoms]  s    zPolyElement.listmonomsc             C   s   t |  S )z$Unordered list of polynomial terms. )r:   r   )r   r2   r2   r3   	listtermsa  s    zPolyElement.listtermsc             C   sF   | | j jkr| | S |s$|   dS x| D ]}| |  |9  < q*W | S )a:  multiply inplace the polynomial p by an element in the
        coefficient ring, provided p is not one of the generators;
        else multiply not inplace

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring('x, y', ZZ)
        >>> p = x + y**2
        >>> p1 = p.imul_num(3)
        >>> p1
        3*x + 3*y**2
        >>> p1 is p
        True
        >>> p = x
        >>> p1 = p.imul_num(3)
        >>> p1
        3*x
        >>> p1 is p
        False

        N)r4   rg   clear)r   rO   r   r2   r2   r3   r  e  s    
zPolyElement.imul_numc             C   s4   | j j}|j}|j}x|  D ]}|||}qW |S )z*Returns GCD of polynomial's coefficients. )r4   r/   r}   rr   rK  )rQ   r/   contrr   r   r2   r2   r3   r     s    zPolyElement.contentc             C   s   |   }|| |fS )z,Returns content and a primitive polynomial. )r   r  )rQ   rP  r2   r2   r3   	primitive  s    zPolyElement.primitivec             C   s   | s| S |  | jS dS )z5Divides all coefficients by the leading coefficient. N)r  r   )rQ   r2   r2   r3   monic  s    zPolyElement.monicc                s,    s| j jS  fdd|  D }| |S )Nc                s   g | ]\}}||  fqS r2   r2   )r7   r   r   )r<  r2   r3   r8     s    z*PolyElement.mul_ground.<locals>.<listcomp>)r4   r}   r   r   )rQ   r<  r   r2   )r<  r3   r     s    zPolyElement.mul_groundc                s*   | j j fdd|  D }| |S )Nc                s   g | ]\}}| |fqS r2   r2   )r7   f_monomf_coeff)r   rj   r2   r3   r8     s    z)PolyElement.mul_monom.<locals>.<listcomp>)r4   rj   r   r   )rQ   r   r   r2   )r   rj   r3   	mul_monom  s    zPolyElement.mul_monomc                sZ   |\ | r s| j jS | j jkr.|  S | j j fdd|  D }| |S )Nc                s"   g | ]\}}||  fqS r2   r2   )r7   rS  rT  )r   r   rj   r2   r3   r8     s    z(PolyElement.mul_term.<locals>.<listcomp>)r4   r}   re   r   rj   r   r   )rQ   r2  r   r2   )r   r   rj   r3   mul_term  s    
zPolyElement.mul_termc                sl   | j j}std| r"|jkr&| S |jrL|j  fdd|  D }nfdd|  D }| |S )Nzpolynomial divisionc                s   g | ]\}}| |fqS r2   r2   )r7   r   r   )r"  r<  r2   r3   r8     s    z*PolyElement.quo_ground.<locals>.<listcomp>c                s$   g | ]\}}|  s||  fqS r2   r2   )r7   r   r   )r<  r2   r3   r8     s    )r4   r/   r  rh   r   r"  r   r   )rQ   r<  r/   r   r2   )r"  r<  r3   r    s    zPolyElement.quo_groundc                sl    \}}|st dn"| s"| jjS || jjkr8| |S |   fdd|  D }| dd |D S )Nzpolynomial divisionc                s   g | ]}| qS r2   r2   )r7   t)r2  r,  r2   r3   r8     s    z(PolyElement.quo_term.<locals>.<listcomp>c             S   s   g | ]}|d k	r|qS )Nr2   )r7   rW  r2   r2   r3   r8     s    )r  r4   r}   re   r  r-  r   r   )rQ   r2  r   r   r   r2   )r2  r,  r3   quo_term  s    

zPolyElement.quo_termc                s|   | j jjrPg }xV|  D ]2\}}|  }| d kr<|  }|||f qW n fdd|  D }| |}|  |S )Nr  c                s   g | ]\}}||  fqS r2   r2   )r7   r   r   )r   r2   r3   r8     s    z,PolyElement.trunc_ground.<locals>.<listcomp>)r4   r/   is_ZZr   r~   r   r   )rQ   r   r   r   r   r   r2   )r   r3   trunc_ground  s    

zPolyElement.trunc_groundc             C   sB   | }|  }|  }|jj||}||}||}|||fS )N)r   r4   r/   rr   r  )r   r3  rQ   fcgcrr   r2   r2   r3   extract_ground  s    

zPolyElement.extract_groundc                s6   | s| j jjS | j jj | fdd|  D S d S )Nc                s   g | ]} |qS r2   r2   )r7   r   )
ground_absr2   r3   r8     s    z%PolyElement._norm.<locals>.<listcomp>)r4   r/   r}   absrK  )rQ   Z	norm_funcr2   )r^  r3   _norm  s    

zPolyElement._normc             C   s
   |  tS )N)r`  rP   )rQ   r2   r2   r3   max_norm  s    zPolyElement.max_normc             C   s
   |  tS )N)r`  r>   )rQ   r2   r2   r3   l1_norm   s    zPolyElement.l1_normc             G   s  | j }| gt| }dg|j }xF|D ]>}x8| D ],}x&t|D ]\}}t|| |||< qBW q4W q&W x t|D ]\}}	|	srd||< qrW t|}tdd |D r||fS g }
xR|D ]J}|j}x4|	 D ](\}}dd t
||D }||t|< qW |
| qW ||
fS )Nr   r   c             s   s   | ]}|d kV  qdS )r   Nr2   )r7   rM   r2   r2   r3   rG     s    z&PolyElement.deflate.<locals>.<genexpr>c             S   s   g | ]\}}|| qS r2   r2   )r7   r   r  r2   r2   r3   r8     s    z'PolyElement.deflate.<locals>.<listcomp>)r4   r:   rd   r   r   r   rS   rI   r}   r   ru   r~   )rQ   r5  r4   rB   Jr   r   r   r6  rM   HhIr   Nr2   r2   r3   deflate  s*    

zPolyElement.deflatec             C   sB   | j j}x4|  D ](\}}dd t||D }||t|< qW |S )Nc             S   s   g | ]\}}|| qS r2   r2   )r7   r   r  r2   r2   r3   r8   (  s    z'PolyElement.inflate.<locals>.<listcomp>)r4   r}   r   ru   rS   )rQ   rc  r   rf  r   rg  r2   r2   r3   inflate$  s
    zPolyElement.inflatec             C   sf   | }|j j}|js6| \}}| \}}|||}|| ||}|jsZ||S | S d S )N)	r4   r/   r   rQ  rq   r"  rr   r   rR  )r   r3  rQ   r/   r[  r\  rO   re  r2   r2   r3   rq   -  s    
zPolyElement.lcmc             C   s   |  |d S )Nr   )	cofactors)rQ   r3  r2   r2   r3   rr   =  s    zPolyElement.gcdc             C   s   | s|s| j j}|||fS | s8| |\}}}|||fS |sV|| \}}}|||fS t| dkr|| |\}}}|||fS t|dkr|| \}}}|||fS | |\}\} }| |\}}}||||||fS )Nr   )r4   r}   	_gcd_zerorT   
_gcd_monomrh  _gcdri  )rQ   r3  r}   re  cffcfgrc  r2   r2   r3   rj  @  s$    




zPolyElement.cofactorsc             C   s4   | j j| j j }}|jr"|||fS | || fS d S )N)r4   rh   r}   r   )rQ   r3  rh   r}   r2   r2   r3   rk  V  s    
zPolyElement._gcd_zeroc                s   | j }|jj}|jj|j}|jt|  d \}}||  x(| D ]\}}||| | qJW |  fg}	| || fg}
|  fdd| D }|	|
|fS )Nr   c                s$   g | ]\}}|| fqS r2   r2   )r7   r7  r8  )_cgcd_mgcd
ground_quorn   r2   r3   r8   j  s    z*PolyElement._gcd_monom.<locals>.<listcomp>)	r4   r/   rr   r"  rs   rn   r:   r   r   )rQ   r3  r4   Z
ground_gcdrs   Zmfcfr7  r8  re  rn  ro  r2   )rp  rq  rr  rn   r3   rl  ]  s    

"zPolyElement._gcd_monomc             C   s:   | j }|jjr| |S |jjr*| |S || |S d S )N)r4   r/   Zis_QQ_gcd_QQrY  _gcd_ZZZdmp_inner_gcd)rQ   r3  r4   r2   r2   r3   rm  m  s    

zPolyElement._gcdc             C   s
   t | |S )N)r   )rQ   r3  r2   r2   r3   ru  w  s    zPolyElement._gcd_ZZc             C   s   | }|j }|j|j d}| \}}| \}}||}||}||\}}}	||}|j|  }
}||	|j
|
|}|	|	|j
|
|}	|||	fS )N)r/   )r4   r   r/   r   r   r   ru  r   rR  r   r"  )r   r3  rQ   r4   r   rs  r8  re  rn  ro  rO   r2   r2   r3   rt  z  s    


zPolyElement._gcd_QQc             C   s.  | }|j }|s||jfS |j}|jr*|jsP||\}}}|jrN| |  }}n|j| d}|	 \}	}|	 \}
}|
|}|
|}||\}}}|j|
|	\}}
}	|
|}|
|}|j}|j}|r|r| |  }}n*| r|
 |  }
}n|r|
 |  }
}||
}||	}||fS )a  
        Cancel common factors in a rational function ``f/g``.

        Examples
        ========

        >>> from sympy.polys import ring, ZZ
        >>> R, x,y = ring("x,y", ZZ)

        >>> (2*x**2 - 2).cancel(x**2 - 2*x + 1)
        (2*x + 2, x - 1)

        )r/   )r4   rh   r/   r   r   rj  r   r   r   r   r   r   )r   r3  rQ   r4   r/   rA   r   r9  r   ZcqZcpZp_negZq_negr2   r2   r3   cancel  s:    






zPolyElement.cancelc       	      C   sd   | j }||}||}|j}x>|  D ]2\}}|| r*|||}||||  ||< q*W |S )a!  Computes partial derivative in ``x``.

        Examples
        ========

        >>> from sympy.polys.rings import ring
        >>> from sympy.polys.domains import ZZ

        >>> _, x, y = ring("x,y", ZZ)
        >>> p = x + x**2*y**3
        >>> p.diff(x)
        2*x*y**3 + 1

        )r4   r   r|   r}   r   rn   r   )	rQ   r<  r4   r   r6  r3  r   r   er2   r2   r3   diff  s    

zPolyElement.diffc             G   sT   dt |  k r| jjkr8n n| tt| jj|S td| jjt |f d S )Nr   z1expected at least 1 and at most %s values, got %s)rT   r4   rd   evaluater:   ru   r.   r   )rQ   r;   r2   r2   r3   r     s     zPolyElement.__call__c                sP  | }t |tr`|d kr`|d |dd   \ }}| |}|sD|S  fdd|D }||S |j}||}|j|}|jdkr|jj}x&|	 D ]\\}}||||  7 }qW |S |
|j}	x|	 D ]t\}
}|
| |
d | |
|d d    }}
|||  }|
|	kr8||	|
  }|r0||	|
< n|	|
= q|r||	|
< qW |	S d S )Nr   r   c                s   g | ]\}}|  |fqS r2   )r   )r7   YrL   )Xr2   r3   r8     s    z(PolyElement.evaluate.<locals>.<listcomp>)rE   r:   ry  r4   r   r/   r   rd   r}   r   r   )r   r<  rL   rQ   r4   r   resultr  r   r   r   r2   )r{  r3   ry    s8    


&

zPolyElement.evaluatec             C   s,  | }t |tr8|d kr8x|D ]\}}|||}qW |S |j}||}|j|}|jdkr|jj}x&|	 D ]\\}}	||	||  7 }qpW |
|S |j}
x|	 D ]x\}}	|| |d | d ||d d    }}|	||  }	||
kr|	|
|  }	|	r|	|
|< n|
|= q|	r|	|
|< qW |
S d S )Nr   )r   )rE   r:   subsr4   r   r/   r   rd   r}   r   r   )r   r<  rL   rQ   r{  r4   r   r|  r  r   r   r   r2   r2   r3   r}  	  s2    


*

zPolyElement.subsc                s(  | j }|j}ttt|jtt|j |d k	r>||fg}nDt|trRt|}n0t|trzt	t|
  fddd}ntdx.t|D ]"\}\}} | ||f||< qW xp|  D ]d\}}	t|}|j}
x2|D ]*\}}|| d }||< |r|
|| 9 }
qW |
t||	f}
||
7 }qW |S )Nc                s    | d  S )Nr   r2   )r   )gens_mapr2   r3   rN   E	  s    z%PolyElement.compose.<locals>.<lambda>)rR   z9expected a generator, value pair a sequence of such pairsr   )r4   r}   r   r:   ru   r.   r   rd   rE   rG  r   r   r   r   r   rh   rV  rS   )rQ   r<  rL   r4   r   Zreplacementsr   r3  r   r   Zsubpolyr   r  r2   )r~  r3   r   :	  s,    


zPolyElement.composec             C   s   | j | |S )N)r4   Zdmp_pdiv)rQ   r3  r2   r2   r3   pdiv]	  s    zPolyElement.pdivc             C   s   | j | |S )N)r4   Zdmp_prem)rQ   r3  r2   r2   r3   prem`	  s    zPolyElement.premc             C   s   | j | |S )N)r4   Zdmp_quo)rQ   r3  r2   r2   r3   pquoc	  s    zPolyElement.pquoc             C   s   | j | |S )N)r4   Z	dmp_exquo)rQ   r3  r2   r2   r3   pexquof	  s    zPolyElement.pexquoc             C   s   | j | |S )N)r4   Zdmp_half_gcdex)rQ   r3  r2   r2   r3   
half_gcdexi	  s    zPolyElement.half_gcdexc             C   s   | j | |S )N)r4   Z	dmp_gcdex)rQ   r3  r2   r2   r3   gcdexl	  s    zPolyElement.gcdexc             C   s   | j | |S )N)r4   Zdmp_subresultants)rQ   r3  r2   r2   r3   subresultantso	  s    zPolyElement.subresultantsc             C   s   | j | |S )N)r4   Zdmp_resultant)rQ   r3  r2   r2   r3   	resultantr	  s    zPolyElement.resultantc             C   s   | j | S )N)r4   Zdmp_discriminant)rQ   r2   r2   r3   discriminantu	  s    zPolyElement.discriminantc             C   s    | j jr| j | S tdd S )Nzpolynomial decomposition)r4   r   Zdup_decomposer!   )rQ   r2   r2   r3   	decomposex	  s    zPolyElement.decomposec             C   s"   | j jr| j | |S tdd S )Nzpolynomial shift)r4   r   Z	dup_shiftr!   )rQ   rL   r2   r2   r3   shift~	  s    zPolyElement.shiftc             C   s    | j jr| j | S tdd S )Nzsturm sequence)r4   r   Z	dup_sturmr!   )rQ   r2   r2   r3   sturm	  s    zPolyElement.sturmc             C   s   | j | S )N)r4   Zdmp_gff_list)rQ   r2   r2   r3   gff_list	  s    zPolyElement.gff_listc             C   s   | j | S )N)r4   Zdmp_sqf_norm)rQ   r2   r2   r3   sqf_norm	  s    zPolyElement.sqf_normc             C   s   | j | S )N)r4   Zdmp_sqf_part)rQ   r2   r2   r3   sqf_part	  s    zPolyElement.sqf_partFc             C   s   | j j| |dS )N)rI   )r4   Zdmp_sqf_list)rQ   rI   r2   r2   r3   sqf_list	  s    zPolyElement.sqf_listc             C   s   | j | S )N)r4   Zdmp_factor_list)rQ   r2   r2   r3   factor_list	  s    zPolyElement.factor_list)N)N)N)N)N)N)N)N)N)F)rX   r   r   r   r   r   r   ra   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r  r
  r	  r  r  r  r  r  r  r  r  r  r  r!  r   r$  r#  __floordiv__Z__div____rfloordiv__Z__rdiv__r-  ro   r  r"  r:  r/  r0  r=  r>  r@  rA  rt   rB  r   r   r   rC  rD  r4  rE  rH  r@   rI  r   rK  r   r   rL  rM  rN  r  r   rQ  rR  r   rU  rV  r  rX  rZ  r  r]  r`  ra  rb  rh  ri  rq   rr   rj  rk  rl  rm  ru  rt  rv  rx  r   ry  r}  r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r2   r2   r2   r3   rK      s  	16620$!M.,%$#!	
9,'#
rK   N)Or   Z
__future__r   r   operatorr   r   r   r   r   r	   typesr
   Zsympy.core.exprr   Zsympy.core.symbolr   r   rH   Zsympy.core.numbersr   r   Zsympy.core.sympifyr   r   Zsympy.core.compatibilityr   r   r   r   Zsympy.ntheory.multinomialr   Zsympy.polys.monomialsr   Zsympy.polys.orderingsr   Zsympy.polys.heuristicgcdr   Zsympy.polys.compatibilityr   Zsympy.polys.polyutilsr   r   r   Zsympy.polys.polyerrorsr   r   r    r!   Z!sympy.polys.domains.domainelementr"   Z"sympy.polys.domains.polynomialringr#   Zsympy.polys.polyoptionsr$   rU   r%   rW   r&   Zsympy.polys.densebasicr'   r(   Zsympy.polys.constructorr)   Zsympy.printing.defaultsr*   Zsympy.utilitiesr+   Zsympy.utilities.magicr,   r4   r5   r9   rC   rJ   rY   r-   r   rK   r2   r2   r2   r3   <module>   sH    5  f