U
    9%e
                    @  s  U d Z ddlm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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$ 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/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z6m7Z8m9Z9 ddl:m;Z;m<Z<m=Z= ddl>m?Z? ddl@mAZAmBZB ddlCmDZD ddlEmFZF eAe.fddZGeAe.fddZHeAe.fdd ZIeAd!d" ZJd#d$ ZKi ZLd%eMd&< G d'd( d(e?eZNG d)d* d*e&e?eeOZPd+S ),zSparse polynomial rings.     )annotations)Any)addmulltlegtge)reduce)GeneratorType)Expr)igcdoo)Symbolsymbols)CantSympifysympify)multinomial_coefficients)IPolys)construct_domain)dmp_to_dictdmp_from_dict)DomainElementPolynomialRingheugcd)MonomialOps)lex)CoercionFailedGeneratorsErrorExactQuotientFailedMultivariatePolynomialError)DomainOrderbuild_options)expr_from_dict_dict_reorder_parallel_dict_from_expr)DefaultPrinting)publicsubsets)is_sequence)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:`~.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   domainorder_ring r5   P/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/sympy/polys/rings.pyring#   s    r7   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'>

    r.   r1   r5   r5   r6   xringB   s    r8   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 r5   )name).0symr5   r5   r6   
<listcomp>}   s     zvring.<locals>.<listcomp>)r/   r-   r   r0   r1   r5   r5   r6   vringa   s    r=   c           
        s   d}t | s| gd } }ttt| } t||}t| |\}}|jdk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 r5   listvaluesr:   repr5   r5   r6   r<      s     zsring.<locals>.<listcomp>)optc                   s"   g | ]} fd d|  D qS )c                   s   i | ]\}}| | qS r5   r5   )r:   mcZ	coeff_mapr5   r6   
<dictcomp>   s      z$sring.<locals>.<listcomp>.<dictcomp>)itemsrA   rF   r5   r6   r<      s     r   )r,   r?   mapr   r%   r(   r2   sumr   dictzipr/   r0   r3   	from_dict)
exprsr   optionsZsinglerC   ZrepscoeffsZ
coeffs_domr4   polysr5   rF   r6   sring   s     

rR   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)seqr5   c                 s  s   | ]}t |tV  qd S N)
isinstancestrr:   sr5   r5   r6   	<genexpr>   s     z!_parse_symbols.<locals>.<genexpr>c                 s  s   | ]}t |tV  qd S rT   )rU   r   rW   r5   r5   r6   rY      s     zbexpected a string, Symbol or expression or a non-empty sequence of strings, Symbols or expressions)rU   rV   _symbolsr   r,   allr    r   r5   r5   r6   _parse_symbols   s    

r]   zdict[Any, Any]_ring_cachec                   @  s@  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dGddZdd Zedd Zedd ZdHddZdd Zdd Zdd  ZeZdId!d"ZdJd#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'dEdF Z(dS )Kr/   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rt.|_/n fdd|_/t0|j|jD ]4\}	}
t1|	t2r|	j3}t4||st5|||
 q|t|< |S )	Nz7polynomial ring and it's ground domain share generatorsPolyElementr7   r   c                 S  s   dS Nr5   r5   )abr5   r5   r6   <lambda>       z"PolyRing.__new__.<locals>.<lambda>c                 S  s   dS ra   r5   )rb   rc   rE   r5   r5   r6   rd      re   c                   s   t |  dS )Nkey)maxfr3   r5   r6   rd      re   )6tupler]   len	DomainOpt
