o
    oh?                     @   s  d Z ddlmZ ddlmZmZmZmZmZm	Z	m
Z
mZmZmZmZmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZmZ dd	lmZmZ dd
l m!Z!m"Z"m#Z#m$Z$m%Z% ddl&m'Z'm(Z(m)Z) ddl*m+Z+ ddl,m-Z-m.Z. ddl/m0Z0m1Z1m2Z2m3Z3 ddl4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z:m;Z; ddl<m=Z= ddl>m?Z? dgZ@G dd dZAeA aBeA aCdd ZDdd ZEe1d'ddZFe1G dd deZGe1G d d! d!eGZHeHZIe=eHeHd"d# ZJe=eHed$d# ZJe1G d%d& d&eZKdS )(z2Implementation of RootOf class and related tools.     )Basic)SExprIntegerFloatIooAddLambdasymbolssympifyRationalDummy)cacheit)is_le)ordered)QQ)MultivariatePolynomialErrorGeneratorsNeededPolynomialErrorDomainError)
symmetrizeviete)roots_linearroots_quadraticroots_binomialpreprocess_rootsroots)PolyPurePolyfactor)together)dup_isolate_complex_roots_sqfdup_isolate_real_roots_sqf)lambdifypublicsiftnumbered_symbols)mpfmpcfindrootworkprec)dps_to_precprec_to_dps)dispatch)chainCRootOfc                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_pure_key_dicta  A minimal dictionary that makes sure that the key is a
    univariate PurePoly instance.

    Examples
    ========

    Only the following actions are guaranteed:

    >>> from sympy.polys.rootoftools import _pure_key_dict
    >>> from sympy import PurePoly
    >>> from sympy.abc import x, y

    1) creation

    >>> P = _pure_key_dict()

    2) assignment for a PurePoly or univariate polynomial

    >>> P[x] = 1
    >>> P[PurePoly(x - y, x)] = 2

    3) retrieval based on PurePoly key comparison (use this
       instead of the get method)

    >>> P[y]
    1

    4) KeyError when trying to retrieve a nonexisting key

    >>> P[y + 1]
    Traceback (most recent call last):
    ...
    KeyError: PurePoly(y + 1, y, domain='ZZ')

    5) ability to query with ``in``

    >>> x + 1 in P
    False

    NOTE: this is a *not* a dictionary. It is a very basic object
    for internal use that makes sure to always address its cache
    via PurePoly instances. It does not, for example, implement
    ``get`` or ``setdefault``.
    c                 C   s
   i | _ d S N)_dictself r6   k/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/sympy/polys/rootoftools.py__init__R   s   
z_pure_key_dict.__init__c                 C   s<   t |tst |trt|jdkstt|dd}| j| S )N   Fexpand)
isinstancer   r   lenfree_symbolsKeyErrorr3   r5   kr6   r6   r7   __getitem__U   s
   

z_pure_key_dict.__getitem__c                 C   sD   t |tst |trt|jdkstdt|dd}|| j|< d S )Nr9   zexpecting univariate expressionFr:   )r<   r   r   r=   r>   
ValueErrorr3   )r5   rA   vr6   r6   r7   __setitem__\   s
   
