a
    kh@P                    @  s  d Z ddl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 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 ddlmZ ddlm Z  ddl!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/m0Z0m1Z1 ddl2m3Z3m4Z4m5Z5m6Z6 ddl7m&Z8m9Z:m;Z; ddl<m=Z=m>Z>m?Z? ddl@mAZA ddlBmCZCmDZD ddlEmFZF ddlGmHZH eCe0fddddZIeCe0fd d!ZJeCe0fd"d#ZKeCd$d% ZLd&d' ZMG d(d) d)eAeZNG d*d+ d+e(eAeeOZPd,S )-zSparse polynomial rings.     )annotations)addmulltlegtge)reduce)GeneratorType)cacheit)Expr)igcd)Symbolsymbols)CantSympifysympify)multinomial_coefficients)IPolys)construct_domain)ninfdmp_to_dictdmp_from_dict)Domain)DomainElementPolynomialRingheugcd)MonomialOps)lexMonomialOrder)CoercionFailedGeneratorsErrorExactQuotientFailedMultivariatePolynomialError)r   Orderbuild_options)expr_from_dict_dict_reorder_parallel_dict_from_expr)DefaultPrinting)publicsubsets)is_sequence)pollutezMonomialOrder | strorderc                 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:`~.MonomialOrder` 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   domainr0   _ring r7   ?/var/www/auris/lib/python3.9/site-packages/sympy/polys/rings.pyring$   s    r9   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:`~.MonomialOrder` 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'>

    r1   r4   r7   r7   r8   xringC   s    r:   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:`~.MonomialOrder` 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 # noqa:
    x + y + z
    >>> type(_)
    <class 'sympy.polys.rings.PolyElement'>

    c                 S  s   g | ]
}|j qS r7   )name).0symr7   r7   r8   
<listcomp>~       zvring.<locals>.<listcomp>)r2   r.   r   r3   r4   r7   r7   r8   vringb   s    r@   c           
        s   d}t | s| gd } }ttt| } t||}t| |\}}|jdu rtdd |D g }t||d\|_}t	t
||  fdd|D }t|j|j|j}tt|j|}	|r||	d fS ||	fS dS )	ad  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 import sring, symbols

    >>> 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 r7   listvaluesr<   repr7   r7   r8   r>      r?   zsring.<locals>.<listcomp>)optc                   s"   g | ]} fd d|  D qS )c                   s   i | ]\}}| | qS r7   r7   r<   mcZ	coeff_mapr7   r8   
<dictcomp>   r?   z$sring.<locals>.<listcomp>.<dictcomp>)itemsrD   rJ   r7   r8   r>      r?   r   )r-   rB   mapr   r&   r)   r5   sumr   dictzipr2   r3   r0   	from_dict)
exprsr   optionssinglerF   ZrepscoeffsZ
coeffs_domr6   polysr7   rJ   r8   sring   s     

rW   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)seqr7   c                 s  s   | ]}t |tV  qd S N)
isinstancestrr<   sr7   r7   r8   	<genexpr>   r?   z!_parse_symbols.<locals>.<genexpr>c                 s  s   | ]}t |tV  qd S rY   )rZ   r   r\   r7   r7   r8   r^      r?   zbexpected a string, Symbol or expression or a non-empty sequence of strings, Symbols or expressions)rZ   r[   _symbolsr   r-   allr"   r   r7   r7   r8   _parse_symbols   s    

rb   c                   @  s~  e Zd ZU dZded< ded< ded< ded	< d
ed< efddZdd Zdd Zdd Z	dd Z
dd Zdd ZdUddZedd Zdd  Zed!d" Zed#d$ Zd%d& ZdVd'd(Zd)d* Zd+d, Zd-d. ZeZdWd/d0ZdXd1d2Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Z d=d> Z!d?d@ Z"dAdB Z#dCdD Z$edEdF Z%edGdH Z&dIdJ Z'dKdL Z(dMdN Z)dOdP Z*dQdR Z+dSdT Z,dS )Yr2   z*Multivariate distributed polynomial ring. ztuple[PolyElement, ...]r3   ztuple[Expr, ...]r   intngensr   r5   r    r0   c                   s  t t|}t|}t|}t  | j||| f}|jrXt|t|j	@ rXt
dt| }||_t||_||_	||_||_ |_t|dj|_d| |_| |_t|j|_|j|jfg|_|rt|}| |_| |_ |! |_"|# |_$|% |_&|' |_(|) |_*n6dd }||_||_ dd |_"||_$||_&||_(||_* t+u rft,|_-n fdd|_-t.|j	|jD ]4\}	}
t/|	t0r|	j1}t2||st3|||
 q|S )Nz7polynomial ring and it's ground domain share generatorsr7   r   c                 S  s   dS Nr7   r7   )abr7   r7   r8   <lambda>   r?   z"PolyRing.__new__.<locals>.<lambda>c                 S  s   dS rf   r7   )rg   rh   rI   r7   r7   r8   ri      r?   c                   s   t |  dS )Nkey)maxfr/   r7   r8   ri      r?   )4tuplerb   len	DomainOpt
preprocessOrderOpt__name__is_Compositesetr   r"   object__new___hash_tuplehash_hashrd   r5   r0   PolyElementnewdtype
zero_monom_gensr3   	_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   rl   leading_expvrP   rZ   r   r;   hasattrsetattr)clsr   r5   r0   rd   ry   objZcodegenZmonunitsymbol	generatorr;   r7   r/   r8   rx      sZ    













zPolyRing.__new__c                 C  sF   | j j}g }t| jD ]&}| |}| j}|||< || qt|S )z(Return a list of polynomial generators. )r5   r   rangerd   monomial_basiszeroappendro   )selfr   r   iexpvpolyr7   r7   r8   r     s    
zPolyRing._gensc                 C  s   | j | j| jfS rY   )r   r5   r0   r   r7   r7   r8   __getnewargs__  s    zPolyRing.__getnewargs__c                 C  s.   | j  }|d= |D ]}|dr||= q|S )Nr   Z	monomial_)__dict__copy
startswith)r   staterk   r7   r7   r8   __getstate__  s    

zPolyRing.__getstate__c                 C  s   | j S rY   )r{   r   r7   r7   r8   __hash__#  s    zPolyRing.__hash__c                 C  s2   t |to0| j| j| j| jf|j|j|j|jfkS rY   )rZ   r2   r   r5   rd   r0   r   otherr7   r7   r8   __eq__&  s
    
zPolyRing.__eq__c                 C  s
   | |k S rY   r7   r   r7   r7   r8   __ne__+  s    zPolyRing.__ne__Nc                 C  s(   |d urt |trt|}| |||S rY   )rZ   rB   ro   _cloner   r   r5   r0   r7   r7   r8   clone.  s    zPolyRing.clonec                 C  s    |  |p| j|p| j|p| jS rY   )	__class__r   r5   r0   r   r7   r7   r8   r   4  s    zPolyRing._clonec                 C  s   dg| j  }d||< t|S )zReturn the ith-basis element. r      )rd   ro   )r   r   Zbasisr7   r7   r8   r   8  s    zPolyRing.monomial_basisc                 C  s
   |  g S rY   )r~   r   r7   r7   r8   r   >  s    zPolyRing.zeroc                 C  s   |  | jS rY   )r~   r   r   r7   r7   r8   r   B  s    zPolyRing.onec                 C  s   t |to|j| kS )zATrue if ``element`` is an element of this ring. False otherwise. )rZ   r|   r9   r   elementr7   r7   r8   
is_elementF  s    zPolyRing.is_elementc                 C  s   | j ||S rY   )r5   convertr   r   orig_domainr7   r7   r8   
domain_newJ  s    zPolyRing.domain_newc                 C  s   |  | j|S rY   )term_newr   )r   coeffr7   r7   r8   
ground_newM  s    zPolyRing.ground_newc                 C  s    |  |}| j}|r|||< |S rY   )r   r   )r   monomr   r   r7   r7   r8   r   P  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n|t |trZtdnht |trn| 	|S t |t
rz| |W S  ty   | | Y S 0 nt |tr| |S | |S d S )N
conversionZparsing)rZ   r|   r9   r5   r   r   NotImplementedErrorr[   rO   rQ   rB   
from_terms
ValueError	from_listr   	from_exprr   r7   r7   r8   ring_newW  s$    










zPolyRing.ring_newc                 C  s8   | j }| j}| D ]\}}|||}|r|||< q|S rY   )r   r   rL   )r   r   r   r   r   r   r   r7   r7   r8   rQ   o  s    

