a
    <bU                  	   @   s  d Z ddlZddlmZ ddlmZ ddlmZmZmZmZm	Z	m
Z
 ddlmZ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/m0Z0m1Z1m2Z2m3Z3m4Z4m5Z5m6Z6m7Z7m8Z8 ddl9m:Z: e
d	krd
Z;ndZ;dZ<e
d	kr4dZ=ndZ=dZ>i Z?dZ@i ZAdZBdZCi ZDdZEdZFdZGi ZHddgZIedeeBd D ]*ZJeIeKdeJ eBd gdeJd   7 ZIq~dd ZLdd ZMdd ZNdd ZOdd d!ZPeLd"d# ZQeLd$d% ZRed&ZSed'ZTed(ZUed)ZVd*d+ ZWeLdd,d-ZXd.d/ ZYd0d1 ZZeLd2d3 Z[eLd4d5 Z\eMe\Z]eMeXZ^eMe[Z_eMeYZ`eMeQZaeMeRZbeLd6d7 ZceLd8d9 ZdeMedZeeMecZfefd:d;Zgd<d= Zhd>d? Ziefd@dAZjefdBdCZkddDdEZldFdG ZmdHdI ZnddJdKZodLdM ZpefdNdOZqdPdQ ZrdRdS ZsdTdU ZtdVdW ZudXdY ZvefdZd[Zwefd\d]Zxefd^d_Zyefd`daZzefdbdcZ{efdddeZ|efdfdgZ}efdhdiZ~ddjdkZdldm Zdndo Zdpdq ZefdrdsZedfdtduZdvdw ZeddfdxdyZefdzd{Zefd|d}Zefd~dZefddZefddZefddZefddZefddZefddZdddZdddZe
dkrzRddlm  m  mZ ej4Z4ejZejqZqejZejZejgZgejZejZejlZlW n  eefy   ed Y n0 dS )a(  
This module implements computation of elementary transcendental
functions (powers, logarithms, trigonometric and hyperbolic
functions, inverse trigonometric and hyperbolic) for real
floating-point numbers.

For complex and interval implementations of the same functions,
see libmpc and libmpi.

    N)bisect   )xrange)MPZMPZ_ZEROMPZ_ONEMPZ_TWOMPZ_FIVEBACKEND)-round_floorround_ceiling
round_downround_upround_nearest
round_fastComplexResultbitcountbctablelshiftrshiftgiant_steps
sqrt_fixedfrom_intto_intfrom_man_expto_fixedto_float
from_floatfrom_rational	normalizefzerofonefnonefhalffinffninffnanmpf_cmpmpf_signmpf_absmpf_posmpf_negmpf_addmpf_submpf_mulmpf_div	mpf_shiftmpf_rdiv_intmpf_pow_intmpf_sqrtreciprocal_rndnegative_rndmpf_perturb
isqrt_fast)ifibpythonX  i  i        i  i	  	      i           c                    s,   d _ d _ fdd} j|_ j|_|S )z
    Decorator for caching computed values of mathematical
    constants. This decorator should be applied to a
    function taking a single argument prec as input and
    returning a fixed-point value with the given precision.
    Nc                    sR    j }| |kr j||  ? S t| d d } |fi | _| _  j||  ? S )Ng?
   )	memo_precmemo_valint)preckwargsrD   Znewprecf f/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/mpmath/libmp/libelefun.pyg^   s    zconstant_memo.<locals>.g)rD   rE   __name____doc__)rJ   rM   rK   rI   rL   constant_memoU   s    rP   c                    s   t f fdd	} j|_|S )z
    Create a function that computes the mpf value for a mathematical
    constant, given a function that computes the fixed-point value.

    Assumptions: the constant is positive and has magnitude ~= 1;
    the fixed-point function rounds to floor.
    c                    s<   | d } |}|t tfv r$|d7 }td|| t|| |S )Nr>   r   r   )r   r   r   r   )rG   rndwpvfixedrK   rL   rJ   r   s
    zdef_mpf_constant.<locals>.f)r   rO   )rU   rJ   rK   rT   rL   def_mpf_constantj   s    rV   c                 C   s   || dkrNt d| d }|s(|d@ r:t|| d  |fS t || d  |fS || d }t| |||\}}}t| |||\}	}
}|
| ||	  ||
 || fS )Nr   rA      )r   r   bsp_acot)qab
