U
    9%e,                     @   s^  d Z dZddlZddlZddlmZ ddlmZm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mZmZmZmZmZmZmZmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZHmIZImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZSmTZTmUZUmVZVmWZWmXZXmYZYmZZZm[Z[m\Z\m]Z]m^Z^mZ dd	l	m_Z_ dd
l	m`Z` eajbZceddZeedkrddlfmgZh ddlfmi  mj  mkZl nddlmmnZh ddl	mmZl ddlmmoZompZpmqZq G dd deheZrG dd dZsetdkrZddluZueuv  dS )z[
This module defines the mpf, mpc classes, and standard functions for
operating with them.
Z	plaintext    N   )StandardBaseContext)
basestringBACKEND)libmp)UMPZMPZ_ZEROMPZ_ONE	int_typesrepr_dpsround_floorround_ceilingdps_to_precround_nearestprec_to_dpsComplexResultto_pickablefrom_pickable	normalizefrom_int
from_floatfrom_strto_intto_floatto_strfrom_rationalfrom_man_expfonefzerofinffninffnanmpf_absmpf_posmpf_negmpf_addmpf_submpf_mulmpf_mul_intmpf_divmpf_rdiv_intmpf_pow_intmpf_modmpf_eqmpf_cmpmpf_ltmpf_gtmpf_lempf_gempf_hashmpf_randmpf_sumbitcountto_fixed
mpc_to_strmpc_to_complexmpc_hashmpc_posmpc_is_nonzerompc_negmpc_conjugatempc_absmpc_addmpc_add_mpfmpc_submpc_sub_mpfmpc_mulmpc_mul_mpfmpc_mul_intmpc_divmpc_div_mpfmpc_powmpc_pow_mpfmpc_pow_intmpc_mpf_divmpf_powmpf_pi
mpf_degreempf_empf_phimpf_ln2mpf_ln10	mpf_eulermpf_catalan	mpf_aperympf_khinchinmpf_glaishermpf_twinprimempf_mertensr
   )function_docs)rationalz\^\(?(?P<re>[\+\-]?\d*(\.\d*)?(e[\+\-]?\d+)?)??(?P<im>[\+\-]?\d*(\.\d*)?(e[\+\-]?\d+)?j)?\)?$sage)Context)PythonMPContext)ctx_mp_python)_mpf_mpc	mpnumericc                   @   s  e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdmddZdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zd#d$ Zd%d& Zd'd( Zd)d* Zd+d, Zd-d. Zed/d0 Zed1d2 Zdnd4d5Zdod6d7Zdpd8d9Zdqd:d;Z drd>d?Z!dsdAdBZ"dCdD Z#dEdF Z$dGdH Z%dIZ&dJZ'dtdLdMZ(dNdO Z)dPdQ Z*dRdS Z+dTdU Z,dVdW Z-dXdY Z.dZd[ Z/d\d] Z0d^d_ Z1d`da Z2dbdc Z3ddde Z4dfdg Z5dhdi Z6djgd3fdkdlZ7d<S )u	MPContextzH
    Context for multiprecision arithmetic with a global precision.
    c                 C   s   t |  d| _d| _| j| j| jg| _tj	| _
