B
    &]\.8                 @   s~  d dl mZmZmZ d dlZd dlZd dlZd dlZd dl	m
Z
 d dlZd dlmZ d dlmZ yd dlZW n ek
r   Y nX G dd deZG dd	 d	eZG d
d deZG dd deZdd ZG dd deZdd Zdd Zdd Zdd Zdd Zy d dlZd dlZde ekZ!W n ek
r<   dZ!Y nX G dd de"Z#d ej$d!fd"d#Z%d$d% Z&d&d' Z'd+d)d*Z(dS ),    )divisionprint_functionabsolute_importN)assert_)reraise)assert_func_equalc               @   s8   e Zd ZdZej ejddfddZdd Zdd Zd	S )
ArgzGenerate a set of numbers on the real axis, concentrating on
    'interesting' regions and covering all orders of magnitude.

    Tc             C   sf   ||krt d|tj kr,dttj }|tjkrFdttj }|| | _| _|| | _| _	d S )Nz#a should be less than or equal to bg      g      ?)

ValueErrornpinfZfinfofloatmaxabinclusive_ainclusive_b)selfr   r   r   r    r   9lib/python3.7/site-packages/scipy/special/_mptestutils.py__init__   s    
zArg.__init__c             C   s  |dk rt d|d dkr*|d }|}n|d }|d }|dkr`tt|t||}nV|dkr|dk rt|||}n4|dkrtj|d|dd}tdt||}t||f}n|dkr"|dkr"td||}|jdkrt|d }	nd}	tjd|	|dd}t||f}n|d dkr>|d }
|
}n|d }
|
d }tjdd|dd}|jdkr|t|d }	nd}	tjd|	|
dd}tdt||}t|||f}t|S )	Nr   za should be positive      
   F)Zendpointi)r	   r
   Zlogspacelog10Zlinspacehstacksizesort)r   r   r   nZnlogptsZnlinptsptsZlinptsZlogptsrightZnlogpts1Znlogpts2Zlogpts1Zlogpts2r   r   r   _positive_values)   sF    
zArg._positive_valuesc       	      C   s  | j | j }}||kr t|S | js.|d7 }| js<|d7 }|d dkrV|d }|}n|d }|d }|dkr| |||}g }nR|dkrg }| | | | }n0| d||}| d| |d  }|dd }t|ddd |f}| js |dd }| js|dd }|S )z%Return an array containing n numbers.r   r   r   N)r   r   r
   Zzerosr   r   r    r   )	r   r   r   r   Zn1Zn2ZposptsZnegptsr   r   r   r   valuesa   s6    
z
Arg.valuesN)	__name__
__module____qualname____doc__r
   r   r   r    r"   r   r   r   r   r      s   8r   c               @   s   e Zd Zdd Zdd ZdS )FixedArgc             C   s   t || _d S )N)r
   asarray_values)r   r"   r   r   r   r      s    zFixedArg.__init__c             C   s   | j S )N)r)   )r   r   r   r   r   r"      s    zFixedArg.valuesN)r#   r$   r%   r   r"   r   r   r   r   r'      s   r'   c               @   s:   e Zd Zeej ej eejejfddZdd ZdS )
ComplexArgc             C   s$   t |j|j| _t |j|j| _d S )N)r   realimag)r   r   r   r   r   r   r      s    zComplexArg.__init__c             C   sX   t tt|}| j|}| j|d }|d d d f d|d d d f    S )Nr   y              ?)intr
   ZfloorZsqrtr+   r"   r,   Zravel)r   r   mxyr   r   r   r"      s    zComplexArg.valuesN)r#   r$   r%   complexr
   r   r   r"   r   r   r   r   r*      s   &r*   c               @   s   e Zd ZdddZdd ZdS )	IntArg  c             C   s   || _ || _d S )N)r   r   )r   r   r   r   r   r   r      s    zIntArg.__init__c             C   sh   t | j| jtd|d  |d t}tdd}t	tj
||f }||| jk|| jk @  }|S )Nr   r      )r   r   r   r"   r   astyper-   r
   ZarangeuniqueZr_)r   r   Zv1Zv2vr   r   r   r"      s
    ,zIntArg.valuesN)r3   r4   )r#   r$   r%   r   r"   r   r   r   r   r2      s   
r2   c             C   s   t | tjr|  }nt| }tdd | D }||t|  td }g }x&t	| |D ]\}}|
|| q\W ttjtj|  |dj}|S )Nc             S   s   g | ]}t |trd ndqS )g      ?g      ?)
isinstancer*   ).0specr   r   r   
<listcomp>   s    zget_args.<locals>.<listcomp>r   r!   )r:   r
   ndarraycopylenr(   sumr7   r-   zipappendr"   ZarrayZbroadcast_arraysZix_ZreshapeT)Zargspecr   argsnargsZmsr<   r.   r   r   r   get_args   s    
 rG   c            
   @   s&   e Zd ZdddZdd	 Zd
d ZdS )
MpmathDataNHz>YnFTc             C   s  |d krDyt tjdd}W n tk
r6   d}Y nX |r@dnd}|| _|| _|| _|| _|| _	|| _
|| _|	| _|
| _|| _t| jtjrt| jjtj| _ntdd | jD | _|
| _|| _|r|dkrt|d	d }|r|dkrt|d	d }|| _|| _d S )
NZSCIPY_XSLOW0Fi  i  c             S   s   g | ]}t |tqS r   )r:   r*   )r;   argr   r   r   r=      s    z'MpmathData.__init__.<locals>.<listcomp>z<lambda>r#   )r-   osenvirongetr	   
scipy_funcmpmath_funcarg_specdpsprecr   rtolatolignore_inf_signnan_okr:   r
   r>   
issubdtypedtypecomplexfloating
is_complexanydistinguish_nan_and_infgetattrnameparam_filter)r   rP   rQ   rR   r`   rS   rT   r   rU   rV   rW   r^   rX   ra   Zis_xslowr   r   r   r      s6    
zMpmathData.__init__c                s6  t jd tjj}tjjtjj	 }}zjd k	rBjg}ndg}j	d k	r\j	tj_	t 
|jt jrztdd  ndd  dd xt|D ]\}}|tj_y<tj fdd	|d
jjjjjjd
 P W q tk