zPolyRing.from_dictc                 C  s   |  t||S rY   )rQ   rO   r   r7   r7   r8   r   z  s    zPolyRing.from_termsc                 C  s   |  t|| jd | jS Nr   )rQ   r   rd   r5   r   r7   r7   r8   r   }  s    zPolyRing.from_listc                   s$   j  fdd  t|S )Nc                   s    | }|d ur|S | jr2tttt | jS | jrNtttt | jS | 	 \}}|j
rx|dkrx |t| S | S d S r   )getZis_Addr	   r   rB   rM   argsZis_Mulr   Zas_base_expZ
is_Integerrc   r   r   )exprr   baseexp_rebuildr5   mappingr   r7   r8   r     s    
z(PolyRing._rebuild_expr.<locals>._rebuild)r5   r   )r   r   r   r7   r   r8   _rebuild_expr  s    zPolyRing._rebuild_exprc                 C  sX   t tt| j| j}z| ||}W n" tyH   td| |f Y n0 | |S d S )Nz@expected an expression convertible to a polynomial in %s, got %s)	rO   rB   rP   r   r3   r   r!   r   r   )r   r   r   r   r7   r7   r8   r     s    zPolyRing.from_exprc                 C  s   |du r| j rd}qd}nt|trj|}d|kr<|| j k r<q| j  |kr\|dkr\| d }qtd| n| |rz| j|}W q ty   td| Y q0 nHt|trz| j|}W q ty   td| Y q0 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   rZ   rc   r   r   r3   indexr[   r   )r   genr   r7   r7   r8   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 | ]\}}| vr|qS r7   r7   r<   r   r]   indicesr7   r8   r>     r?   z!PolyRing.drop.<locals>.<listcomp>ra   N)rv   rM   r   	enumerater   r5   r   r   r3   r   r7   r   r8   drop  s
    zPolyRing.dropc                 C  s$   | j | }|s| jS | j|dS d S )Nra   )r   r5   r   )r   rk   r   r7   r7   r8   __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 )Nr5   r5   z%s is not a composite domain)r5   ru   r   r   r   r   r7   r7   r8   	to_ground  s    zPolyRing.to_groundc                 C  s   t | S rY   r   r   r7   r7   r8   	to_domain  s    zPolyRing.to_domainc                 C  s   ddl m} || j| j| jS )Nr   )	FracField)Zsympy.polys.fieldsr   r   r5   r0   )r   r   r7   r7   r8   to_field  s    zPolyRing.to_fieldc                 C  s   t | jdkS r   rp   r3   r   r7   r7   r8   is_univariate  s    zPolyRing.is_univariatec                 C  s   t | jdkS r   r   r   r7   r7   r8   is_multivariate  s    zPolyRing.is_multivariatec                 G  s8   | j }|D ](}t|tdr*|| j| 7 }q
||7 }q
|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pr   r7   r7   r8   r     s    
zPolyRing.addc                 G  s8   | j }|D ](}t|tdr*|| j| 9 }q
||9 }q
|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   )r   r-   r
   r   r   r7   r7   r8   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 | ]\}}| vr|qS r7   r7   r   r   r7   r8   r>   $  r?   z+PolyRing.drop_to_ground.<locals>.<listcomp>c                   s   g | ]\}}| vr|qS r7   r7   )r<   r   r   r   r7   r8   r>   %  r?   r   r5   N)rv   rM   r   r   r   r3   r   r   r   r7   r   r8   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``ra   Nrv   r   unionr   rB   )r   r   symsr7   r7   r8   compose,  s    zPolyRing.composec                 C  s$   t | jt |}| jt|dS )z9Add the elements of ``symbols`` as generators to ``self``ra   r   )r   r   r   r7   r7   r8   add_gens4  s    zPolyRing.add_gensc                   s   |dk s|| j kr&td|| jf n^|s0| jS | j}tt| j t|D ]4 t fddt| j D }|| 	|| j
j7 }qJ|S dS )zo
        Return the elementary symmetric polynomial of degree *n* over
        this ring's generators.
        r   z7Cannot generate symmetric polynomial of order %s for %sc                 3  s   | ]}t | v V  qd S rY   )rc   r<   r   r]   r7   r8   r^   E  r?   z*PolyRing.symmetric_poly.<locals>.<genexpr>N)rd   r   r3   r   r   r,   r   rc   ro   r   r5   )r   nr   r   r7   r   r8   symmetric_poly9  s    zPolyRing.symmetric_poly)NNN)N)N)N)-rt   
__module____qualname____doc____annotations__r   rx   r   r   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r   __call__rQ   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r7   r7   r7   r8   r2      s`   
>











r2   c                      s  e Zd ZdZ fddZd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/d0 Zd1d2 Zd3d4 Zd5d6 Zd7d8 Z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 Z0e!dYdZ Z1e!d[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| ZBd}d~ ZCdd ZDdd ZEdd ZFdd ZGdd 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 Zdd Zd0ddZd1ddZdd Zd2dd Zdd Zd3ddZd4ddZd5ddZd6d	d
Zd7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d  Zd!d" Zd#d$ Zd8d&d'Zd(d) Z  ZS (9  r|   z5Element of multivariate distributed polynomial ring. c                   s   t  | || _d S rY   )super__init__r9   )r   r9   initr   r7   r8   r   M  s    zPolyElement.__init__c                 C  s   t | tsJ t | jtsJ | jj}t |ts4J |  D ]@\}}||sRJ t|| jj	ksfJ t
dd |D s<J q<d S )Nc                 s  s    | ]}t |to|d kV  qdS )r   N)rZ   rc   )r<   r   r7   r7   r8   r^   [  r?   z%PolyElement._check.<locals>.<genexpr>)rZ   r|   r9   r2   r5   r   rL   Zof_typerp   rd   r`   )r   domr   r   r7   r7   r8   _checkS  s    zPolyElement._checkc                 C  s   |  | j|S rY   )r   r9   )r   r   r7   r7   r8   r}   ]  s    zPolyElement.newc                 C  s
   | j  S rY   )r9   r   r   r7   r7   r8   parent`  s    zPolyElement.parentc                 C  s   | j t|  fS rY   )r9   rB   	itertermsr   r7   r7   r8   r   c  s    zPolyElement.__getnewargs__Nc                 C  s.   | j }|d u r*t| jt|  f | _ }|S rY   )r{   rz   r9   	frozensetrL   )r   r{   r7   r7   r8   r   h  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   r7   r7   r8   r   s  s    zPolyElement.copyc                 C  sZ   | j |kr| S | j j|jkrFttt| | j j|j }||| j jS || | j jS d S rY   )r9   r   rB   rP   r(   r   r5   rQ   )r   new_ringtermsr7   r7   r8   set_ring  s    
zPolyElement.set_ringc                 G  sJ   |s| j j}n(t|| j jkr6td| j jt|f t|  g|R  S )Nz+Wrong number of symbols, expected %s got %s)r9   r   rp   rd   r   r'   as_expr_dict)r   r   r7   r7   r8   as_expr  s    
zPolyElement.as_exprc                   s    | j jj  fdd|  D S )Nc                   s   i | ]\}}| |qS r7   r7   r<   r   r   to_sympyr7   r8   rK     r?   z,PolyElement.as_expr_dict.<locals>.<dictcomp>)r9   r5   r  r   r   r7   r  r8   r     s    
zPolyElement.as_expr_dictc                   sx   | j j}|jr|js|j| fS | }|j |j}|j}|  D ]}| || q@| 	 fdd| 
 D } |fS )Nc                   s   g | ]\}}||  fqS r7   r7   )r<   kvcommonr7   r8   r>     r?   z,PolyElement.clear_denoms.<locals>.<listcomp>)r9   r5   is_Fieldhas_assoc_Ringr   get_ringr   denomrC   r}   rL   )r   r5   Zground_ringr   r
  r   r   r7   r  r8   clear_denoms  s    
zPolyElement.clear_denomsc                 C  s$   t |  D ]\}}|s| |= qdS )z+Eliminate monomials with zero coefficient. NrB   rL   )r   r  r  r7   r7   r8   
strip_zero  s    zPolyElement.strip_zeroc                 C  sH   |s
|  S | j |r"t| |S t| dkr2d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)r9   r   rO   r   rp   r   r   p1p2r7   r7   r8   r     s    zPolyElement.__eq__c                 C  s
   | |k S rY   r7   r  r7   r7   r8   r     s    zPolyElement.__ne__c                 C  s   | j }||r`t|  t| kr,dS |jj}|  D ]}|| | || |s< dS q<dS t| dkrpdS z|j|}W n ty   Y dS 0 |j| 	 ||S dS )z+Approximate equality test for polynomials. FTr   N)