|   t|  tj	| _	|   i | _|   z4tj| jj_tj| jj_tj| jj_tj| jj_W nD tk
r   tj| jj_tj| jj_tj| jj_tj| jj_Y nX tj| j_tj| j_tj| j_d S NF)BaseMPContext__init__trap_complexprettympfmpcconstanttypesr\   mpqZ_mpqdefaultr   init_builtinshyp_summatorsZ_init_aliasesr[   	bernoulliZim_funcZfunc_docZprimepipsiatan2AttributeError__func__digammacospisinpictx r|   L/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/mpmath/ctx_mp.pyrg   ?   s0    



zMPContext.__init__c                 C   s  | j }| j}| t| _| t| _| ttf| _| t	| _
| t| _| t| _| dd dd}|| _| tdd| _| tdd| _| tdd	| _| td
d| _| tdd| _| tdd| _| tdd| _| tdd| _ | t!dd| _"| t#dd| _$| t%dd| _&| t'dd| _(| t)dd| _*| +t,j-t,j.| _/| +t,j0t,j1| _2| +t,j3t,j4| _5| +t,j6t,j7| _8| +t,j9t,j:| _;| +t,j<t,j=| _>| +t,j?t,j@| _A| +t,jBt,jC| _D| +t,jEt,jF| _G| +t,jHt,jI| _J| +t,jKt,jL| _M| +t,jNt,jO| _P| +t,jQt,jR| _S| +t,jTt,jU| _V| +t,jWt,jX| _Y| +t,j6t,j7| _8| +t,jZt,j[| _\| +t,j]t,j^| __| +t,j`t,ja| _b| +t,jct,jd| _e| +t,jft,jg| _h| +t,jit,jj| _k| +t,jlt,jm| _n| +t,jot,jp| _q| +t,jrt,js| _t| +t,jut,jv | _w| _x| +t,jyt,jz| _{| +t,j|t,j}| _~| +t,jt,j| _| +t,jt,j | _| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jt,j| _| +t,jd | _| +t,jd | _| +t,jt,j| _| +t,jt,j| _t| d| j/| _/t| d| j;| _;t| d | j5| _5t| d!| jG| _Gt| d"| jD| _Dd S )#Nc                 S   s   dt d|  dfS )Nr   r   )r	   precZrndr|   r|   r}   <lambda>m       z)MPContext.init_builtins.<locals>.<lambda>zepsilon of working precisionepspizln(2)ln2zln(10)ln10zGolden ratio phiphiz
e = exp(1)ezEuler's constanteulerzCatalan's constantcatalanzKhinchin's constantkhinchinzGlaisher's constantglaisherzApery's constantaperyz1 deg = pi / 180degreezTwin prime constant	twinprimezMertens' constantmertensZ
_sage_sqrtZ	_sage_expZ_sage_lnZ	_sage_cosZ	_sage_sin)rj   rk   make_mpfr   oner   zeromake_mpcjr   infr    ninfr!   nanrl   r   rN   r   rR   r   rS   r   rQ   r   rP   r   rT   r   rU   r   rW   r   rX   r   rV   r   rO   r   rY   r   rZ   r   Z_wrap_libmp_functionr   Zmpf_sqrtZmpc_sqrtsqrtZmpf_cbrtZmpc_cbrtZcbrtZmpf_logZmpc_loglnZmpf_atanZmpc_atanatanZmpf_expZmpc_expexpZmpf_expjZmpc_expjZexpjZ
mpf_expjpiZ
mpc_expjpiZexpjpiZmpf_sinZmpc_sinsinZmpf_cosZmpc_coscosZmpf_tanZmpc_tantanZmpf_sinhZmpc_sinhsinhZmpf_coshZmpc_coshcoshZmpf_tanhZmpc_tanhtanhZmpf_asinZmpc_asinasinZmpf_acosZmpc_acosacosZ	mpf_asinhZ	mpc_asinhasinhZ	mpf_acoshZ	mpc_acoshacoshZ	mpf_atanhZ	mpc_atanhatanhZ
mpf_sin_piZ
mpc_sin_piry   Z
mpf_cos_piZ
mpc_cos_pirx   Z	mpf_floorZ	mpc_floorfloorZmpf_ceilZmpc_ceilceilZmpf_nintZmpc_nintZnintZmpf_fracZmpc_fracfracZmpf_fibonacciZmpc_fibonacciZfibZ	fibonacciZ	mpf_gammaZ	mpc_gammagammaZ
mpf_rgammaZ
mpc_rgammaZrgammaZmpf_loggammaZmpc_loggammaZloggammaZmpf_factorialZmpc_factorialZfac	factorialZmpf_psi0Zmpc_psi0rw   Zmpf_harmonicZmpc_harmonicZharmonicZmpf_eiZmpc_eieiZmpf_e1Zmpc_e1e1Zmpf_ciZmpc_ciZ_ciZmpf_siZmpc_siZ_siZ
mpf_ellipkZ
mpc_ellipkZellipkZ
mpf_ellipeZ
mpc_ellipeZ_ellipeZmpf_agm1Zmpc_agm1Zagm1Zmpf_erfZ_erfZmpf_erfcZ_erfcZmpf_zetaZmpc_zetaZ_zetaZmpf_altzetaZmpc_altzetaZ_altzetagetattr)r{   rj   rk   r   r|   r|   r}   rp   `   s    
 zMPContext.init_builtinsc                 C   s
   | |S N)r7   )r{   xr   r|   r|   r}   r7      s    zMPContext.to_fixedc                 C   s2   |  |}|  |}| tj|j|jf| j S )z
        Computes the Euclidean norm of the vector `(x, y)`, equal
        to `\sqrt{x^2 + y^2}`. Both `x` and `y` must be real.)convertr   r   Z	mpf_hypot_mpf__prec_rounding)r{   r   yr|   r|   r}   hypot   s    

zMPContext.hypotc                 C   sv   t | |}|dkr | |S t|ds.t| j\}}tj||j||dd\}}|d krd| 	|S | 
||fS d S )Nr   r   T)r   )int_rer   hasattrNotImplementedErrorr   r   
mpf_expintr   r   r   r{   nzr   roundingrealimagr|   r|   r}   _gamma_upper_int   s    



zMPContext._gamma_upper_intc                 C   sl   t |}|dkr| |S t|ds(t| j\}}t||j||\}}|d krZ| |S | 	||fS d S )Nr   r   )
r   r   r   r   r   r   r   r   r   r   r   r|   r|   r}   _expint_int   s    



zMPContext._expint_intc                 C   st   t |drTz| tj|j|f| j W S  tk
rP   | jr@ |jtjf}Y qZX n|j	}| 
tj||f| j S Nr   )r   r   r   Zmpf_nthrootr   r   r   rh   r   _mpc_r   Zmpc_nthrootr{   r   r   r|   r|   r}   _nthroot   s    
zMPContext._nthrootc                 C   sR   | j \}}t|dr,| t||j||S t|drN| t||j||S d S Nr   r   )	r   r   r   r   Zmpf_besseljnr   r   Zmpc_besseljnr   )r{   r   r   r   r   r|   r|   r}   _besselj   s
    


zMPContext._besseljr   c                 C   s   | j \}}t|drTt|drTz t|j|j||}| |W S  tk
rR   Y nX t|drl|jtjf}n|j}t|dr|jtjf}n|j}| 	t
||||S r   )r   r   r   Zmpf_agmr   r   r   r   r   r   Zmpc_agm)r{   abr   r   vr|   r|   r}   _agm   s    

 
 zMPContext._agmc                 C   s   |  tjt|f| j S r   )r   r   Zmpf_bernoullir   r   r{   r   r|   r|   r}   rr      s    zMPContext.bernoullic                 C   s   |  tjt|f| j S r   )r   r   Zmpf_zeta_intr   r   r   r|   r|   r}   	_zeta_int   s    zMPContext._zeta_intc                 C   s2   |  |}|  |}| tj|j|jf| j S r   )r   r   r   Z	mpf_atan2r   r   )r{   r   r   r|   r|   r}   rt     s    

zMPContext.atan2c                 C   sX   |  |}t|}| |r8| tj||jf| j S | tj	||j
f| j S d S r   )r   r   _is_real_typer   r   Zmpf_psir   r   r   Zmpc_psir   )r{   mr   r|   r|   r}   rs     s
    

zMPContext.psic                 K   s   t || jkr| |}| |\}}t|drXt|j||\}}| || |fS t|drt	|j
||\}}| || |fS | j|f|| j|f|fS d S r   )typerm   r   _parse_precr   r   Zmpf_cos_sinr   r   Zmpc_cos_sinr   r   r   r   r{   r   kwargsr   r   csr|   r|   r}   cos_sin  s    


zMPContext.cos_sinc                 K   s   t || jkr| |}| |\}}t|drXt|j||\}}| || |fS t|drt	|j
||\}}| || |fS | j|f|| j|f|fS d S r   )r   rm   r   r   r   r   Zmpf_cos_sin_pir   r   Zmpc_cos_sin_pir   r   r   r   r   r|   r|   r}   cospi_sinpi  s    


zMPContext.cospi_sinpic                 C   s   |   }| j|_|S )zP
        Create a copy of the context, with the same working precision.
        )	__class__r   )r{   r   r|   r|   r}   clone)  s    zMPContext.clonec                 C   s   t |dst|tkrdS dS )Nr   FTr   r   complexr{   r   r|   r|   r}   r   4  s    zMPContext._is_real_typec                 C   s   t |dst|tkrdS dS )Nr   TFr   r   r|   r|   r}   _is_complex_type9  s    zMPContext._is_complex_typec                 C   sv   t |dr|jtkS t |dr(t|jkS t|ts>t|tjrBdS | |}t |ds`t |drj| 	|S t
