B
    dd                @   s  d Z ddlmZmZ ddlmZ ddlmZmZm	Z	m
Z
 ddlmZ ddlmZ ddlmZmZmZ ddlmZmZmZmZmZ dd	lmZ dd
lmZmZ ddlmZm Z m!Z! ddl"m#Z#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l0m1Z1 ddl2m3Z4 ddl5m6Z6 ddl7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@ZA ddlBmCZC ddlDmEZE ddlFmGZGmHZHmIZI ddlJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZTmUZU ddlVmWZWmXZXmYZYmZZZm[Z[m\Z\ ddl]m^Z^ ddl_m`Z` ddlambZbmcZcmdZd dd lemfZf dd!lgmhZhmiZi dd"l2Zjdd"lkZkdd#llmmZm d$d% ZnecG d&d' d'eZoecG d(d) d)eoZpecd*d+ Zqd,d- Zrecd.d/ Zsd0d1 Ztd2d3 Zuecdd4d5Zvecd6d7 Zwecd8d9 Zxecd:d; Zyecd<d= Zzecd>d? Z{ecd@dA Z|ecdBdC Z}ecdDdE Z~ecdFdG ZecdHdI ZecdJdK ZecdLdM ZecdNdO ZecdPdQ ZecdRdS ZecdTdU ZecdVdW ZecdXdYdZd[Zecd\d] Zecd^d_ Zecd`da ZecddbdcZecddde ZecddfdgZecdhdi Zecdjdk Zecdldm Zecdndo Zecdpdq Zecdrds Zecdtdu Zecdvdw Zecdxdy Zecdzd{ Zecd|d} Zecd~d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zecdd Zecdd Zecdd ZecdXdddZecdddZecdddZecdddZecdddZecdddZecdd Zecdd ZecddddZecdd Zecdd Z@ecdd ZecG dd deZecdd Zd"S )z8User-friendly public interface to polynomial functions.     )wrapsreduce)mul)SExprAddTuple)Basic)
_sympifyit)Factors	factor_ncfactor_terms)pure_complexevalffastlog_evalf_with_bounded_errorquad_to_mpmath)
Derivative)Mul_keep_coeff)ilcmIInteger)
RelationalEquality)ordered)DummySymbol)sympify_sympify)preorder_traversal	bottom_up)BooleanAtom)polyoptions)construct_domain)FFQQZZ)DomainElement)matrix_fglm)groebner)Monomial)monomial_key)DMPDMFANP)OperationNotSupportedDomainErrorCoercionFailedUnificationFailedGeneratorsNeededPolynomialErrorMultivariatePolynomialErrorExactQuotientFailedPolificationFailedComputationFailedGeneratorsError)basic_from_dict
_sort_gens_unify_gens_dict_reorder_dict_from_expr_parallel_dict_from_expr)together)dup_isolate_real_roots_list)grouppublic
filldedent)sympy_deprecation_warning)iterablesiftN)NoConvergencec                s   t   fdd}|S )Nc                s   t |}t|tr | |S t|try| j|f| j }W nL tk
r   |jrVtS t	| 
  j}||}|tk	rtdddd |S X  | |S ntS d S )Na@  
                        Mixing Poly with non-polynomial expressions in binary
                        operations is deprecated. Either explicitly convert
                        the non-Poly operand to a Poly with as_poly() or
                        convert the Poly to an Expr with as_expr().
                        z1.6z)deprecated-poly-nonpoly-binary-operations)Zdeprecated_since_versionZactive_deprecations_target)r   
isinstancePolyr   	from_exprgensr5   Z	is_MatrixNotImplementedgetattras_expr__name__rF   )fgZexpr_methodresult)func b/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/sympy/polys/polytools.pywrapperC   s&    


z_polifyit.<locals>.wrapper)r   )rU   rX   rV   )rU   rW   	_polifyitB   s    rY   c                   sB  e Zd ZdZdZdZdZdZdd Ze	dd Z
ed	d
 Zedd Zdd Ze	dd Ze	dd Ze	dd Ze	dd Ze	dd Ze	dd Ze	dd Ze	dd Ze	dd  Z fd!d"Zed#d$ Zed%d& Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zd1d2 Z d3d4 Z!dtd6d7Z"d8d9 Z#d:d; Z$d<d= Z%d>d? Z&d@dA Z'dBdC Z(dudDdEZ)dFdG Z*dHdI Z+dJdK Z,dLdM Z-dNdO Z.dPdQ Z/dRdS Z0dvdTdUZ1dwdVdWZ2dxdXdYZ3dydZd[Z4dzd\d]Z5d^d_ Z6d`da Z7dbdc Z8ddde Z9dfdg Z:d{didjZ;d|dkdlZ<dmdn Z=dodp Z>dqdr Z?dsdt Z@d}dudvZAdwdx ZBdydz ZCd{d| ZDd}d~ ZEdd ZFdd ZGdd ZHdd ZIdd ZJdd ZKdd ZLdd ZMdd ZNdd ZOdd ZPdd ZQdd ZRdd ZSd~ddZTdddZUdddZVdddZWdd ZXdddZYdd ZZdd Z[dd Z\dd Z]dddZ^dd Z_dddZ`dd Zadd ZbdddZcdddZddddZedddZfdddĄZgddƄ ZhddȄ ZidddʄZjdd̄ Zkdd΄ ZlddЄ ZmemZnddd҄ZoddԄ ZpdddքZqddd؄ZrdddڄZsdd܄ Ztddބ ZudddZvdd ZwdddZxdddZydd Zzdd Z{dd Z|dd Z}dddZ~dd Zdd Zdd Zdd Zdd Zdd ZdddZdd  Zdd Zdd Zdd ZdddZdd	d
Zdd Zdd ZdddZdddZdddZdddZdddZdddZdddZdd  Zd!d" Zd#d$ Zdd%d&Zed'd( Zed)d* Zed+d, Zed-d. Zed/d0 Zed1d2 Zed3d4 Zed5d6 Zed7d8 Zed9d: Zed;d< Zed=d> Zed?d@ ZedAdB ZdCdD ZdEdF ZedGdH ZedIdJ ZedKdL ZedMdN ZedOdP ZedQdR ZedSedTdU ZedVdW ZedXdY ZedZd[ Zed\d] Zed^d_ Zed`da Zedbedcdd Zedbededf Zedgedhdi Zedbedjdk Zdldm ZddndoZddpdqZdrds Z  ZS (  rK   aP  
    Generic class for representing and operating on polynomial expressions.

    See :ref:`polys-docs` for general documentation.

    Poly is a subclass of Basic rather than Expr but instances can be
    converted to Expr with the :py:meth:`~.Poly.as_expr` method.

    .. deprecated:: 1.6

       Combining Poly with non-Poly objects in binary operations is
       deprecated. Explicitly convert both objects to either Poly or Expr
       first. See :ref:`deprecated-poly-nonpoly-binary-operations`.

    Examples
    ========

    >>> from sympy import Poly
    >>> from sympy.abc import x, y

    Create a univariate polynomial:

    >>> Poly(x*(x**2 + x - 1)**2)
    Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')

    Create a univariate polynomial with specific domain:

    >>> from sympy import sqrt
    >>> Poly(x**2 + 2*x + sqrt(3), domain='R')
    Poly(1.0*x**2 + 2.0*x + 1.73205080756888, x, domain='RR')

    Create a multivariate polynomial:

    >>> Poly(y*x**2 + x*y + 1)
    Poly(x**2*y + x*y + 1, x, y, domain='ZZ')

    Create a univariate polynomial, where y is a constant:

    >>> Poly(y*x**2 + x*y + 1,x)
    Poly(y*x**2 + y*x + 1, x, domain='ZZ[y]')

    You can evaluate the above polynomial as a function of y:

    >>> Poly(y*x**2 + x*y + 1,x).eval(2)
    6*y + 1

    See Also
    ========

    sympy.core.expr.Expr

    )reprM   Tgn $@c             O   s   t ||}d|krtdt|ttttfr:| ||S t	|t
drnt|tr\| ||S | t||S n&t|}|jr| ||S | ||S dS )z:Create a new polynomial instance out of something useful. orderz&'order' keyword is not implemented yet)excludeN)optionsbuild_optionsNotImplementedErrorrJ   r-   r.   r/   r(   _from_domain_elementrG   strdict
_from_dict
_from_listlistr   is_Poly
_from_poly
_from_expr)clsrZ   rM   argsoptrV   rV   rW   __new__   s    
zPoly.__new__c             G   sT   t |tstd| n"|jt|d kr:td||f t| }||_||_|S )z:Construct :class:`Poly` instance from raw representation. z%invalid polynomial representation: %s   zinvalid arguments: %s, %s)	rJ   r-   r5   levlenr	   rl   rZ   rM   )ri   rZ   rM   objrV   rV   rW   new   s    

zPoly.newc             C   s   t | j f| j S )N)r;   rZ   to_sympy_dictrM   )selfrV   rV   rW   expr   s    z	Poly.exprc             C   s   | j f| j S )N)rt   rM   )rs   rV   rV   rW   rj      s    z	Poly.argsc             C   s   | j f| j S )N)rZ   rM   )rs   rV   rV   rW   _hashable_content   s    zPoly._hashable_contentc             O   s   t ||}| ||S )z(Construct a polynomial from a ``dict``. )r]   r^   rc   )ri   rZ   rM   rj   rk   rV   rV   rW   	from_dict   s    zPoly.from_dictc             O   s   t ||}| ||S )z(Construct a polynomial from a ``list``. )r]   r^   rd   )ri   rZ   rM   rj   rk   rV   rV   rW   	from_list   s    zPoly.from_listc             O   s   t ||}| ||S )z*Construct a polynomial from a polynomial. )r]   r^   rg   )ri   rZ   rM   rj   rk   rV   rV   rW   	from_poly   s    zPoly.from_polyc             O   s   t ||}| ||S )z+Construct a polynomial from an expression. )r]   r^   rh   )ri   rZ   rM   rj   rk   rV   rV   rW   rL      s    zPoly.from_exprc             C   s|   |j }|stdt|d }|j}|dkr>t||d\}}n$x"| D ]\}}||||< qHW | jt	|||f| S )z(Construct a polynomial from a ``dict``. z0Cannot initialize from 'dict' without generatorsrm   N)rk   )
rM   r4   ro   domainr$   itemsconvertrq   r-   rv   )ri   rZ   rk   rM   levelry   monomcoeffrV   rV   rW   rc      s    zPoly._from_dictc             C   s~   |j }|stdnt|dkr(tdt|d }|j}|dkrTt||d\}}ntt|j|}| j	t
|||f| S )z(Construct a polynomial from a ``list``. z0Cannot initialize from 'list' without generatorsrm   z#'list' representation not supportedN)rk   )rM   r4   ro   r6   ry   r$   re   mapr{   rq   r-   rw   )ri   rZ   rk   rM   r|   ry   rV   rV   rW   rd     s    zPoly._from_listc             C   s   | |j kr| j|jf|j }|j}|j}|j}|rj|j|krjt|jt|kr`| | |S |j	| }d|kr|r|
|}n|dkr| }|S )z*Construct a polynomial from a polynomial. ry   T)	__class__rq   rZ   rM   fieldry   setrh   rP   reorder
set_domainto_field)ri   rZ   rk   rM   r   ry   rV   rV   rW   rg     s    