hyperbolicZa1mp1q1Zr1p2q2r2rK   rK   rL   rX   {   s    rX   c                 C   sB   t d| t|  d }t| d||\}}}|| |> ||   S )z
    Compute acot(a) or acoth(a) for an integer a with binary splitting; see
    http://numbers.computation.free.fr/Constants/Algorithms/splitting.html
    ffffff?r>   r   )rF   mathlogrX   )rZ   rG   r\   NprY   rrK   rK   rL   
acot_fixed   s    ri   Fc                 C   s>   d}t }| D ](\}}|t|tt||| | 7 }q||? S )z
    Evaluate a Machin-like formula, i.e., a linear combination of
    acot(n) or acoth(n) for specific integer values of n, using fixed-
    point arithmetic. The input should be a list [(c, n), ...], giving
    c*acot[h](n) + ...
    rC   )r   r   ri   )ZcoefsrG   r\   Z	extraprecsrZ   r[   rK   rK   rL   machin   s
    "rk   c                 C   s   t g d| dS )zz
    Computes ln(2). This is done with a hyperbolic Machin-type formula,
    with binary splitting at high precision.
    ))      )i  )r<   i-"  Trk   rG   rK   rK   rL   	ln2_fixed   s    rq   c                 C   s   t g d| dS )zN
    Computes ln(10). This is done with a hyperbolic Machin-type formula.
    )).      )"   1   )r>      Tro   rp   rK   rK   rL   
ln10_fixed   s    rw   iqc i-~ i@	    c                 C   s   ||  dkrbt d| d d| d  d| d  }|d td  d }d| | tt|   }nt|rz|dk rztd	| | | | d }t| ||d |\}}	}
t|||d |\}}}|	| }|| }|
| ||  }|||fS )
z
    Computes the sum from a to b of the series in the Chudnovsky
    formula. Returns g, p, q where p/q is the sum as an exact
    fraction and g is a temporary value used to save work
    for recursive calls.
    r         rA   rW      rB      z  binary splitting)r   CHUD_CCHUD_ACHUD_Bprintbs_chudnovsky)rZ   r[   levelverboserM   rg   rY   ZmidZg1r^   r_   Zg2r`   ra   rK   rK   rL   r      s    (r   c           	      C   sf   t | d d d }|r"td| td|d|\}}}ttd|  > }|t | |t|  t  }|S )z
    Compute floor(pi * 2**prec) as a big integer.

    This is done using Chudnovsky's series (see comments in
    libelefun.py for details).
    gv	O
@g bi ],@rA   zbinary splitting with N =r   )rF   r   r   r7   r}   r~   CHUD_D)	rG   r   Zverbose_baserf   rM   rg   rY   ZsqrtCrS   rK   rK   rL   pi_fixed   s    	
r   c                 C   s   t | d S )N   )r   rp   rK   rK   rL   degree_fixed   s    r   c                 C   sT   ||  dkrt t|fS | | d }t| |\}}t||\}}|| | || fS )ze
    Sum series for exp(1)-1 between a, b, returning the result
    as an exact fraction (p, q).
    r   rA   )r   r   bspe)rZ   r[   r]   r^   r_   r`   ra   rK   rK   rL   r      s    r   c                 C   s8   t d|  t|  d }td|\}}|| | > | S )z
    Computes exp(1). This is done using the ordinary Taylor series for
    exp, with binary splitting. For a description of the algorithm,
    see:

        http://numbers.computation.free.fr/Constants/
            Algorithms/splitting.html
    g?r>   r   )rF   rd   re   r   )rG   rf   rg   rY   rK   rK   rL   e_fixed	  s    r   c                 C   s(   | d7 } t td|  > t| >  }|d? S )z2
    Computes the golden ratio, (1+sqrt(5))/2
    rC   rA      )r7   r	   r   )rG   rZ   rK   rK   rL   	phi_fixed  s    r   c                 C   s&   | d }t ttt|d|| d S )NrC   r   )r   mpf_logr0   mpf_pi)rG   rR   rK   rK   rL   ln_sqrt2pi_fixed*  s    r   c                 C   s   t t| | S )N)r   r   rp   rK   rK   rL   sqrtpi_fixed0  s    r   c                 C   s   | \}}}}|\}}	}
}|r,|
dk r,t d|
dkrNt| d| |	|
>  ||S |
dkr|	dkr|rttt| |d t| ||S t| ||S |rtt| |d t| |	 ||S tt| |d ||	||S t| |d |}tt||||S )zV
    Compute s**t. Raises ComplexResult if s is negative and t is
    fractional.
    r   z,negative number raised to a fractional powerrB   r   rC   )	r   r2   r/   r!   r3   r4   r   mpf_expr.   )rj   trG   rQ   ZssignZsmanZsexpZsbctsigntmanZtexptbccrK   rK   rL   mpf_pow>  s0    r   c           
      C   s  |dkr| |  dfS t | }d}d|dt |  d  }t\}}}}	|d@ r||  }|| }|	|d 7 }	|	tt||	?   }	|	|kr||	| ? }||	| 7 }|}	|d8 }|sq| |  } || }|| d }|tt| |?   }||kr| || ? } ||| 7 }|}|d }qD||fS )zn-th power of a fixed point number with precision prec

       Returns the power in the form man, exp,
       man * 2**exp ~= y**n
    rA   r   r|   r   )r   r!   r   rF   )