r9   r   rv   keysr5   almosteqrp   r   r!   const)r  r  Z	tolerancer9   r  r  r7   r7   r8   r    s     
zPolyElement.almosteqc                 C  s   t | |  fS rY   )rp   r   r   r7   r7   r8   sort_key  s    zPolyElement.sort_keyc                 C  s&   | j |r||  | S tS d S rY   )r9   r   r  NotImplemented)r  r  opr7   r7   r8   _cmp  s    zPolyElement._cmpc                 C  s   |  |tS rY   )r  r   r  r7   r7   r8   __lt__  s    zPolyElement.__lt__c                 C  s   |  |tS rY   )r  r   r  r7   r7   r8   __le__  s    zPolyElement.__le__c                 C  s   |  |tS rY   )r  r   r  r7   r7   r8   __gt__   s    zPolyElement.__gt__c                 C  s   |  |tS rY   )r  r   r  r7   r7   r8   __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   ra   )r9   r   rd   r5   rB   r   r   r   r   r9   r   r   r7   r7   r8   _drop  s    



zPolyElement._dropc                 C  s   |  |\}}| jjdkr8| jr*| dS td| nP|j}|  D ]<\}}|| dkrvt|}||= ||t	|< qFtd| qF|S d S )Nr   zCannot drop %sr   )
r  r9   rd   	is_groundr   r   r   rL   rB   ro   )r   r   r   r9   r   r  r  Kr7   r7   r8   r     s    
zPolyElement.dropc                 C  s6   | j }||}t|j}||= ||j||| dfS )Nr   )r9   r   rB   r   r   r  r7   r7   r8   _drop_to_ground%  s
    

zPolyElement._drop_to_groundc                 C  s   | j jdkrtd| |\}}|j}|jjd }|  D ]b\}}|d | ||d d   }||vr|||  |||< q<||  |||  |7  < q<|S )Nr   z$Cannot drop only generator to groundr   )	r9   rd   r   r   r   r5   r3   r   
mul_ground)r   r   r   r9   r   r   r   monr7   r7   r8   r   -  s     zPolyElement.drop_to_groundc                 C  s   t | | jjd | jjS r   )r   r9   rd   r5   r   r7   r7   r8   to_dense>  s    zPolyElement.to_densec                 C  s   t | S rY   )rO   r   r7   r7   r8   to_dictA  s    zPolyElement.to_dictc                 C  s  | s| | jjjS |d }|d }| j}|j}|j}	|j}
g }|  D ]4\}}|j|}|rfdnd}|	| ||
kr| |}|r|
dr|dd  }n.|r| }|| jjjkr|j||dd}nd	}g }t|	D ]}|| }|sq|j|| |dd}|dkrN|t|ks$|d
k r6|j||dd}n|}|	|||f  q|	d|  q|rn|g| }|	|| qH|d
 dv r|d
}|dkr|d
d d	|S )NZMulZAtom -  + -r   T)strict r   Fz%s)r&  r%  )Z_printr9   r5   r   r   rd   r   r   is_negativer   r   r   Zparenthesizer   rc   joinpopinsert)r   printer
precedenceZexp_patternZ
mul_symbolZprec_mulZ	prec_atomr9   r   rd   zmZsexpvsr   r   negativesignZscoeffZsexpvr   r   r   Zsexpheadr7   r7   r8   r[   D  sT    





zPolyElement.strc                 C  s   | | j jv S rY   )r9   r   r   r7   r7   r8   is_generatort  s    zPolyElement.is_generatorc                 C  s   |  pt | dko| jj| v S r   )rp   r9   r   r   r7   r7   r8   r  x  s    zPolyElement.is_groundc                 C  s   |  pt | dko| jdkS r   )rp   LCr   r7   r7   r8   is_monomial|  s    zPolyElement.is_monomialc                 C  s   t | dkS r   )rp   r   r7   r7   r8   is_term  s    zPolyElement.is_termc                 C  s   | j j| jS rY   )r9   r5   r*  r5  r   r7   r7   r8   r*    s    zPolyElement.is_negativec                 C  s   | j j| jS rY   )r9   r5   is_positiver5  r   r7   r7   r8   r8    s    zPolyElement.is_positivec                 C  s   | j j| jS rY   )r9   r5   is_nonnegativer5  r   r7   r7   r8   r9    s    zPolyElement.is_nonnegativec                 C  s   | j j| jS rY   )r9   r5   is_nonpositiver5  r   r7   r7   r8   r:    s    zPolyElement.is_nonpositivec                 C  s   |  S rY   r7   rm   r7   r7   r8   is_zero  s    zPolyElement.is_zeroc                 C  s   | | j jkS rY   )r9   r   rm   r7   r7   r8   is_one  s    zPolyElement.is_onec                 C  s   | j j| jS rY   )r9   r5   r<  r5  rm   r7   r7   r8   is_monic  s    zPolyElement.is_monicc                 C  s   | j j|  S rY   )r9   r5   r<  contentrm   r7   r7   r8   is_primitive  s    zPolyElement.is_primitivec                 C  s   t dd |  D S )Nc                 s  s   | ]}t |d kV  qdS r   NrN   r<   r   r7   r7   r8   r^     r?   z(PolyElement.is_linear.<locals>.<genexpr>r`   
itermonomsrm   r7   r7   r8   	is_linear  s    zPolyElement.is_linearc                 C  s   t dd |  D S )Nc                 s  s   | ]}t |d kV  qdS )   NrA  rB  r7   r7   r8   r^     r?   z+PolyElement.is_quadratic.<locals>.<genexpr>rC  rm   r7   r7   r8   is_quadratic  s    zPolyElement.is_quadraticc                 C  s   | j jsdS | j | S NT)r9   rd   Z	dmp_sqf_prm   r7   r7   r8   is_squarefree  s    zPolyElement.is_squarefreec                 C  s   | j jsdS | j | S rH  )r9   rd   Zdmp_irreducible_prm   r7   r7   r8   is_irreducible  s    zPolyElement.is_irreduciblec                 C  s    | j jr| j | S tdd S )Nzcyclotomic polynomial)r9   r   Zdup_cyclotomic_pr$   rm   r7   r7   r8   is_cyclotomic  s    zPolyElement.is_cyclotomicc                 C  s   |  dd |  D S )Nc                 S  s   g | ]\}}|| fqS r7   r7   r   r7   r7   r8   r>     r?   z'PolyElement.__neg__.<locals>.<listcomp>)r}   r   r   r7   r7   r8   __neg__  s    zPolyElement.__neg__c                 C  s   | S rY   r7   r   r7   r7   r8   __pos__  s    zPolyElement.__pos__c           
      C  s>  |s|   S | j}||rj|   }|j}|jj}| D ]*\}}|||| }|r^|||< q:||= q:|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 z||}W n ty   t Y S 0 |   }|s|S |j}	|	|  v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   r9   r   r   r5   r   rL   rZ   r|   r   __radd__r  r   r!   r   r  )
r  r  r9   r   r   r   r  r  Zcp2r0  r7   r7   r8   __add__  sB    





zPolyElement.__add__c                 C  s   |   }|s|S | j}z||}W n ty:   t Y S 0 |j}||  vrX|||< n&|||  krn||= n||  |7  < |S d S rY   )r   r9   r   r!   r  r   r  )r  r   r   r9   r0  r7   r7   r8   rN    s    

zPolyElement.__radd__c           	      C  s6  |s|   S | j}||rj|   }|j}|jj}| D ]*\}}|||| }|r^|||< q:||= q:|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 z||}W n ty   t Y S 0 |   }|j}||  v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   r9   r   r   r5   r   rL   rZ   r|   r   __rsub__r  r   r!   r   r  )	r  r  r9   r   r   r   r  r  r0  r7   r7   r8   __sub__  s>    




zPolyElement.__sub__c                 C  sZ   | j }z||}W n ty*   t Y S 0 |j}| D ]}| |  ||< q6||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)r9   r   r!   r  r   )r  r   r9   r   r   r7   r7   r8   rP  E  s    
zPolyElement.__rsub__c                 C  s8  | j }|j}| r|s|S ||r|j}|jj}|j}t| }|  D ]6\}}	|D ](\}
}|||
}||||	|  ||< qVqJ|  |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 z||}W n ty   t Y S 0 |  D ] \}}	|	| }|r|||< q|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)r9   r   r   r   r5   r   rB   rL   r  rZ   r|   r   __rmul__r  r   r!   )r  r  r9   r   r   r   r   Zp2itexp1v1Zexp2Zv2r   r  r7   r7   r8   __mul__a  s<    




zPolyElement.__mul__c                 C  sf   | j j}|s|S z|j |}W n ty6   t Y S 0 |  D ]\}}|| }|r@|||< q@|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)r9   r   r   r!   r  rL   )r  r  r   rS  rT  r  r7   r7   r8   rR    s    

zPolyElement.__rmul__c                 C  s  t |tstd| n|dk r,td| | j}|sJ| r@|jS tdn\t| dkrt|  d \}}|j	}||j
jkr|||||< n|| ||||< |S t|}|dk rtdnV|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#exponent must be an integer, got %sr   z/exponent must be a non-negative integer, got %sz0**0r   zNegative exponentrF        N)rZ   rc   	TypeErrorr   r9   r   rp   rB   rL   r   r5   r   r   square_pow_multinomial_pow_generic)r   r   r9   r   r   r   r7   r7   r8   __pow__  s8    



zPolyElement.__pow__c                 C  s@   | j j}| }|d@ r*|| }|d8 }|s*q<| }|d }q|S )Nr   rF  )r9   r   rY  )r   r   r   rI   r7   r7   r8   r[    s    
zPolyElement._pow_genericc                 C  s   t t| | }| jj}| jj}|  }| jjj}| jj}|D ]|\}}	|}
|	}t||D ](\}\}}|rZ||
||}
||| 9 }qZt	|
}|}|
||| }|r|||< q@||v r@||= q@|S rY   )r   rp   rL   r9   r   r   r5   r   rP   ro   r   )r   r   Zmultinomialsr   r   r   r   r   ZmultinomialZmultinomial_coeffZproduct_monomZproduct_coeffr   r   r   r7   r7   r8   rZ    s*    

zPolyElement._pow_multinomialc                 C  s   | j }|j}|j}t|  }|jj}|j}tt|D ]N}|| }| | }	t|D ]0}
||
 }|||}||||	| |   ||< qTq8|	d}|j}| 
 D ](\}}|||}||||d  ||< q|  |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

        rF  )r9   r   r   rB   r  r5   r   r   rp   imul_numrL   r  )r   r9   r   r   r  r   r   r   Zk1pkjZk2r   r  r  r7   r7   r8   rY    s(    


zPolyElement.squarec                 C  s   | j }|stdnd||r(| |S t|trxt|jtrN|jj |j krNn*t|j jtrt|j jj |krt|| S t	S z|
|}W n ty   t	 Y S 0 | || |fS d S Npolynomial division)r9   ZeroDivisionErrorr   r   rZ   r|   r5   r   __rdivmod__r  r   r!   
quo_ground
rem_groundr  r  r9   r7   r7   r8   
__divmod__:  s     





zPolyElement.__divmod__c                 C  s:   | j }z||}W n ty*   t Y S 0 || S d S rY   )r9   r   r!   r  r   rf  r7   r7   r8   rc  P  s    
zPolyElement.__rdivmod__c                 C  s   | j }|stdnd||r(| |S t|trxt|jtrN|jj |j krNn*t|j jtrt|j jj |krt|| S t	S z|
|}W n ty   t	 Y S 0 | |S d S r`  )r9   rb  r   remrZ   r|   r5   r   __rmod__r  r   r!   re  rf  r7   r7   r8   __mod__Y  s     