zPoly._from_polyc             C   s   t ||\}}| ||S )z+Construct a polynomial from an expression. )r?   rc   )ri   rZ   rk   rV   rV   rW   rh   3  s    zPoly._from_exprc             C   s>   |j }|j}t|d }||g}| jt|||f| S )Nrm   )rM   ry   ro   r{   rq   r-   rw   )ri   rZ   rk   rM   ry   r|   rV   rV   rW   r`   9  s
    zPoly._from_domain_elementc                s
   t   S )N)super__hash__)rs   )r   rV   rW   r   C  s    zPoly.__hash__c             C   sV   t  }| j}x>tt|D ].}x(|  D ]}|| r(||| jO }P q(W qW || jB S )a  
        Free symbols of a polynomial expression.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> Poly(x**2 + 1).free_symbols
        {x}
        >>> Poly(x**2 + y).free_symbols
        {x, y}
        >>> Poly(x**2 + y, x).free_symbols
        {x, y}
        >>> Poly(x**2 + y, x, z).free_symbols
        {x, y}

        )r   rM   rangero   monomsfree_symbolsfree_symbols_in_domain)rs   symbolsrM   ir}   rV   rV   rW   r   F  s    
zPoly.free_symbolsc             C   sX   | j jt  }}|jr2x<|jD ]}||jO }qW n"|jrTx|  D ]}||jO }qBW |S )aj  
        Free symbols of the domain of ``self``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 1).free_symbols_in_domain
        set()
        >>> Poly(x**2 + y).free_symbols_in_domain
        set()
        >>> Poly(x**2 + y, x).free_symbols_in_domain
        {y}

        )rZ   domr   is_Compositer   r   is_EXcoeffs)rs   ry   r   genr~   rV   rV   rW   r   e  s    zPoly.free_symbols_in_domainc             C   s
   | j d S )z
        Return the principal generator.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).gen
        x

        r   )rM   )rs   rV   rV   rW   r     s    zPoly.genc             C   s   |   S )a  Get the ground domain of a :py:class:`~.Poly`

        Returns
        =======

        :py:class:`~.Domain`:
            Ground domain of the :py:class:`~.Poly`.

        Examples
        ========

        >>> from sympy import Poly, Symbol
        >>> x = Symbol('x')
        >>> p = Poly(x**2 + x)
        >>> p
        Poly(x**2 + x, x, domain='ZZ')
        >>> p.domain
        ZZ
        )
get_domain)rs   rV   rV   rW   ry     s    zPoly.domainc             C   s$   | j | j| jj| jjf| j S )z3Return zero polynomial with ``self``'s properties. )rq   rZ   zerorn   r   rM   )rs   rV   rV   rW   r     s    z	Poly.zeroc             C   s$   | j | j| jj| jjf| j S )z2Return one polynomial with ``self``'s properties. )rq   rZ   onern   r   rM   )rs   rV   rV   rW   r     s    zPoly.onec             C   s$   | j | j| jj| jjf| j S )z3Return unit polynomial with ``self``'s properties. )rq   rZ   unitrn   r   rM   )rs   rV   rV   rW   r     s    z	Poly.unitc             C   s"   |  |\}}}}||||fS )a  
        Make ``f`` and ``g`` belong to the same domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f, g = Poly(x/2 + 1), Poly(2*x + 1)

        >>> f
        Poly(1/2*x + 1, x, domain='QQ')
        >>> g
        Poly(2*x + 1, x, domain='ZZ')

        >>> F, G = f.unify(g)

        >>> F
        Poly(1/2*x + 1, x, domain='QQ')
        >>> G
        Poly(2*x + 1, x, domain='QQ')

        )_unify)rR   rS   _perFGrV   rV   rW   unify  s    z
Poly.unifyc                s  t jsZy&jjjjjjjfS  tk
rX   tdf Y nX tjt	rtjt	rt
jj}jjjj|t|d  }j|krtj j|\}}jjkrfdd|D }t	ttt|||}nj}j|krttj j|\}}jjkrXfdd|D }t	ttt|||}	nj}	ntdf j |d f fdd	}
|
||	fS )NzCannot unify %s with %srm   c                s   g | ]}  |jjqS rV   )r{   rZ   r   ).0c)r   rR   rV   rW   
<listcomp>  s    zPoly._unify.<locals>.<listcomp>c                s   g | ]}  |jjqS rV   )r{   rZ   r   )r   r   )r   rS   rV   rW   r     s    c                sB   |d k	r2|d | ||d d   }|s2| | S  j| f| S )Nrm   )to_sympyrq   )rZ   r   rM   remove)ri   rV   rW   r     s
    
zPoly._unify.<locals>.per)r   rf   rZ   r   r   
from_sympyr2   r3   rJ   r-   r=   rM   r   ro   r>   to_dictrb   re   zipr{   r   )rR   rS   rM   rn   Zf_monomsZf_coeffsr   Zg_monomsZg_coeffsr   r   rV   )ri   r   rR   rS   rW   r     s6    &"	zPoly._unifyNc             C   sV   |dkr| j }|dk	rD|d| ||d d  }|sD| jj|S | jj|f| S )ab  
        Create a Poly out of the given representation.

        Examples
        ========

        >>> from sympy import Poly, ZZ
        >>> from sympy.abc import x, y

        >>> from sympy.polys.polyclasses import DMP

        >>> a = Poly(x**2 + 1)

        >>> a.per(DMP([ZZ(1), ZZ(1)], ZZ), gens=[y])
        Poly(y + 1, y, domain='ZZ')

        Nrm   )rM   rZ   r   r   r   rq   )rR   rZ   rM   r   rV   rV   rW   r   	  s    zPoly.perc             C   s&   t | jd|i}| | j|jS )z Set the ground domain of ``f``. ry   )r]   r^   rM   r   rZ   r{   ry   )rR   ry   rk   rV   rV   rW   r   &  s    zPoly.set_domainc             C   s   | j jS )z Get the ground domain of ``f``. )rZ   r   )rR   rV   rV   rW   r   +  s    zPoly.get_domainc             C   s   t j|}| t|S )z
        Set the modulus of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(5*x**2 + 2*x - 1, x).set_modulus(2)
        Poly(x**2 + 1, x, modulus=2)

        )r]   ZModulus
preprocessr   r%   )rR   modulusrV   rV   rW   set_modulus/  s    zPoly.set_modulusc             C   s&   |   }|jrt| S tddS )z
        Get the modulus of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, modulus=2).get_modulus()
        2

        z$not a polynomial over a Galois fieldN)r   Zis_FiniteFieldr   Zcharacteristicr5   )rR   ry   rV   rV   rW   get_modulus@  s    zPoly.get_modulusc             C   sN   || j kr>|jr| ||S y| ||S  tk
r<   Y nX |  ||S )z)Internal implementation of :func:`subs`. )rM   	is_numberevalreplacer5   rP   subs)rR   oldrq   rV   rV   rW   
_eval_subsU  s    
zPoly._eval_subsc             C   sP   | j  \}}g }x.tt| jD ]}||kr"|| j|  q"W | j||dS )a  
        Remove unnecessary generators from ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import a, b, c, d, x

        >>> Poly(a + x, a, b, c, d, x).exclude()
        Poly(a + x, a, x, domain='ZZ')

        )rM   )rZ   r\   r   ro   rM   appendr   )rR   Jrq   rM   jrV   rV   rW   r\   b  s    zPoly.excludec             K   s   |dkr$| j r| j| }}ntd||ks6|| jkr:| S || jkr|| jkr|  }|jrf||jkrt| j}||||< | j	| j
|dS td||| f dS )a  
        Replace ``x`` with ``y`` in generators list.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 1, x).replace(x, y)
        Poly(y**2 + 1, y, domain='ZZ')

        Nz(syntax supported only in univariate case)rM   zCannot replace %s with %s in %s)is_univariater   r5   rM   r   r   r   re   indexr   rZ   )rR   xy_ignorer   rM   rV   rV   rW   r   y  s    
zPoly.replacec             O   s   |   j||S )z-Match expression from Poly. See Basic.match())rP   match)rR   rj   kwargsrV   rV   rW   r     s    z
Poly.matchc             O   s|   t d|}|s t| j|d}nt| jt|kr:tdtttt	| j
 | j| }| jt|| j
jt|d |dS )a  
        Efficiently apply new order of generators.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + x*y**2, x, y).reorder(y, x)
        Poly(y**2*x + x**2, y, x, domain='ZZ')

        rV   )rk   z7generators list can differ only up to order of elementsrm   )rM   )r]   Optionsr<   rM   r   r5   rb   re   r   r>   rZ   r   r   r-   r   ro   )rR   rM   rj   rk   rZ   rV   rV   rW   r     s     zPoly.reorderc             C   s   | j dd}| |}i }x@| D ]4\}}t|d| rHtd|  ||||d < q$W | j|d }| jt|t	|d | j
jf| S )a(  
        Remove dummy generators from ``f`` that are to the left of
        specified ``gen`` in the generators as ordered. When ``gen``
        is an integer, it refers to the generator located at that
        position within the tuple of generators of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> Poly(y**2 + y*z**2, x, y, z).ltrim(y)
        Poly(y**2 + y*z**2, y, z, domain='ZZ')
        >>> Poly(z, x, y, z).ltrim(-1)
        Poly(z, z, domain='ZZ')

        T)nativeNzCannot left trim %srm   )as_dict_gen_to_levelrz   anyr5   rM   rq   r-   rv   ro   rZ   r   )rR   r   rZ   r   termsr}   r~   rM   rV   rV   rW   ltrim  s    
z
Poly.ltrimc          	   G   s   t  }xL|D ]D}y| j|}W n$ tk
rD   td| |f Y qX || qW x6|  D ]*}x$t|D ]\}}||krl|rldS qlW q^W dS )aJ  
        Return ``True`` if ``Poly(f, *gens)`` retains ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> Poly(x*y + 1, x, y, z).has_only_gens(x, y)
        True
        >>> Poly(x*y + z, x, y, z).has_only_gens(x, y)
        False

        z%s doesn't have %s as generatorFT)r   rM   r   
ValueErrorr:   addr   	enumerate)rR   rM   indicesr   r   r}   r   eltrV   rV   rW   has_only_gens  s    
zPoly.has_only_gensc             C   s,   t | jdr| j }n
t| d| |S )z
        Make the ground domain a ring.

        Examples
        ========

        >>> from sympy import Poly, QQ
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, domain=QQ).to_ring()
        Poly(x**2 + 1, x, domain='ZZ')

        to_ring)hasattrrZ   r   r0   r   )rR   rT   rV   rV   rW   r      s    
zPoly.to_ringc             C   s,   t | jdr| j }n
t| d| |S )z
        Make the ground domain a field.

        Examples
        ========

        >>> from sympy import Poly, ZZ
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x, domain=ZZ).to_field()
        Poly(x**2 + 1, x, domain='QQ')

        r   )r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r     s    
zPoly.to_fieldc             C   s,   t | jdr| j }n
t| d| |S )z
        Make the ground domain exact.

        Examples
        ========

        >>> from sympy import Poly, RR
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1.0, x, domain=RR).to_exact()
        Poly(x**2 + 1, x, domain='QQ')

        to_exact)r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r   *  s    
zPoly.to_exactc             C   s4   t | jdd|| jjpdd\}}| j|| j|dS )a  
        Recalculate the ground domain of a polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = Poly(x**2 + 1, x, domain='QQ[y]')
        >>> f
        Poly(x**2 + 1, x, domain='QQ[y]')

        >>> f.retract()
        Poly(x**2 + 1, x, domain='ZZ')
        >>> f.retract(field=True)
        Poly(x**2 + 1, x, domain='QQ')

        T)r   N)r   Z	composite)ry   )r$   r   ry   r   rv   rM   )rR   r   r   rZ   rV   rV   rW   retract?  s    zPoly.retractc             C   sh   |dkrd||  }}}n
|  |}t|t| }}t| jdrT| j|||}n
t| d| |S )z1Take a continuous subsequence of terms of ``f``. Nr   slice)r   intr   rZ   r   r0   r   )rR   r   mnr   rT   rV   rV   rW   r   W  s    

z
Poly.slicec                s    fdd j j|dD S )aQ  
        Returns all non-zero coefficients from ``f`` in lex order.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x + 3, x).coeffs()
        [1, 2, 3]

        See Also
        ========
        all_coeffs
        coeff_monomial
        nth

        c                s   g | ]} j j|qS rV   )rZ   r   r   )r   r   )rR   rV   rW   r   {  s    zPoly.coeffs.<locals>.<listcomp>)r[   )rZ   r   )rR   r[   rV   )rR   rW   r   g  s    zPoly.coeffsc             C   s   | j j|dS )aU  
        Returns all non-zero monomials from ``f`` in lex order.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).monoms()
        [(2, 0), (1, 2), (1, 1), (0, 1)]

        See Also
        ========
        all_monoms

        )r[   )rZ   r   )rR   r[   rV   rV   rW   r   }  s    zPoly.monomsc                s    fdd j j|dD S )ac  
        Returns all non-zero terms from ``f`` in lex order.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 2*x*y**2 + x*y + 3*y, x, y).terms()
        [((2, 0), 1), ((1, 2), 2), ((1, 1), 1), ((0, 1), 3)]

        See Also
        ========
        all_terms

        c                s"   g | ]\}}| j j|fqS rV   )rZ   r   r   )r   r   r   )rR   rV   rW   r     s    zPoly.terms.<locals>.<listcomp>)r[   )rZ   r   )rR   r[   rV   )rR   rW   r     s    z
Poly.termsc                s    fdd j  D S )a  
        Returns all coefficients from a univariate polynomial ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x - 1, x).all_coeffs()
        [1, 0, 2, -1]

        c                s   g | ]} j j|qS rV   )rZ   r   r   )r   r   )rR   rV   rW   r     s    z#Poly.all_coeffs.<locals>.<listcomp>)rZ   
all_coeffs)rR   rV   )rR   rW   r     s    zPoly.all_coeffsc             C   s
   | j  S )a?  
        Returns all monomials from a univariate polynomial ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x - 1, x).all_monoms()
        [(3,), (2,), (1,), (0,)]

        See Also
        ========
        all_terms

        )rZ   
all_monoms)rR   rV   rV   rW   r     s    zPoly.all_monomsc                s    fdd j  D S )a  
        Returns all terms from a univariate polynomial ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x - 1, x).all_terms()
        [((3,), 1), ((2,), 0), ((1,), 2), ((0,), -1)]

        c                s"   g | ]\}}| j j|fqS rV   )rZ   r   r   )r   r   r   )rR   rV   rW   r     s    z"Poly.all_terms.<locals>.<listcomp>)rZ   	all_terms)rR   rV   )rR   rW   r     s    zPoly.all_termsc             O   sv   i }xX|   D ]L\}}|||}t|tr4|\}}n|}|r||krN|||< qtd| qW | j|f|pn| j|S )ah  
        Apply a function to all terms of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> def func(k, coeff):
        ...     k = k[0]
        ...     return coeff//10**(2-k)

        >>> Poly(x**2 + 20*x + 400).termwise(func)
        Poly(x**2 + 2*x + 4, x, domain='ZZ')

        z%s monomial was generated twice)r   rJ   tupler5   rv   rM   )rR   rU   rM   rj   r   r}   r~   rT   rV   rV   rW   termwise  s    



zPoly.termwisec             C   s   t |  S )z
        Returns the number of non-zero terms in ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 2*x - 1).length()
        3

        )ro   r   )rR   rV   rV   rW   length  s    zPoly.lengthFc             C   s$   |r| j j|dS | j j|dS dS )a  
        Switch to a ``dict`` representation.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 2*x*y**2 - y, x, y).as_dict()
        {(0, 1): -1, (1, 2): 2, (2, 0): 1}

        )r   N)rZ   r   rr   )rR   r   r   rV   rV   rW   r     s    zPoly.as_dictc             C   s   |r| j  S | j  S dS )z%Switch to a ``list`` representation. N)rZ   Zto_listZto_sympy_list)rR   r   rV   rV   rW   as_list!  s    
zPoly.as_listc          	   G   s   |s
| j S t|dkrt|d tr|d }t| j}xP| D ]D\}}y||}W n$ tk
rz   t	d| |f Y q@X |||< q@W t
| j f| S )ar  
        Convert a Poly instance to an Expr instance.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = Poly(x**2 + 2*x*y**2 - y, x, y)

        >>> f.as_expr()
        x**2 + 2*x*y**2 - y
        >>> f.as_expr({x: 5})
        10*y**2 - y + 25
        >>> f.as_expr(5, 6)
        379

        rm   r   z%s doesn't have %s as generator)rt   ro   rJ   rb   re   rM   rz   r   r   r:   r;   rZ   rr   )rR   rM   mappingr   valuer   rV   rV   rW   rP   (  s    
zPoly.as_exprc             O   s<   y"t | f||}|jsdS |S W n tk
r6   dS X dS )a{  Converts ``self`` to a polynomial or returns ``None``.

        >>> from sympy import sin
        >>> from sympy.abc import x, y

        >>> print((x**2 + x*y).as_poly())
        Poly(x**2 + x*y, x, y, domain='ZZ')

        >>> print((x**2 + x*y).as_poly(x, y))
        Poly(x**2 + x*y, x, y, domain='ZZ')

        >>> print((x**2 + sin(y)).as_poly(x, y))
        None

        N)rK   rf   r5   )rs   rM   rj   polyrV   rV   rW   as_polyN  s    zPoly.as_polyc             C   s,   t | jdr| j }n
t| d| |S )a  
        Convert algebraic coefficients to rationals.

        Examples
        ========

        >>> from sympy import Poly, I
        >>> from sympy.abc import x

        >>> Poly(x**2 + I*x + 1, x, extension=I).lift()
        Poly(x**4 + 3*x**2 + 1, x, domain='QQ')

        lift)r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r   h  s    
z	Poly.liftc             C   s4   t | jdr| j \}}n
t| d|| |fS )a+  
        Reduce degree of ``f`` by mapping ``x_i**m`` to ``y_i``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**6*y**2 + x**3 + 1, x, y).deflate()
        ((3, 2), Poly(x**2*y + x + 1, x, y, domain='ZZ'))

        deflate)r   rZ   r   r0   r   )rR   r   rT   rV   rV   rW   r   }  s    
zPoly.deflatec             C   sx   | j j}|jr| S |js$td| t| j dr@| j j|d}n
t| d|r\|j| j	 }n| j	|j }| j
|f| S )a  
        Inject ground domain generators into ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = Poly(x**2*y + x*y**3 + x*y + 1, x)

        >>> f.inject()
        Poly(x**2*y + x*y**3 + x*y + 1, x, y, domain='ZZ')
        >>> f.inject(front=True)
        Poly(y**3*x + y*x**2 + y*x + 1, y, x, domain='ZZ')

        z Cannot inject generators over %sinject)front)rZ   r   is_Numericalrf   r1   r   r   r0   r   rM   rq   )rR   r   r   rT   rM   rV   rV   rW   r     s    
zPoly.injectc             G   s   | j j}|jstd| t|}| jd| |krJ| j|d d }}n4| j| d |krv| jd|  d }}ntd|j| }t| j dr| j j	||d}n
t
| d| j|f| S )a  
        Eject selected generators into the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = Poly(x**2*y + x*y**3 + x*y + 1, x, y)

        >>> f.eject(x)
        Poly(x*y**3 + (x**2 + x)*y + 1, y, domain='ZZ[x]')
        >>> f.eject(y)
        Poly(y*x**2 + (y**3 + y)*x + 1, x, domain='ZZ[y]')

        zCannot eject generators over %sNTFz'can only eject front or back generatorseject)r   )rZ   r   r   r1   ro   rM   r_   r   r   r   r0   rq   )rR   rM   r   kZ_gensr   rT   rV   rV   rW   r     s    

z
Poly.ejectc             C   s4   t | jdr| j \}}n
t| d|| |fS )a  
        Remove GCD of terms from the polynomial ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**6*y**2 + x**3*y, x, y).terms_gcd()
        ((3, 1), Poly(x**3*y + 1, x, y, domain='ZZ'))

        	terms_gcd)r   rZ   r   r0   r   )rR   r   rT   rV   rV   rW   r     s    
zPoly.terms_gcdc             C   s.   t | jdr| j|}n
t| d| |S )z
        Add an element of the ground domain to ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x + 1).add_ground(2)
        Poly(x + 3, x, domain='ZZ')

        
add_ground)r   rZ   r   r0   r   )rR   r~   rT   rV   rV   rW   r     s    
zPoly.add_groundc             C   s.   t | jdr| j|}n
t| d| |S )z
        Subtract an element of the ground domain from ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x + 1).sub_ground(2)
        Poly(x - 1, x, domain='ZZ')

        
sub_ground)r   rZ   r   r0   r   )rR   r~   rT   rV   rV   rW   r     s    
zPoly.sub_groundc             C   s.   t | jdr| j|}n
t| d| |S )z
        Multiply ``f`` by a an element of the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x + 1).mul_ground(2)
        Poly(2*x + 2, x, domain='ZZ')

        
mul_ground)r   rZ   r   r0   r   )rR   r~   rT   rV   rV   rW   r      s    
zPoly.mul_groundc             C   s.   t | jdr| j|}n
t| d| |S )aO  
        Quotient of ``f`` by a an element of the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x + 4).quo_ground(2)
        Poly(x + 2, x, domain='ZZ')

        >>> Poly(2*x + 3).quo_ground(2)
        Poly(x + 1, x, domain='ZZ')

        
quo_ground)r   rZ   r   r0   r   )rR   r~   rT   rV   rV   rW   r   5  s    
zPoly.quo_groundc             C   s.   t | jdr| j|}n
t| d| |S )a  
        Exact quotient of ``f`` by a an element of the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x + 4).exquo_ground(2)
        Poly(x + 2, x, domain='ZZ')

        >>> Poly(2*x + 3).exquo_ground(2)
        Traceback (most recent call last):
        ...
        ExactQuotientFailed: 2 does not divide 3 in ZZ

        exquo_ground)r   rZ   r   r0   r   )rR   r~   rT   rV   rV   rW   r   M  s    
zPoly.exquo_groundc             C   s,   t | jdr| j }n
t| d| |S )z
        Make all coefficients in ``f`` positive.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).abs()
        Poly(x**2 + 1, x, domain='ZZ')

        abs)r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r   g  s    
zPoly.absc             C   s,   t | jdr| j }n
t| d| |S )a4  
        Negate all coefficients in ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).neg()
        Poly(-x**2 + 1, x, domain='ZZ')

        >>> -Poly(x**2 - 1, x)
        Poly(-x**2 + 1, x, domain='ZZ')

        neg)r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r   |  s    
zPoly.negc             C   sT   t |}|js| |S | |\}}}}t| jdrB||}n
t| d||S )a[  
        Add two polynomials ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).add(Poly(x - 2, x))
        Poly(x**2 + x - 1, x, domain='ZZ')

        >>> Poly(x**2 + 1, x) + Poly(x - 2, x)
        Poly(x**2 + x - 1, x, domain='ZZ')

        r   )r   rf   r   r   r   rZ   r   r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r     s    

zPoly.addc             C   sT   t |}|js| |S | |\}}}}t| jdrB||}n
t| d||S )a`  
        Subtract two polynomials ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).sub(Poly(x - 2, x))
        Poly(x**2 - x + 3, x, domain='ZZ')

        >>> Poly(x**2 + 1, x) - Poly(x - 2, x)
        Poly(x**2 - x + 3, x, domain='ZZ')

        sub)r   rf   r   r   r   rZ   r   r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r     s    

zPoly.subc             C   sT   t |}|js| |S | |\}}}}t| jdrB||}n
t| d||S )ap  
        Multiply two polynomials ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).mul(Poly(x - 2, x))
        Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ')

        >>> Poly(x**2 + 1, x)*Poly(x - 2, x)
        Poly(x**3 - 2*x**2 + x - 2, x, domain='ZZ')

        r   )r   rf   r   r   r   rZ   r   r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r     s    

zPoly.mulc             C   s,   t | jdr| j }n
t| d| |S )a3  
        Square a polynomial ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x - 2, x).sqr()
        Poly(x**2 - 4*x + 4, x, domain='ZZ')

        >>> Poly(x - 2, x)**2
        Poly(x**2 - 4*x + 4, x, domain='ZZ')

        sqr)r   rZ   r   r0   r   )rR   rT   rV   rV   rW   r     s    
zPoly.sqrc             C   s6   t |}t| jdr"| j|}n
t| d| |S )aX  
        Raise ``f`` to a non-negative power ``n``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x - 2, x).pow(3)
        Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ')

        >>> Poly(x - 2, x)**3
        Poly(x**3 - 6*x**2 + 12*x - 8, x, domain='ZZ')

        pow)r   r   rZ   r   r0   r   )rR   r   rT   rV   rV   rW   r   	  s
    
zPoly.powc             C   sH   |  |\}}}}t| jdr.||\}}n
t| d||||fS )a#  
        Polynomial pseudo-division of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).pdiv(Poly(2*x - 4, x))
        (Poly(2*x + 4, x, domain='ZZ'), Poly(20, x, domain='ZZ'))

        pdiv)r   r   rZ   r   r0   )rR   rS   r   r   r   r   qrrV   rV   rW   r   #  s
    
z	Poly.pdivc             C   s<   |  |\}}}}t| jdr*||}n
t| d||S )aN  
        Polynomial pseudo-remainder of ``f`` by ``g``.

        Caveat: The function prem(f, g, x) can be safely used to compute
          in Z[x] _only_ subresultant polynomial remainder sequences (prs's).

          To safely compute Euclidean and Sturmian prs's in Z[x]
          employ anyone of the corresponding functions found in
          the module sympy.polys.subresultants_qq_zz. The functions
          in the module with suffix _pg compute prs's in Z[x] employing
          rem(f, g, x), whereas the functions with suffix _amv
          compute prs's in Z[x] employing rem_z(f, g, x).

          The function rem_z(f, g, x) differs from prem(f, g, x) in that
          to compute the remainder polynomials in Z[x] it premultiplies
          the divident times the absolute value of the leading coefficient
          of the divisor raised to the power degree(f, x) - degree(g, x) + 1.


        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).prem(Poly(2*x - 4, x))
        Poly(20, x, domain='ZZ')

        prem)r   r   rZ   r   r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r   :  s
    
z	Poly.premc             C   s<   |  |\}}}}t| jdr*||}n
t| d||S )a  
        Polynomial pseudo-quotient of ``f`` by ``g``.

        See the Caveat note in the function prem(f, g).

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).pquo(Poly(2*x - 4, x))
        Poly(2*x + 4, x, domain='ZZ')

        >>> Poly(x**2 - 1, x).pquo(Poly(2*x - 2, x))
        Poly(2*x + 2, x, domain='ZZ')

        pquo)r   r   rZ   r   r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r   a  s
    
z	Poly.pquoc          
   C   sx   |  |\}}}}t| jdrfy||}W qp tk
rb } z||  | W dd}~X Y qpX n
t| d||S )a  
        Polynomial exact pseudo-quotient of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).pexquo(Poly(2*x - 2, x))
        Poly(2*x + 2, x, domain='ZZ')

        >>> Poly(x**2 + 1, x).pexquo(Poly(2*x - 4, x))
        Traceback (most recent call last):
        ...
        ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1

        pexquoN)r   r   rZ   r   r7   rq   rP   r0   )rR   rS   r   r   r   r   rT   excrV   rV   rW   r   }  s    (
zPoly.pexquoc             C   s   |  |\}}}}d}|r<|jr<|js<| |  }}d}t| jdrX||\}}	n
t| d|ry| |	  }
}W n t	k
r   Y nX |
| }}	||||	fS )a  
        Polynomial division with remainder of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x))
        (Poly(1/2*x + 1, x, domain='QQ'), Poly(5, x, domain='QQ'))

        >>> Poly(x**2 + 1, x).div(Poly(2*x - 4, x), auto=False)
        (Poly(0, x, domain='ZZ'), Poly(x**2 + 1, x, domain='ZZ'))

        FTdiv)
r   is_Ringis_Fieldr   r   rZ   r   r0   r   r2   )rR   rS   autor   r   r   r   r   r   r   QRrV   rV   rW   r     s    

zPoly.divc       	      C   s   |  |\}}}}d}|r<|jr<|js<| |  }}d}t| jdrT||}n
t| d|ry| }W n t	k
r   Y nX ||S )ao  
        Computes the polynomial remainder of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x))
        Poly(5, x, domain='ZZ')

        >>> Poly(x**2 + 1, x).rem(Poly(2*x - 4, x), auto=False)
        Poly(x**2 + 1, x, domain='ZZ')

        FTrem)
r   r   r   r   r   rZ   r   r0   r   r2   )	rR   rS   r   r   r   r   r   r   r   rV   rV   rW   r     s    
zPoly.remc       	      C   s   |  |\}}}}d}|r<|jr<|js<| |  }}d}t| jdrT||}n
t| d|ry| }W n t	k
r   Y nX ||S )aa  
        Computes polynomial quotient of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).quo(Poly(2*x - 4, x))
        Poly(1/2*x + 1, x, domain='QQ')

        >>> Poly(x**2 - 1, x).quo(Poly(x - 1, x))
        Poly(x + 1, x, domain='ZZ')

        FTquo)
r   r   r   r   r   rZ   r   r0   r   r2   )	rR   rS   r   r   r   r   r   r   r   rV   rV   rW   r     s    
zPoly.quoc       
   
   C   s   |  |\}}}}d}|r<|jr<|js<| |  }}d}t| jdry||}W q tk
r }	 z|	| 	 |	 W dd}	~	X Y qX n
t
| d|ry| }W n tk
r   Y nX ||S )a  
        Computes polynomial exact quotient of ``f`` by ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).exquo(Poly(x - 1, x))
        Poly(x + 1, x, domain='ZZ')

        >>> Poly(x**2 + 1, x).exquo(Poly(2*x - 4, x))
        Traceback (most recent call last):
        ...
        ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1

        FTexquoN)r   r   r   r   r   rZ   r   r7   rq   rP   r0   r   r2   )
rR   rS   r   r   r   r   r   r   r   r   rV   rV   rW   r     s"    (
z
Poly.exquoc             C   s   t |trXt| j}| |  kr*|k rDn n|dk r>|| S |S qtd|||f n2y| jt|S  tk
r   td| Y nX dS )z3Returns level associated with the given generator. r   z -%s <= gen < %s expected, got %sz"a valid generator expected, got %sN)rJ   r   ro   rM   r5   r   r   r   )rR   r   r   rV   rV   rW   r   7  s    

zPoly._gen_to_levelr   c             C   s0   |  |}t| jdr"| j|S t| ddS )au  
        Returns degree of ``f`` in ``x_j``.

        The degree of 0 is negative infinity.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + y*x + 1, x, y).degree()
        2
        >>> Poly(x**2 + y*x + y, x, y).degree(y)
        1
        >>> Poly(0, x).degree()
        -oo

        degreeN)r   r   rZ   r   r0   )rR   r   r   rV   rV   rW   r   K  s    