z_pure_key_dict.__setitem__c                 C   s$   z| |  W dS  t y   Y dS w )NTF)r?   r@   r6   r6   r7   __contains__c   s   z_pure_key_dict.__contains__N)__name__
__module____qualname____doc__r8   rB   rE   rF   r6   r6   r6   r7   r1   %   s    ,r1   c                 C   s   |   \}}dd |D S )Nc                 S   s    g | ]\}}t |d d|fqS )Fr:   )r   ).0fmr6   r6   r7   
<listcomp>p        z!_pure_factors.<locals>.<listcomp>)factor_list)poly_factorsr6   r6   r7   _pure_factorsn   s   rT   c                 C   s\   dd |   D }tdd |D rdS dd |D }tt|td}t|t tS )zZReturn the number of imaginary roots for irreducible
    univariate polynomial ``f``.
    c                 S   s   g | ]	\\}}||fqS r6   r6   rK   ijr6   r6   r7   rN   w   s    z)_imag_count_of_factor.<locals>.<listcomp>c                 s   s    | ]	\}}|d  V  qdS )   Nr6   rU   r6   r6   r7   	<genexpr>x       z(_imag_count_of_factor.<locals>.<genexpr>r   c                 S   s    g | ]\}}|t | | fqS r6   )r   rU   r6   r6   r7   rN   {   rO   x)	termsanyr   	from_dictdictr   intcount_rootsr   )rL   r\   evenr6   r6   r7   _imag_count_of_factors   s   rc   NTc                 C   s   t | ||||dS )a  An indexed root of a univariate polynomial.

    Returns either a :obj:`ComplexRootOf` object or an explicit
    expression involving radicals.

    Parameters
    ==========

    f : Expr
        Univariate polynomial.
    x : Symbol, optional
        Generator for ``f``.
    index : int or Integer
    radicals : bool
               Return a radical expression if possible.
    expand : bool
             Expand ``f``.
    indexradicalsr;   )r0   )rL   r[   re   rf   r;   r6   r6   r7   rootof   s   rg   c                   @   s   e Zd ZdZdZdddZdS )RootOfzRepresents a root of a univariate polynomial.

    Base class for roots of different kinds of polynomials.
    Only complex roots are currently supported.
    )rQ   NTc                 C   s   t |||||dS )z>Construct a new ``CRootOf`` object for ``k``-th root of ``f``.rd   )rg   )clsrL   r[   re   rf   r;   r6   r6   r7   __new__      zRootOf.__new__NTT)rG   rH   rI   rJ   	__slots__rj   r6   r6   r6   r7   rh      s    rh   c                   @   s  e Zd ZdZdZdZdZdZdUddZe	dd	 Z
d
d Zedd Zedd Zedd Zdd Zdd Ze	dVddZe	dVddZe	dVddZe	dVddZe	dVddZe	dVd 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	dWd0d1Zd2d3 Z d4d5 Z!e	d6d7 Z"d8d9 Z#e	dVd:d;Z$e	e%d<d= Z&e	d>d? Z'e	d@dA Z(e	dBdC Z)e	dDdE Z*dFdG Z+dHdI Z,dJdK Z-dLdM Z.dWdNdOZ/dPdQ Z0dXdSdTZ1dS )YComplexRootOfa  Represents an indexed complex root of a polynomial.

    Roots of a univariate polynomial separated into disjoint
    real or complex intervals and indexed in a fixed order:

    * real roots come first and are sorted in increasing order;
    * complex roots come next and are sorted primarily by increasing
      real part, secondarily by increasing imaginary part.

    Currently only rational coefficients are allowed.
    Can be imported as ``CRootOf``. To avoid confusion, the
    generator must be a Symbol.


    Examples
    ========

    >>> from sympy import CRootOf, rootof
    >>> from sympy.abc import x

    CRootOf is a way to reference a particular root of a
    polynomial. If there is a rational root, it will be returned:

    >>> CRootOf.clear_cache()  # for doctest reproducibility
    >>> CRootOf(x**2 - 4, 0)
    -2

    Whether roots involving radicals are returned or not
    depends on whether the ``radicals`` flag is true (which is
    set to True with rootof):

    >>> CRootOf(x**2 - 3, 0)
    CRootOf(x**2 - 3, 0)
    >>> CRootOf(x**2 - 3, 0, radicals=True)
    -sqrt(3)
    >>> rootof(x**2 - 3, 0)
    -sqrt(3)

    The following cannot be expressed in terms of radicals:

    >>> r = rootof(4*x**5 + 16*x**3 + 12*x**2 + 7, 0); r
    CRootOf(4*x**5 + 16*x**3 + 12*x**2 + 7, 0)

    The root bounds can be seen, however, and they are used by the
    evaluation methods to get numerical approximations for the root.

    >>> interval = r._get_interval(); interval
    (-1, 0)
    >>> r.evalf(2)
    -0.98

    The evalf method refines the width of the root bounds until it
    guarantees that any decimal approximation within those bounds
    will satisfy the desired precision. It then stores the refined
    interval so subsequent requests at or below the requested
    precision will not have to recompute the root bounds and will
    return very quickly.

    Before evaluation above, the interval was

    >>> interval
    (-1, 0)

    After evaluation it is now

    >>> r._get_interval() # doctest: +SKIP
    (-165/169, -206/211)

    To reset all intervals for a given polynomial, the :meth:`_reset` method
    can be called from any CRootOf instance of the polynomial:

    >>> r._reset()
    >>> r._get_interval()
    (-1, 0)

    The :meth:`eval_approx` method will also find the root to a given
    precision but the interval is not modified unless the search
    for the root fails to converge within the root bounds. And
    the secant method is used to find the root. (The ``evalf``
    method uses bisection and will always update the interval.)

    >>> r.eval_approx(2)
    -0.98

    The interval needed to be slightly updated to find that root:

    >>> r._get_interval()
    (-1, -1/2)

    The ``evalf_rational`` will compute a rational approximation
    of the root to the desired accuracy or precision.

    >>> r.eval_rational(n=2)
    -69629/71318

    >>> t = CRootOf(x**3 + 10*x + 1, 1)
    >>> t.eval_rational(1e-1)
    15/256 - 805*I/256
    >>> t.eval_rational(1e-1, 1e-4)
    3275/65536 - 414645*I/131072
    >>> t.eval_rational(1e-4, 1e-4)
    6545/131072 - 414645*I/131072
    >>> t.eval_rational(n=2)
    104755/2097152 - 6634255*I/2097152

    Notes
    =====

    Although a PurePoly can be constructed from a non-symbol generator
    RootOf instances of non-symbols are disallowed to avoid confusion
    over what root is being represented.

    >>> from sympy import exp, PurePoly
    >>> PurePoly(x) == PurePoly(exp(x))
    True
    >>> CRootOf(x - 1, 0)
    1
    >>> CRootOf(exp(x) - 1, 0)  # would correspond to x == 0
    Traceback (most recent call last):
    ...
    sympy.polys.polyerrors.PolynomialError: generator must be a Symbol

    See Also
    ========

    eval_approx
    eval_rational

    )re   TNFc                 C   sJ  t |}|du r|jrd|}}nt |}|dur!|jr!t|}ntd| t||d|d}|js6td|jjs>td|	 }|dkrLtd| || k sU||krat