zPolyElement.__mod__c                 C  s:   | j }z||}W n ty*   t Y S 0 || S d S rY   )r9   r   r!   r  rh  rf  r7   r7   r8   ri  o  s    
zPolyElement.__rmod__c                 C  s   | j }|stdnd||r(| |S t|trxt|jtrN|jj |j krNn*t|j jtrt|j jj |krt|| S t	S z|
|}W n ty   t	 Y S 0 | |S d S r`  )r9   rb  r   quorZ   r|   r5   r   __rtruediv__r  r   r!   rd  rf  r7   r7   r8   __floordiv__x  s     





zPolyElement.__floordiv__c                 C  s:   | j }z||}W n ty*   t Y S 0 || S d S rY   )r9   r   r!   r  rk  rf  r7   r7   r8   __rfloordiv__  s    
zPolyElement.__rfloordiv__c                 C  s   | j }|stdnd||r(| |S t|trxt|jtrN|jj |j krNn*t|j jtrt|j jj |krt|| S t	S z|
|}W n ty   t	 Y S 0 | |S d S r`  )r9   rb  r   exquorZ   r|   r5   r   rl  r  r   r!   rd  rf  r7   r7   r8   __truediv__  s     





zPolyElement.__truediv__c                 C  s:   | j }z||}W n ty*   t Y S 0 || S d S rY   )r9   r   r!   r  ro  rf  r7   r7   r8   rl    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 ur>| ||fS d S d S rY   r7   Z	a_lm_a_lcZ	b_lm_b_lcZa_lmZa_lcZb_lmZb_lcr   Z
domain_quor   r0  r7   r8   term_div  s    
z'PolyElement._term_div.<locals>.term_divc                   sN   | \}}|\}}|kr|}n
||}|d u sF|| sF| ||fS d S d S rY   r7   rq  rr  r7   r8   rs    s    
)r9   r   r5   rk  r   r  )r   r5   rs  r7   rr  r8   	_term_div  s    zPolyElement._term_divc                   s  | j  d}t|trd}|g}t|s.td| sL|rB j jfS g  jfS |D ]}|j  krPtdqPt|} fddt|D }| 	 } j}| 
 }dd |D }	|rnd}
d}|
|k rH|dkrH| }|||| f|	|
 ||
 |	|
  f}|d	ur>|\}}||
 ||f||
< |||
 || f}d
}q|
d
7 }
q|s| }|||| f}||= q| 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

        FTra  z"self and f must have the same ringc                   s   g | ]
} j qS r7   )r   r   r9   r7   r8   r>     r?   z#PolyElement.div.<locals>.<listcomp>c                 S  s   g | ]}|  qS r7   )r   )r<   Zfxr7   r7   r8   r>     r?   r   Nr   )r9   rZ   r|   r`   rb  r   r   rp   r   r   rt  r   _iadd_monom_iadd_poly_monomr   )r   ZfvZ
ret_singlern   r]   Zqvr   rrs  Zexpvsr   Zdivoccurredr   termZexpv1rI   r7   ru  r8   r     sV    



&


zPolyElement.divc                 C  s@  | }t |tr|g}t|s$td|j}|j}|j}|j}|j}| }|j	}	|
 }|j}
|r<|D ]}||	|j	}|d urh|\}}| D ]8\}}|||}|
||||  }|s||= q|||< q| }|d ur||| f}	 q^qh|	\}}||v r||  |7  < n|||< ||= | }|d ur^||| f}	q^|S r`  )rZ   r|   r`   rb  r9   r5   r   r   rt  LTr   r   r   r   )r   Grn   r9   r5   r   r   rx  rs  Zltfr   gZtqrH   rI   mgcgm1Zc1ZltmZltcr7   r7   r8   rh  #  sL    



