o
    8Va                    @   s  d Z ddlmZmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZ 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l0m1Z1m2Z2m3Z3m4Z4 ddl5m6Z7m8Z9m:Z: ddl;m<Z<m=Z=m>Z> ddl?m@Z@ ddlAmBZB ddlCmDZD eBe/fddZEeBe/fddZFeBe/fddZGeBd d! ZHd"d# ZIi ZJG d$d% d%e@e ZKG d&d' d'e'e@eeLZMd(S ))zSparse polynomial rings.     )AnyDict)addmulltlegtge)reduce)GeneratorType)is_sequence)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)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 r4   3/usr/lib/python3/dist-packages/sympy/polys/rings.pyring#   s   r6   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-   r0   r4   r4   r5   xringB   s   
r7   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 r4   )name).0Zsymr4   r4   r5   
<listcomp>}       zvring.<locals>.<listcomp>)r.   r,   r   r/   r0   r4   r4   r5   vringa   s   r<   c           
         s   d}t | s| gd} }ttt| } t||}t| |\}}|jdu rGt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 )	a  Construct a ring deriving generators and domain from options and input expressions.

    Parameters
    ==========

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

    Examples
    ========

    >>> from sympy.core import symbols
    >>> from sympy.polys.rings import sring

    >>> 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 r4   listvaluesr9   Zrepr4   r4   r5   r:          zsring.<locals>.<listcomp>)optc                    s"   g | ]} fd d|  D qS )c                    s   i | ]	\}}| | qS r4   r4   )r9   mcZ	coeff_mapr4   r5   
<dictcomp>       z$sring.<locals>.<listcomp>.<dictcomp>)itemsr@   rE   r4   r5   r:         " r   )r   r>   mapr   r&   r)   r1   sumr   dictzipr.   r/   r2   	from_dict)
Zexprsr   optionsZsinglerB   ZrepscoeffsZ
coeffs_domr3   polysr4   rE   r5   sring   s    

rR   c                 C   sn   t | tr| rt| ddS dS t | tr| fS t| r3tdd | D r(t| S tdd | D r3| S td)NT)seqr4   c                 s       | ]}t |tV  qd S N)
isinstancestrr9   sr4   r4   r5   	<genexpr>       z!_parse_symbols.<locals>.<genexpr>c                 s   rT   rU   )rV   r   rX   r4   r4   r5   rZ      r[   zbexpected a string, Symbol or expression or a non-empty sequence of strings, Symbols or expressions)rV   rW   _symbolsr   r   allr!   r   r4   r4   r5   _parse_symbols   s   

r_   c                   @   s8  e Zd ZdZefddZdd Zdd Zdd	 Zd
d Z	dd Z
dd ZdEddZdd Zedd Zedd ZdFddZdd Zdd Zdd  ZeZdFd!d"ZdFd#d$Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd1d2 Zd3d4 Zd5d6 Z ed7d8 Z!ed9d: Z"d;d< Z#d=d> Z$d?d@ Z%dAdB Z&dCdD Z'dS )Gr.   z*Multivariate distributed polynomial ring. c                    s  t t|}t|}t|}t  | j||| f}t|}|d u r|j	r5t
|t
|j@ r5tdt| }||_t||_tdtfd|i|_||_||_||_ |_d| |_| |_t
|j|_|j|jfg|_|rt|}| |_ |! |_"|# |_$|% |_&|' |_(|) |_*|+ |_,ndd }||_ ||_"dd |_$||_&||_(||_*||_, t-u rdd |_.n fd	d|_.t/|j|jD ]\}	}
t0|	t1r|	j2}t3||st4|||
 q|t|< |S )
Nz7polynomial ring and it's ground domain share generatorsPolyElementr6   r   c                 S      dS Nr4   r4   )abr4   r4   r5   <lambda>       z"PolyRing.__new__.<locals>.<lambda>c                 S   rb   rc   r4   )rd   re   rD   r4   r4   r5   rf      rg   c                 S      t | S rU   maxfr4   r4   r5   rf          c                    s   t |  dS )Nkeyri   rk   r2   r4   r5   rf          )5tupler_   len	DomainOpt
preprocessOrderOpt__name___ring_cachegetis_Compositesetr   r!   object__new___hash_tuplehash_hashtyper`   dtypengensr1   r2   
zero_monom_gensr/   	_gens_setone_oner   r   monomial_mulpowmonomial_powZmulpowmonomial_mulpowZldivmonomial_ldivdivmonomial_divlcmZmonomial_lcmgcdmonomial_gcdr   leading_expvrM   rV   r   r8   hasattrsetattr)clsr   r1   r2   r   r~   objZcodegenZmonunitsymbol	generatorr8   r4   rp   r5   r}      sb   















zPolyRing.__new__c                 C   sF   | j j}g }t| jD ]}| |}| j}|||< || qt|S )z(Return a list of polynomial generators. )r1   r   ranger   monomial_basiszeroappendrr   )selfr   r   iexpvpolyr4   r4   r5   r   	  s   
zPolyRing._gensc                 C   s   | j | j| jfS rU   )r   r1   r2   r   r4   r4   r5   __getnewargs__     zPolyRing.__getnewargs__c                 C   s6   | j  }|d= | D ]\}}|dr||= q|S )Nr   Z	monomial_)__dict__copyrH   
startswith)r   statero   valuer4   r4   r5   __getstate__  s   

zPolyRing.__getstate__c                 C   s   | j S rU   )r   r   r4   r4   r5   __hash__!  s   zPolyRing.__hash__c                 C   s2   t |to| j| j| j| jf|j|j|j|jfkS rU   )rV   r.   r   r1   r   r2   r   otherr4   r4   r5   __eq__$  s
   
zPolyRing.__eq__c                 C   
   | |k S rU   r4   r   r4   r4   r5   __ne__)     
zPolyRing.__ne__Nc                 C   s    |  |p| j|p
| j|p| jS rU   )	__class__r   r1   r2   )r   r   r1   r2   r4   r4   r5   clone,  s    zPolyRing.clonec                 C   s   dg| j  }d||< t|S )zReturn the ith-basis element. r      )r   rr   )r   r   Zbasisr4   r4   r5   r   /  s   zPolyRing.monomial_basisc                 C   s   |   S rU   )r   r   r4   r4   r5   r   5  s   zPolyRing.zeroc                 C   s   |  | jS rU   )r   r   r   r4   r4   r5   r   9     zPolyRing.onec                 C   s   | j ||S rU   )r1   convertr   elementorig_domainr4   r4   r5   
domain_new=     zPolyRing.domain_newc                 C   s   |  | j|S rU   )term_newr   )r   coeffr4   r4   r5   
ground_new@  r   zPolyRing.ground_newc                 C   s    |  |}| j}|r|||< |S rU   )r   r   )r   monomr   r   r4   r4   r5   r   C  s
   
zPolyRing.term_newc                 C   s   t |tr"| |jkr|S t | jtr| jj|jkr| |S tdt |tr+tdt |tr5| 	|S t |t
rOz| |W S  tyN   | | Y S w t |trY| |S | |S )N
conversionZparsing)rV   r`   r6   r1   r   r   NotImplementedErrorrW   rL   rN   r>   
from_terms
ValueError	from_listr   	from_exprr   r   r4   r4   r5   ring_newJ  s&   