preprocessOrderOpt__name__r^   getis_Compositesetr   r    object__new___hash_tuplehash_hashtyper_   dtypengensr2   r3   
zero_monom_gensr0   	_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   rh   leading_expvrL   rU   r   r9   hasattrsetattr)clsr   r2   r3   r|   rw   objZcodegenZmonunitsymbol	generatorr9   r5   rk   r6   rv      s`    















zPolyRing.__new__c                 C  sF   | j j}g }t| jD ]&}| |}| j}|||< || qt|S )z(Return a list of polynomial generators. )r2   r   ranger|   monomial_basiszeroappendrl   )selfr   r~   iexpvpolyr5   r5   r6   r~     s    
zPolyRing._gensc                 C  s   | j | j| jfS rT   )r   r2   r3   r   r5   r5   r6   __getnewargs__  s    zPolyRing.__getnewargs__c                 C  s6   | j  }|d= | D ]\}}|dr||= q|S )Nr   Z	monomial_)__dict__copyrH   
startswith)r   staterg   valuer5   r5   r6   __getstate__  s    

zPolyRing.__getstate__c                 C  s   | j S rT   )ry   r   r5   r5   r6   __hash__   s    zPolyRing.__hash__c                 C  s2   t |to0| j| j| j| jf|j|j|j|jfkS rT   )rU   r/   r   r2   r|   r3   r   otherr5   r5   r6   __eq__#  s
    
zPolyRing.__eq__c                 C  s
   | |k S rT   r5   r   r5   r5   r6   __ne__(  s    zPolyRing.__ne__Nc                 C  s    |  |p| j|p| j|p| jS rT   )	__class__r   r2   r3   )r   r   r2   r3   r5   r5   r6   clone+  s    zPolyRing.clonec                 C  s   dg| j  }d||< t|S )zReturn the ith-basis element. r      )r|   rl   )r   r   Zbasisr5   r5   r6   r   .  s    zPolyRing.monomial_basisc                 C  s   |   S rT   )r{   r   r5   r5   r6   r   4  s    zPolyRing.zeroc                 C  s   |  | jS rT   )r{   r   r   r5   r5   r6   r   8  s    zPolyRing.onec                 C  s   | j ||S rT   )r2   convertr   elementorig_domainr5   r5   r6   
domain_new<  s    zPolyRing.domain_newc                 C  s   |  | j|S rT   )term_newr}   )r   coeffr5   r5   r6   
ground_new?  s    zPolyRing.ground_newc                 C  s    |  |}| j}|r|||< |S rT   )r   r   )r   monomr   r   r5   r5   r6   r   B  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njt |trn| 	|S t |t
rz| |W S  tk
r   | | Y S X nt |tr| |S | |S d S )N
conversionZparsing)rU   r_   r7   r2   r   r   NotImplementedErrorrV   rK   rM   r?   
from_terms
ValueError	from_listr   	from_exprr   r   r5   r5   r6   ring_newI  s$    










zPolyRing.ring_newc                 C  s8   | j }| j}| D ]\}}|||}|r|||< q|S rT   )r   r   rH   )r   r   r   r   r   r   r   r5   r5   r6   rM   a  s    

zPolyRing.from_dictc                 C  s   |  t||S rT   )rM   rK   r   r5   r5   r6   r   l  s    zPolyRing.from_termsc                 C  s   |  t|| jd | jS Nr   )rM   r   r|   r2   r   r5   r5   r6   r   o  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
rx|dkrx |t| S | S d S r   )rr   Zis_Addr
   r   r?   rI   argsZis_Mulr   Zas_base_expZ
is_Integerintr   r   )exprr   baseexp_rebuildr2   mappingr   r5   r6   r   u  s    
z(PolyRing._rebuild_expr.<locals>._rebuild)r2   r   )r   r   r   r5   r   r6   _rebuild_exprr  s    zPolyRing._rebuild_exprc                 C  sZ   t tt| j| j}z| ||}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)	rK   r?   rL   r   r0   r   r   r   r   )r   r   r   r   r5   r5   r6   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rz| j|}W q tk
r   td| Y qX nJt|trz| 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)	r|   rU   r   r   r{   r0   indexrV   r   )r   genr   r5   r5   r6   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 r5   r5   r:   r   rX   indicesr5   r6   r<     s      z!PolyRing.drop.<locals>.<listcomp>r\   N)rt   rI   r   	enumerater   r2   r   r   r0   r   r5   r   r6   drop  s
    zPolyRing.dropc                 C  s$   | j | }|s| jS | j|dS d S )Nr\   )r   r2   r   )r   rg   r   r5   r5   r6   __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 )Nr2   r2   z%s is not a composite domain)r2   rs   r   r   r   r   r5   r5   r6   	to_ground  s    zPolyRing.to_groundc                 C  s   t | S rT   r   r   r5   r5   r6   	to_domain  s    zPolyRing.to_domainc                 C  s   ddl m} || j| j| jS )Nr   )	FracField)Zsympy.polys.fieldsr   r   r2   r3   )r   r   r5   r5   r6   to_field  s    zPolyRing.to_fieldc                 C  s   t | jdkS r   rm   r0   r   r5   r5   r6   is_univariate  s    zPolyRing.is_univariatec                 C  s   t | jdkS r   r   r   r5   r5   r6   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   Zobjspr   r5   r5   r6   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   r5   r5   r6   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 r5   r5   r   r   r5   r6   r<     s      z+PolyRing.drop_to_ground.<locals>.<listcomp>c                   s   g | ]\}}| kr|qS r5   r5   )r:   r   r   r   r5   r6   r<     s      r   r2   N)rt   rI   r   r   r   r0   r   r   r   r5   r   r6   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rt   r   unionr   r?   )r   r   symsr5   r5   r6   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   r5   r5   r6   add_gens&  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 | kV  qd S rT   )r   r:   r   rX   r5   r6   rY   7  s     z*PolyRing.symmetric_poly.<locals>.<genexpr>N)r|   r   r0   r   r   r+   r   r   rl   r   r2   )r   nr   r   r5   r   r6   symmetric_poly+  s    zPolyRing.symmetric_poly)NNN)N)N)N))rq   
__module____qualname____doc__r   rv   r~   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   __call__rM   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r5   r5   r5   r6   r/      sP   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| ZBeAZCeBZDd}d~ ZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdddZLdd ZMdddZNdd ZOdd ZPdd ZQdd ZRdd ZSedd ZTedd ZUdd ZVedd ZWdd ZXdd ZYdddZZd ddZ[d!ddZ\dd Z]dd Z^dd Z_dd Z`dd Zadd Zbdd Zcdd Zddd Zedd Zfdd ZgddĄ ZhddƄ ZiddȄ Zjddʄ Zkdd̄ ZlelZmdd΄ ZnddЄ Zodd҄ ZpddԄ Zqddք Zrdd؄ Zsddڄ Ztdd܄ Zuddބ Zvdd Zwdd Zxdd Zydd Zzdd Z{dd Z|dd Z}dd Z~dd Zd"ddZd#ddZdd Zd$dd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 Zdd Zd%ddZdd ZdS (&  r_   z5Element of multivariate distributed polynomial ring. c                 C  s
   |  |S rT   )r   )r   initr5   r5   r6   new?  s    zPolyElement.newc                 C  s
   | j  S rT   )r7   r   r   r5   r5   r6   parentB  s    zPolyElement.parentc                 C  s   | j t|  fS rT   )r7   r?   	itertermsr   r5   r5   r6   r   E  s    zPolyElement.__getnewargs__Nc                 C  s.   | j }|d kr*t| jt|  f | _ }|S rT   )ry   rx   r7   	frozensetrH   )r   ry   r5   r5   r6   r   J  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   r5   r5   r6   r   U  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 rT   )r7   r   r?   rL   r'   r   r2   rM   )r   new_ringtermsr5   r5   r6   set_ringq  s    