zPolyElement.remc                 C  s   |  |d S Nr   )r   )rn   r{  r7   r7   r8   rk  P  s    zPolyElement.quoc                 C  s$   |  |\}}|s|S t| |d S rY   )r   r#   )rn   r{  qrx  r7   r7   r8   ro  S  s    zPolyElement.exquoc                 C  s^   | | j jv r|  }n| }|\}}||}|du 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)r9   r   r   r   )r   mcZcpselfr   r   rI   r7   r7   r8   rv  [  s    



zPolyElement._iadd_monomc                 C  s~   | }||j jv r| }|\}}|j}|j jj}|j j}| D ]8\}	}
||	|}||||
|  }|rr|||< q@||= q@|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

        )r9   r   r   r   r5   r   r   rL   )r   r  r  r  rH   rI   r   r   r   r  r  kar   r7   r7   r8   rw    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 (``float('-inf')``)

        r   c                 3  s   | ]}|  V  qd S rY   r7   rB  r   r7   r8   r^     r?   z%PolyElement.degree.<locals>.<genexpr>N)r9   r   r   rl   rD  rn   xr7   r  r8   degree  s    zPolyElement.degreec                 C  s0   | 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 (``float('-inf')``)

        N)	r   r9   rd   ro   rM   rl   rB   rP   rD  rm   r7   r7   r8   degrees  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 (``float('-inf')``)

        r   c                 3  s   | ]}|  V  qd S rY   r7   rB  r  r7   r8   r^     r?   z*PolyElement.tail_degree.<locals>.<genexpr>N)r9   r   r   minrD  r  r7   r  r8   tail_degree  s    zPolyElement.tail_degreec                 C  s0   | 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 (``float('-inf')``)

        N)	r   r9   rd   ro   rM   r  rB   rP   rD  rm   r7   r7   r8   tail_degrees  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)r9   r   r   r7   r7   r8   r     s    zPolyElement.leading_expvc                 C  s   |  || jjjS rY   )r   r9   r5   r   r   r   r7   r7   r8   
_get_coeff  s    zPolyElement._get_coeffc                 C  sn   |dkr|  | jjS | 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)
r  r9   r   r   rB   r   rp   r5   r   r   )r   r   r   r   r   r7   r7   r8   r     s    
zPolyElement.coeffc                 C  s   |  | jjS )z"Returns the constant coefficient. )r  r9   r   r   r7   r7   r8   r     s    zPolyElement.constc                 C  s   |  |  S rY   )r  r   r   r7   r7   r8   r5  $  s    zPolyElement.LCc                 C  s    |   }|d u r| jjS |S d S rY   )r   r9   r   r  r7   r7   r8   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

        )r9   r   r   r5   r   r   r   r   r7   r7   r8   leading_monom0  s
    zPolyElement.leading_monomc                 C  s4   |   }|d u r"| jj| jjjfS || |fS d S rY   )r   r9   r   r5   r   r  r  r7   r7   r8   rz  E  s    zPolyElement.LTc                 C  s(   | j j}|  }|du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)r9   r   r   r  r7   r7   r8   leading_termM  s
    zPolyElement.leading_termc                   sP    d u r| j j n
t   tu r6t|dd ddS t| fddddS d S )Nc                 S  s   | d S r  r7   r   r7   r7   r8   ri   h  r?   z%PolyElement._sorted.<locals>.<lambda>T)rk   reversec                   s    | d S r  r7   r  r/   r7   r8   ri   j  r?   )r9   r0   rs   rr   r   sorted)r   rX   r0   r7   r/   r8   _sorteda  s    

zPolyElement._sortedc                 C  s   dd |  |D S )a  Ordered list of polynomial coefficients.

        Parameters
        ==========

        order : :class:`~.MonomialOrder` 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 r7   r7   )r<   _r   r7   r7   r8   r>     r?   z&PolyElement.coeffs.<locals>.<listcomp>r   r   r0   r7   r7   r8   rU   l  s    zPolyElement.coeffsc                 C  s   dd |  |D S )a
  Ordered list of polynomial monomials.

        Parameters
        ==========

        order : :class:`~.MonomialOrder` 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 r7   r7   )r<   r   r  r7   r7   r8   r>     r?   z&PolyElement.monoms.<locals>.<listcomp>r  r  r7   r7   r8   monoms  s    zPolyElement.monomsc                 C  s   |  t|  |S )a  Ordered list of polynomial terms.

        Parameters
        ==========

        order : :class:`~.MonomialOrder` 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)]

        )r  rB   rL   r  r7   r7   r8   r     s    zPolyElement.termsc                 C  s   t |  S )z,Iterator over coefficients of a polynomial. )iterrC   r   r7   r7   r8   
itercoeffs  s    zPolyElement.itercoeffsc                 C  s   t |  S )z)Iterator over monomials of a polynomial. )r  r  r   r7   r7   r8   rD    s    zPolyElement.itermonomsc                 C  s   t |  S )z%Iterator over terms of a polynomial. )r  rL   r   r7   r7   r8   r     s    zPolyElement.itertermsc                 C  s   t |  S )z+Unordered list of polynomial coefficients. rA   r   r7   r7   r8   
listcoeffs  s    zPolyElement.listcoeffsc                 C  s   t |  S )z(Unordered list of polynomial monomials. )rB   r  r   r7   r7   r8   
listmonoms  s    zPolyElement.listmonomsc                 C  s   t |  S )z$Unordered list of polynomial terms. r  r   r7   r7   r8   	listterms  s    zPolyElement.listtermsc                 C  sB   | | j jv r| | S |s$|   dS | D ]}| |  |9  < q(| 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)r9   r   clear)r   rI   r   r7   r7   r8   r]    s    zPolyElement.imul_numc                 C  s0   | j j}|j}|j}|  D ]}|||}q|S )z*Returns GCD of polynomial's coefficients. )r9   r5   r   r   r  )rn   r5   contr   r   r7   r7   r8   r>    s    zPolyElement.contentc                 C  s,   |   }|| jjjkr|| fS || |fS )z,Returns content and a primitive polynomial. )r>  r9   r5   r   rd  )rn   r  r7   r7   r8   	primitive   s    zPolyElement.primitivec                 C  s   | s| S |  | jS dS )z5Divides all coefficients by the leading coefficient. N)rd  r5  rm   r7   r7   r8   monic  s    zPolyElement.monicc                   s,    s| j jS  fdd|  D }| |S )Nc                   s   g | ]\}}||  fqS r7   r7   r   r  r7   r8   r>     r?   z*PolyElement.mul_ground.<locals>.<listcomp>)r9   r   r   r}   )rn   r  r   r7   r  r8   r!    s    zPolyElement.mul_groundc                   s*   | j j fdd|  D }| |S )Nc                   s   g | ]\}}| |fqS r7   r7   r<   Zf_monomZf_coeffr   r   r7   r8   r>     r?   z)PolyElement.mul_monom.<locals>.<listcomp>)r9   r   rL   r}   )rn   r   r   r7   r  r8   	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 r7   r7   r  r   r   r   r7   r8   r>   #  r?   z(PolyElement.mul_term.<locals>.<listcomp>)r9   r   r   r!  r   rL   r}   )rn   ry  r   r7   r  r8   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 )Nra  c                   s   g | ]\}}| |fqS r7   r7   r   rk  r  r7   r8   r>   0  r?   z*PolyElement.quo_ground.<locals>.<listcomp>c                   s$   g | ]\}}|  s||  fqS r7   r7   r   r  r7   r8   r>   2  r?   )r9   r5   rb  r   r  rk  r   r}   )rn   r  r5   r   r7   r  r8   rd  &  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 )Nra  c                   s   g | ]}| qS r7   r7   r<   try  rs  r7   r8   r>   B  r?   z(PolyElement.quo_term.<locals>.<listcomp>c                 S  s   g | ]}|d ur|qS rY   r7   r  r7   r7   r8   r>   C  r?   )rb  r9   r   r   rd  rt  r   r}   )rn   ry  r   r   r   r7   r  r8   quo_term6  s    

zPolyElement.quo_termc                   sx   | j jjrLg }|  D ]2\}}|  }| d kr:|  }|||f qn fdd|  D }| |}|  |S )NrF  c                   s   g | ]\}}||  fqS r7   r7   r   r   r7   r8   r>   Q  r?   z,PolyElement.trunc_ground.<locals>.<listcomp>)r9   r5   is_ZZr   r   r}   r  )rn   r   r   r   r   r   r7   r  r8   trunc_groundE  s    