r   |t|d krtt   Y qX qW W d || tj_tj_	X d S )Ni     c             S   s   t t| S )N)mpmathmpcr1   )r/   r   r   r   mptype   s    z MpmathData.check.<locals>.mptypec             S   s   t t| S )N)rc   Zmpfr   )r/   r   r   r   re      s    c             S   s0   t | jddt | j  kr"tjS t| jS d S )NgؗҜ<r   )absr,   r+   r
   nan	mpf2float)r/   r   r   r   pytype   s    z MpmathData.check.<locals>.pytypec                 s   j t |  S )N)rQ   map)r   )re   ri   r   r   r   <lambda>  s    z"MpmathData.check.<locals>.<lambda>F)Z
vectorizedrU   rV   rW   r^   rX   ra   r   )r
   ZrandomZseedrG   rR   r   rc   ZmprS   rT   rY   rZ   r[   mpc2complex	enumerater   rP   rU   rV   rW   r^   rX   ra   AssertionErrorr@   r   sysexc_info)r   ZargarrZold_dpsZold_precZdps_listjrS   r   )re   ri   r   r   check   s>    





zMpmathData.checkc             C   s"   | j rd| jf S d| jf S d S )Nz<MpmathData: %s (complex)>z<MpmathData: %s>)r\   r`   )r   r   r   r   __repr__  s    zMpmathData.__repr__)
NNNNrI   rJ   FTTN)r#   r$   r%   r   rr   rs   r   r   r   r   rH      s      
$7rH   c              O   s   t | |}|  d S )N)rH   rr   )r   kwdr   r   r   assert_mpmath_equal  s    
rv   c             C   s   t jjdd| S )Nz8    Test not yet functional (too slow), needs more work.)reason)pytestZmarkskip)funcr   r   r   nonfunctional_tooslow#  s    r{   c             C   s   t tj| ddddS )z
    Convert an mpf to the nearest floating point number. Just using
    float directly doesn't work because of results like this:

    with mp.workdps(50):
        float(mpf("0.99999999999999999")) = 0.9999999999999999

       r   )	min_fixed	max_fixed)r   rc   nstr)r/   r   r   r   rh   +  s    	rh   c             C   s   t t| jt| jS )N)r1   rh   r+   r,   )r/   r   r   r   rl   7  s    rl   c                s   dd  fdd}|S )Nc             S   s    t | tjrt| S t| S d S )N)r:   rc   rd   r1   r   )r/   r   r   r   tofloat<  s    ztrace_args.<locals>.tofloatc           	      sb   t jdtt| f  t j  z | |}t jd|  W d t jd t j  X |S )Nz%r: z-> %r
)ro   stderrwritetuplerj   flush)r   rt   r)rz   r   r   r   wrapB  s    