zPolyElement.set_ringc                 G  sH   |s| j j}n(t|| j jkr6td| j jt|f t|  f| S )Nz+Wrong number of symbols, expected %s got %s)r7   r   rm   r|   r   r&   as_expr_dict)r   r   r5   r5   r6   as_exprz  s    
zPolyElement.as_exprc                   s    | j jj  fdd|  D S )Nc                   s   i | ]\}}| |qS r5   r5   r:   r   r   to_sympyr5   r6   rG     s      z,PolyElement.as_expr_dict.<locals>.<dictcomp>)r7   r2   r   r   r   r5   r   r6   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 r5   r5   )r:   kvcommonr5   r6   r<     s     z,PolyElement.clear_denoms.<locals>.<listcomp>)r7   r2   is_Fieldhas_assoc_Ringr   get_ringr   denomr@   r   rH   )r   r2   Zground_ringr   r   r   r   r5   r   r6   clear_denoms  s    
zPolyElement.clear_denomsc                 C  s$   t |  D ]\}}|s| |= qdS )z+Eliminate monomials with zero coefficient. Nr?   rH   )r   r   r   r5   r5   r6   
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)rU   r_   r7   rK   r   rm   rr   r}   p1p2r5   r5   r6   r     s    zPolyElement.__eq__c                 C  s
   | |k S rT   r5   r  r5   r5   r6   r     s    zPolyElement.__ne__c                 C  s   | j }t||jrbt|  t| kr.dS |jj}|  D ]}|| | || |s> dS q>dS t| dkrrdS z|j|}W n t	k
r   Y dS X |j| 
 ||S dS )z+Approximate equality test for polynomials. FTr   N)r7   rU   r{   rt   keysr2   almosteqrm   r   r   const)r  r  Z	tolerancer7   r  r   r5   r5   r6   r    s     zPolyElement.almosteqc                 C  s   t | |  fS rT   )rm   r   r   r5   r5   r6   sort_key  s    zPolyElement.sort_keyc                 C  s(   t || jjr ||  | S tS d S rT   )rU   r7   r{   r
  NotImplemented)r  r  opr5   r5   r6   _cmp  s    zPolyElement._cmpc                 C  s   |  |tS rT   )r  r   r  r5   r5   r6   __lt__  s    zPolyElement.__lt__c                 C  s   |  |tS rT   )r  r   r  r5   r5   r6   __le__  s    zPolyElement.__le__c                 C  s   |  |tS rT   )r  r   r  r5   r5   r6   __gt__  s    zPolyElement.__gt__c                 C  s   |  |tS rT   )r  r	   r  r5   r5   r6   __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\   )r7   r   r|   r2   r?   r   r   r   r   r7   r   r   r5   r5   r6   _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  r7   r|   	is_groundr   r   r   rH   r?   rl   )r   r   r   r7   r   r   r   Kr5   r5   r6   r     s    
zPolyElement.dropc                 C  s6   | j }||}t|j}||= ||j||| dfS )Nr   )r7   r   r?   r   r   r  r5   r5   r6   _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   }||kr|||  |||< q<||  |||  |7  < q<|S )Nr   z$Cannot drop only generator to groundr   )	r7   r|   r   r  r   r2   r0   r   
mul_ground)r   r   r   r7   r   r   r   monr5   r5   r6   r     s     zPolyElement.drop_to_groundc                 C  s   t | | jjd | jjS r   )r   r7   r|   r2   r   r5   r5   r6   to_dense   s    zPolyElement.to_densec                 C  s   t | S rT   )rK   r   r5   r5   r6   to_dict#  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kr|d
}|dkr|d
d d	|S )NZMulZAtom -  + -r   T)strict r   Fz%s)r  r  )Z_printr7   r2   r   r   r|   r}   r   is_negativer   r   r   Zparenthesizer   r   joinpopinsert)r   printer
precedenceZexp_patternZ
mul_symbolZprec_mulZ	prec_atomr7   r   r|   zmZsexpvsr   r   negativesignZscoeffZsexpvr   r   r   Zsexpheadr5   r5   r6   rV   &  sT    