d	| |d
 |f |dk ri||7 }| }|jst| }| ||}	|	dur|	| S t|\}
}| }|jstd| | j||dd}|
| || S )z Construct an indexed complex root of a polynomial.

        See ``rootof`` for the parameters.

        The default value of ``radicals`` is ``False`` to satisfy
        ``eval(srepr(expr) == expr``.
        Nz&expected an integer root index, got %sF)greedyr;   'only univariate polynomials are allowedzgenerator must be a Symbolr   z&Cannot construct CRootOf object for %sz(root index out of [%d, %d] range, got %dr9   z CRootOf is not supported over %sT)lazy)r   
is_Integerr`   rC   r   is_univariater   gen	is_Symboldegree
IndexError
get_domainis_Exactto_exact_roots_trivialr   is_ZZNotImplementedError_indexed_root_postprocess_root)ri   rL   r[   re   rf   r;   rQ   rv   domr   coeffrootr6   r6   r7   rj   .  sB   
zComplexRootOf.__new__c                 C   sR   t | }t||_||_zt| t|j< t| t|j< W |S  ty(   Y |S w )z0Construct new ``CRootOf`` object from raw data. )r   rj   r   rQ   re   _reals_cache_complexes_cacher?   )ri   rQ   re   objr6   r6   r7   _newj  s   

zComplexRootOf._newc                 C      | j | jfS r2   )rQ   re   r4   r6   r6   r7   _hashable_contentz     zComplexRootOf._hashable_contentc                 C   
   | j  S r2   rQ   as_exprr4   r6   r6   r7   expr}     
zComplexRootOf.exprc                 C   s   | j t| jfS r2   )r   r   re   r4   r6   r6   r7   args     zComplexRootOf.argsc                 C   s   t  S r2   )setr4   r6   r6   r7   r>     s   zComplexRootOf.free_symbolsc                 C   s   |    | jtt| j k S )z%Return ``True`` if the root is real. )_ensure_reals_initre   r=   r   rQ   r4   r6   r6   r7   _eval_is_real  s   zComplexRootOf._eval_is_realc                 C   s8   |    | jtt| j kr|  }|j|j dkS dS )z*Return ``True`` if the root is imaginary. r   F)r   re   r=   r   rQ   _get_intervalaxbx)r5   ivlr6   r6   r7   _eval_is_imaginary  s
   z ComplexRootOf._eval_is_imaginaryc                 C      |  d||S )z Get real roots of a polynomial. _real_roots
_get_rootsri   rQ   rf   r6   r6   r7   
real_roots     zComplexRootOf.real_rootsc                 C   r   )z,Get real and complex roots of a polynomial. 
_all_rootsr   r   r6   r6   r7   	all_roots  r   zComplexRootOf.all_rootsc                 C   <   |r|t v rt | }|S t|j |jjdd t |< }|S )z;Get real root isolating intervals for a square-free factor.Tblackbox)r   r#   repto_listr   )ri   currentfactor	use_cache	real_partr6   r6   r7   _get_reals_sqf  s   
zComplexRootOf._get_reals_sqfc                 C   r   )z>Get complex root isolating intervals for a square-free factor.Tr   )r   r"   r   r   r   )ri   r   r   complex_partr6   r6   r7   _get_complexes_sqf  s   
z ComplexRootOf._get_complexes_sqfc              	      s   g }|D ]9\ z|st t  }| fdd|D  W q t y=   |  |} fdd|D }|| Y qw | |}|S )z=Compute real root isolating intervals for a list of factors. c                       g | ]}| fqS r6   r6   rK   rV   r   rA   r6   r7   rN         z,ComplexRootOf._get_reals.<locals>.<listcomp>c                    r   r6   r6   rK   r   r   r6   r7   rN     r   )r?   r   extendr   _reals_sorted)ri   rS   r   realsrr   newr6   r   r7   
_get_reals  s   
zComplexRootOf._get_realsc              	      s   g }t |D ]9\ z|stt  }| fdd|D  W q ty?   |  |} fdd|D }|| Y qw | |}|S )z@Compute complex root isolating intervals for a list of factors. c                    r   r6   r6   r   r   r6   r7   rN     r   z0ComplexRootOf._get_complexes.<locals>.<listcomp>c                    r   r6   r6   r   r   r6   r7   rN     r   )r   r?   r   r   r   _complexes_sorted)ri   rS   r   	complexescr   r   r6   r   r7   _get_complexes  s   
zComplexRootOf._get_complexesc                 C   s   i }t |D ]2\}\}}}t ||d d D ]\}\}}	}
||\}}||	|
f||| d < q|||f||< qt|dd d}|D ]\}}}||v rT|| | qC|g||< qC| D ]\}}|t|< q^|S )z7Make real isolating intervals disjoint and sort roots. r9   Nc                 S   s
   | d j S )Nr   )a)r   r6   r6   r7   <lambda>  s   
 z-ComplexRootOf._reals_sorted.<locals>.<lambda>)key)	enumeraterefine_disjointsortedappenditemsr   )ri   r   cacherV   urL   rA   rW   rD   grM   r   r   rR   r6   r6   r7   r     s   "
zComplexRootOf._reals_sortedc           	      C   s(  t |dd }g }t|D ]}t|}|dkr>|| D ]!\}}}|j|j dkr4| }|j|j dks(||||f qqttt	|| }	 t	|dksQJ t|D ],}|| | \}}}|j|j dkrn|
| qU|j|jkr| }|||f|| |< qUt	||krnqI|||  q|S )Nc                 S   s   | d S )Nr9   r6   )r   r6   r6   r7   r     s    z1ComplexRootOf._refine_imaginary.<locals>.<lambda>r   Tr9   )r&   r   rc   r   r   _inner_refiner   listranger=   remover   )	ri   r   siftedrL   nimagr   rA   potential_imagrV   r6   r6   r7   _refine_imaginary  s6   zComplexRootOf._refine_imaginaryc           
      C   s   t |D ]2\}\}}}t ||d d D ]\}\}}}	||\}}|||	f||| d < q|||f||< q| |}t |D ]"\}\}}}|j|j dkr[| }|j|j dksO|||f||< q@|S )a  return complexes such that no bounding rectangles of non-conjugate
        roots would intersect. In addition, assure that neither ay nor by is
        0 to guarantee that non-real roots are distinct from real roots in
        terms of the y-bounds.
        r9   Nr   )r   r   r   aybyrefine)
ri   r   rV   r   rL   rA   rW   rD   r   rM   r6   r6   r7   _refine_complexes  s   
"
zComplexRootOf._refine_complexesc           
         s   |  |}d\}  fdd|D }tdt|D ]}||   ||d    kr4|||d     qt|D ]\}}|| j|d dku sJJ q9i }|D ]\}}}	||g | qO| D ]\}}|t	|< qb|S )z:Make complex isolating intervals disjoint and sort roots. )r   r9   c                    s   h | ]}|  qS r6   r6   r   Fr6   r7   	<setcomp>;      z2ComplexRootOf._complexes_sorted.<locals>.<setcomp>r9   rX   r   )
r   r   r=   r   r   conj
setdefaultr   r   r   )
ri   r   CfsrV   cmplxr   r   r   rR   r6   r   r7   r   3  s   

zComplexRootOf._complexes_sortedc           	      C   sr   d}t |D ]0\}\}}}||| k r2|d}}|d| D ]\}}}||kr+|d7 }q||f  S ||7 }qdS )ze
        Map initial real root index to an index in a factor where
        the root belongs.
        r   Nr9   )r   )	ri   r   re   rV   rW   rR   r   rA   rQ   r6   r6   r7   _reals_indexR  s   

zComplexRootOf._reals_indexc           	      C   s   d}t |D ]8\}\}}}||| k r:|d}}|d| D ]\}}}||kr+|d7 }q|tt| 7 }||f  S ||7 }qdS )zh
        Map initial complex root index to an index in a factor where
        the root belongs.
        r   Nr9   )r   r=   r   )	ri   r   re   rV   rW   rR   r   rA   rQ   r6   r6   r7   _complexes_indexf  s   

zComplexRootOf._complexes_indexc                 C   s   t dd |D S )z>Count the number of real or complex roots with multiplicities.c                 s   s    | ]\}}}|V  qd S r2   r6   )rK   rR   rA   r6   r6   r7   rY   ~  s    z-ComplexRootOf._count_roots.<locals>.<genexpr>)sum)ri   r   r6   r6   r7   _count_roots{  s   zComplexRootOf._count_rootsc                 C   sz   t |}|rt|dkr|d d dkr|d d |fS | |}| |}||k r0| ||S | |}| ||| S )z/Get a root of a composite polynomial by index. r9   r   )rT   r=   r   r   r   r   r   )ri   rQ   re   rq   rS   r   reals_countr   r6   r6   r7   r~     s    


zComplexRootOf._indexed_rootc                 C   "   | j tvr| | j | j dS dS )z5Ensure that our poly has entries in the reals cache. N)rQ   r   r~   re   r4   r6   r6   r7   r        
z ComplexRootOf._ensure_reals_initc                 C   r   )z9Ensure that our poly has entries in the complexes cache. N)rQ   r   r~   re   r4   r6   r6   r7   _ensure_complexes_init  r   z$ComplexRootOf._ensure_complexes_initc                 C   sF   t |}| |}| |}g }td|D ]}|| || q|S )z*Get real roots of a composite polynomial. r   )rT   r   r   r   r   r   )ri   rQ   rS   r   r   r   re   r6   r6   r7   r     s   

zComplexRootOf._real_rootsc                 C   s   | j | jdd dS )z%
        Reset all intervals
        Fr   N)r   rQ   r4   r6   r6   r7   _reset  s   zComplexRootOf._resetc           
      C   s   t |}| j||d}| |}g }td|D ]}|| || q| j||d}| |}	td|	D ]}|| || q4|S )z6Get real and complex roots of a composite polynomial. r   r   )rT   r   r   r   r   r   r   r   )
ri   rQ   r   rS   r   r   r   re   r   complexes_countr6   r6   r7   r     s   

zComplexRootOf._all_rootsc                 C   sP   |  dkr
t|S |sdS |  dkrt|S | dkr&| r&t|S dS )z7Compute roots in linear, quadratic and binomial cases. r9   NrX   )rv   r   r   lengthTCr   r   r6   r6   r7   r{     s   zComplexRootOf._roots_trivialc                 C   sD   |  }|js| }t|\}}|  }|jstd| ||fS )zBTake heroic measures to make ``poly`` compatible with ``CRootOf``.z"sorted roots not supported over %s)rx   ry   rz   r   r|   r}   )ri   rQ   r   r   r6   r6   r7   _preprocess_roots  s   zComplexRootOf._preprocess_rootsc                 C   s0   |\}}|  ||}|dur|| S | ||S )z:Return the root if it is trivial or a ``CRootOf`` object. N)r{   r   )ri   r   rf   rQ   re   r   r6   r6   r7   r     s
   zComplexRootOf._postprocess_rootc           
      C   s   |j stdt }||j|}td}dd |jD }ttdftdD ]}|j	|vr7|
||i} nq'| |\}}g }t| ||D ]}	||| |	|  qH|S )z.Return postprocessed roots of specified kind. rp   r[   c                 S   s   h | ]}t |qS r6   )strr   r6   r6   r7   r     r   z+ComplexRootOf._get_roots.<locals>.<setcomp>)rs   r   r   subsrt   r   r>   r/   r'   namexreplacer   getattrr   r   )
ri   methodrQ   rf   dr[   
free_namesr   r   r   r6   r6   r7   r     s    
zComplexRootOf._get_rootsc                 C   s   t  at  adS )ag  Reset cache for reals and complexes.

        The intervals used to approximate a root instance are updated
        as needed. When a request is made to see the intervals, the
        most current values are shown. `clear_cache` will reset all
        CRootOf instances back to their original state.

        See Also
        ========

        _reset
        N)r1   r   r   )ri   r6   r6   r7   clear_cache  s   
zComplexRootOf.clear_cachec                 C   sH   |    | jrt| j | j S tt| j }|   t| j | j|  S )z@Internal function for retrieving isolation interval from cache. r   is_realr   rQ   re   r=   r   r   )r5   r   r6   r6   r7   r   !  s   zComplexRootOf._get_intervalc                 C   sP   |    | jr|t| j | j< dS tt| j }|   |t| j | j| < dS )z<Internal function for updating isolation interval in cache. Nr   )r5   intervalr   r6   r6   r7   _set_interval+  s   zComplexRootOf._set_intervalc                 C   s   | S r2   r6   )r5   oldr   r6   r6   r7   
_eval_subs5     zComplexRootOf._eval_subsc                 C   s6   | j r| S | j\}}| |||  jrd S d S )Nr9   )r   r   funcr   r   )r5   r   rV   r6   r6   r7   _eval_conjugate9  s   
"zComplexRootOf._eval_conjugatec              
   C   s  t |}t|D | jj}|js'td}| jr|t9 }t|| j	
||}n| j	}| jr6| j	
|t| }t||}|  }	 | jrktt|j}	tt|j}
|	|
krX|	}ntt|j}|tt|jd  }ns| jrtt|j}	tt|j}
|	|
krttd|	}ntt|jd }|tt|jd  }nAtt|j}tt|j}tt|j}tt|j}||kr||krt||}nttt|j }|ttt|j|jf d  }zVt|||f}| js| jrt|j| jks|	|  kr|
krn n/| jrttd|j}W n4n ||j  kr |kr3n n||j  kr/|kr3n nW nW n ttfy@   Y nw |  }q@W d   n	1 sQw   Y  | !| |r`|S t"#|jj$|tt"#|jj$|  S )a@  Evaluate this complex root to the given precision.

        This uses secant method and root bounds are used to both
        generate an initial guess and to check that the root
        returned is valid. If ever the method converges outside the
        root bounds, the bounds will be made smaller and updated.
        r[   T   0r9   N)%r,   r+   rQ   rt   ru   r   is_imaginaryr   r$   r   r   r   r   r(   r   r   bcenterdxr   r   r)   dyr   r   mapr*   boolimagrealUnboundLocalErrorrC   r   r   r   r   _mpf_)r5   nreturn_mpmathprecr   r   r   r   r   r   r   r   x0x1r   r   r   r   r6   r6   r7   eval_approx?  s   