ddS )a  
        Return *True* if *x* is a NaN (not-a-number), or for a complex
        number, whether either the real or complex part is NaN;
        otherwise return *False*::

            >>> from mpmath import *
            >>> isnan(3.14)
            False
            >>> isnan(nan)
            True
            >>> isnan(mpc(3.14,2.72))
            False
            >>> isnan(mpc(3.14,nan))
            True

        r   r   Fzisnan() needs a number as inputN)r   r   r!   r   
isinstancer
   r\   rn   r   isnan	TypeErrorr   r|   r|   r}   r   >  s    





zMPContext.isnanc                 C   s   |  |s| |rdS dS )a  
        Return *True* if *x* is a finite number, i.e. neither
        an infinity or a NaN.

            >>> from mpmath import *
            >>> isfinite(inf)
            False
            >>> isfinite(-inf)
            False
            >>> isfinite(3)
            True
            >>> isfinite(nan)
            False
            >>> isfinite(3+4j)
            True
            >>> isfinite(mpc(3,inf))
            False
            >>> isfinite(mpc(nan,3))
            False

        FT)isinfr   r   r|   r|   r}   isfiniteZ  s    zMPContext.isfinitec                 C   s   |sdS t |dr,|j\}}}}|o*|dkS t |drJ|j oH| |jS t|tkr^|dkS t|| jr|j	\}}|s|dS |dko|dkS | | 
|S )z<
        Determine if *x* is a nonpositive integer.
        Tr   r   r   r   )r   r   r   isnpintr   r   r
   r   rn   _mpq_r   )r{   r   signmanr   bcpqr|   r|   r}   r   t  s    