zPolyElement.strc                 C  s   | | j jkS rT   )r7   r   r   r5   r5   r6   is_generatorV  s    zPolyElement.is_generatorc                 C  s   |  pt | dko| jj| kS r   )rm   r7   r}   r   r5   r5   r6   r  Z  s    zPolyElement.is_groundc                 C  s   |  pt | dko| jdkS r   )rm   LCr   r5   r5   r6   is_monomial^  s    zPolyElement.is_monomialc                 C  s   t | dkS r   )rm   r   r5   r5   r6   is_termb  s    zPolyElement.is_termc                 C  s   | j j| jS rT   )r7   r2   r   r+  r   r5   r5   r6   r   f  s    zPolyElement.is_negativec                 C  s   | j j| jS rT   )r7   r2   is_positiver+  r   r5   r5   r6   r.  j  s    zPolyElement.is_positivec                 C  s   | j j| jS rT   )r7   r2   is_nonnegativer+  r   r5   r5   r6   r/  n  s    zPolyElement.is_nonnegativec                 C  s   | j j| jS rT   )r7   r2   is_nonpositiver+  r   r5   r5   r6   r0  r  s    zPolyElement.is_nonpositivec                 C  s   |  S rT   r5   ri   r5   r5   r6   is_zerov  s    zPolyElement.is_zeroc                 C  s   | | j jkS rT   )r7   r   ri   r5   r5   r6   is_onez  s    zPolyElement.is_onec                 C  s   | j j| jS rT   )r7   r2   r2  r+  ri   r5   r5   r6   is_monic~  s    zPolyElement.is_monicc                 C  s   | j j|  S rT   )r7   r2   r2  contentri   r5   r5   r6   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rJ   r:   r   r5   r5   r6   rY     s     z(PolyElement.is_linear.<locals>.<genexpr>r[   
itermonomsri   r5   r5   r6   	is_linear  s    zPolyElement.is_linearc                 C  s   t dd |  D S )Nc                 s  s   | ]}t |d kV  qdS )   Nr7  r8  r5   r5   r6   rY     s     z+PolyElement.is_quadratic.<locals>.<genexpr>r9  ri   r5   r5   r6   is_quadratic  s    zPolyElement.is_quadraticc                 C  s   | j jsdS | j | S NT)r7   r|   Z	dmp_sqf_pri   r5   r5   r6   is_squarefree  s    zPolyElement.is_squarefreec                 C  s   | j jsdS | j | S r>  )r7   r|   Zdmp_irreducible_pri   r5   r5   r6   is_irreducible  s    zPolyElement.is_irreduciblec                 C  s    | j jr| j | S tdd S )Nzcyclotomic polynomial)r7   r   Zdup_cyclotomic_pr"   ri   r5   r5   r6   is_cyclotomic  s    zPolyElement.is_cyclotomicc                 C  s   |  dd |  D S )Nc                 S  s   g | ]\}}|| fqS r5   r5   r   r5   r5   r6   r<     s     z'PolyElement.__neg__.<locals>.<listcomp>)r   r   r   r5   r5   r6   __neg__  s    zPolyElement.__neg__c                 C  s   | S rT   r5   r   r5   r5   r6   __pos__  s    zPolyElement.__pos__c           
      C  sB  |s|   S | j}t||jrl|   }|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k
r   t Y 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   r7   rU   r{   rr   r2   r   rH   r_   r   __radd__r  r   r   r}   r  )
r  r  r7   r   rr   r   r   r   Zcp2r&  r5   r5   r6   __add__  sB    




zPolyElement.__add__c                 C  s   |   }|s|S | j}z||}W n tk
r<   t Y S X |j}||  krZ|||< n&|||  krp||= n||  |7  < |S d S rT   )r   r7   r   r   r  r}   r  )r  r   r   r7   r&  r5   r5   r6   rD    s    

zPolyElement.__radd__c           	      C  s:  |s|   S | j}t||jrl|   }|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k
r   t Y 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   r7   rU   r{   rr   r2   r   rH   r_   r   __rsub__r  r   r   r}   r  )	r  r  r7   r   rr   r   r   r   r&  r5   r5   r6   __sub__  s>    



zPolyElement.__sub__c                 C  s\   | j }z||}W n tk
r,   t Y S X |j}| D ]}| |  ||< q8||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)r7   r   r   r  r   )r  r   r7   r   r   r5   r5   r6   rF  '  s    
zPolyElement.__rsub__c                 C  s<  | j }|j}| r|s|S t||jr|j}|jj}|j}t| }|  D ]6\}}	|D ](\}
}|||
}||||	|  ||< qXqL|	  |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k
r   t Y S X |  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)r7   r   rU   r{   rr   r2   r   r?   rH   r  r_   r   __rmul__r  r   r   )r  r  r7   r   rr   r   r   Zp2itexp1v1Zexp2Zv2r   r   r5   r5   r6   __mul__B  s<    



zPolyElement.__mul__c                 C  sh   | j j}|s|S z|j |}W n tk
r8   t Y S X |  D ]\}}|| }|rB|||< qB|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)r7   r   r   r   r  rH   )r  r  r   rI  rJ  r   r5   r5   r6   rH  t  s    

zPolyElement.__rmul__c                 C  s   | j }|s| r|jS tdn\t| dkrzt|  d \}}|j}||jjkrb|||||< 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)r7   r   r   rm   r?   rH   r   r2   r   r   r   square_pow_multinomial_pow_generic)r   r   r7   r   r   r   r5   r5   r6   __pow__  s0    