zPoly.degreec             C   s$   t | jdr| j S t| ddS )z
        Returns a list of degrees of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + y*x + 1, x, y).degree_list()
        (2, 1)

        degree_listN)r   rZ   r   r0   )rR   rV   rV   rW   r   f  s    
zPoly.degree_listc             C   s$   t | jdr| j S t| ddS )a  
        Returns the total degree of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + y*x + 1, x, y).total_degree()
        2
        >>> Poly(x + y**5, x, y).total_degree()
        5

        total_degreeN)r   rZ   r   r0   )rR   rV   rV   rW   r   y  s    
zPoly.total_degreec             C   s~   t |tstdt| || jkr8| j|}| j}nt| j}| j|f }t| jdrp| j	| j
||dS t| ddS )a  
        Returns the homogeneous polynomial of ``f``.

        A homogeneous polynomial is a polynomial whose all monomials with
        non-zero coefficients have the same total degree. If you only
        want to check if a polynomial is homogeneous, then use
        :func:`Poly.is_homogeneous`. If you want not only to check if a
        polynomial is homogeneous but also compute its homogeneous order,
        then use :func:`Poly.homogeneous_order`.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> f = Poly(x**5 + 2*x**2*y**2 + 9*x*y**3)
        >>> f.homogenize(z)
        Poly(x**5 + 2*x**2*y**2*z + 9*x*y**3*z, x, y, z, domain='ZZ')

        z``Symbol`` expected, got %s
homogenize)rM   homogeneous_orderN)rJ   r   	TypeErrortyperM   r   ro   r   rZ   r   r   r0   )rR   sr   rM   rV   rV   rW   r     s    


zPoly.homogenizec             C   s$   t | jdr| j S t| ddS )a-  
        Returns the homogeneous order of ``f``.

        A homogeneous polynomial is a polynomial whose all monomials with
        non-zero coefficients have the same total degree. This degree is
        the homogeneous order of ``f``. If you only want to check if a
        polynomial is homogeneous, then use :func:`Poly.is_homogeneous`.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = Poly(x**5 + 2*x**3*y**2 + 9*x*y**4)
        >>> f.homogeneous_order()
        5

        r   N)r   rZ   r   r0   )rR   rV   rV   rW   r     s    
zPoly.homogeneous_orderc             C   sF   |dk	r|  |d S t| jdr.| j }n
t| d| jj|S )z
        Returns the leading coefficient of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(4*x**3 + 2*x**2 + 3*x, x).LC()
        4

        Nr   LC)r   r   rZ   r  r0   r   r   )rR   r[   rT   rV   rV   rW   r    s    
zPoly.LCc             C   s0   t | jdr| j }n
t| d| jj|S )z
        Returns the trailing coefficient of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x**2 + 3*x, x).TC()
        0

        TC)r   rZ   r  r0   r   r   )rR   rT   rV   rV   rW   r    s    
zPoly.TCc             C   s(   t | jdr| |d S t| ddS )z
        Returns the last non-zero coefficient of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 + 2*x**2 + 3*x, x).EC()
        3

        r   ECN)r   rZ   r   r0   )rR   r[   rV   rV   rW   r    s    zPoly.ECc             C   s   | j t|| jj S )aE  
        Returns the coefficient of ``monom`` in ``f`` if there, else None.

        Examples
        ========

        >>> from sympy import Poly, exp
        >>> from sympy.abc import x, y

        >>> p = Poly(24*x*y*exp(8) + 23*x, x, y)

        >>> p.coeff_monomial(x)
        23
        >>> p.coeff_monomial(y)
        0
        >>> p.coeff_monomial(x*y)
        24*exp(8)

        Note that ``Expr.coeff()`` behaves differently, collecting terms
        if possible; the Poly must be converted to an Expr to use that
        method, however:

        >>> p.as_expr().coeff(x)
        24*y*exp(8) + 23
        >>> p.as_expr().coeff(y)
        24*x*exp(8)
        >>> p.as_expr().coeff(x*y)
        24*exp(8)

        See Also
        ========
        nth: more efficient query using exponents of the monomial's generators

        )nthr+   rM   	exponents)rR   r}   rV   rV   rW   coeff_monomial	  s    #zPoly.coeff_monomialc             G   sV   t | jdr>t|t| jkr&td| jjttt| }n
t	| d| jj
|S )a.  
        Returns the ``n``-th coefficient of ``f`` where ``N`` are the
        exponents of the generators in the term of interest.

        Examples
        ========

        >>> from sympy import Poly, sqrt
        >>> from sympy.abc import x, y

        >>> Poly(x**3 + 2*x**2 + 3*x, x).nth(2)
        2
        >>> Poly(x**3 + 2*x*y**2 + y**2, x, y).nth(1, 2)
        2
        >>> Poly(4*sqrt(x)*y)
        Poly(4*y*(sqrt(x)), y, sqrt(x), domain='ZZ')
        >>> _.nth(1, 1)
        4

        See Also
        ========
        coeff_monomial

        r  z,exponent of each generator must be specified)r   rZ   ro   rM   r   r  re   r   r   r0   r   r   )rR   NrT   rV   rV   rW   r  .  s    
zPoly.nthrm   c             C   s   t dd S )NzyEither convert to Expr with `as_expr` method to use Expr's coeff method or else use the `coeff_monomial` method of Polys.)r_   )rR   r   r   rightrV   rV   rW   r~   P  s    z
Poly.coeffc             C   s   t | |d | jS )a  
        Returns the leading monomial of ``f``.

        The Leading monomial signifies the monomial having
        the highest power of the principal generator in the
        expression f.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LM()
        x**2*y**0

        r   )r+   r   rM   )rR   r[   rV   rV   rW   LM\  s    zPoly.LMc             C   s   t | |d | jS )z
        Returns the last non-zero monomial of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).EM()
        x**0*y**1

        r  )r+   r   rM   )rR   r[   rV   rV   rW   EMp  s    zPoly.EMc             C   s"   |  |d \}}t|| j|fS )a  
        Returns the leading term of ``f``.

        The Leading term signifies the term having
        the highest power of the principal generator in the
        expression f along with its coefficient.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).LT()
        (x**2*y**0, 4)

        r   )r   r+   rM   )rR   r[   r}   r~   rV   rV   rW   LT  s    zPoly.LTc             C   s"   |  |d \}}t|| j|fS )z
        Returns the last non-zero term of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(4*x**2 + 2*x*y**2 + x*y + 3*y, x, y).ET()
        (x**0*y**1, 3)

        r  )r   r+   rM   )rR   r[   r}   r~   rV   rV   rW   ET  s    zPoly.ETc             C   s0   t | jdr| j }n
t| d| jj|S )z
        Returns maximum norm of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(-x**2 + 2*x - 3, x).max_norm()
        3

        max_norm)r   rZ   r  r0   r   r   )rR   rT   rV   rV   rW   r    s    
zPoly.max_normc             C   s0   t | jdr| j }n
t| d| jj|S )z
        Returns l1 norm of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(-x**2 + 2*x - 3, x).l1_norm()
        6

        l1_norm)r   rZ   r  r0   r   r   )rR   rT   rV   rV   rW   r    s    
zPoly.l1_normc             C   s   | }|j jjstj|fS | }|jr2|j j }t|j drN|j 	 \}}n
t
|d|||| }}|rx|js||fS || fS dS )a  
        Clear denominators, but keep the ground domain.

        Examples
        ========

        >>> from sympy import Poly, S, QQ
        >>> from sympy.abc import x

        >>> f = Poly(x/2 + S(1)/3, x, domain=QQ)

        >>> f.clear_denoms()
        (6, Poly(3*x + 2, x, domain='QQ'))
        >>> f.clear_denoms(convert=True)
        (6, Poly(3*x + 2, x, domain='ZZ'))

        clear_denomsN)rZ   r   r   r   Oner   has_assoc_Ringget_ringr   r  r0   r   r   r   )rs   r{   rR   r   r~   rT   rV   rV   rW   r    s    



zPoly.clear_denomsc             C   sv   | }| |\}}}}||}||}|jr2|js:||fS |jdd\}}|jdd\}}||}||}||fS )a  
        Clear denominators in a rational function ``f/g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = Poly(x**2/y + 1, x)
        >>> g = Poly(x**3 + y, x)

        >>> p, q = f.rat_clear_denoms(g)

        >>> p
        Poly(x**2 + y, x, domain='ZZ[y]')
        >>> q
        Poly(y*x**3 + y**2, x, domain='ZZ[y]')

        T)r{   )r   r   r  r  r   )rs   rS   rR   r   r   abrV   rV   rW   rat_clear_denoms  s    

zPoly.rat_clear_denomsc             O   s   | }| ddr"|jjjr"| }t|jdr|sF||jjddS |j}x@|D ]8}t|t	rj|\}}n
|d }}|t
|||}qRW ||S t|ddS )a  
        Computes indefinite integral of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 2*x + 1, x).integrate()
        Poly(1/3*x**3 + x**2 + x, x, domain='QQ')

        >>> Poly(x*y**2 + x, x, y).integrate((0, 1), (1, 0))
        Poly(1/2*x**2*y**2 + 1/2*x**2, x, y, domain='QQ')

        r   T	integraterm   )r   N)getrZ   r   r   r   r   r   r  rJ   r   r   r   r0   )rs   specsrj   rR   rZ   specr   r   rV   rV   rW   r  	  s    




zPoly.integratec             O   s   | ddst| f||S t| jdr|s@| | jjddS | j}x@|D ]8}t|trd|\}}n
|d }}|t|| 	|}qLW | |S t
| ddS )aX  
        Computes partial derivative of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + 2*x + 1, x).diff()
        Poly(2*x + 2, x, domain='ZZ')

        >>> Poly(x*y**2 + x, x, y).diff((0, 0), (1, 1))
        Poly(2*x*y, x, y, domain='ZZ')

        evaluateTdiffrm   )r   N)r  r   r   rZ   r   r  rJ   r   r   r   r0   )rR   r  r   rZ   r  r   r   rV   rV   rW   r  F	  s    




z	Poly.diffc             C   s\  | }|dkrt |tr@|}x | D ]\}}|||}q$W |S t |ttfr|}t|t|jkrltdx$t	|j|D ]\}}|||}qzW |S d| }	}n
|
|}	t|jdst|dy|j||	}
W nx tk
rL   |std||jjf nFt|g\}\}| ||j}||}|||}|j||	}
Y nX |j|
|	dS )a  
        Evaluate ``f`` at ``a`` in the given variable.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> Poly(x**2 + 2*x + 3, x).eval(2)
        11

        >>> Poly(2*x*y + 3*x + y + 2, x, y).eval(x, 2)
        Poly(5*y + 8, y, domain='ZZ')

        >>> f = Poly(2*x*y + 3*x + y + 2*z, x, y, z)

        >>> f.eval({x: 2})
        Poly(5*y + 2*z + 6, y, z, domain='ZZ')
        >>> f.eval({x: 2, y: 5})
        Poly(2*z + 31, z, domain='ZZ')
        >>> f.eval({x: 2, y: 5, z: 7})
        45

        >>> f.eval((2, 5))
        Poly(2*z + 31, z, domain='ZZ')
        >>> f(2, 5)
        Poly(2*z + 31, z, domain='ZZ')

        Nztoo many values providedr   r   zCannot evaluate at %s in %s)r   )rJ   rb   rz   r   r   re   ro   rM   r   r   r   r   rZ   r0   r2   r1   r   r$   r   Zunify_with_symbolsr   r{   r   )rs   r   r  r   rR   r   r   r   valuesr   rT   Za_domainZ
new_domainrV   rV   rW   r   n	  s:    



z	Poly.evalc             G   s
   |  |S )az  
        Evaluate ``f`` at the give values.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y, z

        >>> f = Poly(2*x*y + 3*x + y + 2*z, x, y, z)

        >>> f(2)
        Poly(5*y + 2*z + 6, y, z, domain='ZZ')
        >>> f(2, 5)
        Poly(2*z + 31, z, domain='ZZ')
        >>> f(2, 5, 7)
        45

        )r   )rR   r  rV   rV   rW   __call__	  s    zPoly.__call__c       	      C   sd   |  |\}}}}|r.|jr.| |  }}t| jdrJ||\}}n
t| d||||fS )a  
        Half extended Euclidean algorithm of ``f`` and ``g``.

        Returns ``(s, h)`` such that ``h = gcd(f, g)`` and ``s*f = h (mod g)``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
        >>> g = x**3 + x**2 - 4*x - 4

        >>> Poly(f).half_gcdex(Poly(g))
        (Poly(-1/5*x + 3/5, x, domain='QQ'), Poly(x + 1, x, domain='QQ'))

        
half_gcdex)r   r   r   r   rZ   r!  r0   )	rR   rS   r   r   r   r   r   r  hrV   rV   rW   r!  	  s    

zPoly.half_gcdexc       
      C   sl   |  |\}}}}|r.|jr.| |  }}t| jdrL||\}}}	n
t| d||||||	fS )a  
        Extended Euclidean algorithm of ``f`` and ``g``.

        Returns ``(s, t, h)`` such that ``h = gcd(f, g)`` and ``s*f + t*g = h``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = x**4 - 2*x**3 - 6*x**2 + 12*x + 15
        >>> g = x**3 + x**2 - 4*x - 4

        >>> Poly(f).gcdex(Poly(g))
        (Poly(-1/5*x + 3/5, x, domain='QQ'),
         Poly(1/5*x**2 - 6/5*x + 2, x, domain='QQ'),
         Poly(x + 1, x, domain='QQ'))

        gcdex)r   r   r   r   rZ   r#  r0   )
rR   rS   r   r   r   r   r   r  tr"  rV   rV   rW   r#  	  s    

z
Poly.gcdexc             C   sX   |  |\}}}}|r.|jr.| |  }}t| jdrF||}n
t| d||S )a  
        Invert ``f`` modulo ``g`` when possible.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).invert(Poly(2*x - 1, x))
        Poly(-4/3, x, domain='QQ')

        >>> Poly(x**2 - 1, x).invert(Poly(x - 1, x))
        Traceback (most recent call last):
        ...
        NotInvertible: zero divisor

        invert)r   r   r   r   rZ   r%  r0   )rR   rS   r   r   r   r   r   rT   rV   rV   rW   r%  
  s    

zPoly.invertc             C   s2   t | jdr| jt|}n
t| d| |S )ad  
        Compute ``f**(-1)`` mod ``x**n``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(1, x).revert(2)
        Poly(1, x, domain='ZZ')

        >>> Poly(1 + x, x).revert(1)
        Poly(1, x, domain='ZZ')

        >>> Poly(x**2 - 2, x).revert(2)
        Traceback (most recent call last):
        ...
        NotReversible: only units are reversible in a ring

        >>> Poly(1/x, x).revert(1)
        Traceback (most recent call last):
        ...
        PolynomialError: 1/x contains an element of the generators set

        revert)r   rZ   r&  r   r0   r   )rR   r   rT   rV   rV   rW   r&  .
  s    
zPoly.revertc             C   sB   |  |\}}}}t| jdr*||}n
t| dtt||S )ad  
        Computes the subresultant PRS of ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 1, x).subresultants(Poly(x**2 - 1, x))
        [Poly(x**2 + 1, x, domain='ZZ'),
         Poly(x**2 - 1, x, domain='ZZ'),
         Poly(-2, x, domain='ZZ')]

        subresultants)r   r   rZ   r'  r0   re   r   )rR   rS   r   r   r   r   rT   rV   rV   rW   r'  P
  s
    
zPoly.subresultantsc       	      C   sv   |  |\}}}}t| jdrB|r6|j||d\}}qL||}n
t| d|rj||ddtt||fS ||ddS )a  
        Computes the resultant of ``f`` and ``g`` via PRS.

        If includePRS=True, it includes the subresultant PRS in the result.
        Because the PRS is used to calculate the resultant, this is more
        efficient than calling :func:`subresultants` separately.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = Poly(x**2 + 1, x)

        >>> f.resultant(Poly(x**2 - 1, x))
        4
        >>> f.resultant(Poly(x**2 - 1, x), includePRS=True)
        (4, [Poly(x**2 + 1, x, domain='ZZ'), Poly(x**2 - 1, x, domain='ZZ'),
             Poly(-2, x, domain='ZZ')])

        	resultant)
includePRSr   )r   )r   r   rZ   r(  r0   re   r   )	rR   rS   r)  r   r   r   r   rT   r   rV   rV   rW   r(  i
  s    
zPoly.resultantc             C   s0   t | jdr| j }n
t| d| j|ddS )z
        Computes the discriminant of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + 2*x + 3, x).discriminant()
        -8

        discriminantr   )r   )r   rZ   r*  r0   r   )rR   rT   rV   rV   rW   r*  
  s    
zPoly.discriminantc             C   s   ddl m} || |S )a  Compute the *dispersion set* of two polynomials.

        For two polynomials `f(x)` and `g(x)` with `\deg f > 0`
        and `\deg g > 0` the dispersion set `\operatorname{J}(f, g)` is defined as:

        .. math::
            \operatorname{J}(f, g)
            & := \{a \in \mathbb{N}_0 | \gcd(f(x), g(x+a)) \neq 1\} \\
            &  = \{a \in \mathbb{N}_0 | \deg \gcd(f(x), g(x+a)) \geq 1\}

        For a single polynomial one defines `\operatorname{J}(f) := \operatorname{J}(f, f)`.

        Examples
        ========

        >>> from sympy import poly
        >>> from sympy.polys.dispersion import dispersion, dispersionset
        >>> from sympy.abc import x

        Dispersion set and dispersion of a simple polynomial:

        >>> fp = poly((x - 3)*(x + 3), x)
        >>> sorted(dispersionset(fp))
        [0, 6]
        >>> dispersion(fp)
        6

        Note that the definition of the dispersion is not symmetric:

        >>> fp = poly(x**4 - 3*x**2 + 1, x)
        >>> gp = fp.shift(-3)
        >>> sorted(dispersionset(fp, gp))
        [2, 3, 4]
        >>> dispersion(fp, gp)
        4
        >>> sorted(dispersionset(gp, fp))
        []
        >>> dispersion(gp, fp)
        -oo

        Computing the dispersion also works over field extensions:

        >>> from sympy import sqrt
        >>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
        >>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
        >>> sorted(dispersionset(fp, gp))
        [2]
        >>> sorted(dispersionset(gp, fp))
        [1, 4]

        We can even perform the computations for polynomials
        having symbolic coefficients:

        >>> from sympy.abc import a
        >>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
        >>> sorted(dispersionset(fp))
        [0, 1]

        See Also
        ========

        dispersion

        References
        ==========

        1. [ManWright94]_
        2. [Koepf98]_
        3. [Abramov71]_
        4. [Man93]_
        r   )dispersionset)sympy.polys.dispersionr+  )rR   rS   r+  rV   rV   rW   r+  
  s    HzPoly.dispersionsetc             C   s   ddl m} || |S )a  Compute the *dispersion* of polynomials.

        For two polynomials `f(x)` and `g(x)` with `\deg f > 0`
        and `\deg g > 0` the dispersion `\operatorname{dis}(f, g)` is defined as:

        .. math::
            \operatorname{dis}(f, g)
            & := \max\{ J(f,g) \cup \{0\} \} \\
            &  = \max\{ \{a \in \mathbb{N} | \gcd(f(x), g(x+a)) \neq 1\} \cup \{0\} \}

        and for a single polynomial `\operatorname{dis}(f) := \operatorname{dis}(f, f)`.

        Examples
        ========

        >>> from sympy import poly
        >>> from sympy.polys.dispersion import dispersion, dispersionset
        >>> from sympy.abc import x

        Dispersion set and dispersion of a simple polynomial:

        >>> fp = poly((x - 3)*(x + 3), x)
        >>> sorted(dispersionset(fp))
        [0, 6]
        >>> dispersion(fp)
        6

        Note that the definition of the dispersion is not symmetric:

        >>> fp = poly(x**4 - 3*x**2 + 1, x)
        >>> gp = fp.shift(-3)
        >>> sorted(dispersionset(fp, gp))
        [2, 3, 4]
        >>> dispersion(fp, gp)
        4
        >>> sorted(dispersionset(gp, fp))
        []
        >>> dispersion(gp, fp)
        -oo

        Computing the dispersion also works over field extensions:

        >>> from sympy import sqrt
        >>> fp = poly(x**2 + sqrt(5)*x - 1, x, domain='QQ<sqrt(5)>')
        >>> gp = poly(x**2 + (2 + sqrt(5))*x + sqrt(5), x, domain='QQ<sqrt(5)>')
        >>> sorted(dispersionset(fp, gp))
        [2]
        >>> sorted(dispersionset(gp, fp))
        [1, 4]

        We can even perform the computations for polynomials
        having symbolic coefficients:

        >>> from sympy.abc import a
        >>> fp = poly(4*x**4 + (4*a + 8)*x**3 + (a**2 + 6*a + 4)*x**2 + (a**2 + 2*a)*x, x)
        >>> sorted(dispersionset(fp))
        [0, 1]

        See Also
        ========

        dispersionset

        References
        ==========

        1. [ManWright94]_
        2. [Koepf98]_
        3. [Abramov71]_
        4. [Man93]_
        r   )