zMPContext.isnpintc                 C   sF   dd| j  dd d| j dd d| j dd g}d	|S )
NzMpmath settings:z  mp.prec = %s   z[default: 53]z  mp.dps = %sz[default: 15]z  mp.trap_complex = %sz[default: False]
)r   ljustdpsrh   join)r{   linesr|   r|   r}   __str__  s    zMPContext.__str__c                 C   s
   t | jS r   )r   _precrz   r|   r|   r}   _repr_digits  s    zMPContext._repr_digitsc                 C   s   | j S r   )Z_dpsrz   r|   r|   r}   _str_digits  s    zMPContext._str_digitsFc                    s   t |  fddd|S )a  
        The block

            with extraprec(n):
                <code>

        increases the precision n bits, executes <code>, and then
        restores the precision.

        extraprec(n)(f) returns a decorated version of the function f
        that increases the working precision by n bits before execution,
        and restores the parent precision afterwards. With
        normalize_output=True, it rounds the return value to the parent
        precision.
        c                    s   |   S r   r|   r   r   r|   r}   r     r   z%MPContext.extraprec.<locals>.<lambda>NPrecisionManagerr{   r   normalize_outputr|   r   r}   	extraprec  s    zMPContext.extraprecc                    s   t | d fdd|S )z
        This function is analogous to extraprec (see documentation)
        but changes the decimal precision instead of the number of bits.
        Nc                    s   |   S r   r|   dr   r|   r}   r     r   z$MPContext.extradps.<locals>.<lambda>r   r   r|   r   r}   extradps  s    zMPContext.extradpsc                    s   t |  fddd|S )a  
        The block

            with workprec(n):
                <code>

        sets the precision to n bits, executes <code>, and then restores
        the precision.

        workprec(n)(f) returns a decorated version of the function f
        that sets the precision to n bits before execution,
        and restores the precision afterwards. With normalize_output=True,
        it rounds the return value to the parent precision.
        c                    s    S r   r|   r   r   r|   r}   r     r   z$MPContext.workprec.<locals>.<lambda>Nr   r   r|   r   r}   workprec  s    zMPContext.workprecc                    s   t | d fdd|S )z
        This function is analogous to workprec (see documentation)
        but changes the decimal precision instead of the number of bits.
        Nc                    s    S r   r|   r   r   r|   r}   r     r   z#MPContext.workdps.<locals>.<lambda>r   r   r|   r   r}   workdps  s    zMPContext.workdpsNr|   c                    s    fdd}|S )a
  
        Return a wrapped copy of *f* that repeatedly evaluates *f*
        with increasing precision until the result converges to the
        full precision used at the point of the call.

        This heuristically protects against rounding errors, at the cost of
        roughly a 2x slowdown compared to manually setting the optimal
        precision. This method can, however, easily be fooled if the results
        from *f* depend "discontinuously" on the precision, for instance
        if catastrophic cancellation can occur. Therefore, :func:`~mpmath.autoprec`
        should be used judiciously.

        **Examples**

        Many functions are sensitive to perturbations of the input arguments.
        If the arguments are decimal numbers, they may have to be converted
        to binary at a much higher precision. If the amount of required
        extra precision is unknown, :func:`~mpmath.autoprec` is convenient::

            >>> from mpmath import *
            >>> mp.dps = 15
            >>> mp.pretty = True
            >>> besselj(5, 125 * 10**28)    # Exact input
            -8.03284785591801e-17
            >>> besselj(5, '1.25e30')   # Bad
            7.12954868316652e-16
            >>> autoprec(besselj)(5, '1.25e30')   # Good
            -8.03284785591801e-17

        The following fails to converge because `\sin(\pi) = 0` whereas all
        finite-precision approximations of `\pi` give nonzero values::

            >>> autoprec(sin)(pi) # doctest: +IGNORE_EXCEPTION_DETAIL
            Traceback (most recent call last):
              ...
            NoConvergence: autoprec: prec increased to 2910 without convergence

        As the following example shows, :func:`~mpmath.autoprec` can protect against
        cancellation, but is fooled by too severe cancellation::

            >>> x = 1e-10
            >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
            1.00000008274037e-10
            1.00000000005e-10
            1.00000000005e-10
            >>> x = 1e-50
            >>> exp(x)-1; expm1(x); autoprec(lambda t: exp(t)-1)(x)
            0.0
            1.0e-50
            0.0

        With *catch*, an exception or list of exceptions to intercept
        may be specified. The raised exception is interpreted
        as signaling insufficient precision. This permits, for example,
        evaluating a function where a too low precision results in a
        division by zero::

            >>> f = lambda x: 1/(exp(x)-1)
            >>> f(1e-30)
            Traceback (most recent call last):
              ...
            ZeroDivisionError
            >>> autoprec(f, catch=ZeroDivisionError)(1e-30)
            1.0e+30


        c                     s  j }d kr|}n}z|d _ z| |}W n  k
rR   j}Y nX |d }|_ z| |}W n  k
r   j}Y nX ||krq|| | }|| k rqrtd||| f  |}||krd| |t|d 7 }t||}q\W 5 |_ X |
 S )N
      z)autoprec: target=%s, prec=%s, accuracy=%sz2autoprec: prec increased to %i without convergence   )r   _default_hyper_maxprecr   magprintZNoConvergencer   min)argsr   r   Zmaxprec2Zv1Zprec2Zv2errcatchr{   fmaxprecverboser|   r}   f_autoprec_wrapped  sH    


z.MPContext.autoprec.<locals>.f_autoprec_wrappedr|   )r{   r  r  r  r  r  r|   r
  r}   autoprec  s    D%zMPContext.autoprec   c                    s   t |tr*dd fdd|D  S t |trTdd fdd|D  S t|drnt|jfS t|drd	t|jf d
 S t |t	rt