zPolyElement.trunc_groundc                 C  sB   | }|  }|  }|jj||}||}||}|||fS rY   )r>  r9   r5   r   rd  )r   r|  rn   fcgcr   r7   r7   r8   extract_groundY  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 r7   r7   )r<   r   Z
ground_absr7   r8   r>   j  r?   z%PolyElement._norm.<locals>.<listcomp>)r9   r5   r   absr  )rn   Z	norm_funcr7   r  r8   _norme  s    

zPolyElement._normc                 C  s
   |  tS rY   )r  rl   rm   r7   r7   r8   max_norml  s    zPolyElement.max_normc                 C  s
   |  tS rY   )r  rN   rm   r7   r7   r8   l1_normo  s    zPolyElement.l1_normc                 G  s   | j }| gt| }dg|j }|D ]6}| D ](}t|D ]\}}t|| |||< q<q0q$t|D ]\}}	|	sdd||< qdt|}tdd |D r||fS g }
|D ]F}|j}|	 D ](\}}dd t
||D }||t|< q|
| q||
fS )Nr   r   c                 s  s   | ]}|d kV  qdS r@  r7   )r<   rh   r7   r7   r8   r^     r?   z&PolyElement.deflate.<locals>.<genexpr>c                 S  s   g | ]\}}|| qS r7   r7   r<   r   r_  r7   r7   r8   r>     r?   z'PolyElement.deflate.<locals>.<listcomp>)r9   rB   rd   rD  r   r   ro   r`   r   r   rP   r   )rn   r{  r9   rV   Jr   r   r   rH   rh   HhIr   Nr7   r7   r8   deflater  s*    
zPolyElement.deflatec                 C  s>   | j j}|  D ](\}}dd t||D }||t|< q|S )Nc                 S  s   g | ]\}}|| qS r7   r7   r  r7   r7   r8   r>     r?   z'PolyElement.inflate.<locals>.<listcomp>)r9   r   r   rP   ro   )rn   r  r   r  r   r  r7   r7   r8   inflate  s
    zPolyElement.inflatec                 C  sf   | }|j j}|js6| \}}| \}}|||}|| ||}|jsZ||S | S d S rY   )	r9   r5   r  r  r   rk  r   r!  r  )r   r|  rn   r5   r  r  rI   r  r7   r7   r8   r     s    
zPolyElement.lcmc                 C  s   |  |d S r  )	cofactorsrn   r|  r7   r7   r8   r     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 r   )r9   r   	_gcd_zerorp   
_gcd_monomr  _gcdr  )rn   r|  r   r  cffcfgr  r7   r7   r8   r    s$    




zPolyElement.cofactorsc                 C  s4   | j j| j j }}|jr"|||fS | || fS d S rY   )r9   r   r   r9  )rn   r|  r   r   r7   r7   r8   r    s    
zPolyElement._gcd_zeroc                   s   | j }|jj}|jj|j}|jt|  d \}}||  | D ]\}}||| | qH|  fg}	| || fg}
|  fdd| D }|	|
|fS )Nr   c                   s$   g | ]\}}|| fqS r7   r7   )r<   r}  r~  Z_cgcdZ_mgcdZ
ground_quor   r7   r8   r>     r?   z*PolyElement._gcd_monom.<locals>.<listcomp>)	r9   r5   r   rk  r   r   rB   r   r}   )rn   r|  r9   Z
ground_gcdr   Zmfcfr}  r~  r  r  r  r7   r  r8   r    s    

"zPolyElement._gcd_monomc                 C  s:   | j }|jjr| |S |jjr*| |S || |S d S rY   )r9   r5   Zis_QQ_gcd_QQr  _gcd_ZZZdmp_inner_gcd)rn   r|  r9   r7   r7   r8   r    s    

zPolyElement._gcdc                 C  s
   t | |S rY   r   r  r7   r7   r8   r    s    zPolyElement._gcd_ZZc                 C  s   | }|j }|j|j d}| \}}| \}}||}||}||\}}}	||}|j|  }
}||	|j
|
|}|	|	|j
|
|}	|||	fS )Nr   )r9   r   r5   r	  r  r   r  r5  r  r!  rk  )r   r|  rn   r9   r   r  r~  r  r  r  rI   r7   r7   r8   r    s    


zPolyElement._gcd_QQc                 C  s  | }|j }|s||jfS |j}|jr*|js<||\}}}n|j| d}| \}	}| \}
}|	|}|	|}||\}}}|j|
|	\}}
}	|	|}|	|}|
|
}|
|	}| }||jkrn0||j kr| |  }}n|
|}|
|}||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   )r9   r   r5   r  r  r  r   r	  r  r   r!  canonical_unit)r   r|  rn   r9   r5   r  r   r  r   Zcqcpur7   r7   r8   cancel  s4    









zPolyElement.cancelc                 C  s   | j j}|| jS rY   )r9   r5   r  r5  )rn   r5   r7   r7   r8   r  6	  s    zPolyElement.canonical_unitc           	      C  s`   | j }||}||}|j}|  D ]2\}}|| r(|||}||||  ||< q(|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

        )r9   r   r   r   r   r   r   )	rn   r  r9   r   rH   r|  r   r   er7   r7   r8   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)rp   r9   rd   evaluaterB   rP   r3   r   )rn   rC   r7   r7   r8   r   S	  s     zPolyElement.__call__c                   sH  | }t |tr`|d u r`|d |dd   \ }}| |}|sD|S  fdd|D }||S |j}||}|j|}|jdkr|jj}|	 D ]\\}}||||  7 }q|S |
|j}	|	 D ]t\}
}|
| |
d | |
|d d    }}
|||  }|
|	v r2||	|
  }|r*||	|
< n|	|
= q|r||	|
< q|	S d S )Nr   r   c                   s   g | ]\}}|  |fqS r7   )r   )r<   Yrg   Xr7   r8   r>   c	  r?   z(PolyElement.evaluate.<locals>.<listcomp>)rZ   rB   r  r9   r   r5   r   rd   r   r   r   )r   r  rg   rn   r9   r   resultr   r   r   r   r7   r  r8   r  Y	  s8    


&


zPolyElement.evaluatec                 C  s   | }t |tr4|d u r4|D ]\}}|||}q|S |j}||}|j|}|jdkr|jj}|	 D ]\\}}	||	||  7 }qj|
|S |j}
|	 D ]x\}}	|| |d | d ||d d    }}|	||  }	||
v r
|	|
|  }	|	r|	|
|< n|
|= q|	r|	|
|< q|
S d S )Nr   re   )rZ   rB   subsr9   r   r5   r   rd   r   r   r   )r   r  rg   rn   r  r9   r   r  r   r   r   r   r7   r7   r8   r  	  s2    


*


zPolyElement.subsc                   s  |   }|jj}|s$|jg fS fddt|D i fdd}tt|d }tt|dd}j}|rrd\}}}	t| D ]R\}
\ }t fd	d
|D rt	dd
 t
| D }||kr| |  }}}	q|dkr||	  }nqrg }t
  dd d D ]\}}|||  q|t||7 }|}t|D ]\}
}|||
|9 }qN||8 }qrtt
j}|||fS )aX  
        Rewrite *self* in terms of elementary symmetric polynomials.

        Explanation
        ===========

        If this :py:class:`~.PolyElement` belongs to a ring of $n$ variables,
        we can try to write it as a function of the elementary symmetric
        polynomials on $n$ variables. We compute a symmetric part, and a
        remainder for any part we were not able to symmetrize.

        Examples
        ========

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

        >>> f = x**2 + y**2
        >>> f.symmetrize()
        (x**2 - 2*y, 0, [(x, x + y), (y, x*y)])

        >>> f = x**2 - y**2
        >>> f.symmetrize()
        (x**2 - 2*y, -2*y**2, [(x, x + y), (y, x*y)])

        Returns
        =======

        Triple ``(p, r, m)``
            ``p`` is a :py:class:`~.PolyElement` that represents our attempt
            to express *self* as a function of elementary symmetric
            polynomials. Each variable in ``p`` stands for one of the
            elementary symmetric polynomials. The correspondence is given
            by ``m``.

            ``r`` is the remainder.

            ``m`` is a list of pairs, giving the mapping from variables in
            ``p`` to elementary symmetric polynomials.

            The triple satisfies the equation ``p.compose(m) + r == self``.
            If the remainder ``r`` is zero, *self* is symmetric. If it is
            nonzero, we were not able to represent *self* as symmetric.

        See Also
        ========

        sympy.polys.polyfuncs.symmetrize

        References
        ==========

        .. [1] Lauer, E. Algorithms for symmetrical polynomials, Proc. 1976
            ACM Symp. on Symbolic and Algebraic Computing, NY 242-247.
            https://dl.acm.org/doi/pdf/10.1145/800205.806342

        c                   s   g | ]}  |d  qS )r   )r   r   ru  r7   r8   r>   	  r?   z*PolyElement.symmetrize.<locals>.<listcomp>c                   s,   | |f vr |  |  | |f<  | |f S rY   r7   )r   r   )poly_powersrV   r7   r8   get_poly_power	  s    z.PolyElement.symmetrize.<locals>.get_poly_powerr   r   r   )r   NNc                 3  s"   | ]} |  |d   kV  qdS r@  r7   r   r  r7   r8   r^   	  r?   z)PolyElement.symmetrize.<locals>.<genexpr>c                 s  s   | ]\}}|| V  qd S rY   r7   )r<   r   rH   r7   r7   r8   r^    
  r?   Nre   )r   r9   rd   r   r   rB   r   r   r`   rl   rP   r   r   ro   r3   )r   rn   r   r  r   weightsZ	symmetricZ_heightZ_monomZ_coeffr   r   heightZ	exponentsr  m2productr   r7   )r   r  rV   r9   r8   