zPolyRing.ring_newc                 C   s8   | j }| j}| D ]\}}|||}|r|||< q
|S rU   )r   r   rH   )r   r   r   r   r   r   r   r4   r4   r5   rN   b  s   
zPolyRing.from_dictc                 C   s   |  t||S rU   )rN   rL   r   r4   r4   r5   r   m  r   zPolyRing.from_termsc                 C   s   |  t|| jd | jS Nr   )rN   r   r   r1   r   r4   r4   r5   r   p  s   zPolyRing.from_listc                    s$   j  fdd  t|S )Nc                    s    | }|d ur|S | jrtttt | jS | jr'tttt | jS | 	 \}}|j
r<|dkr< |t| S | S r   )ry   Zis_Addr
   r   r>   rJ   argsZis_Mulr   Zas_base_expZ
is_Integerintr   r   )exprr   baseexp_rebuildr1   mappingr   r4   r5   r   v  s   
z(PolyRing._rebuild_expr.<locals>._rebuild)r1   r   )r   r   r   r4   r   r5   _rebuild_exprs  s   zPolyRing._rebuild_exprc                 C   sP   t tt| j| j}z| ||}W n ty"   td| |f w | |S )Nz@expected an expression convertible to a polynomial in %s, got %s)	rL   r>   rM   r   r/   r   r    r   r   )r   r   r   r   r4   r4   r5   r     s   
zPolyRing.from_exprc                 C   s   |du r| j rd}|S d}|S t|tr9|}d|kr"|| j k r"	 |S | j  |kr3|dkr3| d }|S td| t|| jrVz	| j|}W |S  tyU   td| w t|trrz	| j|}W |S  tyq   td| w td| )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   rV   r   r   r   r/   indexrW   r   )r   genr   r4   r4   r5   r     s<   


zPolyRing.indexc                    s>   t t| j|  fddt| jD }|s| jS | j|dS )z,Remove specified generators from this ring. c                       g | ]
\}}| vr|qS r4   r4   r9   r   rY   indicesr4   r5   r:         z!PolyRing.drop.<locals>.<listcomp>r^   )r{   rJ   r   	enumerater   r1   r   r   r/   r   r4   r   r5   drop  s
   zPolyRing.dropc                 C   s    | j | }|s
| jS | j|dS )Nr^   )r   r1   r   )r   ro   r   r4   r4   r5   __getitem__  s   
zPolyRing.__getitem__c                 C   s2   | j js
t| j dr| j| j j dS td| j  )Nr1   r1   z%s is not a composite domain)r1   rz   r   r   r   r   r4   r4   r5   	to_ground  s   zPolyRing.to_groundc                 C   rh   rU   r   r   r4   r4   r5   	to_domain     zPolyRing.to_domainc                 C   s   ddl m} || j| j| jS )Nr   )	FracField)Zsympy.polys.fieldsr   r   r1   r2   )r   r   r4   r4   r5   to_field  s   zPolyRing.to_fieldc                 C   s   t | jdkS r   rs   r/   r   r4   r4   r5   is_univariate     zPolyRing.is_univariatec                 C   s   t | jdkS r   r   r   r4   r4   r5   is_multivariate  r   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)])

        Zinclude)r   r   r   r   r   Zobjspr   r4   r4   r5   r        
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   r4   r4   r5   r     r   zPolyRing.mulc                    s\   t t| j|  fddt| jD } fddt| jD }|s$| S | j|| j| dS )zd
        Remove specified generators from the ring and inject them into
        its domain.
        c                    r   r4   r4   r   r   r4   r5   r:     r   z+PolyRing.drop_to_ground.<locals>.<listcomp>c                    r   r4   r4   )r9   r   r   r   r4   r5   r:     r   r   r1   )r{   rJ   r   r   r   r/   r   r   r   r4   r   r5   drop_to_ground  s   zPolyRing.drop_to_groundc                 C   s2   | |krt | jt |j}| jt|dS | S )z+Add the generators of ``other`` to ``self``r^   r{   r   unionr   r>   )r   r   symsr4   r4   r5   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   r4   r4   r5   add_gens'  s   zPolyRing.add_gens)NNNrU   )(rw   