|S t | jr|jfS t|S )a3  
        Convert an ``mpf`` or ``mpc`` to a decimal string literal with *n*
        significant digits. The small default value for *n* is chosen to
        make this function useful for printing collections of numbers
        (lists, matrices, etc).

        If *x* is a list or tuple, :func:`~mpmath.nstr` is applied recursively
        to each element. For unrecognized classes, :func:`~mpmath.nstr`
        simply returns ``str(x)``.

        The companion function :func:`~mpmath.nprint` prints the result
        instead of returning it.

        The keyword arguments *strip_zeros*, *min_fixed*, *max_fixed*
        and *show_zero_exponent* are forwarded to :func:`~mpmath.libmp.to_str`.

        The number will be printed in fixed-point format if the position
        of the leading digit is strictly between min_fixed
        (default = min(-dps/3,-5)) and max_fixed (default = dps).

        To force fixed-point format always, set min_fixed = -inf,
        max_fixed = +inf. To force floating-point format, set
        min_fixed >= max_fixed.

            >>> from mpmath import *
            >>> nstr([+pi, ldexp(1,-500)])
            '[3.14159, 3.05494e-151]'
            >>> nprint([+pi, ldexp(1,-500)])
            [3.14159, 3.05494e-151]
            >>> nstr(mpf("5e-10"), 5)
            '5.0e-10'
            >>> nstr(mpf("5e-10"), 5, strip_zeros=False)
            '5.0000e-10'
            >>> nstr(mpf("5e-10"), 5, strip_zeros=False, min_fixed=-11)
            '0.00000000050000'
            >>> nstr(mpf(0), 5, show_zero_exponent=True)
            '0.0e+0'

        z[%s]z, c                 3   s   | ]} j |fV  qd S r   nstr.0r   r{   r   r   r|   r}   	<genexpr>]  s     z!MPContext.nstr.<locals>.<genexpr>z(%s)c                 3   s   | ]} j |fV  qd S r   r  r  r  r|   r}   r  _  s     r   r   ())r   listr   tupler   r   r   r8   r   r   reprmatrixZ__nstr__str)r{   r   r   r   r|   r  r}   r  4  s    (
 
 


zMPContext.nstrc                 C   s   |rnt |trnd| krn| dd}t|}|d}|sFd}|dd}| | 	|| 	|S t
|dr|j\}}||kr| |S tdtd	t| d S )
Nr     rer   im_mpi_z,can only create mpf from zero-width intervalzcannot create mpf from )r   r   lowerreplaceget_complexmatchgrouprstriprk   r   r   r#  r   
ValueErrorr   r  )r{   r   stringsr'  r!  r"  r   r   r|   r|   r}   _convert_fallbackj  s    




zMPContext._convert_fallbackc                 O   s   | j ||S r   )r   )r{   r  r   r|   r|   r}   	mpmathify|  s    zMPContext.mpmathifyc                 C   s   |r| drdS | j\}}d|kr,|d }d|krT|d }|| jkrJdS t|}n&d|krz|d }|| jkrrdS t|}||fS | jS )Nexact)r   r  r   r   r   )getr   r   r   r   )r{   r   r   r   r   r|   r|   r}   r     s$    




zMPContext._parse_precz'the exact result does not fit in memoryzhypsum() failed to converge to the requested %i bits of accuracy
using a working precision of %i bits. Try with a higher maxprec,
maxterms, or set zeroprec.Tc           !      K   s  t |dr|||df}|j}	nt |dr:|||df}|j}	|| jkrXt|d | j|< | j| }
| j}|d| |}d}d}i }d	}t	|D ]\}}|| d
kr||kr|d	krd}t	|d | D ](\}}|| d
kr|d	kr||krd}q|st
dq| |\}}t| }| }||krv|d	krv|dkrv||kr\||  |7  < n|||< t||| d }|t|7 }q||krt| j||| f || }|rtdd |D }ni }|
||	||||f|\}}}| }d}||k r(| D ]$}|d ks||k rd} q(q||d d k p>| }|r|rPq|d} | d k	r|| kr|r~| d	S | jS |d9 }|d7 }|d7 }qt|tkr|r| |S | |S n|S d S )Nr   Rr   Cr   r  2      r   ZFTzpole in hypergeometric series   <   c                 s   s   | ]}|d fV  qd S r   r|   )r  r   r|   r|   r}   r    s     z#MPContext.hypsum.<locals>.<genexpr>   zeroprecr  )r   r   r   rq   r   Zmake_hyp_summatorr   r/  r  	enumerateZeroDivisionErrornint_distancer   maxabsr*  _hypsum_msgdictvaluesrk   r   r   r  r   r   )!r{   r   r   flagsZcoeffsr   Zaccurate_smallr   keyr   Zsummatorr   r  r   ZepsshiftZmagnitude_checkZmax_total_jumpir   okiiccr   r   ZwpZmag_dictZzvZhave_complexZ	magnitudecancelZjumps_resolvedZaccurater8  r|   r|   r}   hypsum  s    







 







zMPContext.hypsumc                 C   s   |  |}| t|j|S )a  
        Computes `x 2^n` efficiently. No rounding is performed.
        The argument `x` must be a real floating-point number (or
        possible to convert into one) and `n` must be a Python ``int``.

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> ldexp(1, 10)
            mpf('1024.0')
            >>> ldexp(1, -3)
            mpf('0.125')

        )r   r   r   Z	mpf_shiftr   r   r|   r|   r}   ldexp  s    
zMPContext.ldexpc                 C   s(   |  |}t|j\}}| ||fS )a=  
        Given a real number `x`, returns `(y, n)` with `y \in [0.5, 1)`,
        `n` a Python integer, and such that `x = y 2^n`. No rounding is
        performed.

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> frexp(7.5)
            (mpf('0.9375'), 3)

        )r   r   Z	mpf_frexpr   r   )r{   r   r   r   r|   r|   r}   frexp   s    