dispersion)r,  r-  )rR   rS   r-  rV   rV   rW   r-  
  s    HzPoly.dispersionc       	      C   sP   |  |\}}}}t| jdr0||\}}}n
t| d||||||fS )a#  
        Returns the GCD of ``f`` and ``g`` and their cofactors.

        Returns polynomials ``(h, cff, cfg)`` such that ``h = gcd(f, g)``, and
        ``cff = quo(f, h)`` and ``cfg = quo(g, h)`` are, so called, cofactors
        of ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).cofactors(Poly(x**2 - 3*x + 2, x))
        (Poly(x - 1, x, domain='ZZ'),
         Poly(x + 1, x, domain='ZZ'),
         Poly(x - 2, x, domain='ZZ'))

        	cofactors)r   r   rZ   r.  r0   )	rR   rS   r   r   r   r   r"  cffcfgrV   rV   rW   r.  9  s
    
zPoly.cofactorsc             C   s<   |  |\}}}}t| jdr*||}n
t| d||S )a  
        Returns the polynomial GCD of ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).gcd(Poly(x**2 - 3*x + 2, x))
        Poly(x - 1, x, domain='ZZ')

        gcd)r   r   rZ   r1  r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r1  V  s
    
zPoly.gcdc             C   s<   |  |\}}}}t| jdr*||}n
t| d||S )a  
        Returns polynomial LCM of ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 1, x).lcm(Poly(x**2 - 3*x + 2, x))
        Poly(x**3 - 2*x**2 - x + 2, x, domain='ZZ')

        lcm)r   r   rZ   r2  r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r2  m  s
    
zPoly.lcmc             C   s<   | j j|}t| j dr(| j |}n
t| d| |S )a  
        Reduce ``f`` modulo a constant ``p``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**3 + 3*x**2 + 5*x + 7, x).trunc(3)
        Poly(-x**3 - x + 1, x, domain='ZZ')

        trunc)rZ   r   r{   r   r3  r0   r   )rR   prT   rV   rV   rW   r3    s
    
z
Poly.truncc             C   sF   | }|r|j jjr| }t|j dr2|j  }n
t|d||S )az  
        Divides all coefficients by ``LC(f)``.

        Examples
        ========

        >>> from sympy import Poly, ZZ
        >>> from sympy.abc import x

        >>> Poly(3*x**2 + 6*x + 9, x, domain=ZZ).monic()
        Poly(x**2 + 2*x + 3, x, domain='QQ')

        >>> Poly(3*x**2 + 4*x + 2, x, domain=ZZ).monic()
        Poly(x**2 + 4/3*x + 2/3, x, domain='QQ')

        monic)rZ   r   r   r   r   r5  r0   r   )rs   r   rR   rT   rV   rV   rW   r5    s    
z
Poly.monicc             C   s0   t | jdr| j }n
t| d| jj|S )z
        Returns the GCD of polynomial coefficients.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(6*x**2 + 8*x + 12, x).content()
        2

        content)r   rZ   r6  r0   r   r   )rR   rT   rV   rV   rW   r6    s    
zPoly.contentc             C   s>   t | jdr| j \}}n
t| d| jj|| |fS )a  
        Returns the content and a primitive form of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**2 + 8*x + 12, x).primitive()
        (2, Poly(x**2 + 4*x + 6, x, domain='ZZ'))

        	primitive)r   rZ   r7  r0   r   r   r   )rR   contrT   rV   rV   rW   r7    s    
zPoly.primitivec             C   s<   |  |\}}}}t| jdr*||}n
t| d||S )a  
        Computes the functional composition of ``f`` and ``g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + x, x).compose(Poly(x - 1, x))
        Poly(x**2 - x, x, domain='ZZ')

        compose)r   r   rZ   r9  r0   )rR   rS   r   r   r   r   rT   rV   rV   rW   r9    s
    
zPoly.composec             C   s2   t | jdr| j }n
t| dtt| j|S )a=  
        Computes a functional decomposition of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**4 + 2*x**3 - x - 1, x, domain='ZZ').decompose()
        [Poly(x**2 - x - 1, x, domain='ZZ'), Poly(x**2 + x, x, domain='ZZ')]

        	decompose)r   rZ   r:  r0   re   r   r   )rR   rT   rV   rV   rW   r:    s    
zPoly.decomposec             C   s.   t | jdr| j|}n
t| d| |S )a  
        Efficiently compute Taylor shift ``f(x + a)``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 2*x + 1, x).shift(2)
        Poly(x**2 + 2*x + 1, x, domain='ZZ')

        shift)r   rZ   r;  r0   r   )rR   r  rT   rV   rV   rW   r;    s    
z
Poly.shiftc             C   s^   | |\}}|  |\}}| |\}}t|jdrJ|j|j|j}n
t|d||S )a3  
        Efficiently evaluate the functional transformation ``q**n * f(p/q)``.


        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 2*x + 1, x).transform(Poly(x + 1, x), Poly(x - 1, x))
        Poly(4, x, domain='ZZ')

        	transform)r   r   rZ   r<  r0   r   )rR   r4  r   Pr   r   rT   rV   rV   rW   r<  #  s    
zPoly.transformc             C   sL   | }|r|j jjr| }t|j dr2|j  }n
t|dtt|j	|S )a  
        Computes the Sturm sequence of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 - 2*x**2 + x - 3, x).sturm()
        [Poly(x**3 - 2*x**2 + x - 3, x, domain='QQ'),
         Poly(3*x**2 - 4*x + 1, x, domain='QQ'),
         Poly(2/9*x + 25/9, x, domain='QQ'),
         Poly(-2079/4, x, domain='QQ')]

        sturm)
rZ   r   r   r   r   r>  r0   re   r   r   )rs   r   rR   rT   rV   rV   rW   r>  =  s    
z
Poly.sturmc                s4   t  jdr j }n
t d fdd|D S )aI  
        Computes greatest factorial factorization of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = x**5 + 2*x**4 - x**3 - 2*x**2

        >>> Poly(f).gff_list()
        [(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)]

        gff_listc                s   g | ]\}}  ||fqS rV   )r   )r   rS   r   )rR   rV   rW   r   o  s    z!Poly.gff_list.<locals>.<listcomp>)r   rZ   r?  r0   )rR   rT   rV   )rR   rW   r?  Z  s    
zPoly.gff_listc             C   s,   t | jdr| j }n
t| d| |S )a  
        Computes the product, ``Norm(f)``, of the conjugates of
        a polynomial ``f`` defined over a number field ``K``.

        Examples
        ========

        >>> from sympy import Poly, sqrt
        >>> from sympy.abc import x

        >>> a, b = sqrt(2), sqrt(3)

        A polynomial over a quadratic extension.
        Two conjugates x - a and x + a.

        >>> f = Poly(x - a, x, extension=a)
        >>> f.norm()
        Poly(x**2 - 2, x, domain='QQ')

        A polynomial over a quartic extension.
        Four conjugates x - a, x - a, x + a and x + a.

        >>> f = Poly(x - a, x, extension=(a, b))
        >>> f.norm()
        Poly(x**4 - 4*x**2 + 4, x, domain='QQ')

        norm)r   rZ   r@  r0   r   )rR   r   rV   rV   rW   r@  q  s    
z	Poly.normc             C   s>   t | jdr| j \}}}n
t| d|| || |fS )af  
        Computes square-free norm of ``f``.

        Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and
        ``r(x) = Norm(g(x))`` is a square-free polynomial over ``K``,
        where ``a`` is the algebraic extension of the ground domain.

        Examples
        ========

        >>> from sympy import Poly, sqrt
        >>> from sympy.abc import x

        >>> s, f, r = Poly(x**2 + 1, x, extension=[sqrt(3)]).sqf_norm()

        >>> s
        1
        >>> f
        Poly(x**2 - 2*sqrt(3)*x + 4, x, domain='QQ<sqrt(3)>')
        >>> r
        Poly(x**4 - 4*x**2 + 16, x, domain='QQ')

        sqf_norm)r   rZ   rA  r0   r   )rR   r  rS   r   rV   rV   rW   rA    s    
zPoly.sqf_normc             C   s,   t | jdr| j }n
t| d| |S )z
        Computes square-free part of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**3 - 3*x - 2, x).sqf_part()
        Poly(x**2 - x - 2, x, domain='ZZ')

        sqf_part)r   rZ   rB  r0   r   )rR   rT   rV   rV   rW   rB    s    
zPoly.sqf_partc                sH   t  jdr j|\}}n
t d jj| fdd|D fS )a   
        Returns a list of square-free factors of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = 2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16

        >>> Poly(f).sqf_list()
        (2, [(Poly(x + 1, x, domain='ZZ'), 2),
             (Poly(x + 2, x, domain='ZZ'), 3)])

        >>> Poly(f).sqf_list(all=True)
        (2, [(Poly(1, x, domain='ZZ'), 1),
             (Poly(x + 1, x, domain='ZZ'), 2),
             (Poly(x + 2, x, domain='ZZ'), 3)])

        sqf_listc                s   g | ]\}}  ||fqS rV   )r   )r   rS   r   )rR   rV   rW   r     s    z!Poly.sqf_list.<locals>.<listcomp>)r   rZ   rC  r0   r   r   )rR   allr~   factorsrV   )rR   rW   rC    s    
zPoly.sqf_listc                s6   t  jdr j|}n
t d fdd|D S )a  
        Returns a list of square-free factors of ``f``.

        Examples
        ========

        >>> from sympy import Poly, expand
        >>> from sympy.abc import x

        >>> f = expand(2*(x + 1)**3*x**4)
        >>> f
        2*x**7 + 6*x**6 + 6*x**5 + 2*x**4

        >>> Poly(f).sqf_list_include()
        [(Poly(2, x, domain='ZZ'), 1),
         (Poly(x + 1, x, domain='ZZ'), 3),
         (Poly(x, x, domain='ZZ'), 4)]

        >>> Poly(f).sqf_list_include(all=True)
        [(Poly(2, x, domain='ZZ'), 1),
         (Poly(1, x, domain='ZZ'), 2),
         (Poly(x + 1, x, domain='ZZ'), 3),
         (Poly(x, x, domain='ZZ'), 4)]

        sqf_list_includec                s   g | ]\}}  ||fqS rV   )r   )r   rS   r   )rR   rV   rW   r     s    z)Poly.sqf_list_include.<locals>.<listcomp>)r   rZ   rF  r0   )rR   rD  rE  rV   )rR   rW   rF    s    
zPoly.sqf_list_includec                sl   t  jdrBy j \}}W qL tk
r>   tj dfgfS X n
t d jj| fdd|D fS )a~  
        Returns a list of irreducible factors of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y

        >>> Poly(f).factor_list()
        (2, [(Poly(x + y, x, y, domain='ZZ'), 1),
             (Poly(x**2 + 1, x, y, domain='ZZ'), 2)])

        factor_listrm   c                s   g | ]\}}  ||fqS rV   )r   )r   rS   r   )rR   rV   rW   r     s    z$Poly.factor_list.<locals>.<listcomp>)	r   rZ   rG  r1   r   r  r0   r   r   )rR   r~   rE  rV   )rR   rW   rG    s    
zPoly.factor_listc                sT   t  jdr8y j }W qB tk
r4    dfgS X n
t d fdd|D S )a  
        Returns a list of irreducible factors of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> f = 2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y

        >>> Poly(f).factor_list_include()
        [(Poly(2*x + 2*y, x, y, domain='ZZ'), 1),
         (Poly(x**2 + 1, x, y, domain='ZZ'), 2)]

        factor_list_includerm   c                s   g | ]\}}  ||fqS rV   )r   )r   rS   r   )rR   rV   rW   r   :  s    z,Poly.factor_list_include.<locals>.<listcomp>)r   rZ   rH  r1   r0   )rR   rE  rV   )rR   rW   rH  !  s    
zPoly.factor_list_includec             C   s
  |dk	r"t |}|dkr"td|dk	r4t |}|dk	rFt |}t| jdrl| jj||||||d}n
t| d|rdd }|stt||S dd	 }	|\}
}tt||
tt|	|fS d
d }|stt||S dd	 }	|\}
}tt||
tt|	|fS dS )a  
        Compute isolating intervals for roots of ``f``.

        For real roots the Vincent-Akritas-Strzebonski (VAS) continued fractions method is used.

        References
        ==========
        .. [#] Alkiviadis G. Akritas and Adam W. Strzebonski: A Comparative Study of Two Real Root
            Isolation Methods . Nonlinear Analysis: Modelling and Control, Vol. 10, No. 4, 297-304, 2005.
        .. [#] Alkiviadis G. Akritas, Adam W. Strzebonski and Panagiotis S. Vigklas: Improving the
            Performance of the Continued Fractions Method Using new Bounds of Positive Roots. Nonlinear
            Analysis: Modelling and Control, Vol. 13, No. 3, 265-279, 2008.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 3, x).intervals()
        [((-2, -1), 1), ((1, 2), 1)]
        >>> Poly(x**2 - 3, x).intervals(eps=1e-2)
        [((-26/15, -19/11), 1), ((19/11, 26/15), 1)]

        Nr   z!'eps' must be a positive rational	intervals)rD  epsinfsupfastsqfc             S   s   | \}}t |t |fS )N)r&   r   )intervalr  r$  rV   rV   rW   _realh  s    zPoly.intervals.<locals>._realc             S   s@   | \\}}\}}t |tt |  t |tt |  fS )N)r&   r   r   )	rectangleuvr  r$  rV   rV   rW   _complexo  s    z Poly.intervals.<locals>._complexc             S   s$   | \\}}}t |t |f|fS )N)r&   r   )rO  r  r$  r   rV   rV   rW   rP  x  s    c             S   sH   | \\\}}\}}}t |tt |  t |tt |  f|fS )N)r&   r   r   )rQ  rR  rS  r  r$  r   rV   rV   rW   rT    s    )	r&   r{   r   r   rZ   rI  r0   re   r   )rR   rD  rJ  rK  rL  rM  rN  rT   rP  rT  Z	real_partZcomplex_partrV   rV   rW   rI  <  s2    



zPoly.intervalsc       	      C   s   |r| j stdt|t| }}|dk	rJt|}|dkrJtd|dk	r\t|}n|dkrhd}t| jdr| jj|||||d\}}n
t	| dt
|t
|fS )a  
        Refine an isolating interval of a root to the given precision.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 3, x).refine_root(1, 2, eps=1e-2)
        (19/11, 26/15)

        z&only square-free polynomials supportedNr   z!'eps' must be a positive rationalrm   refine_root)rJ  stepsrM  )is_sqfr5   r&   r{   r   r   r   rZ   rU  r0   r   )	rR   r  r$  rJ  rV  rM  	check_sqfr   TrV   rV   rW   rU    s    



zPoly.refine_rootc             C   sL  d\}}|dk	r^t |}|tjkr(d}n6| \}}|sDt|}ntttj||fd }}|dk	rt |}|tjkr~d}n6| \}}|st|}ntttj||fd }}|r|rt	| j
dr| j
j||d}n
t| dn^|r |dk	r |tjf}|r|dk	r|tjf}t	| j
dr:| j
j||d}n
t| dt|S )a<  
        Return the number of roots of ``f`` in ``[inf, sup]`` interval.

        Examples
        ========

        >>> from sympy import Poly, I
        >>> from sympy.abc import x

        >>> Poly(x**4 - 4, x).count_roots(-3, 3)
        2
        >>> Poly(x**4 - 4, x).count_roots(0, 1 + 3*I)
        1

        )TTNFcount_real_roots)rK  rL  count_complex_roots)r   r   NegativeInfinityas_real_imagr&   r{   re   r   Infinityr   rZ   rZ  r0   r   r[  r   )rR   rK  rL  Zinf_realZsup_realreZimcountrV   rV   rW   count_roots  s:    




zPoly.count_rootsc             C   s   t jjj| ||dS )a  
        Get an indexed root of a polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = Poly(2*x**3 - 7*x**2 + 4*x + 4)

        >>> f.root(0)
        -1/2
        >>> f.root(1)
        2
        >>> f.root(2)
        2
        >>> f.root(3)
        Traceback (most recent call last):
        ...
        IndexError: root index out of [-3, 2] range, got 3

        >>> Poly(x**5 + x + 1).root(0)
        CRootOf(x**3 - x**2 + 1, 0)

        )radicals)sympypolysrootoftoolsZrootof)rR   r   rb  rV   rV   rW   root  s    z	Poly.rootc             C   s,   t jjjj| |d}|r|S t|ddS dS )aL  
        Return a list of real roots with multiplicities.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**3 - 7*x**2 + 4*x + 4).real_roots()
        [-1/2, 2, 2]
        >>> Poly(x**3 + x + 1).real_roots()
        [CRootOf(x**3 + x + 1, 0)]

        )rb  F)multipleN)rc  rd  re  CRootOf
real_rootsrC   )rR   rg  rb  ZrealsrV   rV   rW   ri  	  s    zPoly.real_rootsc             C   s,   t jjjj| |d}|r|S t|ddS dS )a  
        Return a list of real and complex roots with multiplicities.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**3 - 7*x**2 + 4*x + 4).all_roots()
        [-1/2, 2, 2]
        >>> Poly(x**3 + x + 1).all_roots()
        [CRootOf(x**3 + x + 1, 0),
         CRootOf(x**3 + x + 1, 1),
         CRootOf(x**3 + x + 1, 2)]

        )rb  F)rg  N)rc  rd  re  rh  	all_rootsrC   )rR   rg  rb  rootsrV   rV   rW   rj     s    zPoly.all_roots   2   c                s  ddl m | jrtd|  |  dkr.g S | jjtkrNdd |  D }n| jjt	krdd |  D }t