__module____qualname____doc__r   r}   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   __call__rN   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r4   r4   r4   r5   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ZdddZdd Zdd Zdd Zdd Zdd  Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Zdd Zdd Zdd ZdddZdd ZdS (  r`   z5Element of multivariate distributed polynomial ring. c                 C   s
   |  |S rU   )r   )r   Zinitr4   r4   r5   new0  r   zPolyElement.newc                 C   s
   | j  S rU   )r6   r   r   r4   r4   r5   parent3  r   zPolyElement.parentc                 C   s   | j t|  fS rU   )r6   r>   	itertermsr   r4   r4   r5   r   6     zPolyElement.__getnewargs__Nc                 C   s.   | j }|d u rt| jt|  f | _ }|S rU   )r   r   r6   	frozensetrH   )r   r   r4   r4   r5   r   ;  s   zPolyElement.__hash__c                 C   s
   |  | S )a  Return a copy of polynomial self.

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

        Examples
        ========

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

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

        )r   r   r4   r4   r5   r   F  s   
zPolyElement.copyc                 C   sV   | j |kr| S | j j|jkr#ttt| | j j|j }||| j jS || | j jS rU   )r6   r   r>   rM   r(   r   r1   rN   )r   new_ringtermsr4   r4   r5   set_ringb  s   
zPolyElement.set_ringc                 G   sH   |rt || jjkrtd| jjt |f | jj}t|  g|R  S )Nz&not enough symbols, expected %s got %s)rs   r6   r   r   r   r'   as_expr_dict)r   r   r4   r4   r5   as_exprk  s   zPolyElement.as_exprc                    s    | j jj  fdd|  D S )Nc                    s   i | ]	\}}| |qS r4   r4   r9   r   r   to_sympyr4   r5   rF   u  rG   z,PolyElement.as_expr_dict.<locals>.<dictcomp>)r6   r1   r  r   r   r4   r  r5   r   s  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                       g | ]
\}}||  fqS r4   r4   )r9   kvcommonr4   r5   r:     r   z,PolyElement.clear_denoms.<locals>.<listcomp>)r6   r1   is_Fieldhas_assoc_Ringr   get_ringr   denomr?   r   rH   )r   r1   Zground_ringr   r  r   r   r4   r  r5   clear_denomsw  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  r4   r4   r5   
strip_zero  s
   zPolyElement.strip_zeroc                 C   sN   |s|  S t |tr|j| jkrt| |S t| dkrdS | | jj|k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   F)rV   r`   r6   rL   r   rs   ry   r   p1p2r4   r4   r5   r     s   zPolyElement.__eq__c                 C   r   rU   r4   r  r4   r4   r5   r     r   zPolyElement.__ne__c                 C   s   | j }t||jr1t|  t| krdS |jj}|  D ]}|| | || |s. dS qdS t| dkr9dS z|j|}W n
 t	yK   Y dS w |j| 
 ||S )z+Approximate equality test for polynomials. FTr   )r6   rV   r   r{   keysr1   almosteqrs   r   r    const)r  r  Z	tolerancer6   r  r  r4   r4   r5   r    s$   zPolyElement.almosteqc                 C   s   t | |  fS rU   )rs   r   r   r4   r4   r5   sort_key  r   zPolyElement.sort_keyc                 C   s$   t || jjr||  | S tS rU   )rV   r6   r   r  NotImplemented)r  r  opr4   r4   r5   _cmp  s   zPolyElement._cmpc                 C      |  |tS rU   )r  r   r  r4   r4   r5   __lt__     zPolyElement.__lt__c                 C   r  rU   )r  r   r  r4   r4   r5   __le__  r  zPolyElement.__le__c                 C   r  rU   )r  r   r  r4   r4   r5   __gt__  r  zPolyElement.__gt__c                 C   r  rU   )r  r	   r  r4   r4   r5   __ge__  r  zPolyElement.__ge__c                 C   sD   | j }||}|jdkr||jfS t|j}||= ||j|dfS )Nr   r^   )r6   r   r   r1   r>   r   r   r   r   r6   r   r   r4   r4   r5   _drop  s   



zPolyElement._dropc                 C   s   |  |\}}| jjdkr| jr| dS td| |j}|  D ]\}}|| dkr:t|}||= ||t	|< q"td| |S )Nr   zcan't drop %sr   )
r"  r6   r   	is_groundr   r   r   rH   r>   rr   )r   r   r   r6   r   r  r  Kr4   r4   r5   r     s   
zPolyElement.dropc                 C   s6   | j }||}t|j}||= ||j||| dfS )Nr   )r6   r   r>   r   r   r!  r4   r4   r5   _drop_to_ground  s
   

zPolyElement._drop_to_groundc                 C   s   | j jdkr
td| |\}}|j}|jjd }|  D ]1\}}|d | ||d d   }||vr@|||  |||< q||  |||  |7  < q|S )Nr   z#can't drop only generator to groundr   )	r6   r   r   r%  r   r1   r/   r   
mul_ground)r   r   r   r6   r   r   r   Zmonr4   r4   r5   r     s    zPolyElement.drop_to_groundc                 C   s   t | | jjd | jjS r   )r   r6   r   r1   r   r4   r4   r5   to_dense     zPolyElement.to_densec                 C   rh   rU   )rL   r   r4   r4   r5   to_dict  r   zPolyElement.to_dictc                 C   s  | s
| | jjjS |d }|d }| j}|j}|j}	|j}
g }|  D ]\}}|j|}|r2dnd}|	| ||
krP| |}|rO|
drO|dd  }n|rU| }|| jjkrd|j||dd}nd	}g }t|	D ]=}|| }|suql|j|| |dd}|dkr|t|ks|d
k r|j||dd}n|}|	|||f  ql|	d|  ql|r|g| }|	|| q$|d
 dv r|d
}|dkr|d
d d	|S )NZMulZAtom -  + -r   T)strict r   Fz%s)r+  r*  )Z_printr6   r1   r   r   r   r   r   is_negativer   r   r   Zparenthesizer   r   joinpopinsert)r   ZprinterZ
precedenceZexp_patternZ
mul_symbolZprec_mulZ	prec_atomr6   r   r   zmZsexpvsr   r   negativesignZscoeffZsexpvr   r   r   Zsexpheadr4   r4   r5   rW     sV   