zPolyElement.__pow__c                 C  s@   | j j}| }|d@ r*|| }|d8 }|s*q<| }|d }q|S )Nr   r<  )r7   r   rN  )r   r   r   rE   r5   r5   r6   rP    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@||kr@||= q@|S rT   )r   rm   rH   r7   r   r}   r2   r   rL   rl   rr   )r   r   Zmultinomialsr   r}   r   r   r   ZmultinomialZmultinomial_coeffZproduct_monomZproduct_coeffr   r   r   r5   r5   r6   rO    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

        r<  )r7   r   rr   r?   r  r2   r   r   rm   imul_numrH   r  )r   r7   r   rr   r  r   r   r   Zk1pkjZk2r   r   r   r5   r5   r6   rN    s(    


zPolyElement.squarec                 C  s   | j }|stdnft||jr*| |S t|trzt|jtrP|jj |j krPn*t|j jtrv|j jj |krv|| S t	S z|
|}W n tk
r   t	 Y S X | || |fS d S Npolynomial division)r7   ZeroDivisionErrorrU   r{   r   r_   r2   r   __rdivmod__r  r   r   
quo_ground
rem_groundr  r  r7   r5   r5   r6   
__divmod__  s     




zPolyElement.__divmod__c                 C  s   t S rT   r  r  r5   r5   r6   rX  (  s    zPolyElement.__rdivmod__c                 C  s   | j }|stdnft||jr*| |S t|trzt|jtrP|jj |j krPn*t|j jtrv|j jj |krv|| S t	S z|
|}W n tk
r   t	 Y S X | |S d S rU  )r7   rW  rU   r{   remr_   r2   r   __rmod__r  r   r   rZ  r[  r5   r5   r6   __mod__+  s     




zPolyElement.__mod__c                 C  s   t S rT   r]  r  r5   r5   r6   r_  A  s    zPolyElement.__rmod__c                 C  s   | j }|stdnzt||jr>|jr2| |d  S | |S nPt|trt|jtrd|jj |j krdn*t|j jtr|j jj |kr|	| S t
S z||}W n tk
r   t
 Y S X | |S d S )NrV  r   )r7   rW  rU   r{   r,  quor_   r2   r   __rtruediv__r  r   r   rY  r[  r5   r5   r6   __truediv__D  s$    



zPolyElement.__truediv__c                 C  s   t S rT   r]  r  r5   r5   r6   rb  ]  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 rT   r5   Z	a_lm_a_lcZ	b_lm_b_lcZa_lmZa_lcZb_lmZb_lcr   Z
domain_quor   r&  r5   r6   term_divl  s    
z'PolyElement._term_div.<locals>.term_divc                   sN   | \}}|\}}|kr|}n
||}|d ksF|| sF| ||fS d S d S rT   r5   rd  re  r5   r6   rf  x  s    
)r7   r}   r2   ra  r   r   )r   r2   rf  r5   re  r6   	_term_dive  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	k	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

        FTrV  z"self and f must have the same ringc                   s   g | ]
} j qS r5   )r   r   r7   r5   r6   r<     s     z#PolyElement.div.<locals>.<listcomp>c                 S  s   g | ]}|  qS r5   )r   )r:   Zfxr5   r5   r6   r<     s     r   Nr   )r7   rU   r_   r[   rW  r   r   rm   r   r   rg  r   _iadd_monom_iadd_poly_monomr}   )r   ZfvZ
ret_singlerj   rX   Zqvr   rrf  Zexpvsr   Zdivoccurredr   termZexpv1rE   r5   rh  r6   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 k	rh|\}}| D ]8\}}|||}|
||||  }|s||= q|||< q| }|d k	r||| f}	 q^qh|	\}}||kr||  |7  < n|||< ||= | }|d k	r^||| f}	q^|S rU  )rU   r_   r[   rW  r7   r2   r   r   rg  LTr   rr   r   r   )r   Grj   r7   r2   r   r   rk  rf  Zltfrr   gZtqrD   rE   mgcgm1c1ZltmZltcr5   r5   r6   r^    sL    



zPolyElement.remc                 C  s   |  |d S Nr   )r   )rj   rn  r5   r5   r6   ra    s    zPolyElement.quoc                 C  s$   |  |\}}|s|S t| |d S rT   )r   r!   )rj   rn  qrk  r5   r5   r6   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)r7   r   r   rr   )r   mcZcpselfr   r   rE   r5   r5   r6   ri  
  s    



zPolyElement._iadd_monomc                 C  s~   | }||j jk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

        )r7   r   r   rr   r2   r   r   rH   )r   r  rw  r  rD   rE   rr   r   r   r   r   kar   r5   r5   r6   rj  6  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 r5   r5   r8  r   r5   r6   r<   i  s     z&PolyElement.degree.<locals>.<listcomp>N)r7   r   r   rh   r:  rj   xr5   ry  r6   degree[  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   r7   r|   rl   rI   rh   r?   rL   r:  ri   r5   r5   r6   degreesk  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 r5   r5   r8  ry  r5   r6   r<     s     z+PolyElement.tail_degree.<locals>.<listcomp>N)r7   r   r   minr:  rz  r5   ry  r6   tail_degreew  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   r7   r|   rl   rI   r~  r?   rL   r:  ri   r5   r5   r6   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)r7   r   r   r5   r5   r6   r     s    zPolyElement.leading_expvc                 C  s   |  || jjjS rT   )rr   r7   r2   r   r   r   r5   r5   r6   
_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)r  r7   r}   rU   r{   r?   r   rm   r2   r   r   )r   r   r   r   r   r5   r5   r6   r     s    
zPolyElement.coeffc                 C  s   |  | jjS )z"Returns the constant coefficient. )r  r7   r}   r   r5   r5   r6   r	    s    zPolyElement.constc                 C  s   |  |  S rT   )r  r   r   r5   r5   r6   r+    s    zPolyElement.LCc                 C  s    |   }|d kr| jjS |S d S rT   )r   r7   r}   r  r5   r5   r6   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

        )r7   r   r   r2   r   r   r   r   r5   r5   r6   leading_monom  s
    zPolyElement.leading_monomc                 C  s4   |   }|d kr"| jj| jjjfS || |fS d S rT   )r   r7   r}   r2   r   r  r  r5   r5   r6   rm    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)r7   r   r   r  r5   r5   r6   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 rt  r5   r   r5   r5   r6   rd     re   z%PolyElement._sorted.<locals>.<lambda>T)rg   reversec                   s    | d S rt  r5   r  rk   r5   r6   rd     re   )r7   r3   rp   ro   r   sorted)r   rS   r3   r5   rk   r6   _sorted  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 r5   r5   )r:   _r   r5   r5   r6   r<   3  s     z&PolyElement.coeffs.<locals>.<listcomp>r   r   r3   r5   r5   r6   rP     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 r5   r5   )r:   r   r  r5   r5   r6   r<   M  s     z&PolyElement.monoms.<locals>.<listcomp>r  r  r5   r5   r6   monoms5  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  r?   rH   r  r5   r5   r6   r   O  s    zPolyElement.termsc                 C  s   t |  S )z,Iterator over coefficients of a polynomial. )iterr@   r   r5   r5   r6   