ynrG   bcexpZworkprec_pmpeZpbcrK   rK   rL   int_pow_fixedZ  s8    

r   c                 C   s  d}z*t | |||  }tt|d|  }W nD tyr   t||}t|}td||}t|||}t|}Y n0 d}|}	|}
t||| D ]r}t	||d |
\}}t ||d |
 | | |	 }t
| d| | |	 | }||d t
|||
   | }|}
q|S )N2   g      ?r   rC   rA   )r   r   rF   OverflowErrorr   r1   r   r   r   r   r   )r   r   rG   exp1starty1rh   fnextraZextra1prevprg   r   r   rb   BrK   rK   rL   nthroot_fixed  s(    
r   c                 C   s|  | \}}}}|rt d|sd| tkr(tS | tkrL|dkr<tS |dkrHtS tS |sTtS |dk r`tS tS d}|dk r|dkr|tS |dkrt| ||S |dkrtt| ||S t| }d}d}	||	7 }| }|d	krX|d
ks|tdd|d   k rX|d }
t	|}t
d||
}t| ||
|}t|d |d |d |d ||} |rTtt| ||	 |S | S |d|  ||  }
|dkr|
|
d 7 }
|
|
|  }
||
 }d}|| }|dk rd}| }|r||| 7 }n||| 8 }t||}d}|| |d |
  | | }d}|r$|dks|dkr<d}n|dks8|dkr<d}t|| ||
|}t||||} |rttt| ||	 |S | S dS )zanth-root of a positive number

    Use the Newton method when faster, otherwise use x**(1/n)
    znth root of a negative numberr   FrA   r   rB   Trz   r>   i N     gL<@gףp=
?rC   rW   ur   drJ   N)r   r&   r    r!   r$   r*   r/   r4   rF   r   r1   r   r   r   r   r   )rj   r   rG   rQ   signmanr   r   Zflag_inverseZextra_inverseprec2r   Znthrh   shiftZsign1esr   r   Z	rnd_shiftrK   rK   rL   mpf_nthroot  s    ,"


r   c                 C   s   t | d||S )zcubic root of a positive numberrW   )r   )rj   rG   rQ   rK   rK   rL   mpf_cbrt  s    r   c           	      C   s   | t v r(t |  \}}||kr(||| ? S |d }|tkrp|du rHt|}t| }| || > }t||||  }nttt| |d |}| tk r||ft | < ||| ? S )z`
    Fast computation of log(n), caching the value for small n,
    intended for zeta sums.
    rC   Nrz   )	log_int_cacheLOG_TAYLOR_SHIFTrq   r   log_taylor_cachedr   r   r   MAX_LOG_INT_CACHE)	r   rG   ln2valueZvprecrR   rh   xrS   rK   rK   rL   log_int_fixed  s    r   c                 C   sJ   d}| | d? }|dkr,t | | dk r,| S t| | }|} |d7 }q| S )z^
    Fixed-point computation of agm(a,b), assuming
    a, b both close to unit magnitude.
    r   r   r|   r<   )absr7   )rZ   r[   rG   iZanewrK   rK   rL   	agm_fixed  s    
r   c                 C   s   | |  |? }| } }}|r>|| |? }|| |? }||7 }q|t |> 7 }|| |d ? }|t| |>  |? }|  } }}|r|| |? }|| |? }||7 }qzt |> |d>  }|| |? }t|||}t||> | S )a*  
    Fixed-point computation of -log(x) = log(1/x), suitable
    for large precision. It is required that 0 < x < 1. The
    algorithm used is the Sasaki-Kanada formula

        -log(x) = pi/agm(theta2(x)^2,theta3(x)^2). [1]

    For faster convergence in the theta functions, x should
    be chosen closer to 0.

    Guard bits must be added by the caller.

    HYPOTHESIS: if x = 2^(-n), n bits need to be added to
    account for the truncation to a fixed-point number,
    and this is the only significant cancellation error.

    The number of bits lost to roundoff is small and can be
    considered constant.

    [1] Richard P. Brent, "Fast Algorithms for High-Precision
        Computation of Elementary Functions (extended abstract)",
        http://wwwmaths.anu.edu.au/~brent/pd/RNC7-Brent.pdf

    rA   r   )r   r7   r   r   )r   rG   x2rj   rZ   r[   r   rg   rK   rK   rL   log_agm)  s$    