zPolyElement.strc                 C   s   | | j jv S rU   )r6   r   r   r4   r4   r5   is_generatorD  r   zPolyElement.is_generatorc                 C   s   |  pt | dko| jj| v S r   )rs   r6   r   r   r4   r4   r5   r#  H  s   zPolyElement.is_groundc                 C   s   |  pt | dko| jdkS r   )rs   LCr   r4   r4   r5   is_monomialL  s   zPolyElement.is_monomialc                 C   s   t | dkS r   )rs   r   r4   r4   r5   is_termP  r   zPolyElement.is_termc                 C      | j j| jS rU   )r6   r1   r/  r8  r   r4   r4   r5   r/  T     zPolyElement.is_negativec                 C   r;  rU   )r6   r1   is_positiver8  r   r4   r4   r5   r=  X  r<  zPolyElement.is_positivec                 C   r;  rU   )r6   r1   is_nonnegativer8  r   r4   r4   r5   r>  \  r<  zPolyElement.is_nonnegativec                 C   r;  rU   )r6   r1   is_nonpositiver8  r   r4   r4   r5   r?  `  r<  zPolyElement.is_nonpositivec                 C   s   |  S rU   r4   rk   r4   r4   r5   is_zerod  s   zPolyElement.is_zeroc                 C   s   | | j jkS rU   )r6   r   rk   r4   r4   r5   is_oneh  r   zPolyElement.is_onec                 C   r;  rU   )r6   r1   rA  r8  rk   r4   r4   r5   is_monicl  r<  zPolyElement.is_monicc                 C   s   | j j|  S rU   )r6   r1   rA  contentrk   r4   r4   r5   is_primitivep  s   zPolyElement.is_primitivec                 C      t dd |  D S )Nc                 s       | ]	}t |d kV  qdS r   NrK   r9   r   r4   r4   r5   rZ   v      z(PolyElement.is_linear.<locals>.<genexpr>r]   
itermonomsrk   r4   r4   r5   	is_lineart     zPolyElement.is_linearc                 C   rE  )Nc                 s   rF  )   NrH  rI  r4   r4   r5   rZ   z  rJ  z+PolyElement.is_quadratic.<locals>.<genexpr>rK  rk   r4   r4   r5   is_quadraticx  rN  zPolyElement.is_quadraticc                 C      | j jsdS | j | S NT)r6   r   Z	dmp_sqf_prk   r4   r4   r5   is_squarefree|     zPolyElement.is_squarefreec                 C   rQ  rR  )r6   r   Zdmp_irreducible_prk   r4   r4   r5   is_irreducible  rT  zPolyElement.is_irreduciblec                 C      | j jr
| j | S td)Nzcyclotomic polynomial)r6   r   Zdup_cyclotomic_pr#   rk   r4   r4   r5   is_cyclotomic  s   zPolyElement.is_cyclotomicc                 C   s   |  dd |  D S )Nc                 S   s   g | ]	\}}|| fqS r4   r4   r  r4   r4   r5   r:     rG   z'PolyElement.__neg__.<locals>.<listcomp>)r   r   r   r4   r4   r5   __neg__  r(  zPolyElement.__neg__c                 C   s   | S rU   r4   r   r4   r4   r5   __pos__     zPolyElement.__pos__c           
      C   s<  |s|   S | j}t||jr6|   }|j}|jj}| D ]\}}|||| }|r0|||< q||= q|S t|tr^t|jt	rI|jj|jkrInt|jjt	r\|jjj|kr\|
| S tS z||}W n typ   t Y S w |   }|sy|S |j}	|	|  vr|||	< |S |||	  kr||	= |S ||	  |7  < |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

        )r   r6   rV   r   ry   r1   r   rH   r`   r   __radd__r  r   r    r   r  )
r  r  r6   r   ry   r   r  r  Zcp2r3  r4   r4   r5   __add__  sH   


zPolyElement.__add__c                 C   s   |   }|s|S | j}z||}W n ty   t Y S w |j}||  vr-|||< |S |||  kr9||= |S ||  |7  < |S rU   )r   r6   r   r    r  r   r  )r  nr   r6   r3  r4   r4   r5   r[    s$   zPolyElement.__radd__c           	      C   s4  |s|   S | j}t||jr6|   }|j}|jj}| D ]\}}|||| }|r0|||< q||= q|S t|tr^t|jt	rI|jj|jkrInt|jjt	r\|jjj|kr\|
| S tS z||}W n typ   t Y S w |   }|j}||  vr| ||< |S ||| kr||= |S ||  |8  < |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

        )r   r6   rV   r   ry   r1   r   rH   r`   r   __rsub__r  r   r    r   r  )	r  r  r6   r   ry   r   r  r  r3  r4   r4   r5   __sub__  sD   



zPolyElement.__sub__c                 C   sV   | j }z||}W n ty   t Y S w |j}| D ]	}| |  ||< q||7 }|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

        )r6   r   r    r  r   )r  r]  r6   r   r   r4   r4   r5   r^    s   zPolyElement.__rsub__c                 C   s0  | j }|j}| r
|s|S t||jrH|j}|jj}|j}t| }|  D ]\}}	|D ]\}
}|||
}||||	|  ||< q,q&|	  |S t|t
rpt|jtr[|jj |j kr[nt|j jtrn|j jj |krn|| S tS z||}W n ty   t Y S w |  D ]\}}	|	| }|r|||< q|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

        )r6   r   rV   r   ry   r1   r   r>   rH   r  r`   r   __rmul__r  r   r    )r  r  r6   r   ry   r   r   Zp2itexp1v1Zexp2Zv2r   r  r4   r4   r5   __mul__0  sB   


zPolyElement.__mul__c                 C   sb   | j j}|s|S z|j |}W n ty   t Y S w |  D ]\}}|| }|r.|||< q |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

        )r6   r   r   r    r  rH   )r  r  r   ra  rb  r  r4   r4   r5   r`  b  s   zPolyElement.__rmul__c                 C   s   | j }|s| r
|jS tdt| dkr;t|  d \}}|j}|dkr/|||||< |S || ||||< |S t|}|dk rGtd|dkrO| 	 S |dkrW| 
 S |dkra| | 
  S t| dkrl| |S | |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 exponentrO        )r6   r   r   rs   r>   rH   r   r   r   r   square_pow_multinomial_pow_generic)r   r]  r6   r   r   r   r4   r4   r5   __pow__  s2   

zPolyElement.__pow__c                 C   sB   | j j}| }	 |d@ r|| }|d8 }|s	 |S | }|d }q)NTr   rO  )r6   r   rf  )r   r]  r   rD   r4   r4   r5   rh    s   zPolyElement._pow_genericc                 C   s   t t| | }| jj}| jj}|  }| jjj}| jj}|D ]>\}}	|}
|	}t||D ]\}\}}|rA||
||}
||| 9 }q-t	|
}|}|
||| }|rW|||< q ||v r^||= q |S rU   )r   rs   rH   r6   r   r   r1   r   rM   rr   ry   )r   r]  Zmultinomialsr   r   r   r   r   ZmultinomialZmultinomial_coeffZproduct_monomZproduct_coeffr   r   r   r4   r4   r5   rg    s.   