itercoeffsi  s    zPolyElement.itercoeffsc                 C  s   t |  S )z)Iterator over monomials of a polynomial. )r  r  r   r5   r5   r6   r:  m  s    zPolyElement.itermonomsc                 C  s   t |  S )z%Iterator over terms of a polynomial. )r  rH   r   r5   r5   r6   r   q  s    zPolyElement.itertermsc                 C  s   t |  S )z+Unordered list of polynomial coefficients. r>   r   r5   r5   r6   
listcoeffsu  s    zPolyElement.listcoeffsc                 C  s   t |  S )z(Unordered list of polynomial monomials. )r?   r  r   r5   r5   r6   
listmonomsy  s    zPolyElement.listmonomsc                 C  s   t |  S )z$Unordered list of polynomial terms. r  r   r5   r5   r6   	listterms}  s    zPolyElement.listtermsc                 C  sB   | | j jk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)r7   r   clear)r   rE   r   r5   r5   r6   rR    s    zPolyElement.imul_numc                 C  s0   | j j}|j}|j}|  D ]}|||}q|S )z*Returns GCD of polynomial's coefficients. )r7   r2   r   r   r  )rj   r2   contr   r   r5   r5   r6   r4    s    zPolyElement.contentc                 C  s   |   }|| |fS )z,Returns content and a primitive polynomial. )r4  rY  )rj   r  r5   r5   r6   	primitive  s    zPolyElement.primitivec                 C  s   | s| S |  | jS dS )z5Divides all coefficients by the leading coefficient. N)rY  r+  ri   r5   r5   r6   monic  s    zPolyElement.monicc                   s,    s| j jS  fdd|  D }| |S )Nc                   s   g | ]\}}||  fqS r5   r5   r   r{  r5   r6   r<     s     z*PolyElement.mul_ground.<locals>.<listcomp>)r7   r   r   r   )rj   r{  r   r5   r  r6   r    s    zPolyElement.mul_groundc                   s*   | j j fdd|  D }| |S )Nc                   s   g | ]\}}| |fqS r5   r5   r:   Zf_monomZf_coeffr   r   r5   r6   r<     s     z)PolyElement.mul_monom.<locals>.<listcomp>)r7   r   rH   r   )rj   r   r   r5   r  r6   	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 r5   r5   r  r   r   r   r5   r6   r<     s     z(PolyElement.mul_term.<locals>.<listcomp>)r7   r   r}   r  r   rH   r   )rj   rl  r   r5   r  r6   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 )NrV  c                   s   g | ]\}}| |fqS r5   r5   r   ra  r{  r5   r6   r<     s     z*PolyElement.quo_ground.<locals>.<listcomp>c                   s$   g | ]\}}|  s||  fqS r5   r5   r   r  r5   r6   r<     s      )r7   r2   rW  r   r   ra  r   r   )rj   r{  r2   r   r5   r  r6   rY    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 )NrV  c                   s   g | ]}| qS r5   r5   r:   trl  rf  r5   r6   r<     s     z(PolyElement.quo_term.<locals>.<listcomp>c                 S  s   g | ]}|d k	r|qS rT   r5   r  r5   r5   r6   r<     s      )rW  r7   r   r}   rY  rg  r   r   )rj   rl  r   r   r   r5   r  r6   quo_term  s    

zPolyElement.quo_termc                   sx   | j jjrLg }|  D ]2\}}|  }| d kr:|  }|||f qn fdd|  D }| |}|  |S )Nr<  c                   s   g | ]\}}||  fqS r5   r5   r   r   r5   r6   r<     s     z,PolyElement.trunc_ground.<locals>.<listcomp>)r7   r2   is_ZZr   r   r   r  )rj   r   r   r   r   r   r5   r  r6   trunc_ground  s    

zPolyElement.trunc_groundc                 C  sB   | }|  }|  }|jj||}||}||}|||fS rT   )r4  r7   r2   r   rY  )r   ro  rj   fcgcr   r5   r5   r6   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 r5   r5   )r:   r   Z
ground_absr5   r6   r<     s     z%PolyElement._norm.<locals>.<listcomp>)r7   r2   r   absr  )rj   Z	norm_funcr5   r  r6   _norm  s    

zPolyElement._normc                 C  s
   |  tS rT   )r  rh   ri   r5   r5   r6   max_norm  s    zPolyElement.max_normc                 C  s
   |  tS rT   )r  rJ   ri   r5   r5   r6   l1_norm  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 r6  r5   )r:   rc   r5   r5   r6   rY   0  s     z&PolyElement.deflate.<locals>.<genexpr>c                 S  s   g | ]\}}|| qS r5   r5   r:   r   rT  r5   r5   r6   r<   9  s     z'PolyElement.deflate.<locals>.<listcomp>)r7   r?   r|   r:  r   r   rl   r[   r   r   rL   r   )rj   rn  r7   rQ   Jr   r   r   rD   rc   HhIr   Nr5   r5   r6   deflate  s*    