symmetrize	  s>    ;

zPolyElement.symmetrizec                   s  | j }|j}tt|jt|j |d ur6||fg}n@t|trJt|}n,t|trnt	|
  fddd}ntdt|D ]"\}\}} | ||f||< q~|  D ]`\}}	t|}|j}
|D ]*\}}|| d }||< |r|
|| 9 }
q|
t||	f}
||
7 }q|S )Nc                   s    | d  S r  r7   )r  Zgens_mapr7   r8   ri   $
  r?   z%PolyElement.compose.<locals>.<lambda>rj   z9expected a generator, value pair a sequence of such pairsr   )r9   r   rO   rP   r3   r   rd   rZ   rB   r  rL   r   r   r   r   r   r  ro   )rn   r  rg   r9   r   replacementsr  r|  r   r   Zsubpolyr   r   r7   r  r8   r   
  s,    



zPolyElement.composec                   sh   | }|j | fdd| D }|s4|j jS t| \}}fdd|D }|j tt||S )aU  
        Coefficient of ``self`` with respect to ``x**deg``.

        Treating ``self`` as a univariate polynomial in ``x`` this finds the
        coefficient of ``x**deg`` as a polynomial in the other generators.

        Parameters
        ==========

        x : generator or generator index
            The generator or generator index to compute the expression for.
        deg : int
            The degree of the monomial to compute the expression for.

        Returns
        =======

        :py:class:`~.PolyElement`
            The coefficient of ``x**deg`` as a polynomial in the same ring.

        Examples
        ========

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

        >>> p = 2*x**4 + 3*y**4 + 10*z**2 + 10*x*z**2
        >>> deg = 2
        >>> p.coeff_wrt(2, deg) # Using the generator index
        10*x + 10
        >>> p.coeff_wrt(z, deg) # Using the generator
        10*x + 10
        >>> p.coeff(z**2) # shows the difference between coeff and coeff_wrt
        10

        See Also
        ========

        coeff, coeffs

        c                   s$   g | ]\}}|  kr||fqS r7   r7   rG   degr   r7   r8   r>   e
  r?   z)PolyElement.coeff_wrt.<locals>.<listcomp>c                   s,   g | ]$}|d   d | d d   qS )Nre   r   r7   )r<   rH   r  r7   r8   r>   k
  r?   )r9   r   r   r   rP   rQ   rO   )r   r  r  r   r   r  rU   r7   r  r8   	coeff_wrt9
  s    *zPolyElement.coeff_wrtc                 C  s   | }|j |}||}||}|dk r4td|| }}||k rJ|S || d }|||}	|j j| }
|||}|| |d  }}||	 }|| |
|  }|| }||}||k rnqqn|	| }|| S )a  
        Pseudo-remainder of the polynomial ``self`` with respect to ``g``.

        The pseudo-quotient ``q`` and pseudo-remainder ``r`` with respect to
        ``z`` when dividing ``f`` by ``g`` satisfy ``m*f = g*q + r``,
        where ``deg(r,z) < deg(g,z)`` and
        ``m = LC(g,z)**(deg(f,z) - deg(g,z)+1)``.

        See :meth:`pdiv` for explanation of pseudo-division.


        Parameters
        ==========

        g : :py:class:`~.PolyElement`
            The polynomial to divide ``self`` by.
        x : generator or generator index, optional
            The main variable of the polynomials and default is first generator.

        Returns
        =======

        :py:class:`~.PolyElement`
            The pseudo-remainder polynomial.

        Raises
        ======

        ZeroDivisionError : If ``g`` is the zero polynomial.

        Examples
        ========

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

        >>> f = x**2 + x*y
        >>> g = 2*x + 2
        >>> f.prem(g) # first generator is chosen by default if it is not given
        -4*y + 4
        >>> f.rem(g) # shows the difference between prem and rem
        x**2 + x*y
        >>> f.prem(g, y) # generator is given
        0
        >>> f.prem(g, 1) # generator index is given
        0

        See Also
        ========

        pdiv, pquo, pexquo, sympy.polys.domains.ring.Ring.rem

        r   ra  r   r9   r   r  rb  r  r3   )r   r|  r  rn   dfdgrx  drr  lc_gxplc_rr_  Rr{  rI   r7   r7   r8   premn
  s,    6



zPolyElement.premc                 C  s  | }|j |}||}||}|dk r4td|||  }}}||k rT||fS || d }	|||}
|j j| }|||}|| |	d  }}	||
 }||||   }||
 }|| ||  }|| }||}||k rxqqx|