zMPContext.frexpc                 K   s`   |  |\}}| |}t|dr6| t|j||S t|drT| t|j||S t	ddS )a  
        Negates the number *x*, giving a floating-point result, optionally
        using a custom precision and rounding mode.

        See the documentation of :func:`~mpmath.fadd` for a detailed description
        of how to specify precision and rounding.

        **Examples**

        An mpmath number is returned::

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fneg(2.5)
            mpf('-2.5')
            >>> fneg(-5+2j)
            mpc(real='5.0', imag='-2.0')

        Precise control over rounding is possible::

            >>> x = fadd(2, 1e-100, exact=True)
            >>> fneg(x)
            mpf('-2.0')
            >>> fneg(x, rounding='f')
            mpf('-2.0000000000000004')

        Negating with and without roundoff::

            >>> n = 200000000000000000000001
            >>> print(int(-mpf(n)))
            -200000000000000016777216
            >>> print(int(fneg(n)))
            -200000000000000016777216
            >>> print(int(fneg(n, prec=log(n,2)+1)))
            -200000000000000000000001
            >>> print(int(fneg(n, dps=log(n,10)+1)))
            -200000000000000000000001
            >>> print(int(fneg(n, prec=inf)))
            -200000000000000000000001
            >>> print(int(fneg(n, dps=inf)))
            -200000000000000000000001
            >>> print(int(fneg(n, exact=True)))
            -200000000000000000000001

        r   r   2Arguments need to be mpf or mpc compatible numbersN)
r   r   r   r   r$   r   r   r=   r   r*  )r{   r   r   r   r   r|   r|   r}   fneg  s    .


zMPContext.fnegc              	   K   s   |  |\}}| |}| |}zt|drvt|drR| t|j|j||W S t|drv| t|j|j||W S t|drt|dr| t|j|j||W S t|dr| t	|j|j||W S W n" t
tfk
r   t| jY nX t
ddS )a  
        Adds the numbers *x* and *y*, giving a floating-point result,
        optionally using a custom precision and rounding mode.

        The default precision is the working precision of the context.
        You can specify a custom precision in bits by passing the *prec* keyword
        argument, or by providing an equivalent decimal precision with the *dps*
        keyword argument. If the precision is set to ``+inf``, or if the flag
        *exact=True* is passed, an exact addition with no rounding is performed.

        When the precision is finite, the optional *rounding* keyword argument
        specifies the direction of rounding. Valid options are ``'n'`` for
        nearest (default), ``'f'`` for floor, ``'c'`` for ceiling, ``'d'``
        for down, ``'u'`` for up.

        **Examples**

        Using :func:`~mpmath.fadd` with precision and rounding control::

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fadd(2, 1e-20)
            mpf('2.0')
            >>> fadd(2, 1e-20, rounding='u')
            mpf('2.0000000000000004')
            >>> nprint(fadd(2, 1e-20, prec=100), 25)
            2.00000000000000000001
            >>> nprint(fadd(2, 1e-20, dps=15), 25)
            2.0
            >>> nprint(fadd(2, 1e-20, dps=25), 25)
            2.00000000000000000001
            >>> nprint(fadd(2, 1e-20, exact=True), 25)
            2.00000000000000000001

        Exact addition avoids cancellation errors, enforcing familiar laws
        of numbers such as `x+y-x = y`, which don't hold in floating-point
        arithmetic with finite precision::

            >>> x, y = mpf(2), mpf('1e-1000')
            >>> print(x + y - x)
            0.0
            >>> print(fadd(x, y, prec=inf) - x)
            1.0e-1000
            >>> print(fadd(x, y, exact=True) - x)
            1.0e-1000

        Exact addition can be inefficient and may be impossible to perform
        with large magnitude differences::

            >>> fadd(1, '1e-100000000000000000000', prec=inf)
            Traceback (most recent call last):
              ...
            OverflowError: the exact result does not fit in memory

        r   r   rK  N)r   r   r   r   r%   r   r   rA   r   r@   r*  OverflowError_exact_overflow_msgr{   r   r   r   r   r   r|   r|   r}   faddF  s"    8







zMPContext.faddc              	   K   s   |  |\}}| |}| |}zt|drzt|drR| t|j|j||W S t|drz| t|jtf|j	||W S t|drt|dr| t
|j	|j||W S t|dr| t|j	|j	||W S W n" ttfk
r   t| jY nX tddS )a  
        Subtracts the numbers *x* and *y*, giving a floating-point result,
        optionally using a custom precision and rounding mode.

        See the documentation of :func:`~mpmath.fadd` for a detailed description
        of how to specify precision and rounding.

        **Examples**

        Using :func:`~mpmath.fsub` with precision and rounding control::

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fsub(2, 1e-20)
            mpf('2.0')
            >>> fsub(2, 1e-20, rounding='d')
            mpf('1.9999999999999998')
            >>> nprint(fsub(2, 1e-20, prec=100), 25)
            1.99999999999999999999
            >>> nprint(fsub(2, 1e-20, dps=15), 25)
            2.0
            >>> nprint(fsub(2, 1e-20, dps=25), 25)
            1.99999999999999999999
            >>> nprint(fsub(2, 1e-20, exact=True), 25)
            1.99999999999999999999

        Exact subtraction avoids cancellation errors, enforcing familiar laws
        of numbers such as `x-y+y = x`, which don't hold in floating-point
        arithmetic with finite precision::

            >>> x, y = mpf(2), mpf('1e1000')
            >>> print(x - y + y)
            0.0
            >>> print(fsub(x, y, prec=inf) + y)
            2.0
            >>> print(fsub(x, y, exact=True) + y)
            2.0

        Exact addition can be inefficient and may be impossible to perform
        with large magnitude differences::

            >>> fsub(1, '1e-100000000000000000000', prec=inf)
            Traceback (most recent call last):
              ...
            OverflowError: the exact result does not fit in memory

        r   r   rK  N)r   r   r   r   r&   r   r   rB   r   r   rC   r*  rM  rN  rO  r|   r|   r}   fsub  s"    0







zMPContext.fsubc              	   K   s   |  |\}}| |}| |}zt|drvt|drR| t|j|j||W S t|drv| t|j|j||W S t|drt|dr| t|j|j||W S t|dr| t	|j|j||W S W n" t
tfk
r   t| jY nX t
ddS )a  
        Multiplies the numbers *x* and *y*, giving a floating-point result,
        optionally using a custom precision and rounding mode.

        See the documentation of :func:`~mpmath.fadd` for a detailed description
        of how to specify precision and rounding.

        **Examples**

        The result is an mpmath number::

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fmul(2, 5.0)
            mpf('10.0')
            >>> fmul(0.5j, 0.5)
            mpc(real='0.0', imag='0.25')

        Avoiding roundoff::

            >>> x, y = 10**10+1, 10**15+1
            >>> print(x*y)
            10000000001000010000000001
            >>> print(mpf(x) * mpf(y))
            1.0000000001e+25
            >>> print(int(mpf(x) * mpf(y)))
            10000000001000011026399232
            >>> print(int(fmul(x, y)))
            10000000001000011026399232
            >>> print(int(fmul(x, y, dps=25)))
            10000000001000010000000001
            >>> print(int(fmul(x, y, exact=True)))
            10000000001000010000000001

        Exact multiplication with complex numbers can be inefficient and may
        be impossible to perform with large magnitude differences between
        real and imaginary parts::

            >>> x = 1+2j
            >>> y = mpc(2, '1e-100000000000000000000')
            >>> fmul(x, y)
            mpc(real='2.0', imag='4.0')
            >>> fmul(x, y, rounding='u')
            mpc(real='2.0', imag='4.0000000000000009')
            >>> fmul(x, y, exact=True)
            Traceback (most recent call last):
              ...
            OverflowError: the exact result does not fit in memory

        r   r   rK  N)r   r   r   r   r'   r   r   rE   r   rD   r*  rM  rN  rO  r|   r|   r}   fmul  s"    3







zMPContext.fmulc                 K   s   |  |\}}|std| |}| |}t|drt|drZ| t|j|j||S t|dr| t|jt	f|j
||S t|drt|dr| t|j
|j||S t|dr| t|j
|j
||S tddS )a  
        Divides the numbers *x* and *y*, giving a floating-point result,
        optionally using a custom precision and rounding mode.

        See the documentation of :func:`~mpmath.fadd` for a detailed description
        of how to specify precision and rounding.

        **Examples**

        The result is an mpmath number::

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fdiv(3, 2)
            mpf('1.5')
            >>> fdiv(2, 3)
            mpf('0.66666666666666663')
            >>> fdiv(2+4j, 0.5)
            mpc(real='4.0', imag='8.0')

        The rounding direction and precision can be controlled::

            >>> fdiv(2, 3, dps=3)    # Should be accurate to at least 3 digits
            mpf('0.6666259765625')
            >>> fdiv(2, 3, rounding='d')
            mpf('0.66666666666666663')
            >>> fdiv(2, 3, prec=60)
            mpf('0.66666666666666667')
            >>> fdiv(2, 3, rounding='u')
            mpf('0.66666666666666674')

        Checking the error of a division by performing it at higher precision::

            >>> fdiv(2, 3) - fdiv(2, 3, prec=100)
            mpf('-3.7007434154172148e-17')

        Unlike :func:`~mpmath.fadd`, :func:`~mpmath.fmul`, etc., exact division is not
        allowed since the quotient of two floating-point numbers generally
        does not have an exact floating-point representation. (In the
        future this might be changed to allow the case where the division
        is actually exact.)

            >>> fdiv(2, 3, exact=True)
            Traceback (most recent call last):
              ...
            ValueError: division is not an exact operation

        z"division is not an exact operationr   r   rK  N)r   r*  r   r   r   r)   r   r   rG   r   r   rH   rO  r|   r|   r}   fdiv  s     1







zMPContext.fdivc                 C   s  t |}|tkrt|| jfS |tjkr|j\}}t||\}}d| |krV|d7 }n|sd|| jfS tt	|||  t| }||fS t
|dr|j}| j}	n|t
|dr|j\}}
|
\}}}}|r|| }	n|
tkr| j}	ntdn4| |}t
|ds
t
|dr| |S td|\}}}}|| }|dk rDd}|}n|r|dkrd||> }| j}nn|dkr|d? d }d}nR| d }||? }|d@ r|d7 }||> | }n|||> 8 }|d? }|t| }|r| }n|tkr| j}d}ntd|t||	fS )	a  
        Return `(n,d)` where `n` is the nearest integer to `x` and `d` is
        an estimate of `\log_2(|x-n|)`. If `d < 0`, `-d` gives the precision
        (measured in bits) lost to cancellation when computing `x-n`.

            >>> from mpmath import *
            >>> n, d = nint_distance(5)
            >>> print(n); print(d)
            5
            -inf
            >>> n, d = nint_distance(mpf(5))
            >>> print(n); print(d)
            5
            -inf
            >>> n, d = nint_distance(mpf(5.00000001))
            >>> print(n); print(d)
            5
            -26
            >>> n, d = nint_distance(mpf(4.99999999))
            >>> print(n); print(d)
            5
            -26
            >>> n, d = nint_distance(mpc(5,10))
            >>> print(n); print(d)
            5
            4
            >>> n, d = nint_distance(mpc(5,0.000001))
            >>> print(n); print(d)
            5
            -19

        r  r   r   r   zrequires a finite numberzrequires an mpf/mpcr   )r   r
   r   r   r\   rn   r   divmodr6   r=  r   r   r   r   r*  r   r;  r   r<  )r{   r   Ztypxr   r   r   rr   r!  Zim_distr"  ZisignZimanZiexpZibcr   r   r   r   r  Zre_disttr|   r|   r}   r;  Y  sl    !
















zMPContext.nint_distancec                 C   s2   | j }z| j}|D ]}||9 }qW 5 || _ X |
 S )aT  
        Calculates a product containing a finite number of factors (for
        infinite products, see :func:`~mpmath.nprod`). The factors will be
        converted to mpmath numbers.

            >>> from mpmath import *
            >>> mp.dps = 15; mp.pretty = False
            >>> fprod([1, 2, 0.5, 7])
            mpf('7.0')

        )r   r   )r{   Zfactorsorigr   r   r|   r|   r}   fprod  s    zMPContext.fprodc                 C   s   |  t| jS )z
        Returns an ``mpf`` with value chosen randomly from `[0, 1)`.
        The number of randomly generated bits in the mantissa is equal
        to the working precision.
        )r   r4   r   rz   r|   r|   r}   rand  s    zMPContext.randc                    s   |   fddd f S )a  
        Given Python integers `(p, q)`, returns a lazy ``mpf`` representing
        the fraction `p/q`. The value is updated with the precision.

            >>> from mpmath import *
            >>> mp.dps = 15
            >>> a = fraction(1,100)
            >>> b = mpf(1)/100
            >>> print(a); print(b)
            0.01
            0.01
            >>> mp.dps = 30
            >>> print(a); print(b)      # a will be accurate
            0.01
            0.0100000000000000002081668171172
            >>> mp.dps = 15
        c                    s   t  | |S r   )r   r~   r   r   r|   r}   r     r   z$MPContext.fraction.<locals>.<lambda>z%s/%s)rl   )r{   r   r   r|   r[  r}   fraction  s    
zMPContext.fractionc                 C   s   t | |S r   r=  r   r   r|   r|   r}   absmin  s    zMPContext.absminc                 C   s   t | |S r   r]  r   r|   r|   r}   absmax  s    zMPContext.absmaxc                 C   s,   t |dr(|j\}}| || |gS |S )Nr#  )r   r#  r   )r{   r   r   r   r|   r|   r}   
_as_points  s    

zMPContext._as_pointsr   c           	         sl     |rt|dstt|} j}t|j|||||\}} fdd|D } fdd|D }||fS )Nr   c                    s   g | ]}  |qS r|   r   )r  r   rz   r|   r}   
<listcomp>  s     z+MPContext._zetasum_fast.<locals>.<listcomp>c                    s   g | ]}  |qS r|   ra  )r  r   rz   r|   r}   rb    s     )Zisintr   r   r   r   r   Zmpc_zetasumr   )	r{   r   r   r   ZderivativesZreflectr   ZxsZysr|   rz   r}   _zetasum_fast  s    zMPContext._zetasum_fast)r   )F)F)F)F)Nr|   F)r  )T)8__name__
__module____qualname____doc__rg   rp   r7   r   r   r   r   r   r   rr   r   rt   rs   r   r   r   r   r   r   r   r   r   propertyr   r   r   r   r   r   r  r  r,  r-  r   rN  r>  rH  rI  rJ  rL  rP  rQ  rR  rS  r;  rY  rZ  r\  r^  r_  r`  rc  r|   r|   r|   r}   rd   :   sl   !V