r   c                 C   s   t |D ]}t| |> } qt|> }| | |> | |  }|dk }|rH| }|| |? }|| |? }|}	|d }
|| |? }d}|r|	|| 7 }	|d7 }|
|| 7 }
|| |? }|d7 }q||
| |? }
|	|
 d| > }|r| S |S )a:  
    Fixed-point calculation of log(x). It is assumed that x is close
    enough to 1 for the Taylor series to converge quickly. Convergence
    can be improved by specifying r > 0 to compute
    log(x^(1/2^r))*2^r, at the cost of performing r square roots.

    The caller must provide sufficient guard bits.
    r   rW   rz   rA   r   )r   r7   r   )r   rG   rh   r   onerS   r   v2v4s0s1krj   rK   rK   rL   
log_taylorX  s0    	
r   c                 C   s&  | |t  ? }t| }|| }||ftv r:t||f \}}n(||t  > }t||d}||ft||f< ||L }||L }| | |> | }||> t|> |  }|| |? }	|	|	 |? }
|}|d }||
 |? }d}|r||| 7 }|d7 }||| 7 }||
 |? }|d7 }q||	 |? }|| d> }|| S )zd
    Fixed-point computation of log(x), assuming x in (0.5, 2)
    and prec <= LOG_TAYLOR_PREC.
    r<   rW   rz   rA   r   )r   cache_prec_stepslog_taylor_cacher   r   )r   rG   r   Zcached_precdprecrZ   Zlog_ar   rS   r   r   r   r   r   rj   rK   rK   rL   r   z  s6    