|   fdd|  D }nNfdd|  D }yd	d |D }W n$ tk
r   td
| jj Y nX tjj}tj_zy>tj|||d|  d d}tttt|fddd}W n| tk
r   y>tj|||d|  d d}tttt|fddd}W n& tk
r   td|f Y nX Y nX W d|tj_X |S )a  
        Compute numerical approximations of roots of ``f``.

        Parameters
        ==========

        n ... the number of digits to calculate
        maxsteps ... the maximum number of iterations to do

        If the accuracy `n` cannot be reached in `maxsteps`, it will raise an
        exception. You need to rerun with higher maxsteps.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 3).nroots(n=15)
        [-1.73205080756888, 1.73205080756888]
        >>> Poly(x**2 - 3).nroots(n=30)
        [-1.73205080756887729352744634151, 1.73205080756887729352744634151]

        r   )signz$Cannot compute numerical roots of %sc             S   s   g | ]}t |qS rV   )r   )r   r~   rV   rV   rW   r   ^  s    zPoly.nroots.<locals>.<listcomp>c             S   s   g | ]
}|j qS rV   )r   )r   r~   rV   rV   rW   r   `  s    c                s   g | ]}t |  qS rV   )r   )r   r~   )facrV   rW   r   b  s    c                s   g | ]}|j  d  qS ))r   )r   r]  )r   r~   )r   rV   rW   r   d  s   c             S   s   g | ]}t j| qS rV   )mpmathZmpc)r   r~   rV   rV   rW   r   g  s    z!Numerical domain expected, got %sF
   )maxstepscleanuperrorZ	extraprecc                s$   | j r
dnd| jt| j  | j fS )Nrm   r   )imagrealr   )r   )rn  rV   rW   <lambda>x      zPoly.nroots.<locals>.<lambda>)keyrl  c                s$   | j r
dnd| jt| j  | j fS )Nrm   r   )ru  rv  r   )r   )rn  rV   rW   rw    rx  z7convergence to root failed; try n < %s or maxsteps > %sN)Z$sympy.functions.elementary.complexesrn  is_multivariater6   r   rZ   r   r'   r   r&   r   r   r1   rp  mpdpsZ	polyrootsre   r   r   sortedrI   )rR   r   rr  rs  r   Zdenomsr|  rk  rV   )ro  r   rn  rW   nroots9  sL    


zPoly.nrootsc             C   sT   | j rtd|  i }x8|  d D ](\}}|jr$| \}}||| | < q$W |S )a  
        Compute roots of ``f`` by factorization in the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**6 - 4*x**4 + 4*x**3 - x**2).ground_roots()
        {0: 2, 1: 2}

        z!Cannot compute ground roots of %srm   )rz  r6   rG  	is_linearr   )rR   rk  factorr   r  r  rV   rV   rW   ground_roots  s    
zPoly.ground_rootsc             C   sr   | j rtdt|}|jr.|dkr.t|}ntd| | j}td}| | j	
|| | ||}|||S )af  
        Construct a polynomial with n-th powers of roots of ``f``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = Poly(x**4 - x**2 + 1)

        >>> f.nth_power_roots_poly(2)
        Poly(x**4 - 2*x**3 + 3*x**2 - 2*x + 1, x, domain='ZZ')
        >>> f.nth_power_roots_poly(3)
        Poly(x**4 + 2*x**2 + 1, x, domain='ZZ')
        >>> f.nth_power_roots_poly(4)
        Poly(x**4 + 2*x**3 + 3*x**2 + 2*x + 1, x, domain='ZZ')
        >>> f.nth_power_roots_poly(12)
        Poly(x**4 - 4*x**3 + 6*x**2 - 4*x + 1, x, domain='ZZ')

        zmust be a univariate polynomialrm   z&'n' must an integer and n >= 1, got %sr$  )rz  r6   r   
is_Integerr   r   r   r   r(  r   rL   r   )rR   r   r
  r   r$  r   rV   rV   rW   nth_power_roots_poly  s    
zPoly.nth_power_roots_polyc                s   | j rtd| j }| j |}|d }td| di \}}}}t|}|d |d    fdd}	|	||	| }
}|
j	|j	 d |
j
|j
 d  |k S )a  
        Decide whether two roots of this polynomial are equal.

        Examples
        ========

        >>> from sympy import Poly, cyclotomic_poly, exp, I, pi
        >>> f = Poly(cyclotomic_poly(5))
        >>> r0 = exp(2*I*pi/5)
        >>> indices = [i for i, r in enumerate(f.all_roots()) if f.same_root(r, r0)]
        >>> print(indices)
        [3]

        Raises
        ======

        DomainError
            If the domain of the polynomial is not :ref:`ZZ`, :ref:`QQ`,
            :ref:`RR`, or :ref:`CC`.
        MultivariatePolynomialError
            If the polynomial is not univariate.
        PolynomialError
            If the polynomial is of degree < 2.

        zMust be a univariate polynomial	   rm      c                s   t t|  dS )N)r   )r   r   )r   )r   rV   rW   rw    rx  z Poly.same_root.<locals>.<lambda>)rz  r6   rZ   Zmignotte_sep_bound_squaredry   	get_fieldr   r   r   rv  ru  )rR   r  r  Zdom_delta_sqZdelta_sqZeps_sqr   r   r   ZevABrV   )r   rW   	same_root  s    
zPoly.same_rootc             C   s   |  |\}}}}t|dr,|j||d}n
t| d|s~|jrH| }|\}}	}
}||}||	}	||	 ||
||fS tt||S dS )a  
        Cancel common factors in a rational function ``f/g``.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x))
        (1, Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))

        >>> Poly(2*x**2 - 2, x).cancel(Poly(x**2 - 2*x + 1, x), include=True)
        (Poly(2*x + 2, x, domain='ZZ'), Poly(x - 1, x, domain='ZZ'))

        cancel)includeN)	r   r   r  r0   r  r  r   r   r   )rR   rS   r  r   r   r   r   rT   cpcqr4  r   rV   rV   rW   r    s    



zPoly.cancelc             C   s   | j jS )a  
        Returns ``True`` if ``f`` is a zero polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(0, x).is_zero
        True
        >>> Poly(1, x).is_zero
        False

        )rZ   is_zero)rR   rV   rV   rW   r  $  s    zPoly.is_zeroc             C   s   | j jS )a  
        Returns ``True`` if ``f`` is a unit polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(0, x).is_one
        False
        >>> Poly(1, x).is_one
        True

        )rZ   is_one)rR   rV   rV   rW   r  7  s    zPoly.is_onec             C   s   | j jS )a   
        Returns ``True`` if ``f`` is a square-free polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 - 2*x + 1, x).is_sqf
        False
        >>> Poly(x**2 - 1, x).is_sqf
        True

        )rZ   rW  )rR   rV   rV   rW   rW  J  s    zPoly.is_sqfc             C   s   | j jS )a   
        Returns ``True`` if the leading coefficient of ``f`` is one.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x + 2, x).is_monic
        True
        >>> Poly(2*x + 2, x).is_monic
        False

        )rZ   is_monic)rR   rV   rV   rW   r  ]  s    zPoly.is_monicc             C   s   | j jS )a;  
        Returns ``True`` if GCD of the coefficients of ``f`` is one.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(2*x**2 + 6*x + 12, x).is_primitive
        False
        >>> Poly(x**2 + 3*x + 6, x).is_primitive
        True

        )rZ   is_primitive)rR   rV   rV   rW   r  p  s    zPoly.is_primitivec             C   s   | j jS )aJ  
        Returns ``True`` if ``f`` is an element of the ground domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x, x).is_ground
        False
        >>> Poly(2, x).is_ground
        True
        >>> Poly(y, x).is_ground
        True

        )rZ   	is_ground)rR   rV   rV   rW   r    s    zPoly.is_groundc             C   s   | j jS )a,  
        Returns ``True`` if ``f`` is linear in all its variables.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x + y + 2, x, y).is_linear
        True
        >>> Poly(x*y + 2, x, y).is_linear
        False

        )rZ   r  )rR   rV   rV   rW   r    s    zPoly.is_linearc             C   s   | j jS )a6  
        Returns ``True`` if ``f`` is quadratic in all its variables.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x*y + 2, x, y).is_quadratic
        True
        >>> Poly(x*y**2 + 2, x, y).is_quadratic
        False

        )rZ   is_quadratic)rR   rV   rV   rW   r    s    zPoly.is_quadraticc             C   s   | j jS )a%  
        Returns ``True`` if ``f`` is zero or has only one term.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(3*x**2, x).is_monomial
        True
        >>> Poly(3*x**2 + 1, x).is_monomial
        False

        )rZ   is_monomial)rR   rV   rV   rW   r    s    zPoly.is_monomialc             C   s   | j jS )aZ  
        Returns ``True`` if ``f`` is a homogeneous polynomial.

        A homogeneous polynomial is a polynomial whose all monomials with
        non-zero coefficients have the same total degree. If you want not
        only to check if a polynomial is homogeneous but also compute its
        homogeneous order, then use :func:`Poly.homogeneous_order`.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + x*y, x, y).is_homogeneous
        True
        >>> Poly(x**3 + x*y, x, y).is_homogeneous
        False

        )rZ   is_homogeneous)rR   rV   rV   rW   r    s    zPoly.is_homogeneousc             C   s   | j jS )aG  
        Returns ``True`` if ``f`` has no factors over its domain.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> Poly(x**2 + x + 1, x, modulus=2).is_irreducible
        True
        >>> Poly(x**2 + 1, x, modulus=2).is_irreducible
        False

        )rZ   is_irreducible)rR   rV   rV   rW   r    s    zPoly.is_irreduciblec             C   s   t | jdkS )a  
        Returns ``True`` if ``f`` is a univariate polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + x + 1, x).is_univariate
        True
        >>> Poly(x*y**2 + x*y + 1, x, y).is_univariate
        False
        >>> Poly(x*y**2 + x*y + 1, x).is_univariate
        True
        >>> Poly(x**2 + x + 1, x, y).is_univariate
        False

        rm   )ro   rM   )rR   rV   rV   rW   r     s    zPoly.is_univariatec             C   s   t | jdkS )a  
        Returns ``True`` if ``f`` is a multivariate polynomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x, y

        >>> Poly(x**2 + x + 1, x).is_multivariate
        False
        >>> Poly(x*y**2 + x*y + 1, x, y).is_multivariate
        True
        >>> Poly(x*y**2 + x*y + 1, x).is_multivariate
        False
        >>> Poly(x**2 + x + 1, x, y).is_multivariate
        True

        rm   )ro   rM   )rR   rV   rV   rW   rz    s    zPoly.is_multivariatec             C   s   | j jS )a  
        Returns ``True`` if ``f`` is a cyclotomic polnomial.

        Examples
        ========

        >>> from sympy import Poly
        >>> from sympy.abc import x

        >>> f = x**16 + x**14 - x**10 + x**8 - x**6 + x**2 + 1

        >>> Poly(f).is_cyclotomic
        False

        >>> g = x**16 + x**14 - x**10 - x**8 - x**6 + x**2 + 1

        >>> Poly(g).is_cyclotomic
        True

        )rZ   is_cyclotomic)rR   rV   rV   rW   r  *  s    zPoly.is_cyclotomicc             C   s   |   S )N)r   )rR   rV   rV   rW   __abs__B  s    zPoly.__abs__c             C   s   |   S )N)r   )rR   rV   rV   rW   __neg__E  s    zPoly.__neg__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   __add__H  s    zPoly.__add__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __radd__L  s    zPoly.__radd__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   __sub__P  s    zPoly.__sub__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __rsub__T  s    zPoly.__rsub__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   __mul__X  s    zPoly.__mul__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __rmul__\  s    zPoly.__rmul__r   c             C   s    |j r|dkr| |S tS d S )Nr   )r  r   rN   )rR   r   rV   rV   rW   __pow__`  s    
zPoly.__pow__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   
__divmod__g  s    zPoly.__divmod__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __rdivmod__k  s    zPoly.__rdivmod__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   __mod__o  s    zPoly.__mod__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __rmod__s  s    zPoly.__rmod__c             C   s
   |  |S )N)r   )rR   rS   rV   rV   rW   __floordiv__w  s    zPoly.__floordiv__c             C   s
   | | S )N)r   )rR   rS   rV   rV   rW   __rfloordiv__{  s    zPoly.__rfloordiv__rS   c             C   s   |   |   S )N)rP   )rR   rS   rV   rV   rW   __truediv__  s    zPoly.__truediv__c             C   s   |  |    S )N)rP   )rR   rS   rV   rV   rW   __rtruediv__  s    zPoly.__rtruediv__otherc          
   C   sv   | | }}|j sFy|j||j| d}W n tttfk
rD   dS X |j|jkrVdS |jj|jjkrjdS |j|jkS )N)ry   F)	rf   r   rM   r   r5   r1   r2   rZ   r   )rs   r  rR   rS   rV   rV   rW   __eq__  s    
zPoly.__eq__c             C   s
   | |k S )NrV   )rR   rS   rV   rV   rW   __ne__  s    zPoly.__ne__c             C   s   | j  S )N)r  )rR   rV   rV   rW   __bool__  s    zPoly.__bool__c             C   s   |s| |kS |  t|S d S )N)
_strict_eqr   )rR   rS   strictrV   rV   rW   eq  s    zPoly.eqc             C   s   | j ||d S )N)r  )r  )rR   rS   r  rV   rV   rW   ne  s    zPoly.nec             C   s*   t || jo(| j|jko(| jj|jddS )NT)r  )rJ   r   rM   rZ   r  )rR   rS   rV   rV   rW   r    s    zPoly._strict_eq)NN)N)N)N)N)N)N)FF)F)F)T)T)T)T)r   )N)N)rm   F)N)N)N)N)F)NT)T)T)T)F)N)N)T)T)F)F)FNNNFF)NNFF)NN)T)TT)TT)rl  rm  T)F)F)F)rQ   
__module____qualname____doc__	__slots__is_commutativerf   Z_op_priorityrl   classmethodrq   propertyrt   rj   ru   rv   rw   rx   rL   rc   rd   rg   rh   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   r   r   r   r   r   r   r   r   r   r   rP   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r	  r  r~   r  r  r  r  r  r  r  r  r  r  Z_eval_derivativer   r   r!  r#  r%  r&  r'  r(  r*  r+  r-  r.  r1  r2  r3  r5  r6  r7  r9  r:  r;  r<  r>  r?  r@  rA  rB  rC  rF  rG  rH  rI  rU  ra  rf  ri  rj  r~  r  r  r  r  r  r  rW  r  r  r  r  r  r  r  r  r   rz  r  r  r  rY   r  r  r  r  r  r  r
   rN   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  __classcell__rV   rV   )r   rW   rK   d   sr  5
3#$"%&%*''%%*"%"''(&K!"%KK
#!L%?P(3%rK   c                   sV   e Zd ZdZdd Z fddZedd Zede	d	d
 Z
dd Zdd Z  ZS )PurePolyz)Class for representing pure polynomials. c             C   s   | j fS )z$Allow SymPy to hash Poly instances. )rZ   )rs   rV   rV   rW   ru     s    zPurePoly._hashable_contentc                s
   t   S )N)r   r   )rs   )r   rV   rW   r     s    zPurePoly.__hash__c             C   s   | j S )aR  
        Free symbols of a polynomial.

        Examples
        ========

        >>> from sympy import PurePoly
        >>> from sympy.abc import x, y

        >>> PurePoly(x**2 + 1).free_symbols
        set()
        >>> PurePoly(x**2 + y).free_symbols
        set()
        >>> PurePoly(x**2 + y, x).free_symbols
        {y}

        )r   )rs   rV   rV   rW   r     s    zPurePoly.free_symbolsr  c          
   C   s   | | }}|j sFy|j||j| d}W n tttfk
rD   dS X t|jt|jkr^dS |jj	|jj	kry|jj	
|jj	|j}W n tk
r   dS X ||}||}|j|jkS )N)ry   F)rf   r   rM   r   r5   r1   r2   ro   rZ   r   r   r3   r   )rs   r  rR   rS   r   rV   rV   rW   r    s     


zPurePoly.__eq__c             C   s   t || jo| jj|jddS )NT)r  )rJ   r   rZ   r  )rR   rS   rV   rV   rW   r    s    zPurePoly._strict_eqc                s   t |}|jsZy&| jj| j| j| j| jj|fS  tk
rX   td| |f Y nX t| j	t|j	kr~td| |f t
| jtrt
|jtstd| |f | j | j	}| jj|jj|}| j|}|j|}||d f fdd	}||||fS )NzCannot unify %s with %sc                sB   |d k	r2|d | ||d d   }|s2| | S  j| f| S )Nrm   )r   rq   )rZ   r   rM   r   )ri   rV   rW   r     s
    
zPurePoly._unify.<locals>.per)r   rf   rZ   r   r   r   r2   r3   ro   rM   rJ   r-   r   r   r{   )rR   rS   rM   r   r   r   r   rV   )ri   rW   r     s"    &	zPurePoly._unify)rQ   r  r  r  ru   r   r  r   r
   rN   r  r  r   r  rV   rV   )r   rW   r    s   r  c             O   s   t ||}t| |S )z+Construct a polynomial from an expression. )r]   r^   _poly_from_expr)rt   rM   rj   rk   rV   rV   rW   poly_from_expr  s    r  c             C   s  | t |  }} t| ts&t||| nJ| jrb| j| |}|j|_|j|_|j	dkrZd|_	||fS |j
rp| 
 } t| |\}}|jst||| ttt|  \}}|j}|dkrt||d\|_}ntt|j|}ttt||}t||}|j	dkr
d|_	||fS )z+Construct a polynomial from an expression. NT)rk   F)r   rJ   r	   r8   rf   r   rg   rM   ry   rd  expandr?   re   r   rz   r$   r   r   rb   rK   rc   )rt   rk   origr   rZ   r   r   ry   rV   rV   rW   r    s2    

r  c             O   s   t ||}t| |S )z(Construct polynomials from expressions. )r]   r^   _parallel_poly_from_expr)exprsrM   rj   rk   rV   rV   rW   parallel_poly_from_expr:  s    r  c             C   s  ddl m} t| dkr| \}}t|trt|tr|j||}|j||}||\}}|j|_|j	|_	|j
dkr~d|_
||g|fS t| g  }} g g  }}d}x`t|D ]T\}	}
t|
}
t|
tr|
jr||	 q||	 |jr|
 }
nd}| |
 qW |rt||| d|rBx|D ]}	| |	  | |	< q(W t| |\}}|jsft||| dx$|jD ]}t||rntdqnW g g  }}g }g }xH|D ]@}ttt|  \}}|| || |t| qW |j	}|dkrt||d\|_	}ntt|j|}x,|D ]$}||d|  ||d }q"W g }x@t||D ]2\}}ttt||}t||}|| qZW |j
dkrt||_
||fS )	z(Construct polynomials from expressions. r   )	Piecewiser  NTFz&Piecewise generators do not make sense)rk   )$sympy.functions.elementary.piecewiser  ro   rJ   rK   r   rg   r   rM   ry   rd  re   r   r   r	   rf   r   r  r8   rP   r@   r5   r   rz   extendr$   r   r   rb   rc   bool)r  rk   r  rR   rS   ZorigsZ_exprsZ_polysfailedr   rt   repsr   Zcoeffs_listlengthsr   r   rZ   r   r   ry   rd  r   rV   rV   rW   r  A  sv    












r  c             C   s   t | } || kr|| |< | S )z7Add a new ``(key, value)`` pair to arguments ``dict``. )rb   )rj   ry  r   rV   rV   rW   _update_args  s    r  c             C   s   t | dd} t |ddj}| jr0| }| j}n*| j}|sZ|rLt| \}}nt| |\}}|rn| rhtjS tjS |s| jr||jkrt|  \}}||jkrtjS n4| jst	| j
dkrttd| tt| j
|f ||}t|trt|S tjS )a  
    Return the degree of ``f`` in the given variable.

    The degree of 0 is negative infinity.

    Examples
    ========

    >>> from sympy import degree
    >>> from sympy.abc import x, y

    >>> degree(x**2 + y*x + 1, gen=x)
    2
    >>> degree(x**2 + y*x + 1, gen=y)
    1
    >>> degree(0, x)
    -oo

    See also
    ========

    sympy.polys.polytools.Poly.total_degree
    degree_list
    T)r  rm   z
         A symbolic generator of interest is required for a multivariate
         expression like func = %s, e.g. degree(func, gen = %s) instead of
         degree(func, gen = %s).
        )r   	is_Numberrf   rP   r  r   Zeror\  rM   ro   r   r   rE   nextr   r   rJ   r   r   )rR   r   Z
gen_is_Numr4  ZisNumr   rT   rV   rV   rW   r     s,    

r   c             G   sH   t | }|jr| }|jr"d}n| jr2|p0| j}t|| }t|S )a  
    Return the total_degree of ``f`` in the given variables.

    Examples
    ========
    >>> from sympy import total_degree, Poly
    >>> from sympy.abc import x, y

    >>> total_degree(1)
    0
    >>> total_degree(x + x*y)
    2
    >>> total_degree(x + x*y, x)
    1

    If the expression is a Poly and no variables are given
    then the generators of the Poly will be used:

    >>> p = Poly(x + x*y, y)
    >>> total_degree(p)
    1

    To deal with the underlying expression of the Poly, convert
    it to an Expr:

    >>> total_degree(p.as_expr())
    2

    This is done automatically if any variables are given:

    >>> total_degree(p, x)
    1

    See also
    ========
    degree
    r   )r   rf   rP   r  rM   rK   r   r   )rR   rM   r4  rvrV   rV   rW   r     s    (
r   c          
   O   sl   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | }ttt|S )z
    Return a list of degrees of ``f`` in all variables.

    Examples
    ========

    >>> from sympy import degree_list
    >>> from sympy.abc import x, y

    >>> degree_list(x**2 + y*x + 1)
    (2, 1)

    rd  r   rm   N)	r]   allowed_flagsr  r8   r9   r   r   r   r   )rR   rM   rj   r   rk   r   degreesrV   rV   rW   r     s    r   c          
   O   sd   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX |j|jdS )z
    Return the leading coefficient of ``f``.

    Examples
    ========

    >>> from sympy import LC
    >>> from sympy.abc import x, y

    >>> LC(4*x**2 + 2*x*y**2 + x*y + 3*y)
    4

    rd  r  rm   N)r[   )r]   r  r  r8   r9   r  r[   )rR   rM   rj   r   rk   r   rV   rV   rW   r  5  s    r  c          
   O   sl   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX |j|jd}| S )z
    Return the leading monomial of ``f``.

    Examples
    ========

    >>> from sympy import LM
    >>> from sympy.abc import x, y

    >>> LM(4*x**2 + 2*x*y**2 + x*y + 3*y)
    x**2

    rd  r  rm   N)r[   )r]   r  r  r8   r9   r  r[   rP   )rR   rM   rj   r   rk   r   r}   rV   rV   rW   r  N  s    r  c          
   O   st   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX |j|jd\}}||  S )z
    Return the leading term of ``f``.

    Examples
    ========

    >>> from sympy import LT
    >>> from sympy.abc import x, y

    >>> LT(4*x**2 + 2*x*y**2 + x*y + 3*y)
    4*x**2

    rd  r  rm   N)r[   )r]   r  r  r8   r9   r  r[   rP   )rR   rM   rj   r   rk   r   r}   r~   rV   rV   rW   r  h  s    r  c       
   
   O   s   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX ||\}}	|js| |	 fS ||	fS dS )z
    Compute polynomial pseudo-division of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import pdiv
    >>> from sympy.abc import x

    >>> pdiv(x**2 + 1, 2*x - 4)
    (2*x + 4, 20)

    rd  r   r  N)r]   r  r  r8   r9   r   rd  rP   )
rR   rS   rM   rj   r   r   rk   r   r   r   rV   rV   rW   r     s     r   c       	   
   O   s~   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX ||}|jsv| S |S dS )z
    Compute polynomial pseudo-remainder of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import prem
    >>> from sympy.abc import x

    >>> prem(x**2 + 1, 2*x - 4)
    20

    rd  r   r  N)r]   r  r  r8   r9   r   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r     s     
r   c       	   
   O   s   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX y||}W n tk
r   t| |Y nX |js| S |S dS )z
    Compute polynomial pseudo-quotient of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import pquo
    >>> from sympy.abc import x

    >>> pquo(x**2 + 1, 2*x - 4)
    2*x + 4
    >>> pquo(x**2 - 1, 2*x - 1)
    2*x + 1

    rd  r   r  N)	r]   r  r  r8   r9   r   r7   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r     s     r   c       	   
   O   s~   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX ||}|jsv| S |S dS )a_  
    Compute polynomial exact pseudo-quotient of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import pexquo
    >>> from sympy.abc import x

    >>> pexquo(x**2 - 1, 2*x - 2)
    2*x + 2

    >>> pexquo(x**2 + 1, 2*x - 4)
    Traceback (most recent call last):
    ...
    ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1

    rd  r   r  N)r]   r  r  r8   r9   r   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r     s     
r   c       
   
   O   s   t |ddg y t| |ff||\\}}}W n. tk
r^ } ztdd|W dd}~X Y nX |j||jd\}}	|js| |	 fS ||	fS dS )a  
    Compute polynomial division of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import div, ZZ, QQ
    >>> from sympy.abc import x

    >>> div(x**2 + 1, 2*x - 4, domain=ZZ)
    (0, x**2 + 1)
    >>> div(x**2 + 1, 2*x - 4, domain=QQ)
    (x/2 + 1, 5)

    r   rd  r   r  N)r   )	r]   r  r  r8   r9   r   r   rd  rP   )
rR   rS   rM   rj   r   r   rk   r   r   r   rV   rV   rW   r     s     r   c       	   
   O   s   t |ddg y t| |ff||\\}}}W n. tk
r^ } ztdd|W dd}~X Y nX |j||jd}|js~| S |S dS )a  
    Compute polynomial remainder of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import rem, ZZ, QQ
    >>> from sympy.abc import x

    >>> rem(x**2 + 1, 2*x - 4, domain=ZZ)
    x**2 + 1
    >>> rem(x**2 + 1, 2*x - 4, domain=QQ)
    5

    r   rd  r   r  N)r   )	r]   r  r  r8   r9   r   r   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r   $  s     r   c       	   
   O   s   t |ddg y t| |ff||\\}}}W n. tk
r^ } ztdd|W dd}~X Y nX |j||jd}|js~| S |S dS )z
    Compute polynomial quotient of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import quo
    >>> from sympy.abc import x

    >>> quo(x**2 + 1, 2*x - 4)
    x/2 + 1
    >>> quo(x**2 - 1, x - 1)
    x + 1

    r   rd  r   r  N)r   )	r]   r  r  r8   r9   r   r   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r   D  s     r   c       	   
   O   s   t |ddg y t| |ff||\\}}}W n. tk
r^ } ztdd|W dd}~X Y nX |j||jd}|js~| S |S dS )aQ  
    Compute polynomial exact quotient of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import exquo
    >>> from sympy.abc import x

    >>> exquo(x**2 - 1, x - 1)
    x + 1

    >>> exquo(x**2 + 1, 2*x - 4)
    Traceback (most recent call last):
    ...
    ExactQuotientFailed: 2*x - 4 does not divide x**2 + 1

    r   rd  r   r  N)r   )	r]   r  r  r8   r9   r   r   rd  rP   )	rR   rS   rM   rj   r   r   rk   r   r   rV   rV   rW   r   d  s     r   c             O   s   t |ddg y t| |ff||\\}}}W n~ tk
r } z`t|j\}\}	}
y||	|
\}}W n  tk
r   tdd|Y nX |	||	|fS W dd}~X Y nX |j||j
d\}}|js| | fS ||fS dS )aT  
    Half extended Euclidean algorithm of ``f`` and ``g``.

    Returns ``(s, h)`` such that ``h = gcd(f, g)`` and ``s*f = h (mod g)``.

    Examples
    ========

    >>> from sympy import half_gcdex
    >>> from sympy.abc import x

    >>> half_gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
    (3/5 - x/5, x + 1)

    r   rd  r!  r  N)r   )r]   r  r  r8   r$   r  r!  r_   r9   r   r   rd  rP   )rR   rS   rM   rj   r   r   rk   r   ry   r  r  r  r"  rV   rV   rW   r!    s     &r!  c             O   s   t |ddg y t| |ff||\\}}}W n tk