zPolyElement._pow_multinomialc                 C   s   | j }|j}|j}t|  }|jj}|j}tt|D ]'}|| }| | }	t|D ]}
||
 }|||}||||	| |   ||< q*q|	d}|j}| 
 D ]\}}|||}||||d  ||< qP|  |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

        rO  )r6   r   ry   r>   r  r1   r   r   rs   imul_numrH   r  )r   r6   r   ry   r  r   r   r   Zk1ZpkjZk2r   r  r  r4   r4   r5   rf    s*   


zPolyElement.squarec                 C   s   | j }|s	tdt||jr| |S t|tr<t|jtr'|jj |j kr'nt|j jtr:|j jj |kr:|| S t	S z|
|}W n tyN   t	 Y S w | || |fS Npolynomial division)r6   ZeroDivisionErrorrV   r   r   r`   r1   r   __rdivmod__r  r   r    
quo_ground
rem_groundr  r  r6   r4   r4   r5   
__divmod__   s"   


zPolyElement.__divmod__c                 C      t S rU   r  r  r4   r4   r5   ro    rZ  zPolyElement.__rdivmod__c                 C   s   | j }|s	tdt||jr| |S t|tr<t|jtr'|jj |j kr'nt|j jtr:|j jj |kr:|| S t	S z|
|}W n tyN   t	 Y S w | |S rl  )r6   rn  rV   r   remr`   r1   r   __rmod__r  r   r    rq  rr  r4   r4   r5   __mod__  s"   



zPolyElement.__mod__c                 C   rt  rU   ru  r  r4   r4   r5   rw  /  rZ  zPolyElement.__rmod__c                 C   s   | j }|s	tdt||jr|jr| |d  S | |S t|trEt|jtr0|jj |j kr0nt|j jtrC|j jj |krC|	| S t
S z||}W n tyW   t
 Y S w | |S )Nrm  r   )r6   rn  rV   r   r9  quor`   r1   r   __rtruediv__r  r   r    rp  rr  r4   r4   r5   __truediv__2  s&   



zPolyElement.__truediv__c                 C   rt  rU   ru  r  r4   r4   r5   rz  K  rZ  zPolyElement.__rtruediv__c                    sL   | j j| j j}|j | j j|jr fdd}|S  fdd}|S )Nc                    sB   | \}}|\}}|kr|}n||}|d ur| ||fS d S rU   r4   Z	a_lm_a_lcZ	b_lm_b_lcZa_lmZa_lcZb_lmZb_lcr   Z
domain_quor   r3  r4   r5   term_divZ  s   
z'PolyElement._term_div.<locals>.term_divc                    sJ   | \}}|\}}|kr|}n||}|d u s#|| s#| ||fS d S rU   r4   r|  r}  r4   r5   r~  f  s   
)r6   r   r1   ry  r   r
  )r   r1   r~  r4   r}  r5   	_term_divS  s   zPolyElement._term_divc                    s  | j  d}t|trd}|g}tdd |D rtd| s+|r& j jfS g  jfS |D ]}|j  kr8tdq-t|} fddt|D }| 	 } j}| 
 }d	d |D }	|rd
}
d
}|
|k r|d
kr| }|||| f|	|
 ||
 |	|
  f}|dur|\}}||
 ||f||
< |||
 || f}d}n|
d7 }
|
|k r|d
ksh|s| }|||| f}||= |s\| jkr||7 }|r|s҈ j|fS |d
 |fS ||fS )aU  Division algorithm, see [CLO] p64.

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

        All polynomials are required not to be Laurent polynomials.

        Examples
        ========

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

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

        FTc                 s       | ]}| V  qd S rU   r4   )r9   rl   r4   r4   r5   rZ         z"PolyElement.div.<locals>.<genexpr>rm  z"self and f must have the same ringc                    s   g | ]} j qS r4   )r   )r9   r   r6   r4   r5   r:     r;   z#PolyElement.div.<locals>.<listcomp>c                 S   s   g | ]}|  qS r4   )r   )r9   Zfxr4   r4   r5   r:         r   Nr   )r6   rV   r`   anyrn  r   r   rs   r   r   r  r   _iadd_monom_iadd_poly_monomr   )r   ZfvZ
ret_singlerl   rY   Zqvr   rr~  Zexpvsr   Zdivoccurredr   termZexpv1rD   r4   r  r5   r   t  s\   


&


zPolyElement.divc                 C   sH  | }t |tr
|g}tdd |D rtd|j}|j}|j}|j}|j}| }|j	}	|
 }|j}
|r|D ]A}||	|j	}|d ury|\}}| D ]\}}|||}|
||||  }|sd||= qL|||< qL| }|d urw||| f}	 n'q8|	\}}||v r||  |7  < n|||< ||= | }|d ur||| f}	|s6|S )Nc                 s   r  rU   r4   )r9   gr4   r4   r5   rZ     r  z"PolyElement.rem.<locals>.<genexpr>rm  )rV   r`   r  rn  r6   r1   r   r   r  LTr   ry   r   r   )r   Grl   r6   r1   r   r   r  r~  Zltfry   r  ZtqrC   rD   mgcgZm1Zc1ZltmZltcr4   r4   r5   rv    sP   


zPolyElement.remc                 C      |  |d S Nr   )r   )rl   r  r4   r4   r5   ry    r   zPolyElement.quoc                 C   s    |  |\}}|s|S t| |rU   )r   r"   )rl   r  qr  r4   r4   r5   exquo  s   
zPolyElement.exquoc                 C   sb   | | j jv r|  }n| }|\}}||}|du r |||< |S ||7 }|r,|||< |S ||= |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)r6   r   r   ry   )r   mcZcpselfr   r   rD   r4   r4   r5   r    s   

zPolyElement._iadd_monomc                 C   s~   | }||j jv r| }|\}}|j}|j jj}|j j}| D ]\}	}
||	|}||||
|  }|r9|||< 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

        )r6   r   r   ry   r1   r   r   rH   )r   r  r  r  rC   rD   ry   r   r   r  r  kar   r4   r4   r5   r  $  s   