r   c                 C   s  | \}}}}|s4| t krtS | tkr(tS | tkr4tS |r@td|d }|dkrp|sXt S t|t| | ||S || }t|}	|	dkrd|	 }
|
rt|> | }n|t|d >  }t	|}|| }||krt
|
||	| ||d}t||
||S ||7 }|	dkr&t	|	|kr&t|t| | ||S |tkr\tt||| |}|r||t| 7 }nH| t }|| }t| |} || 7 }tt| || }||t| 8 }t|| ||S )zj
    Compute the natural logarithm of the mpf value x. If x is negative,
    ComplexResult is raised.
    zlogarithm of a negative numberr>   r   r   i'  )r    r%   r$   r&   r   r   rq   r   r   r   r   r6   LOG_TAYLOR_PRECr   r   LOG_AGM_MAG_PREC_RATIOr0   r   r   )r   rG   rQ   r   r   r   r   rR   magZabs_magr   r   r   Zcancellationr   r]   Zoptimal_magr   rK   rK   rL   r     sN    




r   c           
      C   s  |d s||  } }| d sz|d sR| |  kr6t kr>n ntS t| |fv rNtS tS | t krjtt|||S | tkrvtS tS t| | }t||}d}t|||| }t|td}|d |d  }	|t ks|	| d k rt|||| t	|d |d  }t
t|||dS )z1
    Computes log(sqrt(a^2+b^2)) accurately.
    r   r>   rC   rA   rW   rB   )r    r%   r&   r$   r   r)   r.   r,   r"   minr0   )
rZ   r[   rG   rQ   Za2b2r   h2	cancelledZmag_cancelledrK   rK   rL   mpf_log_hypot  s.    


"r   c           
      C   s   |dkr$t t| |d ? d }nt t| d|  }d}tt|d d| ? }d}t||D ]h}||7 }||| > }t||\}}||> | }|t| ||  |> t|> |d |?   }	||	 }|}qdt||| S )Nd   5   g      @Cg       @r   rA   )rd   atanrF   r   r   cos_sin_fixedr   r   )
r   rG   rh   r   Zextra_prR   cossintanrZ   rK   rK   rL   atan_newton  s    *r   c                 C   sp   dt |d > d }|| }| |ftv r:t| |f \}}n&| |t > }t||}||ft| |f< ||? ||? fS )Nr   r>   )r   atan_taylor_cacheATAN_TAYLOR_SHIFTr   )r   rG   r   r   rZ   atan_arK   rK   rL   atan_taylor_get_cached"  s    
r   c                 C   s   | |t  ? }t||\}}| | }||> |d |? || |?  t|>    }}|d |? }|| |? }	|d }
||	 |? }d}|r||| 7 }|d7 }|
|| 7 }
||	 |? }|d7 }q~|
| |? }
||
 }|| S )NrA   rW   rz   )r   r   r   )r   rG   r   rZ   r   r   r   rS   r   r   r   r   rj   rK   rK   rL   atan_taylor1  s$    ,
r   c                 C   s,   | st t||dS tt t|t| dS )NrB   )r0   r   r+   r5   )r   rG   rQ   rK   rK   rL   atan_infE  s    r   c                 C   s  | \}}}}|sH| t krt S | tkr0td||S | tkrDtd||S tS || }||d krht|||S | |d krt| d| ||S |d t| }|dkrtd| |} d}	nd}	t| |}
|r|
 }
|t	k rt
|
|}n
t|
|}|	rt|d? d | }|r| }t|| ||S )Nr   r   r>      rA   TF)r    r$   r   r%   r&   r6   r   r1   r   ATAN_TAYLOR_PRECr   r   r   r   )r   rG   rQ   r   r   r   r   r   rR   Z
reciprocalr   rZ   rK   rK   rL   mpf_atanJ  s6    

r   c                 C   sD  |\}}}}| \}}	}
}|	s| t krF|tkrFt|dkr<t S t||S | ttfv r|ttfv rbtS | tkrztt||dS ttt|t| dS tS |rtt	t| ||t| S |s|tkrtS |tkrt S |tkrt||S | t krt S tt||dS t
t| ||d |d }|r4tt|d |||S t|||S d S )Nr   rB   r|   )r    r&   r(   r   r$   r%   r0   r+   r5   	mpf_atan2r   r/   r,   r*   )r   r   rG   rQ   ZxsignZxmanZxexpZxbcZysignZymanZyexpZybcZtquorK   rK   rL   r   m  s<    