zPolyElement.deflatec                 C  s>   | j j}|  D ](\}}dd t||D }||t|< q|S )Nc                 S  s   g | ]\}}|| qS r5   r5   r  r5   r5   r6   r<   D  s     z'PolyElement.inflate.<locals>.<listcomp>)r7   r   r   rL   rl   )rj   r  r   r  r   r  r5   r5   r6   inflate@  s
    zPolyElement.inflatec                 C  sf   | }|j j}|js6| \}}| \}}|||}|| ||}|jsZ||S | S d S rT   )	r7   r2   r   r  r   ra  r   r  r  )r   ro  rj   r2   r  r  rE   r  r5   r5   r6   r   I  s    
zPolyElement.lcmc                 C  s   |  |d S rt  )	cofactorsrj   ro  r5   r5   r6   r   Y  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   )r7   r   	_gcd_zerorm   
_gcd_monomr  _gcdr  )rj   ro  r   r  cffcfgr  r5   r5   r6   r  \  s$    




zPolyElement.cofactorsc                 C  s4   | j j| j j }}|jr"|||fS | || fS d S rT   )r7   r   r   r/  )rj   ro  r   r   r5   r5   r6   r  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 r5   r5   )r:   rp  rq  Z_cgcdZ_mgcdZ
ground_quor   r5   r6   r<     s     z*PolyElement._gcd_monom.<locals>.<listcomp>)	r7   r2   r   ra  r   r   r?   r   r   )rj   ro  r7   Z
ground_gcdr   mfcfrp  rq  r  r  r  r5   r  r6   r  y  s    

"zPolyElement._gcd_monomc                 C  s:   | j }|jjr| |S |jjr*| |S || |S d S rT   )r7   r2   Zis_QQ_gcd_QQr  _gcd_ZZZdmp_inner_gcd)rj   ro  r7   r5   r5   r6   r    s    

zPolyElement._gcdc                 C  s
   t | |S rT   r   r  r5   r5   r6   r    s    zPolyElement._gcd_ZZc                 C  s   | }|j }|j|j d}| \}}| \}}||}||}||\}}}	||}|j|  }
}||	|j
|
|}|	|	|j
|
|}	|||	fS )Nr   )r7   r   r2   r   r  r   r  r+  r  r  ra  )r   ro  rj   r7   r   r  rq  r  r  r  rE   r5   r5   r6   r    s    


zPolyElement._gcd_QQc                 C  s  | }|j }|s||jfS |j}|jr*|js<||\}}}n|j| d}| \}	}| \}
}|	|}|	|}||\}}}|j|
|	\}}
}	|	|}|	|}|
|
}|
|	}| }||jkr|| }}n2||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   )r7   r   r2   r   r   r  r   r   r  r   r  canonical_unit)r   ro  rj   r7   r2   r  r   ru  r   Zcqcpur5   r5   r6   cancel  s4    









zPolyElement.cancelc                 C  s   | j j}|| jS rT   )r7   r2   r  r+  )rj   r2   r5   r5   r6   r    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

        )r7   r   r   r   r   r   r   )	rj   r{  r7   r   rD   ro  r   r   er5   r5   r6   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)rm   r7   r|   evaluater?   rL   r0   r   )rj   r@   r5   r5   r6   r    	  s     zPolyElement.__call__c                   sH  | }t |tr`|d k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    }}
|||  }|
|	kr2||	|
  }|r*||	|
< n|	|
= q|r||	|
< q|	S d S )Nr   r   c                   s   g | ]\}}|  |fqS r5   )r   )r:   Yrb   Xr5   r6   r<   	  s     z(PolyElement.evaluate.<locals>.<listcomp>)rU   r?   r  r7   r   r2   r   r|   r   r   r   )r   r{  rb   rj   r7   r   resultr   r   r   r   r5   r  r6   r  	  s8    


&


zPolyElement.evaluatec                 C  s   | }t |tr4|d kr4|D ]\}}|||}q|S |j}||}|j|}|jdkr|jj}|	 D ]\\}}	||	||  7 }qj|
|S |j}
|	 D ]x\}}	|| |d | d ||d d    }}|	||  }	||
kr
|	|
|  }	|	r|	|
|< n|
|= q|	r|	|
|< q|
S d S )Nr   r`   )rU   r?   subsr7   r   r2   r   r|   r   r   r   )r   r{  rb   rj   r  r7   r   r  r   r   r   r   r5   r5   r6   r  2	  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   rh  r5   r6   r<   	  s     z*PolyElement.symmetrize.<locals>.<listcomp>c                   s,   | |f kr |  |  | |f<  | |f S rT   r5   )r   r   )poly_powersrQ   r5   r6   get_poly_power	  s    z.PolyElement.symmetrize.<locals>.get_poly_powerr   r   r   )r   NNc                 3  s"   | ]} |  |d   kV  qdS r6  r5   r   r  r5   r6   rY   	  s     z)PolyElement.symmetrize.<locals>.<genexpr>c                 S  s   g | ]\}}|| qS r5   r5   )r:   r   rD   r5   r5   r6   r<   	  s     Nr`   )r   r7   r|   r   r   r?   r   r   r[   rh   rL   r   r   rl   r0   )r   rj   r   r  r   weightsZ	symmetric_heightZ_monomZ_coeffr   r   heightZ	exponentsrr  m2productr   r5   )r   r  rQ   r7   r6   
symmetrizeY	  s>    ;