<
IzComplexRootOf.eval_approxc                 K   s   | j t|d|S )z2Evaluate this complex root to the given precision.r
  )eval_rationalr-   _evalf)r5   r  kwargsr6   r6   r7   _eval_evalf  s   zComplexRootOf._eval_evalf   c           	      C   s  |p|}|r#d}t |tr|ntt|}t |tr|ntt|}n	td|d   }|  }	 | jrZ|r=t|j| }|j|d}|j}t|}tj	}|rX|j
t|| k rYnonm| jr|rjt|jd | }d}|j||d}|jd }t|}tj	}|r|jt|| k rn?n=|rt|jd | }t|jd | }|||}|j}tt|\}}|r|j
t|d | k r|jt|d | k rnq1| | |t|  S )	a  
        Return a Rational approximation of ``self`` that has real
        and imaginary component approximations that are within ``dx``
        and ``dy`` of the true values, respectively. Alternatively,
        ``n`` digits of precision can be specified.

        The interval is refined with bisection and is sure to
        converge. The root bounds are updated when the refinement
        is complete so recalculation at the same or lesser precision
        will not have to repeat the refinement and should be much
        faster.

        The following example first obtains Rational approximation to
        1e-8 accuracy for all roots of the 4-th order Legendre
        polynomial. Since the roots are all less than 1, this will
        ensure the decimal representation of the approximation will be
        correct (including rounding) to 6 digits:

        >>> from sympy import legendre_poly, Symbol
        >>> x = Symbol("x")
        >>> p = legendre_poly(4, x, polys=True)
        >>> r = p.real_roots()[-1]
        >>> r.eval_rational(10**-8).n(6)
        0.861136

        It is not necessary to a two-step calculation, however: the
        decimal representation can be computed directly:

        >>> r.evalf(17)
        0.86113631159405258

        N
   rX   T)r  r9   )r  r  r   )r<   r   r   r   r   r   absr  refine_sizeZeror  r   r  r  r   r   )	r5   r  r  r
  rtolr   r   r  r  r6   r6   r7   r    sT   !