r   c                 C   sv   | \}}}}|| dkr,| t tfvr,td|d }t| | }tt ttt ||||}	t| |	|}
tt	|
||dS )Nr   z%asin(x) is real only for -1 <= x <= 1   r   )
r!   r"   r   r.   r,   r3   r-   r/   r0   r   r   rG   rQ   r   r   r   r   rR   rZ   r[   r   rK   rK   rL   mpf_asin  s    
r   c                 C   s   | \}}}}|| dkr>| t tfvr,td| tkr>t||S |d }t| | }ttt |||}	t|	tt | ||}
t	t
|
||dS )Nr   z%acos(x) is real only for -1 <= x <= 1r   r   )r!   r"   r   r   r.   r3   r-   r/   r,   r0   r   r   rK   rK   rL   mpf_acos  s    

r   c           
      C   s   |d }| \}}}}|| }|dk rJ|| k r@t | d| ||S || 7 }ttt| | t||}	tt| |	|}	|rtt|	|t| S t|	||S d S )Nr>   r   )	r6   r3   r,   r.   r!   r)   r+   r   r5   )
r   rG   rQ   rR   r   r   r   r   r   rY   rK   rK   rL   	mpf_asinh  s    

r   c                 C   sJ   |d }t | tdkrtdttt| | t||}tt| ||||S )Nr   rB   z acosh(x) is real only for x >= 1)r'   r!   r   r3   r,   r.   r"   r   )r   rG   rQ   rR   rY   rK   rK   rL   	mpf_acosh  s
    r   c                 C   s   | \}}}}|s,|r,| t tfv r$| S td|| }|dkr`|dkrX|dkrXttg| S td|d }|dk r|| k rt| |||S || 7 }t| t|}	tt| |}
t	t
t|	|
|||dS )Nz&atanh(x) is real only for -1 <= x <= 1r   r   r   r   rB   )r    r&   r   r$   r%   r6   r,   r!   r-   r0   r   r/   )r   rG   rQ   r   r   r   r   r   rR   rZ   r[   rK   rK   rL   	mpf_atanh  s$    

r   c                 C   s   | \}}}}|s | t krtS | S t|| }|dkr\|dk sH|t|kr\ttt| ||S || d }t|}	tt	|	dt
|}
t|	| |}t| |}t|||}t|||}t||
||}|S )Nr   rC   r>   r   )r%   r&   r   r   r   r8   r   mpf_phir,   r0   r"   r   
mpf_cos_pir/   r-   )r   rG   rQ   r   r   r   r   sizerR   rZ   r[   r   rS   rK   rK   rL   mpf_fibonacci  s$    
r   c                 C   s  | dk r|  } d}nd}t d|d  }t| | }td|| }ddt||   }|| }| || K } t|> }|dk}	|tk r.| |  |?  }
}|
|
 |? }t }}d}|r||d |  }||7 }|d7 }||d |  }||7 }|d7 }|| |? }q|
| |? }|	r|| | }n|| | }nt d|d  }| |  |?  }
}||
g}td|D ]}||d |
 |?  q`tg| }d}|r t|D ]P}||d |  }|	r|d@ r||  |8  < n||  |7  < |d7 }q||d  |? }qtd|D ]}|| ||  |? ||< q
t|| }|dkrt	|| ||>  }|rd|| }n|| }t|D ]}|| |? }qt||? S |d }t|D ]}|| |? | }qt	t
||> ||  }|r| }||? ||? fS d	S )
z
    Taylor series for cosh/sinh or cos/sin.

    type = 0 -- returns exp(x)  (slightly faster than cosh+sinh)
    type = 1 -- returns (cosh(x), sinh(x))
    type = 2 -- returns (cos(x), sin(x))
    r   r         ?rC   rA   g333333?rc   rB   N)rF   r   maxr   EXP_SERIES_U_CUTOFFr   r   appendsumr7   r   )r   rG   typer   rh   Zxmagr   rR   r   Zaltr   rZ   Zx4r   r   r   r   r   Zxpowersr   Zsumsrj   rS   ZpshiftrK   rK   rL   exponential_series  sr    
  
"