zPolyElement._iadd_poly_monomc                    <   | j | | st S  dk rdS t fdd|  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                       g | ]}|  qS r4   r4   rI  r   r4   r5   r:   W  r  z&PolyElement.degree.<locals>.<listcomp>)r6   r   r   rj   rL  rl   xr4   r  r5   degreeI     zPolyElement.degreec                 C   .   | s
t  f| jj S ttttt|   S )z
        A tuple containing leading degrees in all variables.

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

        )	r   r6   r   rr   rJ   rj   r>   rM   rL  rk   r4   r4   r5   degreesY     zPolyElement.degreesc                    r  )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                    r  r4   r4   rI  r  r4   r5   r:   s  r  z+PolyElement.tail_degree.<locals>.<listcomp>)r6   r   r   minrL  r  r4   r  r5   tail_degreee  r  zPolyElement.tail_degreec                 C   r  )z
        A tuple containing tail degrees in all variables.

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

        )	r   r6   r   rr   rJ   r  r>   rM   rL  rk   r4   r4   r5   tail_degreesu  r  zPolyElement.tail_degreesc                 C   s   | r| j | 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)r6   r   r   r4   r4   r5   r     s   zPolyElement.leading_expvc                 C   s   |  || jjjS rU   )ry   r6   r1   r   r   r   r4   r4   r5   
_get_coeff  r   zPolyElement._get_coeffc                 C   sl   |dkr|  | jjS t|| jjr0t| }t|dkr0|d \}}|| jjj	kr0|  |S t
d| )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 %s)r  r6   r   rV   r   r>   r   rs   r1   r   r   )r   r   r   r   r   r4   r4   r5   r     s   
zPolyElement.coeffc                 C   s   |  | jjS )z!Returns the constant coeffcient. )r  r6   r   r   r4   r4   r5   r    r   zPolyElement.constc                 C   s   |  |  S rU   )r  r   r   r4   r4   r5   r8    r   zPolyElement.LCc                 C   s   |   }|d u r| jjS |S rU   )r   r6   r   r  r4   r4   r5   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

        )r6   r   r   r1   r   r   r   r   r4   r4   r5   leading_monom  s
   zPolyElement.leading_monomc                 C   s0   |   }|d u r| jj| jjjfS || |fS rU   )r   r6   r   r1   r   r  r  r4   r4   r5   r    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)r6   r   r   r  r4   r4   r5   leading_term  s
   zPolyElement.leading_termc                    sL    d u r	| j j nt   tu rt|dd ddS t| fddddS )Nc                 S   s   | d S r  r4   r   r4   r4   r5   rf     rm   z%PolyElement._sorted.<locals>.<lambda>T)ro   reversec                    s    | d S r  r4   r  rp   r4   r5   rf     rq   )r6   r2   rv   ru   r   sorted)r   rS   r2   r4   rp   r5   _sorted  s   

zPolyElement._sortedc                 C      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 r4   r4   )r9   _r   r4   r4   r5   r:   !  r  z&PolyElement.coeffs.<locals>.<listcomp>r   r   r2   r4   r4   r5   rP   	     zPolyElement.coeffsc                 C   r  )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 r4   r4   )r9   r   r  r4   r4   r5   r:   ;  r  z&PolyElement.monoms.<locals>.<listcomp>r  r  r4   r4   r5   monoms#  r  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  r4   r4   r5   r   =  r  zPolyElement.termsc                 C      t |  S )z,Iterator over coefficients of a polynomial. )iterr?   r   r4   r4   r5   
itercoeffsW  r   zPolyElement.itercoeffsc                 C   r  )z)Iterator over monomials of a polynomial. )r  r  r   r4   r4   r5   rL  [  r   zPolyElement.itermonomsc                 C   r  )z%Iterator over terms of a polynomial. )r  rH   r   r4   r4   r5   r   _  r   zPolyElement.itertermsc                 C   r  )z+Unordered list of polynomial coefficients. r=   r   r4   r4   r5   
listcoeffsc  r   zPolyElement.listcoeffsc                 C   r  )z(Unordered list of polynomial monomials. )r>   r  r   r4   r4   r5   
listmonomsg  r   zPolyElement.listmonomsc                 C   r  )z$Unordered list of polynomial terms. r  r   r4   r4   r5   	listtermsk  r   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)r6   r   clear)r   rD   r   r4   r4   r5   rj  o  s   zPolyElement.imul_numc                 C   s0   | j j}|j}|j}|  D ]}|||}q|S )z*Returns GCD of polynomial's coefficients. )r6   r1   r   r   r  )rl   r1   contr   r   r4   r4   r5   rC    s   zPolyElement.contentc                 C   s   |   }|| |fS )z,Returns content and a primitive polynomial. )rC  rp  )rl   r  r4   r4   r5   	primitive  s   zPolyElement.primitivec                 C   s   | s| S |  | jS )z5Divides all coefficients by the leading coefficient. )rp  r8  rk   r4   r4   r5   monic  s   zPolyElement.monicc                    s,    s| j jS  fdd|  D }| |S )Nc                    r  r4   r4   r  r  r4   r5   r:     r   z*PolyElement.mul_ground.<locals>.<listcomp>)r6   r   r   r   )rl   r  r   r4   r  r5   r&    s   
zPolyElement.mul_groundc                    s*   | j j fdd|  D }| |S )Nc                    s   g | ]\}}| |fqS r4   r4   r9   Zf_monomZf_coeffr   r   r4   r5   r:         z)PolyElement.mul_monom.<locals>.<listcomp>)r6   r   rH   r   )rl   r   r   r4   r  r5   	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 r4   r4   r  r   r   r   r4   r5   r:     rI   z(PolyElement.mul_term.<locals>.<listcomp>)r6   r   r   r&  r   rH   r   )rl   r  r   r4   r  r5   mul_term  s   

zPolyElement.mul_termc                    sl   | j j}s
td| r|jkr| S |jr&|j  fdd|  D }nfdd|  D }| |S )Nrm  c                    s   g | ]\}}| |fqS r4   r4   r  ry  r  r4   r5   r:     r  z*PolyElement.quo_ground.<locals>.<listcomp>c                    s$   g | ]\}}|  s||  fqS r4   r4   r  r  r4   r5   r:        $ )r6   r1   rn  r   r
  ry  r   r   )rl   r  r1   r   r4   r  r5   rp    s   