r } zjt|j\}\}	}
y||	|
\}}}W n  tk
r   tdd|Y nX |	||	||	|fS W dd}~X Y nX |j||j
d\}}}|js| | | fS |||fS dS )aZ  
    Extended Euclidean algorithm of ``f`` and ``g``.

    Returns ``(s, t, h)`` such that ``h = gcd(f, g)`` and ``s*f + t*g = h``.

    Examples
    ========

    >>> from sympy import gcdex
    >>> from sympy.abc import x

    >>> gcdex(x**4 - 2*x**3 - 6*x**2 + 12*x + 15, x**3 + x**2 - 4*x - 4)
    (3/5 - x/5, x**2/5 - 6*x/5 + 2, x + 1)

    r   rd  r#  r  N)r   )r]   r  r  r8   r$   r  r#  r_   r9   r   r   rd  rP   )rR   rS   rM   rj   r   r   rk   r   ry   r  r  r  r$  r"  rV   rV   rW   r#    s     .r#  c             O   s   t |ddg y t| |ff||\\}}}W nh tk
r } zJt|j\}\}	}
y|||	|
S  tk
r   t	dd|Y nX W dd}~X Y nX |j||j
d}|js| S |S dS )a  
    Invert ``f`` modulo ``g`` when possible.

    Examples
    ========

    >>> from sympy import invert, S, mod_inverse
    >>> from sympy.abc import x

    >>> invert(x**2 - 1, 2*x - 1)
    -4/3

    >>> invert(x**2 - 1, x - 1)
    Traceback (most recent call last):
    ...
    NotInvertible: zero divisor

    For more efficient inversion of Rationals,
    use the :obj:`~.mod_inverse` function:

    >>> mod_inverse(3, 5)
    2
    >>> (S(2)/5).invert(S(7)/3)
    5/2

    See Also
    ========

    sympy.core.numbers.mod_inverse

    r   rd  r%  r  N)r   )r]   r  r  r8   r$   r  r   r%  r_   r9   r   rd  rP   )rR   rS   rM   rj   r   r   rk   r   ry   r  r  r"  rV   rV   rW   r%    s    ! $r%  c       	   
   O   s   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX ||}|js|dd |D S |S dS )z
    Compute subresultant PRS of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import subresultants
    >>> from sympy.abc import x

    >>> subresultants(x**2 + 1, x**2 - 1)
    [x**2 + 1, x**2 - 1, -2]

    rd  r'  r  Nc             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r   #  s    z!subresultants.<locals>.<listcomp>)r]   r  r  r8   r9   r'  rd  )	rR   rS   rM   rj   r   r   rk   r   rT   rV   rV   rW   r'  
  s     
r'  F)r)  c         
   O   s   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX |rv|j||d\}	}
n
||}	|js|r|	 dd |
D fS |	 S |r|	|
fS |	S dS )z
    Compute resultant of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import resultant
    >>> from sympy.abc import x

    >>> resultant(x**2 + 1, x**2 - 1)
    4

    rd  r(  r  N)r)  c             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r   E  s    zresultant.<locals>.<listcomp>)r]   r  r  r8   r9   r(  rd  rP   )rR   rS   r)  rM   rj   r   r   rk   r   rT   r   rV   rV   rW   r(  (  s     
r(  c          
   O   st   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | }|jsl| S |S dS )z
    Compute discriminant of ``f``.

    Examples
    ========

    >>> from sympy import discriminant
    >>> from sympy.abc import x

    >>> discriminant(x**2 + 2*x + 3)
    -8

    rd  r*  rm   N)r]   r  r  r8   r9   r*  rd  rP   )rR   rM   rj   r   rk   r   rT   rV   rV   rW   r*  M  s    r*  c             O   s   t |dg y t| |ff||\\}}}W n tk
r } zjt|j\}\}	}
y||	|
\}}}W n  tk
r   tdd|Y nX |	||	||	|fS W dd}~X Y nX ||\}}}|j
s| | | fS |||fS dS )a  
    Compute GCD and cofactors of ``f`` and ``g``.

    Returns polynomials ``(h, cff, cfg)`` such that ``h = gcd(f, g)``, and
    ``cff = quo(f, h)`` and ``cfg = quo(g, h)`` are, so called, cofactors
    of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import cofactors
    >>> from sympy.abc import x

    >>> cofactors(x**2 - 1, x**2 - 3*x + 2)
    (x - 1, x + 1, x - 2)

    rd  r.  r  N)r]   r  r  r8   r$   r  r.  r_   r9   r   rd  rP   )rR   rS   rM   rj   r   r   rk   r   ry   r  r  r"  r/  r0  rV   rV   rW   r.  k  s     .r.  c          
      s  t | } fdd}|| }|dk	r*|S tdg yt| f\}}t| dkrtdd | D r| d   fd	d
| dd D }tdd |D rd}x|D ]}	t||	 d }qW t | S W nJ t	k
r }
 z*||
j
}|dk	r|S tdt| |
W dd}
~
X Y nX |s>|js2tjS td|dS |d |dd  }}x"|D ]}||}|jrZP qZW |js| S |S dS )z
    Compute GCD of a list of polynomials.

    Examples
    ========

    >>> from sympy import gcd_list
    >>> from sympy.abc import x

    >>> gcd_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
    x - 1

    c                sn   sj sjt | \}}|s|jS |jrj|d |dd   }}x$|D ]}|||}||r@P q@W ||S d S )Nr   rm   )r$   r   r   r1  r  r   )seqry   numbersrT   number)rj   rM   rV   rW   try_non_polynomial_gcd  s    


z(gcd_list.<locals>.try_non_polynomial_gcdNrd  rm   c             s   s   | ]}|j o|jV  qd S )N)is_algebraicis_irrational)r   r   rV   rV   rW   	<genexpr>  s    zgcd_list.<locals>.<genexpr>r  c                s   g | ]} |   qS rV   )ratsimp)r   r   )r  rV   rW   r     s    zgcd_list.<locals>.<listcomp>c             s   s   | ]}|j V  qd S )N)is_rational)r   frcrV   rV   rW   r    s    r   gcd_list)rk   )r   r]   r  r  ro   rD  r2  as_numer_denomr   r8   r  r9   rd  r   r  rK   r1  r  rP   )r  rM   rj   r  rT   rd  rk   lstlcr  r   r   rV   )r  rj   rM   rW   r    sB    

"

r  c             O   sJ  t | dr,|dk	r|f| }t| f||S |dkr<tdt|dg ypt| |ff||\\}}}tt| |f\}}|jr|j	r|jr|j	r|| 
 }	|	jrt||	 d  S W nl tk
r& }
 zLt|
j\}\}}y||||S  tk
r   tdd|
Y nX W dd}
~
X Y nX ||}|jsB| S |S dS )z
    Compute GCD of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import gcd
    >>> from sympy.abc import x

    >>> gcd(x**2 - 1, x**2 - 3*x + 2)
    x - 1

    __iter__Nz2gcd() takes 2 arguments or a sequence of argumentsrd  r   r1  r  )r   r  r   r]   r  r  r   r   r  r  r  r  r   r  r8   r$   r  r   r1  r_   r9   rd  rP   )rR   rS   rM   rj   r   r   rk   r  r  r  r   ry   rT   rV   rV   rW   r1    s0    

$
r1  c          
      s  t | } fdd}|| }|dk	r*|S tdg yt| f\}}t| dkrtdd | D r| d   fd	d
| dd D }tdd |D rd}x|D ]}	t||	 d }qW  | S W nJ tk
r }
 z*||
j	}|dk	r|S t
dt| |
W dd}
~
X Y nX |s:|js.tjS td|dS |d |dd  }}x|D ]}||}qVW |jsz| S |S dS )z
    Compute LCM of a list of polynomials.

    Examples
    ========

    >>> from sympy import lcm_list
    >>> from sympy.abc import x

    >>> lcm_list([x**3 - 1, x**2 - 1, x**2 - 3*x + 2])
    x**5 - x**4 - 2*x**3 - x**2 + x + 2

    c                sb   s^ s^t | \}}|s|jS |jr^|d |dd   }}x|D ]}|||}q@W ||S d S )Nr   rm   )r$   r   r   r2  r   )r  ry   r  rT   r  )rj   rM   rV   rW   try_non_polynomial_lcm.  s    

z(lcm_list.<locals>.try_non_polynomial_lcmNrd  rm   c             s   s   | ]}|j o|jV  qd S )N)r  r  )r   r   rV   rV   rW   r  I  s    zlcm_list.<locals>.<genexpr>r  c                s   g | ]} |   qS rV   )r  )r   r   )r  rV   rW   r   K  s    zlcm_list.<locals>.<listcomp>c             s   s   | ]}|j V  qd S )N)r  )r   r  rV   rV   rW   r  L  s    lcm_list)rk   r   )r   r]   r  r  ro   rD  r2  r  r8   r  r9   rd  r   r  rK   rP   )r  rM   rj   r  rT   rd  rk   r  r  r  r   r   rV   )r  rj   rM   rW   r    s>    

"
r  c             O   sF  t | dr,|dk	r|f| }t| f||S |dkr<tdt|dg ylt| |ff||\\}}}tt| |f\}}|jr|j	r|jr|j	r|| 
 }	|	jr||	 d  S W nl tk
r" }
 zLt|
j\}\}}y||||S  tk
r   tdd|
Y nX W dd}
~
X Y nX ||}|js>| S |S dS )z
    Compute LCM of ``f`` and ``g``.

    Examples
    ========

    >>> from sympy import lcm
    >>> from sympy.abc import x

    >>> lcm(x**2 - 1, x**2 - 3*x + 2)
    x**3 - 2*x**2 - x + 2

    r  Nz2lcm() takes 2 arguments or a sequence of argumentsrd  rm   r2  r  )r   r  r   r]   r  r  r   r   r  r  r  r  r  r8   r$   r  r   r2  r_   r9   rd  rP   )rR   rS   rM   rj   r   r   rk   r  r  r  r   ry   rT   rV   rV   rW   r2  k  s0    

$
r2  c          
      s  t | }t| tr2t fdd| j| jgD  S t| trJtd| f t| trZ| jr^|S  	ddr| j
 fdd| jD  } d d d< t|f S  d	d
}t dg yt| f \}}W n& tk
r  } z|jS d}~X Y nX | \}	} |jjrR|jjr2| jd
d\}
} |  \}} |jjrX||
 }ntj}tdd t| j|	D  }|dkrtj}|dkr|S |rt|||   S t||  dd \}} t|||  ddS )az  
    Remove GCD of terms from ``f``.

    If the ``deep`` flag is True, then the arguments of ``f`` will have
    terms_gcd applied to them.

    If a fraction is factored out of ``f`` and ``f`` is an Add, then
    an unevaluated Mul will be returned so that automatic simplification
    does not redistribute it. The hint ``clear``, when set to False, can be
    used to prevent such factoring when all coefficients are not fractions.

    Examples
    ========

    >>> from sympy import terms_gcd, cos
    >>> from sympy.abc import x, y
    >>> terms_gcd(x**6*y**2 + x**3*y, x, y)
    x**3*y*(x**3*y + 1)

    The default action of polys routines is to expand the expression
    given to them. terms_gcd follows this behavior:

    >>> terms_gcd((3+3*x)*(x+x*y))
    3*x*(x*y + x + y + 1)

    If this is not desired then the hint ``expand`` can be set to False.
    In this case the expression will be treated as though it were comprised
    of one or more terms:

    >>> terms_gcd((3+3*x)*(x+x*y), expand=False)
    (3*x + 3)*(x*y + x)

    In order to traverse factors of a Mul or the arguments of other
    functions, the ``deep`` hint can be used:

    >>> terms_gcd((3 + 3*x)*(x + x*y), expand=False, deep=True)
    3*x*(x + 1)*(y + 1)
    >>> terms_gcd(cos(x + x*y), deep=True)
    cos(x*(y + 1))

    Rationals are factored out by default:

    >>> terms_gcd(x + y/2)
    (2*x + y)/2

    Only the y-term had a coefficient that was a fraction; if one
    does not want to factor out the 1/2 in cases like this, the
    flag ``clear`` can be set to False:

    >>> terms_gcd(x + y/2, clear=False)
    x + y/2
    >>> terms_gcd(x*y/2 + y**2, clear=False)
    y*(x/2 + y)

    The ``clear`` flag is ignored if all coefficients are fractions:

    >>> terms_gcd(x/3 + y/2, clear=False)
    (2*x + 3*y)/6

    See Also
    ========
    sympy.core.exprtools.gcd_terms, sympy.core.exprtools.factor_terms

    c             3   s   | ]}t |f V  qd S )N)r   )r   r  )rj   rM   rV   rW   r    s    zterms_gcd.<locals>.<genexpr>z5Inequalities cannot be used with terms_gcd. Found: %sdeepFc                s   g | ]}t |f qS rV   )r   )r   r  )rj   rM   rV   rW   r     s    zterms_gcd.<locals>.<listcomp>r  clearTrd  N)r{   c             S   s   g | ]\}}|| qS rV   rV   )r   r   r   rV   rV   rW   r     s    rm   )r  ) r   rJ   r   lhsrhsr   r   r   is_Atomr  rU   rj   popr   r]   r  r  r8   rt   ry   r   r   r  r7  r   r  r   r   rM   r   rP   Zas_coeff_Mul)rR   rM   rj   r  rq   r  r   rk   r   r   denomr~   termrV   )rj   rM   rW   r     sF    C
 







r   c          
   O   s|   t |ddg yt| f||\}}W n. tk
rV } ztdd|W dd}~X Y nX |t|}|jst| S |S dS )z
    Reduce ``f`` modulo a constant ``p``.

    Examples
    ========

    >>> from sympy import trunc
    >>> from sympy.abc import x

    >>> trunc(2*x**3 + 3*x**2 + 5*x + 7, 3)
    -x**3 - x + 1

    r   rd  r3  rm   N)	r]   r  r  r8   r9   r3  r   rd  rP   )rR   r4  rM   rj   r   rk   r   rT   rV   rV   rW   r3    s    r3  c          
   O   s|   t |ddg yt| f||\}}W n. tk
rV } ztdd|W dd}~X Y nX |j|jd}|jst| S |S dS )z
    Divide all coefficients of ``f`` by ``LC(f)``.

    Examples
    ========

    >>> from sympy import monic
    >>> from sympy.abc import x

    >>> monic(3*x**2 + 4*x + 2)
    x**2 + 4*x/3 + 2/3

    r   rd  r5  rm   N)r   )	r]   r  r  r8   r9   r5  r   rd  rP   )rR   rM   rj   r   rk   r   rT   rV   rV   rW   r5  2  s    r5  c          
   O   s^   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | S )z
    Compute GCD of coefficients of ``f``.

    Examples
    ========

    >>> from sympy import content
    >>> from sympy.abc import x

    >>> content(6*x**2 + 8*x + 12)
    2

    rd  r6  rm   N)r]   r  r  r8   r9   r6  )rR   rM   rj   r   rk   r   rV   rV   rW   r6  P  s    r6  c          
   O   s   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | \}}|jst|| fS ||fS dS )a  
    Compute content and the primitive form of ``f``.

    Examples
    ========

    >>> from sympy.polys.polytools import primitive
    >>> from sympy.abc import x

    >>> primitive(6*x**2 + 8*x + 12)
    (2, 3*x**2 + 4*x + 6)

    >>> eq = (2 + 2*x)*x + 2

    Expansion is performed by default:

    >>> primitive(eq)
    (2, x**2 + x + 1)

    Set ``expand`` to False to shut this off. Note that the
    extraction will not be recursive; use the as_content_primitive method
    for recursive, non-destructive Rational extraction.

    >>> primitive(eq, expand=False)
    (1, x*(2*x + 2) + 2)

    >>> eq.as_content_primitive()
    (2, x*(x + 1) + 1)

    rd  r7  rm   N)r]   r  r  r8   r9   r7  rd  rP   )rR   rM   rj   r   rk   r   r8  rT   rV   rV   rW   r7  i  s     r7  c       	   
   O   s~   t |dg y t| |ff||\\}}}W n. tk
r\ } ztdd|W dd}~X Y nX ||}|jsv| S |S dS )z
    Compute functional composition ``f(g)``.

    Examples
    ========

    >>> from sympy import compose
    >>> from sympy.abc import x

    >>> compose(x**2 + x, x - 1)
    x**2 - x

    rd  r9  r  N)r]   r  r  r8   r9   r9  rd  rP   )	rR   rS   rM   rj   r   r   rk   r   rT   rV   rV   rW   r9    s     
r9  c          
   O   sz   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | }|jsrdd |D S |S dS )z
    Compute functional decomposition of ``f``.

    Examples
    ========

    >>> from sympy import decompose
    >>> from sympy.abc import x

    >>> decompose(x**4 + 2*x**3 - x - 1)
    [x**2 - x - 1, x**2 + x]

    rd  r:  rm   Nc             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r     s    zdecompose.<locals>.<listcomp>)r]   r  r  r8   r9   r:  rd  )rR   rM   rj   r   rk   r   rT   rV   rV   rW   r:    s    r:  c          
   O   s   t |ddg yt| f||\}}W n. tk