|	 }|| }|| }||fS )a|  
        Computes the pseudo-division of the polynomial ``self`` with respect to ``g``.

        The pseudo-division algorithm is used to find the pseudo-quotient ``q``
        and pseudo-remainder ``r`` such that ``m*f = g*q + r``, where ``m``
        represents the multiplier and ``f`` is the dividend polynomial.

        The pseudo-quotient ``q`` and pseudo-remainder ``r`` are polynomials in
        the variable ``x``, with the degree of ``r`` with respect to ``x``
        being strictly less than the degree of ``g`` with respect to ``x``.

        The multiplier ``m`` is defined as
        ``LC(g, x) ^ (deg(f, x) - deg(g, x) + 1)``,
        where ``LC(g, x)`` represents the leading coefficient of ``g``.

        It is important to note that in the context of the ``prem`` method,
        multivariate polynomials in a ring, such as ``R[x,y,z]``, are treated
        as univariate polynomials with coefficients that are polynomials,
        such as ``R[x,y][z]``. When dividing ``f`` by ``g`` with respect to the
        variable ``z``, the pseudo-quotient ``q`` and pseudo-remainder ``r``
        satisfy ``m*f = g*q + r``, where ``deg(r, z) < deg(g, z)``
        and ``m = LC(g, z)^(deg(f, z) - deg(g, z) + 1)``.

        In this function, the pseudo-remainder ``r`` can be obtained using the
        ``prem`` method, the pseudo-quotient ``q`` can
        be obtained using the ``pquo`` method, and
        the function ``pdiv`` itself returns a tuple ``(q, r)``.


        Parameters
        ==========

        g : :py:class:`~.PolyElement`
            The polynomial to divide ``self`` by.
        x : generator or generator index, optional
            The main variable of the polynomials and default is first generator.

        Returns
        =======

        :py:class:`~.PolyElement`
            The pseudo-division polynomial (tuple of ``q`` and ``r``).

        Raises
        ======

        ZeroDivisionError : If ``g`` is the zero polynomial.

        Examples
        ========

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

        >>> f = x**2 + x*y
        >>> g = 2*x + 2
        >>> f.pdiv(g) # first generator is chosen by default if it is not given
        (2*x + 2*y - 2, -4*y + 4)
        >>> f.div(g) # shows the difference between pdiv and div
        (0, x**2 + x*y)
        >>> f.pdiv(g, y) # generator is given
        (2*x**3 + 2*x**2*y + 6*x**2 + 2*x*y + 8*x + 4, 0)
        >>> f.pdiv(g, 1) # generator index is given
        (2*x**3 + 2*x**2*y + 6*x**2 + 2*x*y + 8*x + 4, 0)

        See Also
        ========

        prem
            Computes only the pseudo-remainder more efficiently than
            `f.pdiv(g)[1]`.
        pquo
            Returns only the pseudo-quotient.
        pexquo
            Returns only an exact pseudo-quotient having no remainder.
        div
            Returns quotient and remainder of f and g polynomials.

        r   ra  r   r  )r   r|  r  rn   r  r  r  rx  r  r  r  r  r  r_  Qr  r{  rI   r7   r7   r8   pdiv
  s4    P


zPolyElement.pdivc                 C  s   | }| ||d S )aW  
        Polynomial pseudo-quotient in multivariate polynomial ring.

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

        >>> f = x**2 + x*y
        >>> g = 2*x + 2*y
        >>> h = 2*x + 2
        >>> f.pquo(g)
        2*x
        >>> f.quo(g) # shows the difference between pquo and quo
        0
        >>> f.pquo(h)
        2*x + 2*y - 2
        >>> f.quo(h) # shows the difference between pquo and quo
        0

        See Also
        ========

        prem, pdiv, pexquo, sympy.polys.domains.ring.Ring.quo

        r   )r  )r   r|  r  rn   r7   r7   r8   pquoG  s    zPolyElement.pquoc                 C  s,   | }| ||\}}|jr|S t||dS )a  
        Polynomial exact pseudo-quotient in multivariate polynomial ring.

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

        >>> f = x**2 + x*y
        >>> g = 2*x + 2*y
        >>> h = 2*x + 2
        >>> f.pexquo(g)
        2*x
        >>> f.exquo(g) # shows the difference between pexquo and exquo
        Traceback (most recent call last):
        ...
        ExactQuotientFailed: 2*x + 2*y does not divide x**2 + x*y
        >>> f.pexquo(h)
        Traceback (most recent call last):
        ...
        ExactQuotientFailed: 2*x + 2 does not divide x**2 + x*y

        See Also
        ========

        prem, pdiv, pquo, sympy.polys.domains.ring.Ring.exquo

        N)r  r;  r#   )r   r|  r  rn   r  rx  r7   r7   r8   pexquoe  s
    zPolyElement.pexquoc                 C  sX  | }|j |}||}||}||k r@|| }}|| }}|dkrPddgS |dkr`|dgS ||g}|| }d|d  }|||}	|	| }	|||}
|
| }d|g}| }|	rT|	|}||	 ||	||| f\}}}}|
 ||  }|||}	|	|}	|||}
|dkr@|
 | }||d  }||}n|
 }||  q|S )a  
        Computes the subresultant PRS of two polynomials ``self`` and ``g``.

        Parameters
        ==========

        g : :py:class:`~.PolyElement`
            The second polynomial.
        x : generator or generator index
            The variable with respect to which the subresultant sequence is computed.

        Returns
        =======

        R : list
            Returns a list polynomials representing the subresultant PRS.

        Examples
        ========

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

        >>> f = x**2*y + x*y
        >>> g = x + y
        >>> f.subresultants(g) # first generator is chosen by default if not given
        [x**2*y + x*y, x + y, y**3 - y**2]
        >>> f.subresultants(g, 0) # generator index is given
        [x**2*y + x*y, x + y, y**3 - y**2]
        >>> f.subresultants(g, y) # generator is given
        [x**2*y + x*y, x + y, x**3 + x**2]

        r   r   r   )r9   r   r  r  r  r   ro  )r   r|  r  rn   r   rH   r  drh   r  lcrI   Sr  r   r  r7   r7   r8   subresultants  sF    "








zPolyElement.subresultantsc                 C  s   | j | |S rY   )r9   Zdmp_half_gcdexr  r7   r7   r8   
half_gcdex  s    zPolyElement.half_gcdexc                 C  s   | j | |S rY   )r9   Z	dmp_gcdexr  r7   r7   r8   gcdex  s    zPolyElement.gcdexc                 C  s   | j | |S rY   )r9   Zdmp_resultantr  r7   r7   r8   	resultant  s    zPolyElement.resultantc                 C  s   | j | S rY   )r9   Zdmp_discriminantrm   r7   r7   r8   discriminant  s    zPolyElement.discriminantc                 C  s    | j jr| j | S tdd S )Nzpolynomial decomposition)r9   r   Zdup_decomposer$   rm   r7   r7   r8   	decompose  s    zPolyElement.decomposec                 C  s"   | j jr| j | |S tdd S )Nzshift: use shift_list instead)r9   r   Z	dup_shiftr$   rn   rg   r7   r7   r8   shift  s    zPolyElement.shiftc                 C  s   | j | |S rY   )r9   Z	dmp_shiftr  r7   r7   r8   
shift_list  s    zPolyElement.shift_listc                 C  s    | j jr| j | S tdd S )Nzsturm sequence)r9   r   Z	dup_sturmr$   rm   r7   r7   r8   sturm  s    zPolyElement.sturmc                 C  s   | j | S rY   )r9   Zdmp_gff_listrm   r7   r7   r8   gff_list  s    zPolyElement.gff_listc                 C  s   | j | S rY   )r9   Zdmp_normrm   r7   r7   r8   norm  s    zPolyElement.normc                 C  s   | j | S rY   )r9   Zdmp_sqf_normrm   r7   r7   r8   sqf_norm  s    zPolyElement.sqf_normc                 C  s   | j | S rY   )r9   Zdmp_sqf_partrm   r7   r7   r8   sqf_part  s    zPolyElement.sqf_partFc                 C  s   | j j| |dS )N)r`   )r9   Zdmp_sqf_list)rn   r`   r7   r7   r8   sqf_list  s    zPolyElement.sqf_listc                 C  s   | j | S rY   )r9   Zdmp_factor_listrm   r7   r7   r8   factor_list  s    zPolyElement.factor_list)N)N)N)N)N)N)N)N)N)N)N)N)N)N)F)rt   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   r4  r  r6  r7  r*  r8  r9  r:  r;  r<  r=  r?  rE  rG  rI  rJ  rK  rL  rM  rO  rN  rQ  rP  rU  rR  r\  r[  rZ  rY  rg  rc  rj  ri  rm  rn  rp  rl  rt  r   rh  rk  ro  rv  rw  r  r  r  r  r   r  r   r  r5  r  r  rz  r  r  rU   r  r   r  rD  r   r  r  r  r]  r>  r  r  r!  r  r  rd  r  r  re  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  __classcell__r7   r7   r   r8   r|   J  sT  
	0
















6646%				!L-,%%


#!	
8,'m 5[~%]r|   N)Qr   
__future__r   operatorr   r   r   r   r   r   	functoolsr	   typesr
   Zsympy.core.cacher   Zsympy.core.exprr   Zsympy.core.intfuncr   Zsympy.core.symbolr   r   r_   Zsympy.core.sympifyr   r   Zsympy.ntheory.multinomialr   Zsympy.polys.compatibilityr   Zsympy.polys.constructorr   Zsympy.polys.densebasicr   r   r   Zsympy.polys.domains.domainr   Z!sympy.polys.domains.domainelementr   Z"sympy.polys.domains.polynomialringr   Zsympy.polys.heuristicgcdr   Zsympy.polys.monomialsr   Zsympy.polys.orderingsr   r    Zsympy.polys.polyerrorsr!   r"   r#   r$   Zsympy.polys.polyoptionsrq   r%   rs   r&   Zsympy.polys.polyutilsr'   r(   r)   Zsympy.printing.defaultsr*   Zsympy.utilitiesr+   r,   Zsympy.utilities.iterablesr-   Zsympy.utilities.magicr.   r9   r:   r@   rW   rb   r2   rO   r|   r7   r7   r7   r8   <module>   sP    
4   	