zPolyElement.quo_groundc                    sj    \}}|s
t d| s| jjS || jjkr| |S |   fdd|  D }| dd |D S )Nrm  c                    s   g | ]}| qS r4   r4   r9   tr  r~  r4   r5   r:     s    z(PolyElement.quo_term.<locals>.<listcomp>c                 S   s   g | ]}|d ur|qS rU   r4   r  r4   r4   r5   r:     rA   )rn  r6   r   r   rp  r  r   r   )rl   r  r   r   r   r4   r  r5   quo_term  s   
zPolyElement.quo_termc                    sx   | j jjr&g }|  D ]\}}|  }| d kr|  }|||f qn fdd|  D }| |}|  |S )NrO  c                    s   g | ]
\}}||  fqS r4   r4   r  r   r4   r5   r:     r   z,PolyElement.trunc_ground.<locals>.<listcomp>)r6   r1   is_ZZr   r   r   r  )rl   r   r   r   r   r   r4   r  r5   trunc_ground  s   

zPolyElement.trunc_groundc                 C   sB   | }|  }|  }|jj||}||}||}|||fS rU   )rC  r6   r1   r   rp  )r   r  rl   fcgcr   r4   r4   r5   extract_ground  s   


zPolyElement.extract_groundc                    s2   | s| j jjS | j jj | fdd|  D S )Nc                    s   g | ]} |qS r4   r4   )r9   r   Z
ground_absr4   r5   r:     r  z%PolyElement._norm.<locals>.<listcomp>)r6   r1   r   absr  )rl   Z	norm_funcr4   r  r5   _norm   s   

zPolyElement._normc                 C   
   |  tS rU   )r  rj   rk   r4   r4   r5   max_norm  r   zPolyElement.max_normc                 C   r  rU   )r  rK   rk   r4   r4   r5   l1_norm
  r   zPolyElement.l1_normc                 G   s   | j }| gt| }dg|j }|D ]}| D ]}t|D ]\}}t|| |||< qqqt|D ]
\}}	|	s<d||< q2t|}tdd |D rN||fS g }
|D ]#}|j}|	 D ]\}}dd t
||D }||t|< q[|
| qR||
fS )Nr   r   c                 s   s    | ]}|d kV  qdS rG  r4   )r9   re   r4   r4   r5   rZ     s    z&PolyElement.deflate.<locals>.<genexpr>c                 S   s   g | ]\}}|| qS r4   r4   r9   r   rk  r4   r4   r5   r:   '  rA   z'PolyElement.deflate.<locals>.<listcomp>)r6   r>   r   rL  r   r   rr   r]   r   r   rM   r   )rl   r  r6   rQ   Jr   r   r   rC   re   HhIr   Nr4   r4   r5   deflate  s0   zPolyElement.deflatec                 C   s>   | j j}|  D ]\}}dd t||D }||t|< q|S )Nc                 S   s   g | ]\}}|| qS r4   r4   r  r4   r4   r5   r:   2  rA   z'PolyElement.inflate.<locals>.<listcomp>)r6   r   r   rM   rr   )rl   r  r   r  r   r  r4   r4   r5   inflate.  s
   zPolyElement.inflatec                 C   sb   | }|j j}|js| \}}| \}}|||}|| ||}|js-||S | S rU   )	r6   r1   r
  r  r   ry  r   r&  r  )r   r  rl   r1   r  r  rD   r  r4   r4   r5   r   7  s   
zPolyElement.lcmc                 C   r  r  )	cofactorsrl   r  r4   r4   r5   r   G  r   zPolyElement.gcdc                 C   s   | s|s| j j}|||fS | s| |\}}}|||fS |s+|| \}}}|||fS t| dkr>| |\}}}|||fS t|dkrQ|| \}}}|||fS | |\}\} }| |\}}}||||||fS r   )r6   r   	_gcd_zerors   
_gcd_monomr  _gcdr  )rl   r  r   r  cffcfgr  r4   r4   r5   r  J  s$   




zPolyElement.cofactorsc                 C   s0   | j j| j j}}|jr|||fS | || fS rU   )r6   r   r   r>  )rl   r  r   r   r4   r4   r5   r  `  s   
zPolyElement._gcd_zeroc                    s   | j }|jj}|jj|j}|jt|  d \}}|| | D ]\}}||| | q$|  fg}	| || fg}
|  fdd| D }|	|
|fS )Nr   c                    s$   g | ]\}}|| fqS r4   r4   )r9   r  r  Z_cgcdZ_mgcdZ
ground_quor   r4   r5   r:   t  r  z*PolyElement._gcd_monom.<locals>.<listcomp>)	r6   r1   r   ry  r   r   r>   r   r   )rl   r  r6   Z
ground_gcdr   Zmfcfr  r  r  r  r  r4   r  r5   r  g  s   

"
zPolyElement._gcd_monomc                 C   s6   | j }|jjr| |S |jjr| |S || |S rU   )r6   r1   Zis_QQ_gcd_QQr  _gcd_ZZZdmp_inner_gcd)rl   r  r6   r4   r4   r5   r  w  s   

zPolyElement._gcdc                 C   s
   t | |S rU   r   r  r4   r4   r5   r    r   zPolyElement._gcd_ZZc                 C   s   | }|j }|j|j d}| \}}| \}}||}||}||\}}}	||}|j| }
}||	|j
|
|}|	|	|j
|
|}	|||	fS )Nr   )r6   r   r1   r  r  r   r  r8  r  r&  ry  )r   r  rl   r6   r   r  r  r  r  r  rD   r4   r4   r5   r    s   



zPolyElement._gcd_QQc                 C   s&  | }|j }|s||jfS |j}|jr|js||\}}}nD|j| d}| \}	}| \}
}|	|}|	|}||\}}}|j|
|	\}}
}	|	|}|	|}|
|
}|
|	}| }||jkrt||}}||fS ||j kr| | }}||fS |
|}|
|}||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   )r6   r   r1   r
  r  r  r   r  r  r   r&  canonical_unit)r   r  rl   r6   r1   r  r   r  r   Zcqcpur4   r4   r5   cancel  s8   










zPolyElement.cancelc                 C   s   | j j}|| jS rU   )r6   r1   r  r8  )rl   r1   r4   r4   r5   r    s   zPolyElement.canonical_unitc           	      C   s`   | j }||}||}|j}|  D ]\}}|| 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

        )r6   r   r   r   r   r   r   )	rl   r  r6   r   rC   r  r   r   er4   r4   r5   diff  s   