rV } ztdd|W dd}~X Y nX |j|jd}|jszdd |D S |S dS )	z
    Compute Sturm sequence of ``f``.

    Examples
    ========

    >>> from sympy import sturm
    >>> from sympy.abc import x

    >>> sturm(x**3 - 2*x**2 + x - 3)
    [x**3 - 2*x**2 + x - 3, 3*x**2 - 4*x + 1, 2*x/9 + 25/9, -2079/4]

    r   rd  r>  rm   N)r   c             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r     s    zsturm.<locals>.<listcomp>)r]   r  r  r8   r9   r>  r   rd  )rR   rM   rj   r   rk   r   rT   rV   rV   rW   r>    s    r>  c          
   O   sz   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | }|jsrdd |D S |S dS )a&  
    Compute a list of greatest factorial factors of ``f``.

    Note that the input to ff() and rf() should be Poly instances to use the
    definitions here.

    Examples
    ========

    >>> from sympy import gff_list, ff, Poly
    >>> from sympy.abc import x

    >>> f = Poly(x**5 + 2*x**4 - x**3 - 2*x**2, x)

    >>> gff_list(f)
    [(Poly(x, x, domain='ZZ'), 1), (Poly(x + 2, x, domain='ZZ'), 4)]

    >>> (ff(Poly(x), 1)*ff(Poly(x + 2), 4)) == f
    True

    >>> f = Poly(x**12 + 6*x**11 - 11*x**10 - 56*x**9 + 220*x**8 + 208*x**7 -         1401*x**6 + 1090*x**5 + 2715*x**4 - 6720*x**3 - 1092*x**2 + 5040*x, x)

    >>> gff_list(f)
    [(Poly(x**3 + 7, x, domain='ZZ'), 2), (Poly(x**2 + 5*x, x, domain='ZZ'), 3)]

    >>> ff(Poly(x**3 + 7, x), 2)*ff(Poly(x**2 + 5*x, x), 3) == f
    True

    rd  r?  rm   Nc             S   s   g | ]\}}|  |fqS rV   )rP   )r   rS   r   rV   rV   rW   r     s    zgff_list.<locals>.<listcomp>)r]   r  r  r8   r9   r?  rd  )rR   rM   rj   r   rk   r   rE  rV   rV   rW   r?    s     r?  c             O   s   t ddS )z3Compute greatest factorial factorization of ``f``. zsymbolic falling factorialN)r_   )rR   rM   rj   rV   rV   rW   gff   s    r  c       	   
   O   s   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | \}}}|jst|| | fS t|||fS dS )a  
    Compute square-free norm of ``f``.

    Returns ``s``, ``f``, ``r``, such that ``g(x) = f(x-sa)`` and
    ``r(x) = Norm(g(x))`` is a square-free polynomial over ``K``,
    where ``a`` is the algebraic extension of the ground domain.

    Examples
    ========

    >>> from sympy import sqf_norm, sqrt
    >>> from sympy.abc import x

    >>> sqf_norm(x**2 + 1, extension=[sqrt(3)])
    (1, x**2 - 2*sqrt(3)*x + 4, x**4 - 4*x**2 + 16)

    rd  rA  rm   N)	r]   r  r  r8   r9   rA  rd  r   rP   )	rR   rM   rj   r   rk   r   r  rS   r   rV   rV   rW   rA  &  s    rA  c          
   O   st   t |dg yt| f||\}}W n. tk
rT } ztdd|W dd}~X Y nX | }|jsl| S |S dS )z
    Compute square-free part of ``f``.

    Examples
    ========

    >>> from sympy import sqf_part
    >>> from sympy.abc import x

    >>> sqf_part(x**3 - 3*x - 2)
    x**2 - x - 2

    rd  rB  rm   N)r]   r  r  r8   r9   rB  rd  rP   )rR   rM   rj   r   rk   r   rT   rV   rV   rW   rB  H  s    rB  c             C   s&   |dkrdd }ndd }t | |dS )z&Sort a list of ``(expr, exp)`` pairs. rN  c             S   s.   | \}}|j j }|t|t|jt|j|fS )N)rZ   ro   rM   ra   ry   )rp   r   exprZ   rV   rV   rW   ry  i  s    z_sorted_factors.<locals>.keyc             S   s.   | \}}|j j }t|t|j|t|j|fS )N)rZ   ro   rM   ra   ry   )rp   r   r  rZ   rV   rV   rW   ry  n  s    )ry  )r}  )rE  methodry  rV   rV   rW   _sorted_factorsf  s    
r  c             C   s   t dd | D  S )z*Multiply a list of ``(expr, exp)`` pairs. c             S   s   g | ]\}}|  | qS rV   )rP   )r   rR   r   rV   rV   rW   r   x  s    z$_factors_product.<locals>.<listcomp>)r   )rE  rV   rV   rW   _factors_productv  s    r  c                s  t jg  }dd t| D }x|D ]}|jsFt|trRt|rR||9 }q(nV|jr|j	t j
kr|j\} |jr jr||9 }q(|jr| f q(n|t j } yt||\}}W n2 tk
r }	 z|	j f W dd}	~	X Y q(X t||d }
|
 \}}|t jk	rP jr(||  9 }n(|jr@| f n||t jf  t jkrh| q( jr fdd|D  q(g }x@|D ]8\}}| jr||  f n|||f qW t| f q(W |dkrfdddd	 D D |fS )
z.Helper function for :func:`_symbolic_factor`. c             S   s"   g | ]}t |d r| n|qS )_eval_factor)r   r  )r   r   rV   rV   rW   r     s   z)_symbolic_factor_list.<locals>.<listcomp>NZ_listc                s   g | ]\}}||  fqS rV   rV   )r   rR   r   )r  rV   rW   r     s    rN  c                s(   g | ]  t t fd dD  fqS )c             3   s   | ]\}}| kr|V  qd S )NrV   )r   rR   r   )r   rV   rW   r    s    z3_symbolic_factor_list.<locals>.<listcomp>.<genexpr>)r   r   )r   )rE  )r   rW   r     s   c             S   s   h | ]\}}|qS rV   rV   )r   r   r   rV   rV   rW   	<setcomp>  s    z(_symbolic_factor_list.<locals>.<setcomp>)r   r  r   	make_argsr  rJ   r   r   is_PowbaseZExp1rj   r   r  r8   rt   rO   r  Zis_positiver  
is_integerrP   r  )rt   rk   r  r~   rj   argr  r   r   r   rU   Z_coeffZ_factorsr  rR   r   rV   )r  rE  rW   _symbolic_factor_list{  sT    
"


r  c                s   t | trFt| dr|  S tt| d d \}}t|t|S t| drl| j fdd| j	D  S t| dr| 
 fdd| D S | S d	S )
z%Helper function for :func:`_factor`. r  fraction)r  rj   c                s   g | ]}t | qS rV   )_symbolic_factor)r   r  )r  rk   rV   rW   r     s    z$_symbolic_factor.<locals>.<listcomp>r  c                s   g | ]}t | qS rV   )r  )r   r  )r  rk   rV   rW   r     s    N)rJ   r   r   r  r  rA   r   r  rU   rj   r   )rt   rk   r  r~   rE  rV   )r  rk   rW   r    s    



r  c             C   sX  t |ddg t ||}t| } t| ttfrHt| trJ| d }}nt|  \}}t	|||\}}t	|||\}	}
|
r|j
std|  |tdd}xJ||
fD ]>}x8t|D ],\}\}}|jst||\}}||f||< qW qW t||}t|
|}
|js$dd |D }d	d |
D }
||	 }|j
s<||fS |||
fS ntd|  d
S )z>Helper function for :func:`sqf_list` and :func:`factor_list`. fracrd  rm   za polynomial expected, got %sT)r  c             S   s   g | ]\}}|  |fqS rV   )rP   )r   rR   r   rV   rV   rW   r     s    z(_generic_factor_list.<locals>.<listcomp>c             S   s   g | ]\}}|  |fqS rV   )rP   )r   rR   r   rV   rV   rW   r     s    N)r]   r  r^   r   rJ   r   rK   rA   r  r  r  r5   clonerb   r   rf   r  r  rd  )rt   rM   rj   r  rk   Znumerr  r  fpr  ZfqZ_optrE  r   rR   r   r   r~   rV   rV   rW   _generic_factor_list  s6    



r  c             C   s<   | dd}t|g  t||}||d< tt| ||S )z4Helper function for :func:`sqf` and :func:`factor`. r  T)r  r]   r  r^   r  r   )rt   rM   rj   r  r  rk   rV   rV   rW   _generic_factor  s
    r  c                s   ddl m  d fdd	}d fdd	}dd	 }|  jr|| r|  }|| |}|rp|d |d
 d|d fS || |}|rdd|d |d
 fS dS )a!  
    try to transform a polynomial to have rational coefficients

    try to find a transformation ``x = alpha*y``

    ``f(x) = lc*alpha**n * g(y)`` where ``g`` is a polynomial with
    rational coefficients, ``lc`` the leading coefficient.

    If this fails, try ``x = y + beta``
    ``f(x) = g(y)``

    Returns ``None`` if ``g`` not found;
    ``(lc, alpha, None, g)`` in case of rescaling
    ``(None, None, beta, g)`` in case of translation

    Notes
    =====

    Currently it transforms only polynomials without roots larger than 2.

    Examples
    ========

    >>> from sympy import sqrt, Poly, simplify
    >>> from sympy.polys.polytools import to_rational_coeffs
    >>> from sympy.abc import x
    >>> p = Poly(((x**2-1)*(x-2)).subs({x:x*(1 + sqrt(2))}), x, domain='EX')
    >>> lc, r, _, g = to_rational_coeffs(p)
    >>> lc, r
    (7 + 5*sqrt(2), 2 - 2*sqrt(2))
    >>> g
    Poly(x**3 + x**2 - 1/4*x - 1/4, x, domain='QQ')
    >>> r1 = simplify(1/r)
    >>> Poly(lc*r**3*(g.as_expr()).subs({x:x*r1}), x, domain='EX') == p
    True

    r   )simplifyNc                sF  t | jdkr| jd js"d| fS |  }|  }|p<| }| dd } fdd|D }t |dkrB|d rB |d |d  }g }xtt |D ].} || ||d   }|jsP |	| qW  d| }	| jd }
|
| g}x6td|d D ]$}|	||d  |
||    q W t
| } t| } ||	| fS dS )a$  
        try rescaling ``x -> alpha*x`` to convert f to a polynomial
        with rational coefficients.
        Returns ``alpha, f``; if the rescaling is successful,
        ``alpha`` is the rescaling factor, and ``f`` is the rescaled
        polynomial; else ``alpha`` is ``None``.
        rm   r   Nc                s   g | ]} |qS rV   rV   )r   coeffx)r  rV   rW   r   /  s    z<to_rational_coeffs.<locals>._try_rescale.<locals>.<listcomp>r  )ro   rM   r  r   r  r5  r   r   r  r   r   rK   )rR   f1r   r  r   Z
rescale1_xZcoeffs1r   r  Z	rescale_xr   rS  )r  rV   rW   _try_rescale!  s0    

$
z(to_rational_coeffs.<locals>._try_rescalec       	         s   t | jdkr| jd js"d| fS |  }|p4| }| dd } |d }|jr|jst|j	dd dd\}}|j
|  | }||}||fS dS )a+  
        try translating ``x -> x + alpha`` to convert f to a polynomial
        with rational coefficients.
        Returns ``alpha, f``; if the translating is successful,
        ``alpha`` is the translating factor, and ``f`` is the shifted
        polynomial; else ``alpha`` is ``None``.
        rm   r   Nc             S   s
   | j dkS )NT)r  )zrV   rV   rW   rw  S  rx  z<to_rational_coeffs.<locals>._try_translate.<locals>.<lambda>T)binary)ro   rM   r  r   r5  r   is_Addr  rH   rj   rU   r;  )	rR   r  r   r   r   ratZnonratalphaf2)r  rV   rW   _try_translateC  s    
z*to_rational_coeffs.<locals>._try_translatec             S   st   |   }d}xb|D ]Z}xTt|D ]F}t|j}dd | D }|sHq"t|dkrXd}t|dkr"dS q"W qW |S )zS
        Return True if ``f`` is a sum with square roots but no other root
        Fc             S   s,   g | ]$\}}|j r|jr|jd kr|jqS )r  )r   Zis_Rationalr   )r   r  ZwxrV   rV   rW   r   b  s    zAto_rational_coeffs.<locals>._has_square_roots.<locals>.<listcomp>r  T)r   r   r  r   rE  rz   minmax)r4  r   Zhas_sqr   r   rR   r   rV   rV   rW   _has_square_rootsY  s    

z-to_rational_coeffs.<locals>._has_square_rootsrm   r  )N)N)sympy.simplify.simplifyr  r   r   r5  )rR   r   r  r
  r  r   rV   )r  rW   to_rational_coeffs  s    &"

r  c          	   C   s  ddl m} t| |dd}| }t|}|s2dS |\}}}}	t|	 }
|r||
d | ||  }|d| }g }x|
dd d D ],}|||d ||| i|d f qW nJ|
d }g }x<|
dd d D ](}||d ||| i|d f qW ||fS )a  
    helper function to factor polynomial using to_rational_coeffs

    Examples
    ========

    >>> from sympy.polys.polytools import _torational_factor_list
    >>> from sympy.abc import x
    >>> from sympy import sqrt, expand, Mul
    >>> p = expand(((x**2-1)*(x-2)).subs({x:x*(1 + sqrt(2))}))
    >>> factors = _torational_factor_list(p, x); factors
    (-2, [(-x*(1 + sqrt(2))/2 + 1, 1), (-x*(1 + sqrt(2)) - 1, 1), (-x*(1 + sqrt(2)) + 1, 1)])
    >>> expand(factors[0]*Mul(*[z[0] for z in factors[1]])) == p
    True
    >>> p = expand(((x**2-1)*(x-2)).subs({x:x + sqrt(2)}))
    >>> factors = _torational_factor_list(p, x); factors
    (1, [(x - 2 + sqrt(2), 1), (x - 1 + sqrt(2), 1), (x + 1 + sqrt(2), 1)])
    >>> expand(factors[0]*Mul(*[z[0] for z in factors[1]])) == p
    True

    r   )r  ZEX)ry   Nrm   )	r  r  rK   r   r  rG  rP   r   r   )r4  r   r  p1r   resr  r   r$  rS   rE  r   r1r  r  rV   rV   rW   _torational_factor_listx  s&    .(r  c             O   s   t | ||ddS )z
    Compute a list of square-free factors of ``f``.

    Examples
    ========

    >>> from sympy import sqf_list
    >>> from sympy.abc import x

    >>> sqf_list(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
    (2, [(x + 1, 2), (x + 2, 3)])

    rN  )r  )r  )rR   rM   rj   rV   rV   rW   rC    s    rC  c             O   s   t | ||ddS )z
    Compute square-free factorization of ``f``.

    Examples
    ========

    >>> from sympy import sqf
    >>> from sympy.abc import x

    >>> sqf(2*x**5 + 16*x**4 + 50*x**3 + 76*x**2 + 56*x + 16)
    2*(x + 1)**2*(x + 2)**3

    rN  )r  )r  )rR   rM   rj   rV   rV   rW   rN    s    rN  c             O   s   t | ||ddS )a  
    Compute a list of irreducible factors of ``f``.

    Examples
    ========

    >>> from sympy import factor_list
    >>> from sympy.abc import x, y

    >>> factor_list(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y)
    (2, [(x + y, 1), (x**2 + 1, 2)])

    r  )r  )r  )rR   rM   rj   rV   rV   rW   rG    s    rG  )r  c      
   
      s   t | } |rx fdd}t| |} i }| tt}x8|D ]0}t|f }|jsZ|jr:||kr:|||< q:W | |S yt	|  ddS  t
k
r }	 z| jst| S t
|	W dd}	~	X Y nX dS )a  
    Compute the factorization of expression, ``f``, into irreducibles. (To
    factor an integer into primes, use ``factorint``.)

    There two modes implemented: symbolic and formal. If ``f`` is not an
    instance of :class:`Poly` and generators are not specified, then the
    former mode is used. Otherwise, the formal mode is used.

    In symbolic mode, :func:`factor` will traverse the expression tree and
    factor its components without any prior expansion, unless an instance
    of :class:`~.Add` is encountered (in this case formal factorization is
    used). This way :func:`factor` can handle large or symbolic exponents.

    By default, the factorization is computed over the rationals. To factor
    over other domain, e.g. an algebraic or finite field, use appropriate
    options: ``extension``, ``modulus`` or ``domain``.

    Examples
    ========

    >>> from sympy import factor, sqrt, exp
    >>> from sympy.abc import x, y

    >>> factor(2*x**5 + 2*x**4*y + 4*x**3 + 4*x**2*y + 2*x + 2*y)
    2*(x + y)*(x**2 + 1)**2

    >>> factor(x**2 + 1)
    x**2 + 1
    >>> factor(x**2 + 1, modulus=2)
    (x + 1)**2
    >>> factor(x**2 + 1, gaussian=True)
    (x - I)*(x + I)

    >>> factor(x**2 - 2, extension=sqrt(2))
    (x - sqrt(2))*(x + sqrt(2))

    >>> factor((x**2 - 1)/(x**2 + 4*x + 4))
    (x - 1)*(x + 1)/(x + 2)**2
    >>> factor((x**2 + 4*x + 4)**10000000*(x**2 + 1))
    (x + 2)**20000000*(x**2 + 1)

    By default, factor deals with an expression as a whole:

    >>> eq = 2**(x**2 + 2*x + 1)
    >>> factor(eq)
    2**(x**2 + 2*x + 1)

    If the ``deep`` flag is True then subexpressions will
    be factored:

    >>> factor(eq, deep=True)
    2**((x + 1)**2)

    If the ``fraction`` flag is False then rational expressions
    will not be combined. By default it is True.

    >>> factor(5*x + 3*exp(2 - 7*x), deep=True)
    (5*x*exp(7*x) + 3*exp(2))*exp(-7*x)
    >>> factor(5*x + 3*exp(2 - 7*x), deep=True, fraction=False)
    5*x + 3*exp(2)*exp(-7*x)

    See Also
    ========
    sympy.ntheory.factor_.factorint

    c                s$   t | f }|js|jr |S | S )zS
            Factor, but avoid changing the expression when unable to.
            )r  is_Mulr  )rt   ro  )rj   rM   rV   rW   _try_factor   s    zfactor.<locals>._try_factorr  )r  N)r   r!   Zatomsr   r   r  r  r  xreplacer  r5   r  r   )
rR   r  rM   rj   r  ZpartialsZmuladdr4  ro  msgrV   )rj   rM   rW   r    s"    D	


r  c          	   C   s8  t | dsByt| } W n tk
r*   g S X | j||||||dS t| dd\}}	t|	jdkrdtx t|D ]\}
}|j	j	||
< qnW |dk	r|	j
|}|dkrtd|dk	r|	j
|}|dk	r|	j
|}t||	j
|||||d	}g }x@|D ]8\\}}}|	j
||	j
| }}|||f|f qW |S dS )
a/  
    Compute isolating intervals for roots of ``f``.

    Examples
    ========

    >>> from sympy import intervals
    >>> from sympy.abc import x

    >>> intervals(x**2 - 3)
    [((-2, -1), 1), ((1, 2), 1)]
    >>> intervals(x**2 - 3, eps=1e-2)
    [((-26/15, -19/11), 1), ((19/11, 26/15), 1)]

    r  )rD  rJ  rK  rL  rM  rN  r&   )ry   rm   Nr   z!'eps' must be a positive rational)rJ  rK  rL  r  rM  )r   rK   r4   rI  r  ro   rM   r6   r   rZ   ry   r{   r   rB   r   r   )r   rD  rJ  rK  rL  r  rM  rN  rd  rk   r   r   rI  rT   r  r$  r   rV   rV   rW   rI  =  s4    
rI  c             C   s^   y&t | }t| t s$|jjs$tdW n  tk
rF   td|  Y nX |j||||||dS )z
    Refine an isolating interval of a root to the given precision.

    Examples
    ========

    >>> from sympy import refine_root
    >>> from sympy.abc import x

    >>> refine_root(x**2 - 3, 1, 2, eps=1e-2)
    (19/11, 26/15)

    zgenerator must be a Symbolz,Cannot refine a root of %s, not a polynomial)rJ  rV  rM  rX  )rK   rJ   r   	is_Symbolr5   r4   rU  )rR   r  r$  rJ  rV  rM  rX  r   rV   rV   rW   rU  u  s    rU  c             C   sZ   y*t | dd}t| t s(|jjs(tdW n  tk
rJ   td|  Y nX |j||dS )a  
    Return the number of roots of ``f`` in ``[inf, sup]`` interval.

    If one of ``inf`` or ``sup`` is complex, it will return the number of roots
    in the complex rectangle with corners at ``inf`` and ``sup``.

    Examples
    ========

    >>> from sympy import count_roots, I
    >>> from sympy.abc import x

    >>> count_roots(x**4 - 4, -3, 3)
    2
    >>> count_roots(x**4 - 4, 0, 1 + 3*I)
    1

    F)greedyzgenerator must be a Symbolz*Cannot count roots of %s, not a polynomial)rK  rL  )rK   rJ   r   r  r5   r4   ra  )rR   rK  rL  r   rV   rV   rW   ra    s    ra  Tc             C   sX   y*t | dd}t| t s(|jjs(tdW n  tk
rJ   td|  Y nX |j|dS )z
    Return a list of real roots with multiplicities of ``f``.

    Examples
    ========

    >>> from sympy import real_roots
    >>> from sympy.abc import x

    >>> real_roots(2*x**3 - 7*x**2 + 4*x + 4)
    [-1/2, 2, 2]
    F)r  zgenerator must be a Symbolz1Cannot compute real roots of %s, not a polynomial)rg  )rK   rJ   r   r  r5   r4   ri  )rR   rg  r   rV   rV   rW   ri    s    ri  rl  rm  c             C   s\   y*t | dd}t| t s(|jjs(tdW n  tk
rJ   td|  Y nX |j|||dS )aL  
    Compute numerical approximations of roots of ``f``.

    Examples
    ========

    >>> from sympy import nroots
    >>> from sympy.abc import x

    >>> nroots(x**2 - 3, n=15)
    [-1.73205080756888, 1.73205080756888]
    >>> nroots(x**2 - 3, n=30)
    [-1.73205080756887729352744634151, 1.73205080756887729352744634151]

    F)r  zgenerator must be a Symbolz6Cannot compute numerical roots of %s, not a polynomial)r   rr  rs  )rK   rJ   r   r  r5   r4   r~  )rR   r   rr  rs  r   rV   rV   rW   r~    s    r~  c          
   O   sv   t |g  y2t| f||\}}t| ts<|jjs<tdW n. tk