zPolyElement.symmetrizec                   s  | j }|j}tt|jt|j |d k	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 rt  r5   )r   Zgens_mapr5   r6   rd   	  re   z%PolyElement.compose.<locals>.<lambda>rf   z9expected a generator, value pair a sequence of such pairsr   )r7   r   rK   rL   r0   r   r|   rU   r?   r  rH   r   r   r   r   r   r  rl   )rj   r{  rb   r7   r   Zreplacementsr   ro  r   r   Zsubpolyr   r   r5   r  r6   r   	  s,    



zPolyElement.composec                 C  s   | j | |S rT   )r7   Zdmp_pdivr  r5   r5   r6   pdiv	  s    zPolyElement.pdivc                 C  s   | j | |S rT   )r7   Zdmp_premr  r5   r5   r6   prem	  s    zPolyElement.premc                 C  s   | j | |S rT   )r7   Zdmp_quor  r5   r5   r6   pquo	  s    zPolyElement.pquoc                 C  s   | j | |S rT   )r7   Z	dmp_exquor  r5   r5   r6   pexquo	  s    zPolyElement.pexquoc                 C  s   | j | |S rT   )r7   Zdmp_half_gcdexr  r5   r5   r6   
half_gcdex	  s    zPolyElement.half_gcdexc                 C  s   | j | |S rT   )r7   Z	dmp_gcdexr  r5   r5   r6   gcdex	  s    zPolyElement.gcdexc                 C  s   | j | |S rT   )r7   Zdmp_subresultantsr  r5   r5   r6   subresultants	  s    zPolyElement.subresultantsc                 C  s   | j | |S rT   )r7   Zdmp_resultantr  r5   r5   r6   	resultant	  s    zPolyElement.resultantc                 C  s   | j | S rT   )r7   Zdmp_discriminantri   r5   r5   r6   discriminant
  s    zPolyElement.discriminantc                 C  s    | j jr| j | S tdd S )Nzpolynomial decomposition)r7   r   Zdup_decomposer"   ri   r5   r5   r6   	decompose
  s    zPolyElement.decomposec                 C  s"   | j jr| j | |S tdd S )Nzpolynomial shift)r7   r   Z	dup_shiftr"   )rj   rb   r5   r5   r6   shift

  s    zPolyElement.shiftc                 C  s    | j jr| j | S tdd S )Nzsturm sequence)r7   r   Z	dup_sturmr"   ri   r5   r5   r6   sturm
  s    zPolyElement.sturmc                 C  s   | j | S rT   )r7   Zdmp_gff_listri   r5   r5   r6   gff_list
  s    zPolyElement.gff_listc                 C  s   | j | S rT   )r7   Zdmp_sqf_normri   r5   r5   r6   sqf_norm
  s    zPolyElement.sqf_normc                 C  s   | j | S rT   )r7   Zdmp_sqf_partri   r5   r5   r6   sqf_part
  s    zPolyElement.sqf_partFc                 C  s   | j j| |dS )N)r[   )r7   Zdmp_sqf_list)rj   r[   r5   r5   r6   sqf_list
  s    zPolyElement.sqf_listc                 C  s   | j | S rT   )r7   Zdmp_factor_listri   r5   r5   r6   factor_list"
  s    zPolyElement.factor_list)N)N)N)N)N)N)N)N)N)F)rq   r   r   r   r   r   r   ry   r   r   r   r   r   r  r  r   r   r  r
  r  r  r  r  r  r  r   r  r   r  r  rV   r   r*  r  r,  r-  r   r.  r/  r0  r1  r2  r3  r5  r;  r=  r?  r@  rA  rB  rC  rE  rD  rG  rF  rK  rH  rQ  rP  rO  rN  r\  rX  r`  r_  rc  rb  __floordiv____rfloordiv__rg  r   r^  ra  rv  ri  rj  r|  r}  r  r  r   r  r   r	  r+  r  r  rm  r  r  rP   r  r   r  r:  r   r  r  r  rR  r4  r  r  r  r  r  rY  r  r  rZ  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  r5   r5   r5   r6   r_   <  sJ  	0
















6620$!L-,%%


#!	
8,'m#
r_   N)Qr   
__future__r   typingr   operatorr   r   r   r   r   r	   	functoolsr
   typesr   Zsympy.core.exprr   Zsympy.core.numbersr   r   Zsympy.core.symbolr   r   rZ   Zsympy.core.sympifyr   r   Zsympy.ntheory.multinomialr   Zsympy.polys.compatibilityr   Zsympy.polys.constructorr   Zsympy.polys.densebasicr   r   Z!sympy.polys.domains.domainelementr   Z"sympy.polys.domains.polynomialringr   Zsympy.polys.heuristicgcdr   Zsympy.polys.monomialsr   Zsympy.polys.orderingsr   Zsympy.polys.polyerrorsr   r    r!   r"   Zsympy.polys.polyoptionsr#   rn   r$   rp   r%   Zsympy.polys.polyutilsr&   r'   r(   Zsympy.printing.defaultsr)   Zsympy.utilitiesr*   r+   Zsympy.utilities.iterablesr,   Zsympy.utilities.magicr-   r7   r8   r=   rR   r]   r^   __annotations__r/   rK   r_   r5   r5   r5   r6   <module>   sN    
4  z