zPolyElement.diffc                 G   sP   dt |  k r| jjkrn n| tt| jj|S td| jjt |f )Nr   z1expected at least 1 and at most %s values, got %s)rs   r6   r   evaluater>   rM   r/   r   )rl   r?   r4   r4   r5   r     s    zPolyElement.__call__c                    s@  | }t |tr0|d u r0|d |dd  \ }}| |}|s"|S  fdd|D }||S |j}||}|j|}|jdkr[|jj}|	 D ]\\}}||||  7 }qK|S |
|j}	|	 D ]8\}
}|
| |
d | |
|d d   }}
|||  }|
|	v r||	|
  }|r||	|
< qe|	|
= qe|r||	|
< qe|	S )Nr   r   c                    s   g | ]\}}|  |fqS r4   )r   )r9   Yrd   Xr4   r5   r:     r  z(PolyElement.evaluate.<locals>.<listcomp>)rV   r>   r  r6   r   r1   r   r   r   r   r   )r   r  rd   rl   r6   r   resultr]  r   r   r   r4   r  r5   r    s:   


&
zPolyElement.evaluatec                 C   s  | }t |tr|d u r|D ]
\}}|||}q|S |j}||}|j|}|jdkrH|jj}|	 D ]\\}}	||	||  7 }q5|
|S |j}
|	 D ]:\}}	|| |d | d ||d d   }}|	||  }	||
v r|	|
|  }	|	r|	|
|< qO|
|= qO|	r|	|
|< qO|
S )Nr   ra   )rV   r>   subsr6   r   r1   r   r   r   r   r   )r   r  rd   rl   r  r6   r   r  r]  r   r   r   r4   r4   r5   r   	  s4   


*
zPolyElement.subsc                    s  | j }|j}ttt|jtt|j |d ur||fg}n"t|tr)t|}nt|tr=t	t|
  fddd}ntdt|D ]\}\}} | ||f||< qE|  D ]0\}}	t|}|j}
|D ]\}}|| d}||< |r}|
|| 9 }
qh|
t||	f}
||
7 }q[|S )Nc                    s    | d  S r  r4   )r  Zgens_mapr4   r5   rf   R	  rq   z%PolyElement.compose.<locals>.<lambda>rn   z9expected a generator, value pair a sequence of such pairsr   )r6   r   rL   r>   rM   r/   r   r   rV   r  rH   r   r   r   r   r   r  rr   )rl   r  rd   r6   r   Zreplacementsr  r  r   r   Zsubpolyr   r]  r4   r  r5   r   G	  s.   



zPolyElement.composec                 C      | j | |S rU   )r6   Zdmp_pdivr  r4   r4   r5   pdivj	  r   zPolyElement.pdivc                 C   r  rU   )r6   Zdmp_premr  r4   r4   r5   premm	  r   zPolyElement.premc                 C   r  rU   )r6   Zdmp_quor  r4   r4   r5   pquop	  r   zPolyElement.pquoc                 C   r  rU   )r6   Z	dmp_exquor  r4   r4   r5   pexquos	  r   zPolyElement.pexquoc                 C   r  rU   )r6   Zdmp_half_gcdexr  r4   r4   r5   
half_gcdexv	  r   zPolyElement.half_gcdexc                 C   r  rU   )r6   Z	dmp_gcdexr  r4   r4   r5   gcdexy	  r   zPolyElement.gcdexc                 C   r  rU   )r6   Zdmp_subresultantsr  r4   r4   r5   subresultants|	  r   zPolyElement.subresultantsc                 C   r  rU   )r6   Zdmp_resultantr  r4   r4   r5   	resultant	  r   zPolyElement.resultantc                 C      | j | S rU   )r6   Zdmp_discriminantrk   r4   r4   r5   discriminant	  r  zPolyElement.discriminantc                 C   rV  )Nzpolynomial decomposition)r6   r   Zdup_decomposer#   rk   r4   r4   r5   	decompose	     zPolyElement.decomposec                 C   s   | j jr| j | |S td)Nzpolynomial shift)r6   r   Z	dup_shiftr#   )rl   rd   r4   r4   r5   shift	  s   zPolyElement.shiftc                 C   rV  )Nzsturm sequence)r6   r   Z	dup_sturmr#   rk   r4   r4   r5   sturm	  r   zPolyElement.sturmc                 C   r  rU   )r6   Zdmp_gff_listrk   r4   r4   r5   gff_list	  r  zPolyElement.gff_listc                 C   r  rU   )r6   Zdmp_sqf_normrk   r4   r4   r5   sqf_norm	  r  zPolyElement.sqf_normc                 C   r  rU   )r6   Zdmp_sqf_partrk   r4   r4   r5   sqf_part	  r  zPolyElement.sqf_partFc                 C   s   | j j| |dS )N)r]   )r6   Zdmp_sqf_list)rl   r]   r4   r4   r5   sqf_list	  r   zPolyElement.sqf_listc                 C   r  rU   )r6   Zdmp_factor_listrk   r4   r4   r5   factor_list	  r  zPolyElement.factor_listrU   )F)rw   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)  rW   r   r7  r#  r9  r:  r/  r=  r>  r?  r@  rA  rB  rD  rM  rP  rS  rU  rW  rX  rY  r\  r[  r_  r^  rc  r`  ri  rh  rg  rf  rs  ro  rx  rw  r{  rz  __floordiv____rfloordiv__r  r   rv  ry  r  r  r  r  r  r  r  r   r  r   r  r8  r  r  r  r  r  rP   r  r   r  rL  r   r  r  r  rj  rC  r  r  r&  r  r  rp  r  r  rq  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  r4   r4   r4   r5   r`   -  sJ   	0
















6620$!L-,%%


#!	
8,'#
r`   N)Nr   typingr   r   operatorr   r   r   r   r   r	   	functoolsr
   typesr   Zsympy.core.compatibilityr   Zsympy.core.exprr   Zsympy.core.numbersr   r   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   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$   rt   r%   rv   r&   Zsympy.polys.polyutilsr'   r(   r)   Zsympy.printing.defaultsr*   Zsympy.utilitiesr+   Zsympy.utilities.magicr,   r6   r7   r<   rR   r_   rx   r.   rL   r`   r4   r4   r4   r5   <module>   sN     
5  j