rl } zt	dd|W dd}~X Y nX |
 S )z
    Compute roots of ``f`` by factorization in the ground domain.

    Examples
    ========

    >>> from sympy import ground_roots
    >>> from sympy.abc import x

    >>> ground_roots(x**6 - 4*x**4 + 4*x**3 - x**2)
    {0: 2, 1: 2}

    zgenerator must be a Symbolr  rm   N)r]   r  r  rJ   rK   r   r  r5   r8   r9   r  )rR   rM   rj   r   rk   r   rV   rV   rW   r    s    r  c          
   O   s   t |g  y2t| f||\}}t| ts<|jjs<tdW n. tk
rl } zt	dd|W dd}~X Y nX |
|}|js| S |S dS )a  
    Construct a polynomial with n-th powers of roots of ``f``.

    Examples
    ========

    >>> from sympy import nth_power_roots_poly, factor, roots
    >>> from sympy.abc import x

    >>> f = x**4 - x**2 + 1
    >>> g = factor(nth_power_roots_poly(f, 2))

    >>> g
    (x**2 - x + 1)**2

    >>> R_f = [ (r**2).expand() for r in roots(f) ]
    >>> R_g = roots(g).keys()

    >>> set(R_f) == set(R_g)
    True

    zgenerator must be a Symbolr  rm   N)r]   r  r  rJ   rK   r   r  r5   r8   r9   r  rd  rP   )rR   r   rM   rj   r   rk   r   rT   rV   rV   rW   r    s    
r  )	_signsimpc               sD  ddl m} ddlm  ddlm} t|dg t| } |rF|| } i }d|kr^|d |d< t	| t
tfs| jst	| tst	| ts| S t| dd} |  \}}nt| dkr| \}}t	|trt	|tr|j|d	< |j|d
< |dd|d< | |  }}n t	| trt| S td|  y`|  r:t |||ff||\}	\}
}|	jst	| t
tfsv|  S tj||fS W n tk
r } z| jr|  st|| js| j r
t!| j" fdddd\}}dd |D }| j#t$| j#| f| S g }t%| }t&| xZ|D ]R}t	|t
tt'fr>q$y|(|t$|f |)  W n t*k
rr   Y nX q$W | +t,|S W dd}~X Y nX d|
$| }\}}|ddrd	|kr|	j-|d	< t	| t
tfs|| |   S | |  }}|dds|||fS |t|f||t|f||fS dS )a[  
    Cancel common factors in a rational function ``f``.

    Examples
    ========

    >>> from sympy import cancel, sqrt, Symbol, together
    >>> from sympy.abc import x
    >>> A = Symbol('A', commutative=False)

    >>> cancel((2*x**2 - 2)/(x**2 - 2*x + 1))
    (2*x + 2)/(x - 1)
    >>> cancel((sqrt(3) + sqrt(15)*A)/(sqrt(2) + sqrt(10)*A))
    sqrt(6)/2

    Note: due to automatic distribution of Rationals, a sum divided by an integer
    will appear as a sum. To recover a rational form use `together` on the result:

    >>> cancel(x/2 + 1)
    x/2 + 1
    >>> together(_)
    (x + 2)/2
    r   )signsimp)r  )sringrd  T)radicalr  rM   ry   zunexpected argument: %sc                s   | j dko|   S )NT)r  has)r   )r  rV   rW   rw  }  s    zcancel.<locals>.<lambda>)r  c             S   s   g | ]}t |qS rV   )r  )r   r   rV   rV   rW   r     s    zcancel.<locals>.<listcomp>Nrm   F).r  r  r  r  sympy.polys.ringsr  r]   r  r   rJ   r   r   r  r   r   r   r  ro   rK   rM   ry   r  rP   r   r  r5   Zngensr  r   r  r  r  r  rH   rj   rU   r  r    r  r"   r   skipr_   r  rb   r   )rR   r  rM   rj   r  r  rk   r4  r   r   r   r   r  r   ncr  poter=  r   rV   )r  rW   r  8  s|    


 

r  c          
      s  t |ddg y"t| gt| f||\} W n. tk
r` } ztdd|W dd}~X Y nX  j}d} jr|jr|j	s 
t| d d}dd	lm} | j j j\}	}
x4t|D ](\}}| jj }|	|||< qW |d |d
d \}} fdd|D }tt| }|rnydd |D |  }}W n tk
rb   Y nX || }} jsdd |D | fS ||fS dS )a<  
    Reduces a polynomial ``f`` modulo a set of polynomials ``G``.

    Given a polynomial ``f`` and a set of polynomials ``G = (g_1, ..., g_n)``,
    computes a set of quotients ``q = (q_1, ..., q_n)`` and the remainder ``r``
    such that ``f = q_1*g_1 + ... + q_n*g_n + r``, where ``r`` vanishes or ``r``
    is a completely reduced polynomial with respect to ``G``.

    Examples
    ========

    >>> from sympy import reduced
    >>> from sympy.abc import x, y

    >>> reduced(2*x**4 + y**2 - x**2 + y**3, [x**3 - x, y**3 - y])
    ([2*x, 1], x**2 + y**2 + y)

    rd  r   reducedr   NF)ry   T)xringrm   c                s   g | ]}t t| qS rV   )rK   rc   rb   )r   r   )rk   rV   rW   r     s    zreduced.<locals>.<listcomp>c             S   s   g | ]}|  qS rV   )r   )r   r   rV   rV   rW   r     s    c             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r     s    )r]   r  r  re   r8   r9   ry   r   r   r   r  rb   r  r  r"  rM   r[   r   r   rZ   r   rv   r   rK   rc   r   r2   rd  rP   )rR   r   rM   rj   rd  r   ry   r   r"  _ringr   r   r   r   r   _Q_rrV   )rk   rW   r!    s6    "
r!  c             O   s   t | f||S )a  
    Computes the reduced Groebner basis for a set of polynomials.

    Use the ``order`` argument to set the monomial ordering that will be
    used to compute the basis. Allowed orders are ``lex``, ``grlex`` and
    ``grevlex``. If no order is specified, it defaults to ``lex``.

    For more information on Groebner bases, see the references and the docstring
    of :func:`~.solve_poly_system`.

    Examples
    ========

    Example taken from [1].

    >>> from sympy import groebner
    >>> from sympy.abc import x, y

    >>> F = [x*y - 2*y, 2*y**2 - x**2]

    >>> groebner(F, x, y, order='lex')
    GroebnerBasis([x**2 - 2*y**2, x*y - 2*y, y**3 - 2*y], x, y,
                  domain='ZZ', order='lex')
    >>> groebner(F, x, y, order='grlex')
    GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
                  domain='ZZ', order='grlex')
    >>> groebner(F, x, y, order='grevlex')
    GroebnerBasis([y**3 - 2*y, x**2 - 2*y**2, x*y - 2*y], x, y,
                  domain='ZZ', order='grevlex')

    By default, an improved implementation of the Buchberger algorithm is
    used. Optionally, an implementation of the F5B algorithm can be used. The
    algorithm can be set using the ``method`` flag or with the
    :func:`sympy.polys.polyconfig.setup` function.

    >>> F = [x**2 - x - 1, (2*x - 1) * y - (x**10 - (1 - x)**10)]

    >>> groebner(F, x, y, method='buchberger')
    GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex')
    >>> groebner(F, x, y, method='f5b')
    GroebnerBasis([x**2 - x - 1, y - 55], x, y, domain='ZZ', order='lex')

    References
    ==========

    1. [Buchberger01]_
    2. [Cox97]_

    )GroebnerBasis)r   rM   rj   rV   rV   rW   r*     s    3r*   c             O   s   t | f||jS )a[  
    Checks if the ideal generated by a Groebner basis is zero-dimensional.

    The algorithm checks if the set of monomials not divisible by the
    leading monomial of any element of ``F`` is bounded.

    References
    ==========

    David A. Cox, John B. Little, Donal O'Shea. Ideals, Varieties and
    Algorithms, 3rd edition, p. 230

    )r&  is_zero_dimensional)r   rM   rj   rV   rV   rW   r'    s    r'  c               @   s   e Zd ZdZdd Zedd Zedd Zedd	 Z	ed
d Z
edd Zedd Zedd Zdd Zdd Zdd Zdd Zdd Zdd Zedd Zd d! Zd(d#d$Zd%d& Zd'S ))r&  z%Represents a reduced Groebner basis. c          
      s   t |ddg yt|f||\} W n2 tk
rZ } ztdt||W dd}~X Y nX ddlm} | j j	 j
fdd|D }t| jd	} fd
d|D }| | S )z>Compute a reduced Groebner basis for a system of polynomials. rd  r  r*   Nr   )PolyRingc                s    g | ]}|r  |j qS rV   )rv   rZ   r   )r   r   )ringrV   rW   r   3  s    z)GroebnerBasis.__new__.<locals>.<listcomp>)r  c                s   g | ]}t | qS rV   )rK   rc   )r   rS   )rk   rV   rW   r   6  s    )r]   r  r  r8   r9   ro   r  r(  rM   ry   r[   	_groebnerr  _new)ri   r   rM   rj   rd  r   r(  r   rV   )rk   r)  rW   rl   '  s    "zGroebnerBasis.__new__c             C   s   t | }t||_||_|S )N)r	   rl   r   _basis_options)ri   basisr]   rp   rV   rV   rW   r+  :  s    

zGroebnerBasis._newc             C   s$   dd | j D }t| t| jj fS )Nc             s   s   | ]}|  V  qd S )N)rP   )r   r4  rV   rV   rW   r  E  s    z%GroebnerBasis.args.<locals>.<genexpr>)r,  r   r-  rM   )rs   r.  rV   rV   rW   rj   C  s    zGroebnerBasis.argsc             C   s   dd | j D S )Nc             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r   J  s    z'GroebnerBasis.exprs.<locals>.<listcomp>)r,  )rs   rV   rV   rW   r  H  s    zGroebnerBasis.exprsc             C   s
   t | jS )N)re   r,  )rs   rV   rV   rW   rd  L  s    zGroebnerBasis.polysc             C   s   | j jS )N)r-  rM   )rs   rV   rV   rW   rM   P  s    zGroebnerBasis.gensc             C   s   | j jS )N)r-  ry   )rs   rV   rV   rW   ry   T  s    zGroebnerBasis.domainc             C   s   | j jS )N)r-  r[   )rs   rV   rV   rW   r[   X  s    zGroebnerBasis.orderc             C   s
   t | jS )N)ro   r,  )rs   rV   rV   rW   __len__\  s    zGroebnerBasis.__len__c             C   s    | j jrt| jS t| jS d S )N)r-  rd  iterr  )rs   rV   rV   rW   r  _  s    
zGroebnerBasis.__iter__c             C   s   | j jr| j}n| j}|| S )N)r-  rd  r  )rs   itemr.  rV   rV   rW   __getitem__e  s    zGroebnerBasis.__getitem__c             C   s   t | jt| j fS )N)hashr,  r   r-  rz   )rs   rV   rV   rW   r   m  s    zGroebnerBasis.__hash__c             C   sP   t || jr$| j|jko"| j|jkS t|rH| jt|kpF| jt|kS dS d S )NF)rJ   r   r,  r-  rG   rd  re   r  )rs   r  rV   rV   rW   r  p  s
    zGroebnerBasis.__eq__c             C   s
   | |k S )NrV   )rs   r  rV   rV   rW   r  x  s    zGroebnerBasis.__ne__c             C   sX   dd }t dgt| j }| jj}x*| jD ] }|j|d}||r,||9 }q,W t|S )a{  
        Checks if the ideal generated by a Groebner basis is zero-dimensional.

        The algorithm checks if the set of monomials not divisible by the
        leading monomial of any element of ``F`` is bounded.

        References
        ==========

        David A. Cox, John B. Little, Donal O'Shea. Ideals, Varieties and
        Algorithms, 3rd edition, p. 230

        c             S   s   t tt| dkS )Nrm   )sumr   r  )monomialrV   rV   rW   
single_var  s    z5GroebnerBasis.is_zero_dimensional.<locals>.single_varr   )r[   )r+   ro   rM   r-  r[   rd  r  rD  )rs   r6  r  r[   r   r5  rV   rV   rW   r'  {  s    z!GroebnerBasis.is_zero_dimensionalc                s   | j   j}t|}||kr | S | js.tdt| j} j} t	|
 |d ddlm} | j j|\}}x4t|D ](\}	}
|
 jj }
||
||	< q~W t|||} fdd|D }|jsdd |D }| _| | S )a  
        Convert a Groebner basis from one ordering to another.

        The FGLM algorithm converts reduced Groebner bases of zero-dimensional
        ideals from one ordering to another. This method is often used when it
        is infeasible to compute a Groebner basis with respect to a particular
        ordering directly.

        Examples
        ========

        >>> from sympy.abc import x, y
        >>> from sympy import groebner

        >>> F = [x**2 - 3*y - x + 1, y**2 - 2*x + y - 1]
        >>> G = groebner(F, x, y, order='grlex')

        >>> list(G.fglm('lex'))
        [2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7]
        >>> list(groebner(F, x, y, order='lex'))
        [2*x - y**2 - y + 1, y**4 + 2*y**3 - 3*y**2 - 16*y + 7]

        References
        ==========

        .. [1] J.C. Faugere, P. Gianni, D. Lazard, T. Mora (1994). Efficient
               Computation of Zero-dimensional Groebner Bases by Change of
               Ordering

        z?Cannot convert Groebner bases of ideals with positive dimension)ry   r[   r   )r"  c                s   g | ]}t t| qS rV   )rK   rc   rb   )r   rS   )rk   rV   rW   r     s    z&GroebnerBasis.fglm.<locals>.<listcomp>c             S   s   g | ]}|j d dd qS )T)r{   rm   )r  )r   rS   rV   rV   rW   r     s    )r-  r[   r,   r'  r_   re   r,  ry   r  rb   r  r  r"  rM   r   r   rZ   r   rv   r)   r   r+  )rs   r[   Z	src_orderZ	dst_orderrd  ry   r"  r#  r   r   r   r   rV   )rk   rW   fglm  s.    

zGroebnerBasis.fglmTc                sX  t || j}|gt| j }| j  j}d}|rV|jrV|jsV t	|
 d d}ddlm} | j j j\}}	x4t|D ](\}
}| jj }||||
< qW |d |dd \}} fdd	|D }t t	| }|r.yd
d	 |D |  }}W n tk
r"   Y nX || }} jsLdd	 |D | fS ||fS dS )a#  
        Reduces a polynomial modulo a Groebner basis.

        Given a polynomial ``f`` and a set of polynomials ``G = (g_1, ..., g_n)``,
        computes a set of quotients ``q = (q_1, ..., q_n)`` and the remainder ``r``
        such that ``f = q_1*f_1 + ... + q_n*f_n + r``, where ``r`` vanishes or ``r``
        is a completely reduced polynomial with respect to ``G``.

        Examples
        ========

        >>> from sympy import groebner, expand
        >>> from sympy.abc import x, y

        >>> f = 2*x**4 - x**2 + y**3 + y**2
        >>> G = groebner([x**3 - x, y**3 - y])

        >>> G.reduce(f)
        ([2*x, 1], x**2 + y**2 + y)
        >>> Q, r = _

        >>> expand(sum(q*g for q, g in zip(Q, G)) + r)
        2*x**4 - x**2 + y**3 + y**2
        >>> _ == f
        True

        F)ry   Tr   )r"  rm   Nc                s   g | ]}t t| qS rV   )rK   rc   rb   )r   r   )rk   rV   rW   r     s    z(GroebnerBasis.reduce.<locals>.<listcomp>c             S   s   g | ]}|  qS rV   )r   )r   r   rV   rV   rW   r     s    c             S   s   g | ]}|  qS rV   )rP   )r   r   rV   rV   rW   r     s    )rK   rh   r-  re   r,  ry   r   r   r  rb   r  r  r"  rM   r[   r   r   rZ   r   rv   r   rc   r   r2   rd  rP   )rs   rt   r   r   rd  ry   r   r"  r#  r   r   r   r   r$  r%  rV   )rk   rW   r     s2    
zGroebnerBasis.reducec             C   s   |  |d dkS )am  
        Check if ``poly`` belongs the ideal generated by ``self``.

        Examples
        ========

        >>> from sympy import groebner
        >>> from sympy.abc import x, y

        >>> f = 2*x**3 + y**3 + 3*y
        >>> G = groebner([x**2 + y**2 - 1, x*y - 2])

        >>> G.contains(f)
        True
        >>> G.contains(f + 1)
        False

        rm   r   )r   )rs   r   rV   rV   rW   contains  s    zGroebnerBasis.containsN)T)rQ   r  r  r  rl   r  r+  r  rj   r  rd  rM   ry   r[   r/  r  r2  r   r  r  r'  r7  r   r8  rV   rV   rV   rW   r&  #  s&   	 B
Ar&  c                s^   t g   fdd t| } | jr8t| f|S dkrHdd< t |} | |S )z
    Efficiently transform an expression into a polynomial.

    Examples
    ========

    >>> from sympy import poly
    >>> from sympy.abc import x

    >>> poly(x*(x**2 + x - 1)**2)
    Poly(x**5 + 2*x**4 - x**3 - 2*x**2 + x, x, domain='ZZ')

    c       
         s  g g  }}xt | D ]}g g  }}xpt|D ]b}|jrN| || q2|jr|jjr|jjr|jdkr| |j|	|j q2|| q2W |s|| q|d }x|dd  D ]}|
|}qW |rt| }|jr|
|}n|
t||}|| qW |s$t| |}	n^|d }	x |dd  D ]}|	|}	q:W |rt | }|jrp|	|}	n|	t||}	|	j|ddS )Nr   rm   rM   rV   )r   r  r   r  r   r  r  r  r  r   r   r  rK   rh   r   r   r  )
rt   rk   r   Z
poly_termsr  rE  Zpoly_factorsr  productrT   )_polyrj   rV   rW   r:  E  sB    

zpoly.<locals>._polyr  F)r]   r  r   rf   rK   r^   )rt   rM   rj   rk   rV   )r:  rj   rW   r   4  s    4r   )r   )N)N)FNNNFFF)NNFF)NN)T)rl  rm  T)r  	functoolsr   r   operatorr   Z
sympy.corer   r   r   r   Zsympy.core.basicr	   Zsympy.core.decoratorsr
   Zsympy.core.exprtoolsr   r   r   Zsympy.core.evalfr   r   r   r   r   Zsympy.core.functionr   Zsympy.core.mulr   r   Zsympy.core.numbersr   r   r   Zsympy.core.relationalr   r   Zsympy.core.sortingr   Zsympy.core.symbolr   r   Zsympy.core.sympifyr   r   Zsympy.core.traversalr    r!   Zsympy.logic.boolalgr"   Zsympy.polysr#   r]   Zsympy.polys.constructorr$   Zsympy.polys.domainsr%   r&   r'   Z!sympy.polys.domains.domainelementr(   Zsympy.polys.fglmtoolsr)   Zsympy.polys.groebnertoolsr*   r*  Zsympy.polys.monomialsr+   Zsympy.polys.orderingsr,   Zsympy.polys.polyclassesr-   r.   r/   Zsympy.polys.polyerrorsr0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   Zsympy.polys.polyutilsr;   r<   r=   r>   r?   r@   Zsympy.polys.rationaltoolsrA   Zsympy.polys.rootisolationrB   Zsympy.utilitiesrC   rD   rE   Zsympy.utilities.exceptionsrF   Zsympy.utilities.iterablesrG   rH   rc  rp  Zmpmath.libmp.libhyperrI   rY   rK   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  r1  r  r2  r   r3  r5  r6  r7  r9  r:  r>  r?  r  rA  rB  r  r  r  r  r  r  r  r  rC  rN  rG  r  rI  rU  ra  ri  r~  r  r  r  r!  r'  r&  r   rV   rV   rV   rW   <module>   s2  4
 "                                h](_
:5##   #''5$)U3N2v./":,	,b7 ,f<6  