ztrace_args.<locals>.wrapr   )rz   r   r   )rz   r   r   
trace_args;  s    
r   	setitimerFc               @   s   e Zd ZdS )TimeoutErrorN)r#   r$   r%   r   r   r   r   r   W  s   r   g      ?Tc                s4   t r"|r"dd  fdd}n fdd}|S )a  
    Decorator for setting a timeout for pure-Python functions.

    If the function does not return within `timeout` seconds, the
    value `return_val` is returned instead.

    On POSIX this uses SIGALRM by default. On non-POSIX, settrace is
    used. Do not use this with threads: the SIGALRM implementation
    does probably not work well. The settrace implementation only
    traces the current thread.

    The settrace implementation slows down execution speed. Slowdown
    by a factor around 10 is probably typical.
    c             S   s
   t  d S )N)r   )Zsignumframer   r   r   sigalrm_handlerk  s    z%time_limited.<locals>.sigalrm_handlerc                s    fdd}|S )Nc           
      sd   t  t j}t t j z$y
 | |S  tk
r<   S X W d t t jd t  t j| X d S )Nr   )signalSIGALRMr   ITIMER_REALr   )r   rt   Zold_handler)rz   
return_valr   timeoutr   r   r   o  s    

z(time_limited.<locals>.deco.<locals>.wrapr   )rz   r   )r   r   r   )rz   r   decon  s    
ztime_limited.<locals>.decoc                s    fdd}|S )Nc           	      sb   t     fddt z.y
| |S  tk
rL   td  S X W d td  X d S )Nc                s   t     krt S )N)timer   )r   ZeventrL   )
start_timer   tracer   r   r     s    z7time_limited.<locals>.deco.<locals>.wrap.<locals>.trace)r   ro   settracer   )r   rt   )rz   r   r   )r   r   r   r   |  s    



z(time_limited.<locals>.deco.<locals>.wrapr   )rz   r   )r   r   )rz   r   r   {  s    )POSIX)r   r   Zuse_sigalrmr   r   )r   r   r   r   time_limited[  s
    r   c                s    fdd}|S )z9Decorate function to return nan if it raises an exceptionc                 s&   y
 | |S  t k
r    tjS X d S )N)	Exceptionr
   rg   )r   rt   )rz   r   r   r     s    
zexception_to_nan.<locals>.wrapr   )rz   r   r   )rz   r   exception_to_nan  s    r   c                s    fdd}|S )z1Decorate function to return nan if it returns infc                 s    | |}t |st jS |S )N)r
   Zisfiniterg   )r   rt   r9   )rz   r   r   r     s    

zinf_to_nan.<locals>.wrapr   )rz   r   r   )rz   r   
inf_to_nan  s    r   FFg<c          	   C   s  yt |  W n tk
r(   t| } Y nX t |}t | |krFtdg }xdt|D ]X}y4tt| | ||  ||t||   k W qT tk
r   || Y qTX qTW t	t
t|}dg}|dt || x|D ]}tj| | |ddd}	tj|| |ddd}
|| dkr(d}n*t| | ||  ||  }t|d}|d||	|
| qW |rtd	d
| dS )z}
    Compare lists of mpmath.mpf's or mpmath.mpc's directly so that it
    can be done to higher precision than double.

    zLengths of inputs not equal. z4Bad results ({} out of {}) for the following points:r   )r}   r~   r      z{}: {} != {} (rdiff {})Fr   N)r@   	TypeErrorlistrn   ranger   rc   ZfabsrC   r-   rf   r
   r   formatr   join)ZresZstdrV   rU   r   ZfailureskZndigitsmsgZresrepZstdrepZrdiffr   r   r   mp_assert_allclose  s6    4
r   )r   r   ))Z
__future__r   r   r   rM   ro   r   Znumpyr
   Znumpy.testingr   rx   Zscipy._lib.sixr   Zscipy.special._testutilsr   rc   ImportErrorobjectr   r'   r*   r2   rG   rH   rv   r{   rh   rl   r   posixr   dirr   r   r   rg   r   r   r   r   r   r   r   r   <module>   sD   of
4