"zComplexRootOf.eval_rational)NFTT)F)NNr  )2rG   rH   rI   rJ   rm   
is_complex	is_number	is_finiterj   classmethodr   r   propertyr   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  r6   r6   r6   r7   rn      s     
<




















Xrn   c                 C   s   | |kS r2   r6   )lhsrhsr6   r6   r7   _eval_is_eq  s   r#  c                 C   s  |j sd S |js
dS | j| jj |j}|du rdS |j|jf}| j| jf}d |vs.J ||kr8d |vr8dS |	 \}}| jr`|rEdS | 
 }dd |j|jfD \}}	t||ko^||	kS | 
 }dd |j|j|j|jfD \}
}}}t|
|ot||ot||ot||S )NFc                 S      g | ]}t t|qS r6   r   r   )rK   rR   r6   r6   r7   rN         z_eval_is_eq.<locals>.<listcomp>c                 S   r$  r6   r%  )rK   rW   r6   r6   r7   rN     r&  )r  r  r   r   r>   popis_zeror   r   as_real_imagr   r   r   r   r   r   r   r   r   )r!  r"  zosreimrV   r   r   r1r2i1i2r6   r6   r7   r#    s0   (c                   @   s   e Zd ZdZdZd"ddZed#dd	Zed#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dd Zdd Zd d! ZdS )$RootSumz:Represents a sum of all roots of a univariate polynomial. )rQ   funautoNTFc                 C   s  |  ||\}}|jstd|du rt|j|j}n"t|dd}|r7d|jv r7t|ts6t|j||j}ntd| |j	d |j
}	}|tjurS||	||	 }| }
||	s`|
| S |jrk||	\}}ntj}|jry||	\}}ntj}t|	|}| ||}t|g }}|D ]8\}}|jr|t|d }n!|r|jrtt|t|}n|r|s| |||}n| ||}|||  q|t|  |
|  S )z>Construct a new ``RootSum`` instance of roots of a polynomial.rp   Nis_FunctionFr9   z&expected a univariate function, got %sr   ) 
_transformrs   r   r
   rt   r   nargsr<   rC   	variablesr   r   Oner   rv   hasis_Addas_independentr  is_Mul_is_func_rationalrT   	is_linearr   is_quadraticr   r  r   r   _rational_caser   r	   )ri   r   r   r[   r5  	quadraticr   rQ   is_funcvardeg	add_const	mul_constrationalrS   r\   rA   termr6   r6   r7   rj     sP   




zRootSum.__new__c                 C   s    t | }||_||_||_|S )z(Construct new raw ``RootSum`` instance. )r   rj   rQ   r4  r5  )ri   rQ   r   r5  r   r6   r6   r7   r   Z  s
   