k
6
U6JBEBbrd   c                   @   s.   e Zd ZdddZdd Zdd Zdd	 Zd
S )r   Fc                 C   s   || _ || _|| _|| _d S r   )r{   precfundpsfunr   )selfr{   ri  rj  r   r|   r|   r}   rg     s    zPrecisionManager.__init__c                    s   t   fdd}|S )Nc                     s   j j}zzjr$j jj _nj jj _jrr | |}t|tkrhtdd |D W S |
 W S  | |W S W 5 |j _X d S )Nc                 S   s   g | ]
}|
 qS r|   r|   )r  r   r|   r|   r}   rb  '  s     z8PrecisionManager.__call__.<locals>.g.<locals>.<listcomp>)r{   r   ri  rj  r   r   r   r  )r  r   rX  r   r  rk  r|   r}   g  s    

z$PrecisionManager.__call__.<locals>.g)	functoolswraps)rk  r  rm  r|   rl  r}   __call__  s    zPrecisionManager.__call__c                 C   s:   | j j| _| jr$| | j j| j _n| | j j| j _d S r   )r{   r   origpri  rj  r   )rk  r|   r|   r}   	__enter__.  s    
zPrecisionManager.__enter__c                 C   s   | j | j_dS re   )rq  r{   r   )rk  exc_typeexc_valexc_tbr|   r|   r}   __exit__4  s    
zPrecisionManager.__exit__N)F)rd  re  rf  rg   rp  rr  rv  r|   r|   r|   r}   r     s   
r   __main__)wrg  __docformat__rn  r!  Zctx_baser   Zlibmp.backendr   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/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   r:   r;   r<   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   rG   rH   rI   rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r[   r\   object__new__newcompiler&  Zsage.libs.mpmath.ext_mainr^   rf   ZlibsZmpmathZext_mainZ_mpf_moduler`   r_   ra   rb   rc   rd   r   rd  doctesttestmodr|   r|   r|   r}   <module>   s@    ]

         d$