r   c           
      C   s   |t krt| |dS t|d }||7 }t|>  }}d}| |  |?  }}|r|| }||7 }|d7 }|| }||7 }|d7 }|| |? }qH||  |? }|| }|}	|r|| |? }|d8 }q||	? S )z
    Compute exp(x) as a fixed-point number. Works for any x,
    but for speed should have |x| < 1. For an arbitrary number,
    use exp(x) = exp(x-m*log(2)) * 2^m where m = floor(x/log(2)).
    r   r   rA   r   )EXP_COSH_CUTOFFr   rF   r   )
r   rG   rh   r   r   r   rZ   r   rj   r   rK   rK   rL   exp_basecase>  s$    
r   c                 C   sJ   |t kr(t| |d\}}|| || fS t| |}t|| > | }||fS )z(
    Computation of exp(x), exp(-x)
    r   )r   r   r   r   )r   rG   coshsinhrZ   r[   rK   rK   rL   exp_expneg_basecaseW  s    
r   c                 C   s4  |t krt| |dS |t }| |? }t|}|tvrl|dt  t > }t|dt  d\}}|d? |d? ft|< t| \}}t | }||L }||L }| ||> 8 } t|> }	| }
d}| |  |?  }|r|| }|	|7 }	|d7 }||  |? }|| }|
|7 }
|d7 }||  |?  }q|	| |
|  |? |
| |	|  |? fS )z
    Compute cos(x), sin(x) as fixed-point numbers, assuming x
    in [0, pi/2). For an arbitrary number, use x' = x - m*(pi/2)
    where m = floor(x/(pi/2)) along with quarter-period symmetries.
    rA   rC   r   )COS_SIN_CACHE_PRECr   COS_SIN_CACHE_STEPrF   cos_sin_cacher   )r   rG   Zprecsr   r   wZcos_tZsin_toffsetr   r   r   rZ   rK   rK   rL   cos_sin_basecaseb  s,    $(r  c                 C   s6  | \}}}}|r|| }|d }|r,| }|dkrb|dkrbt |td|  }	t|	||> ||S || k rztt|||S |dkr|| }
||
 }|dkr||> }n
|| ? }t|
}t||\}}t|}||L }n(|| }|dkr||> }n
|| ? }d}t||}t||| ||S |s$tS | t	kr2t
S | S )N   r:   r   g333333?r   )mpf_erF   r2   r6   r!   rq   divmodr   r   r%   r    )r   rG   rQ   r   r   r   r   r   rR   ewpmodr   r   lg2r   rK   rK   rL   r     sB    