zRootSum._newc                 C   sB   |j j|j s
|j S | ||}|r|s| |||S | ||S )z$Construct new ``RootSum`` instance. )r   r;  r9  r?  r   rB  )ri   rQ   r   r5  rI  r6   r6   r7   r   e  s   zRootSum.newc                 C   s   t ||dd}t|S )z)Transform an expression to a polynomial. F)ro   )r   r   )ri   r   r[   rQ   r6   r6   r7   r7  r  s   zRootSum._transformc                 C   s   |j d |j}}||S )z*Check if a lambda is a rational function. r   )r9  r   is_rational_function)ri   rQ   r   rE  r   r6   r6   r7   r?  x  s   
zRootSum._is_func_rationalc                    s  t d|  }|jd |j t fdd|D }t| \}}t| }| }| }z	t	||dd}W n t
yI   d|f}}Y n	w t|  \}	}z	t	||dd}W n t
yj   d|f}}
Y n	w t|  \}}
t||
 dd	\}}t||g }}t||D ]\\}}\}}|||f qt|D ]\}\}}||||< qt|}|d| }||d }
|durt	tt|	|g|jR   }n|\}|durt	tt||
g|jR   }n|
\}t|| S )
z#Handle the rational function case. zr:%dr   c                 3   s    | ]	}  |V  qd S r2   )r   rK   r   r   rE  r6   r7   rY     rZ   z)RootSum._rational_case.<locals>.<genexpr>F)domainr;   NT)formal)r   rv   r9  r   r   r!   as_numer_denomr   r;   r   r   zipr\   r   r   r   r   r   r=   r_   gensr   r    )ri   rQ   r   r   rL   pqrN  p_coeffp_monomq_coeffq_monomcoeffsmappingformulasvaluessymrR   valrV   r   r
  r6   rM  r7   rB  ~  sF   ""zRootSum._rational_casec                 C   r   r2   )rQ   r4  r4   r6   r6   r7   r     r   zRootSum._hashable_contentc                 C   r   r2   r   r4   r6   r6   r7   r     r   zRootSum.exprc                 C   s   | j | j| jjfS r2   )r   r4  rQ   rt   r4   r6   r6   r7   r     rk   zRootSum.argsc                 C   s   | j j| jjB S r2   )rQ   r>   r4  r4   r6   r6   r7   r>     r   zRootSum.free_symbolsc                 C   s   dS )NTr6   r4   r6   r6   r7   is_commutative  r   zRootSum.is_commutativec                    sJ   | dds S t jdd}t| j k r S t fdd|D  S )Nr   T)multiplec                       g | ]}  |qS r6   r4  rL  r4   r6   r7   rN     r   z RootSum.doit.<locals>.<listcomp>)getr   rQ   r=   rv   r	   )r5   hints_rootsr6   r4   r7   doit  s   zRootSum.doitc              	      sH   z j jt|d}W n ttfy     Y S w t fdd|D  S )Nr  c                    ra  r6   rb  rL  r4   r6   r7   rN     r   z'RootSum._eval_evalf.<locals>.<listcomp>)rQ   nrootsr-   r   r   r	   )r5   r  re  r6   r4   r7   r    s   zRootSum._eval_evalfc                 C   s.   | j j\}}t|||}| | j|| jS r2   )r4  r   r
   diffr   rQ   r5  )r5   r[   rE  r   r   r6   r6   r7   _eval_derivative  s   zRootSum._eval_derivative)NNTFr  )rG   rH   rI   rJ   rm   rj   r  r   r   r7  r?  rB  r   r   r   r   r>   r_  rf  r  ri  r6   r6   r6   r7   r3    s4    
<



5



r3  rl   )LrJ   sympy.core.basicr   
sympy.corer   r   r   r   r   r   r	   r
   r   r   r   r   sympy.core.cacher   sympy.core.relationalr   sympy.core.sortingr   sympy.polys.domainsr   sympy.polys.polyerrorsr   r   r   r   sympy.polys.polyfuncsr   r   sympy.polys.polyrootsr   r   r   r   r   sympy.polys.polytoolsr   r   r    sympy.polys.rationaltoolsr!   sympy.polys.rootisolationr"   r#   sympy.utilitiesr$   r%   r&   r'   mpmathr(   r)   r*   r+   mpmath.libmp.libmpfr,   r-   sympy.multipledispatchr.   	itertoolsr/   __all__r1   r   r   rT   rc   rg   rh   rn   r0   r#  r3  r6   r6   r6   r7   <module>   sV    8E      O