r   c                 C   sP  | \}}}}|s\|r\|r4| t kr$tS | tkr0tS tS | t krDt t fS | tkrTt tfS ttfS || }|d }	|dk r||	 k r|rt| d| ||S ttd||}
t| |||}|
|fS |	| 7 }	|dkr2dd|d >  |	kr2|rtttg| d| ||S ttt| ||d }}|r*t	|}||fS |dkr|	| }|| }|dkr`||> }n
|| ? }t
|}t||\}}t|}||L }n*||	 }|dkr||> }n
|| ? }d}t||	\}}||d| ?  }
||d| ?  }|r| }|r||	> |
 }t||	 ||S t|
||	 d ||}
t|||	 d ||}|
|fS d	S )
z4Simultaneously compute (cosh(x), sinh(x)) for real xr  r   r   rC   rW   rB   rA   N)r$   r!   r%   r"   r&   r6   r0   r   r)   r+   rq   r  rF   r   r   )r   rG   rQ   tanhr   r   r   r   r   rR   r   r   r   rj   r  r   r   r  r   rZ   r[   rK   rK   rL   mpf_cosh_sinh  sj    










r
  c                 C   s   |dkrd}d|> }|| | }t |d }|d? }|| }	|	dkrN| |	> }
n
| |	 ? }
t|
|\}}||krx|| }n|}||| d ? rt|}||? }
|| }q|d7 }qn2|| 7 }|| }	|	dkr| |	> }
n
| |	 ? }
d}|
||fS )Nr   r>   r   rC   )r   r  rF   )r   r   r   rR   r   Zcancellation_precr  pi2Zpi4r   r   r   r   smallrK   rK   rL   mod_pi2  s6    





r  c                 C   s  | \}}}}|s^|r t t  }	}
n
tt }	}
|dkr:|	|
fS |dkrF|	S |dkrR|
S |dkr^|
S || }|d }|dk r|| k r|rt| t|} ttd||}	t| d| ||}
|dkr|	|
fS |dkr|	S |dkr|
S |dkrt| |||S |r|dkr|dkr(t}	ttft|d@ |A  }
n |dkr>tt }	}
n
tt }	}
|dkrZ|	|
fS |dkrh|	S |dkrv|
S |dkrt|
|	||S || d ? d d? }||| d >  }t	|| }|d | }|| }|dkr||> }n
|| ? }|t
| |? }nt||||\}}}t||\}	}
|d@ }|dkrH|
 |	 }	}
n0|dkrb|	 |
  }	}
n|dkrx|
|	  }	}
|r|
 }
|dkrt|	| ||}	t|
| ||}
|	|
fS |dkrt|	| ||S |dkrt|
| ||S |dkrt|
|	||S dS )z
    which:
    0 -- return cos(x), sin(x)
    1 -- return cos(x)
    2 -- return sin(x)
    3 -- return tan(x)

    if pi=True, compute for pi*x
    r   r   rA   rW   rC   rB   N)r&   r!   r    r.   r   r6   r"   boolr/   r   r   r  r  r   r   )r   rG   rQ   whichpir   r   r   r   r   rj   r   rR   r   Zmag2r   r   r]   rK   rK   rL   mpf_cos_sin  sx    













r  c                 C   s   t | ||dS Nr   r  r   rG   rQ   rK   rK   rL   mpf_cosb      r  c                 C   s   t | ||dS )NrA   r  r  rK   rK   rL   mpf_sinc  r  r  c                 C   s   t | ||dS )NrW   r  r  rK   rK   rL   mpf_tand  r  r  c                 C   s   t | ||ddS )Nr   r   r  r  rK   rK   rL   mpf_cos_sin_pie  r  r  c                 C   s   t | ||ddS r  r  r  rK   rK   rL   r   f  r  r   c                 C   s   t | ||ddS )NrA   r   r  r  rK   rK   rL   
mpf_sin_pig  r  r  c                 C   s   t | ||d S Nr   r
  r  rK   rK   rL   mpf_coshh  r  r  c                 C   s   t | ||d S r  r  r  rK   rK   rL   mpf_sinhi  r  r  c                 C   s   t | ||ddS )Nr   )r	  r  r  rK   rK   rL   mpf_tanhj  r  r  c                 C   s   |d u rt |d }t| |\}}t|}t||\}}|d@ }|dkrP||fS |dkrb| |fS |dkrv| | fS |dkr|| fS d S )Nr   rW   r   rA   )r   r  rF   r  )r   rG   r  r   r   r   rj   r]   rK   rK   rL   r   o  s    r   c                 C   sN   |d u rt |}t| |\}}t|}t||}|dkr@||> S || ? S d S r  )rq   r  rF   r   )r   rG   r   r   r   rS   rK   rK   rL   	exp_fixed{  s    
r   Zsagez)Warning: Sage imports in libelefun failed)F)FN)N)r   )r   )N)N)rO   rd   r   backendr   r   r   r   r   r	   r
   Zlibmpfr   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   Z
libintmathr8   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rP   rV   rX   ri   rk   rq   rw   r~   r   r}   r   r   r   r   r   r   r   r   r   r  Z
mpf_degreeZmpf_ln2Zmpf_ln10r   r   Z
mpf_sqrtpiZmpf_ln_sqrt2pir   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sage.libs.mpmath.ext_libmpZlibsZmpmathZ	ext_libmpZ_lbmpImportErrorAttributeErrorr   rK   rK   rK   rL   <module>   s    


(		


#



	6S
/
""H,##
K-C$O



