B
     \H                 @   s^  d Z 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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mZ e ZejZed	Zed
Zdd Ze Z dZ!e"ee!Z#e$ee%ee!ee egZ&e'e&Z(dd Z)dd Z*dd Z+dd Z,dd Z-dd Z.dd Z/dd Z0dd Z1d d! Z2d"d# Z3d$d% Z4ed&ej5d'd( Z6ed)ej5d*d( Z6d+d, Z7ed-d.d/ Z8ed0d1d/ Z8ed2ej9ej9ed3ej9ej9d4d5 Z:ed6ed7ed7ej9ed7ej9ej9d8d9 Z;d:d; Z<d<d= Z=ed>ej>d?d@ Z?dAdB Z@edCej>dDdE ZAedCej>ej>dFdG ZBedCej>ej>ej>dHdI ZCedJej>ej>dKdL ZDedMej>dNdO ZEedMej>ej>dPdG ZBedQej9ej9dRdS ZFedTej9ej9dUdS ZFdVdS ZFedWej9ej9dXdY ZGedWej9ej9ej9dZd[ ZHed\ej9ej9ej9d]d[ ZHd^d_ ZIed`ej9ej9dadb ZJedcej9eddej9eddej9ej9dedb ZJdfdg ZKedhej9ej9didj ZLedkej9ej9dldj ZLdmdn ZMedoej9dpdq ZNedrej9dsdt ZOeduedrdvdt ZOedwedwej9edwej9ej9dxdy ZPedzej9ej9d{d| ZQd}d~ ZRedej9dd ZSedej9dd ZTedej9ej9dd ZUedej9dd ZVedej9ej9dd ZWedej9ej9dd ZWdd ZXedej>ej9dd ZYedej9dd ZZedej9ej9dd Z[edej9dd Z\edej9ej9dd Z]edej>ej>ej>dd Z^ededej9edej9ej9dd Z_ededej9edej9ej9dd Z`edej9dd Zaedejbej9dd Zcededej9dd Zdedej9dd Zeededej9dd Zfeddd Zgedej9dd Zhedej9ej9dd Ziedej9ddĄ ZjddƄ ZkeejlddȄ Zmee	jjlddȄ Zmee	jjndd˄ Zox4dD ],\ZpZqeepfejrfeq  epfdd΄ZsqW ee	jjtddЄ Ztee	jjudd҄ Zuee	jjvdddՄZvee	jjwdddׄZwdS )z6
Implement the random and np.random module functions.
    )print_functionabsolute_importdivisionN)ir)overloadregister_jitable)Registryimpl_ret_untrackedimpl_ret_new_ref)	signature)
_helperlibcgutilstypes    @   c             C   s   t t| S )N)r   Constantint32_t)x r   7lib/python3.7/site-packages/numba/targets/randomimpl.py	const_int   s    r   ip  c             C   sR   |dkst d| }ttd}|j||}|jd |jd ||dS )z
    Get a pointer to the given thread-local random state
    (depending on *name*: "py" or "np").
    If the state isn't initialized, it is lazily initialized with
    system entropy.
    )pynpznumba_get_%s_random_stater   ZreadnoneZnounwind)	AssertionErrorr   FunctionTypernd_state_ptr_tmoduleget_or_insert_functionZ
attributesaddcall)contextbuildernameZ	func_namefntyfnr   r   r   get_state_ptr2   s    r%   c             C   s   t | |dS )z@
    Get a pointer to the thread-local Python random state.
    r   )r%   )r    r!   r   r   r   get_py_state_ptrC   s    r&   c             C   s   t | |dS )z?
    Get a pointer to the thread-local Numpy random state.
    r   )r%   )r    r!   r   r   r   get_np_state_ptrI   s    r'   c             C   s   t | |ddS )Nr   )r   gep_inbounds)r!   	state_ptrr   r   r   get_index_ptrQ   s    r*   c             C   s   t | |ddS )Nr      )r   r(   )r!   r)   r   r   r   get_array_ptrT   s    r,   c             C   s   t | |ddS )Nr      )r   r(   )r!   r)   r   r   r   get_has_gauss_ptrW   s    r.   c             C   s   t | |ddS )Nr      )r   r(   )r!   r)   r   r   r   get_gauss_ptrZ   s    r0   c             C   s6   t t  tf}| jj|d}|jd d |S )z<
    Get the internal function to shuffle the MT taste.
    Znumba_rnd_shuffler   Z	nocapture)	r   r   VoidTyper   functionr   r   argsZadd_attribute)r!   r#   r$   r   r   r   get_rnd_shuffle]   s    r4   c       	   
   C   s"  t ||}||}|d|t}t||, t|}|||f |t	d| W dQ R X ||}t
||}|t||d|}||t	d}||| ||||t	d}|||||t	dt	d}|||||t	dt	d	}||||t	d
}|S )zB
    Get the next int32 generated by the PRNG at *state_ptr*.
    z>=r   Nr+         l   VX:    l     _    )r*   loadicmp_unsignedN_constr   if_unlikelyr4   r   storer   r,   r(   r   xorlshrand_shl)	r    r!   r)   ZidxptridxZneed_reshuffler$   Z	array_ptryr   r   r   get_next_int32g   s&    



rD   c             C   st   | t| ||td}| t| ||td}||t}||t}|||||t	tdt	tdS )zC
    Get the next double generated by the PRNG at *state_ptr*.
          g      Ag      @C)
r?   rD   r   ZuitofpdoubleZfdivfaddfmulr   r   )r    r!   r)   abr   r   r   get_next_double   s    rL   c                s  t |jd fdd}t t td} d|} |\}}	|" ||}
  	|
t| W dQ R X |	r r| 
|}t }
s| 
|}  	|
t  	|tt td} || W dQ R X W dQ R X  |S )z2
    Get the next integer with width *nbits*.
    r   c                sl     | }t }rR t|jd} | ||j} ||S  | ||jS d S )Nr   )	subrD   not_r   r   typer?   zextr@   )nbitsshiftrC   mask)r!   c32r    is_numpyr)   r   r   get_shifted_int   s    z%get_next_int.<locals>.get_shifted_intr   z<=N)r   r   rO   r   Zalloca_once_valueint64_tr:   if_elser=   rP   rM   rD   r   rA   r9   )r    r!   r)   rQ   rU   rV   retZis_32bZifsmallZiflargelowhightotalr   )r!   rT   r    rU   r)   r   get_next_int   s&    
 r]   c                sX   |j }| | t|t fdd|t|d D  }t|ft|d   }||fS )z
    Assuming a homogeneous signature (same type for result and all arguments),
    fill in the *defaults* if missing from the arguments.
    c             3   s   | ]}t  |V  qd S )N)r   r   ).0d)lltyr   r   	<genexpr>   s    z!_fill_defaults.<locals>.<genexpr>Nr+   )return_typeget_data_typetuplelenr   )r    r!   sigr3   defaultstyr   )r`   r   _fill_defaults   s
    
*ri   zrandom.seedc          	   C   s(   t | |||t| |d}t| ||j|S )Nr   )
_seed_implr%   r	   rb   )r    r!   rf   r3   resr   r   r   	seed_impl   s    
rl   znp.random.seedc          	   C   s(   t | |||t| |d}t| ||j|S )Nr   )rj   r%   r	   rb   )r    r!   rf   r3   rk   r   r   r   rl      s    
c             C   sH   |\}t t  ttf}|jj|d}||||f | 	t
jd S )NZnumba_rnd_init)r   r   r1   r   r   r2   r   r   r   Zget_constantr   none)r    r!   rf   r3   r)   Z
seed_valuer#   r$   r   r   r   rj      s
    rj   zrandom.randomc             C   s(   t | |d}t| ||}t| ||j|S )Nr   )r%   rL   r	   rb   )r    r!   rf   r3   r)   rk   r   r   r   random_impl   s    rn   znp.random.randomc             C   s(   t | |d}t| ||}t| ||j|S )Nr   )r%   rL   r	   rb   )r    r!   rf   r3   r)   rk   r   r   r   rn      s    zrandom.gausszrandom.normalvariatec             C   s    t | |||d}t| ||j|S )Nr   )_gauss_implr	   rb   )r    r!   rf   r3   rk   r   r   r   
gauss_impl   s    rp   znp.random.standard_normalznp.random.normalc             C   s4   t | |||d\}}t| |||d}t| ||j|S )N)g        g      ?r   )ri   ro   r	   rb   )r    r!   rf   r3   rk   r   r   r   np_gauss_impl   s    rq   c                s    fdd}|S )Nc                 sl   xBd   d } d   d }| |  ||  }|dk r|dkrP qW t dt | | }||  || fS )zG
        Compute a pair of numbers on the normal distribution.
        g       @g      ?g        g       )mathsqrtlog)Zx1Zx2Zr2f)_randomr   r   compute_gauss_pair   s    z,_gauss_pair_impl.<locals>.compute_gauss_pairr   )rv   rw   r   )rv   r   _gauss_pair_impl   s    rx   c             C   s>  |j }| |}t| ||}tjtjjd| }tj||dd}	t||}
t||}t	||
|}||\}}|( ||
|
|	 |td| W d Q R X |` | |t|tt|dd}t||d\}}|||
 |||	 |td| W d Q R X W d Q R X |\}}|||||
|	S )N)r   r   result)r"   r   r-   r   r+   )rb   rc   r%   randomr   r   alloca_oncer0   r.   Zis_truer9   rX   r=   r   compile_internalrx   r   r   ZUniTupleZunpack_tuplerH   rI   )r    r!   rf   r3   staterh   r`   r)   rv   rY   Z	gauss_ptrZhas_gauss_ptrZ	has_gaussZthenZ	otherwiseZpairfirstsecondmusigmar   r   r   ro     s2    


$ro   zrandom.getrandbitsc       
   	   C   s   |\}| d|td}| d|td}t|||| d}| j|t|f W d Q R X t| |d}t	| |||d}	t
| ||j|	S )Nz>=A   z==r   z getrandbits() limited to 64 bitsr   F)r:   r   r   r<   or_	call_convreturn_user_excOverflowErrorr%   r]   r	   rb   )
r    r!   rf   r3   rQ   	too_largeZ	too_smallmsgr)   rk   r   r   r   getrandbits_impl*  s    r   c          
      sR  t  |jtd}td}tj dd}  |||   	d||8  
 
 |||}	 |	| | W d Q R X   	d||8   
 |||}	 |	| | W d Q R X  |t  	d| d}
j t|
f W d Q R X ttjjg} jj|d	 }d
krr |n}  ||tjgt ttjtj dd fdd}d
kr2  	d|<\}}|  | W d Q R X | |  W d Q R X W d Q R X n|   
|  |S )Nr   r+   n)r"   <>z<=zempty range for randrange()zllvm.ctlz.%sr   rc                 s~     d}   d} |   |  t dk} |} d|} || |  |  | d S )Nwhilez	while.endr   z>=)append_basic_blockbranchposition_at_endr]   truncicmp_signedZcbranchr=   )Zbbwhilebbendr   r   )r!   r    r   rQ   rptrr}   r)   rh   r   r   get_numa  s    




z _randrange_impl.<locals>.get_numz==)r%   rO   r   r   r   r{   r=   rM   if_thenr   r   r9   Zsdivr<   r   r   
ValueErrorr   Ztrue_bitr2   r   r   r   r   r   widthrX   mul)r    r!   startstopstepr}   ZzeroZoneZnptrwr   r#   r$   Znm1r   Zis_oneZ
is_not_oner   )r!   r    r   rQ   r   r}   r)   rh   r   _randrange_impl7  sB    
	
r   zrandom.randrangec             C   sD   |\}t |jd}t |jd}t| ||||d}t| ||j|S )Nr   r+   r   )r   r   rO   r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   randrange_impl_1|  s
    r   c             C   s8   |\}}t |jd}t| ||||d}t| ||j|S )Nr+   r   )r   r   rO   r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   randrange_impl_2  s    r   c             C   s,   |\}}}t | ||||d}t| ||j|S )Nr   )r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   randrange_impl_3  s    
r   zrandom.randintc             C   sD   |\}}t |jd}|||}t| ||||d}t| ||j|S )Nr+   r   )r   r   rO   r   r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   randint_impl_1  s
    r   znp.random.randintc             C   sD   |\}t |jd}t |jd}t| ||||d}t| ||j|S )Nr   r+   r   )r   r   rO   r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   randint_impl_2  s
    r   c             C   s8   |\}}t |jd}t| ||||d}t| ||j|S )Nr+   r   )r   r   rO   r   r	   rb   )r    r!   rf   r3   r   r   r   rk   r   r   r   r     s    zrandom.uniformc             C   s    t | |||d}t| ||j|S )Nr   )uniform_implr	   rb   )r    r!   rf   r3   rk   r   r   r   r     s    r   znp.random.uniformc             C   s    t | |||d}t| ||j|S )Nr   )r   r	   rb   )r    r!   rf   r3   rk   r   r   r   r     s    c       
      C   s@   t | ||}|\}}|||}t| ||}	|||||	S )N)r%   ZfsubrL   rH   rI   )
r    r!   rf   r3   r}   r)   rJ   rK   r   r   r   r   r   r     s
    zrandom.triangularc             C   s^   |j }|\}}t| |d}t| ||}dd }	| ||	t|fd  |||f}
t| ||j |
S )Nr   c             S   s<   | }d}||kr"d| }|| }}||| t ||   S )Ng      ?g      ?)rr   rs   )randvalrZ   r[   ucr   r   r   triangular_impl_2  s    
z,triangular_impl_2.<locals>.triangular_impl_2   )rb   r%   rL   r|   r   r	   )r    r!   rf   r3   flttyrZ   r[   r)   r   r   rk   r   r   r   r     s    r   c             C   s.   |\}}}t | |||||d}t| ||j|S )Nr   )_triangular_impl_3r	   rb   )r    r!   rf   r3   rZ   r[   moderk   r   r   r   triangular_impl_3  s    
r   znp.random.triangularc             C   s.   |\}}}t | |||||d}t| ||j|S )Nr   )r   r	   rb   )r    r!   rf   r3   rZ   r   r[   rk   r   r   r   r     s    
c          	   C   sH   |j }t| ||}t| ||}	dd }
| ||
t|fd  |	|||fS )Nc             S   s\   ||kr|S | }|| ||  }||krBd| }d| }|| }}||| t ||   S )Ng      ?)rr   rs   )r   rZ   r[   r   r   r   r   r   r   r     s    
z-_triangular_impl_3.<locals>.triangular_impl_3rE   )rb   r%   rL   r|   r   )r    r!   rf   rZ   r[   r   r}   r   r)   r   r   r   r   r   r     s    r   zrandom.gammavariatec             C   s"   t | |||tj}t| ||j|S )N)_gammavariate_implrz   r	   rb   )r    r!   rf   r3   rk   r   r   r   gammavariate_impl  s    r   znp.random.standard_gammaznp.random.gammac             C   s8   t | |||d\}}t| |||tjj}t| ||j|S )N)Ng      ?)ri   r   r   rz   r	   rb   )r    r!   rf   r3   rk   r   r   r   r     s    c                s^   t jt jt jt jdt j }d dd  fdd}| ||||S )Ng       @g      @g      ?g      @c                s  | dks|dkrt d| dkrԈd|  d }|   }| | }x }d|  k r\dk s`qB qBd  }|d|  | }| | }|| | }	|||  | }
|
 d|	  dks|
|	krB|| S qBW n| dkr }x|dkr }qW | | S x }|   }|| }|dkr:|d|   }n|| |   } }|dkrr||| d  krP n|| krP qW || S dS )	z1Gamma distribution.  Taken from CPython.
        g        z*gammavariate: alpha and beta must be > 0.0g      ?g       @gHz>gP?g      @N)r   )alphabetaZainvZbbbZcccu1u2vr   zr   r   rK   p)LOG4SG_MAGICCONST_e_exp_logrv   _sqrtr   r   r   	  sH    
 




z-_gammavariate_impl.<locals>.gammavariate_impl)rr   exprt   rs   epir|   )r    r!   rf   r3   rv   TWOPIr   r   )r   r   r   r   r   rv   r   r   r     s    
7r   zrandom.betavariatec             C   s"   t | |||tj}t| ||j|S )N)_betavariate_implrz   Zgammavariater	   rb   )r    r!   rf   r3   rk   r   r   r   betavariate_implD  s    
r   znp.random.betac             C   s$   t | |||tjj}t| ||j|S )N)r   r   rz   gammar	   rb   )r    r!   rf   r3   rk   r   r   r   r   K  s    

c                s    fdd}|  ||||S )Nc                s,    | d}|dkrdS || |d  S dS )z0Beta distribution.  Taken from CPython.
        g      ?g        Nr   )r   r   rC   )r   r   r   r   T  s    
z+_betavariate_impl.<locals>.betavariate_impl)r|   )r    r!   rf   r3   r   r   r   )r   r   r   R  s    r   zrandom.expovariatec                s:   t j tj  fdd}| ||||}t| ||j|S )Nc                s    d   |  S )z7Exponential distribution.  Taken from CPython.
        g      ?r   )Zlambd)r   rv   r   r   expovariate_impli  s    z*expovariate_impl.<locals>.expovariate_impl)rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r   c  s    
r   znp.random.exponentialc                s<   t jjtj  fdd}| ||||}t| ||j|S )Nc                s    d   |  S )Ng      ?r   )scale)r   rv   r   r   exponential_impl|  s    z*exponential_impl.<locals>.exponential_impl)r   rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r   w  s    r   znp.random.standard_exponentialc                s<   t jjtj  fdd}| ||||}t| ||j|S )Nc                  s    d   S )Ng      ?r   r   )r   rv   r   r   r     s    z*exponential_impl.<locals>.exponential_impl)r   rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s    znp.random.lognormalc             C   s8   t | |||d\}}t| |||tjj}t| ||j|S )N)g        g      ?)ri   _lognormvariate_implr   rz   Znormalr	   rb   )r    r!   rf   r3   rk   r   r   r   np_lognormal_impl  s    

r   zrandom.lognormvariatec             C   s"   t | |||tj}t| ||j|S )N)r   rz   Zgaussr	   rb   )r    r!   rf   r3   rk   r   r   r   lognormvariate_impl  s    r   c                s$   t j  fdd}| ||||S )Nc                s    | |S )Nr   )r   r   )r   _gaussr   r   r     s    z1_lognormvariate_impl.<locals>.lognormvariate_impl)rr   r   r|   )r    r!   rf   r3   r   r   r   )r   r   r   r     s    r   zrandom.paretovariatec                s2   t j   fdd}| ||||}t| ||j|S )Nc                s   d   }d|d|    S )z)Pareto distribution.  Taken from CPython.g      ?r   )r   r   )rv   r   r   paretovariate_impl  s    
z.paretovariate_impl.<locals>.paretovariate_impl)rz   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )rv   r   r     s
    r   znp.random.paretoc                s4   t jj  fdd}| ||||}t| ||j|S )Nc                s   d   }d|d|    d S )Ng      ?r+   r   )r   r   )rv   r   r   pareto_impl  s    
z pareto_impl.<locals>.pareto_impl)r   rz   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )rv   r   r     s    r   zrandom.weibullvariatec                s:   t j tj  fdd}| ||||}t| ||j|S )Nc                s    d  }|  | d|   S )z*Weibull distribution.  Taken from CPython.g      ?r   )r   r   r   )r   rv   r   r   weibullvariate_impl  s    
z0weibullvariate_impl.<locals>.weibullvariate_impl)rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s    r   znp.random.weibullc                s<   t jjtj  fdd}| ||||}t| ||j|S )Nc                s   d  } | d|   S )Ng      ?r   )r   r   )r   rv   r   r   weibull_impl  s    
z"weibull_impl.<locals>.weibull_impl)r   rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s
    r   zrandom.vonmisesvariatec             C   s"   t | |||tj}t| ||j|S )N)_vonmisesvariate_implrz   r	   rb   )r    r!   rf   r3   rk   r   r   r   vonmisesvariate_impl  s    r   znp.random.vonmisesc             C   s$   t | |||tjj}t| ||j|S )N)r   r   rz   r	   rb   )r    r!   rf   r3   rk   r   r   r   r     s    c                sN   t jt jt jt jt jd   fdd}| ||||S )Ng       @c                s   |dkr   S d| }|d||   }xN }| }|||  } }|d||  k sx|d| | kr0P q0W d| }|| d||   }	 }
|
dkr| |	   }n| |	   }|S )zCircular data distribution.  Taken from CPython.
        Note the algorithm in Python 2.6 and Numpy is different:
        http://bugs.python.org/issue17141
        gư>g      ?g      ?r   )r   Zkappasr   r   r   r_   r   qru   Zu3Ztheta)r   _acos_cosr   _pirv   r   r   r   r     s$    
$z3_vonmisesvariate_impl.<locals>.vonmisesvariate_impl)rr   r   rs   ZcosZacosr   r|   )r    r!   rf   r3   rv   r   r   )r   r   r   r   r   rv   r   r   r     s    (r   znp.random.binomialc                s:   |j }tjj  fdd}| ||||}t| ||j |S )Nc                sX  | dk rt dd|  kr$dks.n t d|dkr:dS |dkrF| S |dk}|rZd| }d| }d}||  }x0|dkr|d	K }| d	L } ||  }| dksptqpW | | }t| |d
t|| d   }d}d}	x|dkrRd}
  }|}xd|
|krN||kr |	|r| |
 n|
7 }	|d8 }P ||8 }|
d7 }
| |
 d | | |
|  }qW qW |	S )z
        Binomial distribution.  Numpy's variant of the BINV algorithm
        is used.
        (Numpy uses BTPE for n*p >= 30, though)
        r   zbinomial(): n <= 0g        g      ?zbinomial(): p outside of [0, 1]g      ?r+   gx0 r-   g      $@F)r   r   minrr   rs   )r   r   Zflippedr   ZnitersZqnr   ZboundZfinishedr\   XUZpx)rv   r   r   binomial_impl%  sH    
 
$z$binomial_impl.<locals>.binomial_impl)rb   r   rz   r|   r	   )r    r!   rf   r3   inttyr   rk   r   )rv   r   r      s
    2r   znp.random.chisquarec             C   s(   dd }|  ||||}t| ||j|S )Nc             S   s   dt j| d  S )Ng       @)r   rz   standard_gamma)dfr   r   r   chisquare_impl^  s    z&chisquare_impl.<locals>.chisquare_impl)r|   r	   rb   )r    r!   rf   r3   r   rk   r   r   r   r   [  s    r   znp.random.fc             C   s(   dd }|  ||||}t| ||j|S )Nc             S   s    t j| | t j||   S )N)r   rz   Z	chisquare)ZnumZdenomr   r   r   f_implh  s    zf_impl.<locals>.f_impl)r|   r	   rb   )r    r!   rf   r3   r   rk   r   r   r   r   e  s    r   znp.random.geometricc                s<   t jj |j fdd}| ||||}t| ||j|S )Nc                s   | dks| dkrt dd|  }| dkrhd}|  }}  }x$||krb||9 }||7 }|d7 }q@W |S ttd   t| S d S )Ng        g      ?z geometric(): p outside of (0, 1]gUUUUUU?r+   )r   rr   Zceilrt   )r   r   r   sumprodr   )rv   r   r   r   geometric_implu  s    
z&geometric_impl.<locals>.geometric_impl)r   rz   rb   r|   r	   )r    r!   rf   r3   r   rk   r   )rv   r   r   r   p  s
    r   znp.random.gumbelc                s<   t jjtj  fdd}| ||||}t| ||j|S )Nc                s    d  }| |  |   S )Ng      ?r   )locr   r   )r   rv   r   r   gumbel_impl  s    
z gumbel_impl.<locals>.gumbel_impl)r   rz   rr   rt   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s
    r   znp.random.hypergeometricc                s<   t jjtj  fdd}| ||||}t| ||j|S )Nc                s~   ||  | }t t|| }|}|}x6|dkrX|dkrX|  |||   8 }|d8 }q$W t|| }| |krv|| S |S dS )z'Numpy's algorithm for hypergeometric().g        r   r+   N)floatr   int)ZngoodZnbadZnsamplesZd1Zd2YKZ)_floorrv   r   r   hypergeometric_impl  s    z0hypergeometric_impl.<locals>.hypergeometric_impl)r   rz   rr   floorr|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s
    r   znp.random.laplacec                sP   t jjtj  fdd}t| |||d\}}| ||||}t| ||j|S )Nc                s>    }|dk r"| | ||   S | | d| |   S d S )Ng      ?g       @r   )r   r   r   )r   rv   r   r   laplace_impl  s    z"laplace_impl.<locals>.laplace_impl)g        g      ?)r   rz   rr   rt   ri   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s    r   znp.random.logisticc                sP   t jjtj  fdd}t| |||d\}}| ||||}t| ||j|S )Nc                s    }| | |d|    S )Ng      ?r   )r   r   r   )r   rv   r   r   logistic_impl  s    z$logistic_impl.<locals>.logistic_impl)g        g      ?)r   rz   rr   rt   ri   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   rv   r   r     s    r   znp.random.logseriesc                sL   |j tjjtjtj  fdd}| ||||}t| ||j |S )Nc                s   | dks| dkrt dd|  }x` }|| kr8dS  }d ||  }||| krrd||  S ||kr~dS dS q&W dS )z"Numpy's algorithm for logseries().g        g      ?z logseries(): p outside of (0, 1]r+   r-   N)r   )r   r   Vr   r   )r   r   rv   r   r   r   logseries_impl  s    z&logseries_impl.<locals>.logseries_impl)rb   r   rz   rr   rt   r   r|   r	   )r    r!   rf   r3   r   rk   r   )r   r   rv   r   r   r     s    r   znp.random.negative_binomialc                s>   t jj t jj fdd}| ||||}t| ||j|S )Nc                sB   | dkrt d|dk s |dkr(t d | d| | }|S )Nr   znegative_binomial(): n <= 0g        g      ?z(negative_binomial(): p outside of [0, 1])r   )r   r   r   )_gamma_poissonr   r   negative_binomial_impl  s    z6negative_binomial_impl.<locals>.negative_binomial_impl)r   rz   r   Zpoissonr|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   r   r   r     s
    r   znp.random.poissonc          	      sV  t | |}tj|tdd}|d}|d}t|dkr|\}|d|tt	d}	|
|	L tttt	f}
|jj|
d}||||f}||| || W d Q R X || || tjjtj  fd	d
}t|dkrt|jtj}tt	df}| ||||}||| || || ||}t| ||j|S )NrY   )r"   bbcontr   r+   z>=g      $@Znumba_poisson_ptrsc                sZ   | dk rt d| dkrdS  |  }d}d}x& }||9 }||krJ|S |d7 }q0W dS )a+  Numpy's algorithm for poisson() on small *lam*.

        This method is invoked only if the parameter lambda of the
        distribution is small ( < 10 ). The algorithm used is described
        in "Knuth, D. 1969. 'Seminumerical Algorithms. The Art of
        Computer Programming' vol 2.
        g        zpoisson(): lambda < 0r   g      ?r+   N)r   )lamZenlamr   r   r   )r   rv   r   r   poisson_impl  s    
z"poisson_impl.<locals>.poisson_implr   g      ?)r'   r   r{   rW   r   re   Zfcmp_orderedr   r   rG   r   r   r   r2   r   r   r   r=   r   r   r   rz   rr   r   r   rb   r   Zfloat64r|   r9   r	   )r    r!   rf   r3   r)   Zretptrr   r   r   Zbig_lamr#   r$   rY   r   rk   r   )r   rv   r   r     s8    








r   znp.random.powerc             C   s(   dd }|  ||||}t| ||j|S )Nc             S   s2   | dkrt dtdttj   d|  S )Ng        zpower(): a <= 0r+   g      ?)r   rr   powr   r   rz   Zstandard_exponential)rJ   r   r   r   
power_implD  s    zpower_impl.<locals>.power_impl)r|   r	   rb   )r    r!   rf   r3   r   rk   r   r   r   r   A  s    r   znp.random.rayleighc                sH   t jj  fdd}t| |||d\}}| ||||}t| ||j|S )Nc                s.   | dkrt d| tdtd     S )Ng        zrayleigh(): mode <= 0g       g      ?)r   rr   rs   rt   )r   )rv   r   r   rayleigh_implS  s    z$rayleigh_impl.<locals>.rayleigh_impl)g      ?)r   rz   ri   r|   r	   rb   )r    r!   rf   r3   r   rk   r   )rv   r   r   N  s
    r   znp.random.standard_cauchyc                s4   t jj  fdd}| ||||}t| ||j|S )Nc                  s        S )Nr   r   )r   r   r   cauchy_impla  s    z cauchy_impl.<locals>.cauchy_impl)r   rz   standard_normalr|   r	   rb   )r    r!   rf   r3   r   rk   r   )r   r   r   ]  s    r   znp.random.standard_tc             C   s(   dd }|  ||||}t| ||j|S )Nc             S   s:   t j }t j| d }t| d | t| }|S )Ng       @)r   rz   r   r   rr   rs   )r   NGr   r   r   r   standard_t_implk  s    
z(standard_t_impl.<locals>.standard_t_impl)r|   r	   rb   )r    r!   rf   r3   r   rk   r   r   r   r   h  s    r   znp.random.waldc             C   s(   dd }|  ||||}t| ||j|S )Nc             S   s   | dkrt d|dkr t d| d|  }tj }| | | }| ||td| | ||     }tj }|| | |  kr|S | |  | S d S )Ng        zwald(): mean <= 0zwald(): scale <= 0g       @r   )r   r   rz   r   rr   rs   )Zmeanr   Zmu_2lr   r   r   r   r   r   	wald_implx  s    
&
zwald_impl.<locals>.wald_impl)r|   r	   rb   )r    r!   rf   r3   r   rk   r   r   r   r   u  s    r   znp.random.zipfc                s<   t jj |j fdd}| ||||}t| ||j|S )Nc                s   | dkrt d| d }d| }xfd   }  }t|d|  }dd|  | }|dkr"|| |d  |d  || kr"|S q"W d S )Ng      ?zzipf(): a <= 1g       @g      r+   )r   rr   r   )rJ   Zam1rK   r   r   r   T)rv   r   r   r   	zipf_impl  s    
(zzipf_impl.<locals>.zipf_impl)r   rz   rb   r|   r	   )r    r!   rf   r3   r  rk   r   )rv   r   r   r    s
    r  c                s\   t | tjstd|dkr&tjj n|dkr4tj | jdkrL fdd}n fdd}|S )Nz1The argument to shuffle() should be a buffer typer   r   r+   c                sN   | j d d }x:|dkrH |d }| | | |  | |< | |< |d8 }qW d S )Nr   r+   )shape)arrij)randr   r   impl  s
    
zdo_shuffle_impl.<locals>.implc                sZ   | j d d }xF|dkrT |d }t| | t| |  | |< | |< |d8 }qW d S )Nr   r+   )r  r   copy)r  r  r  )r  r   r   r    s
    
&)	
isinstancer   ZBuffer	TypeErrorr   rz   randintZ	randrangendim)r  rngr  r   )r  r   do_shuffle_impl  s    

r  c             C   s
   t | dS )Nr   )r  )r  r   r   r   shuffle_impl  s    r  c             C   s
   t | dS )Nr   )r  )r  r   r   r   r    s    c             C   s4   t | tjrdd }nt | tjr,dd }nd }|S )Nc             S   s   t | }t j| |S )N)r   arangerz   shuffle)r   rC   r   r   r   permutation_impl  s    
z*permutation_impl.<locals>.permutation_implc             S   s   |   }tj| |S )N)r  r   rz   r  )r   Zarr_copyr   r   r   r    s    )r	  r   IntegerArray)r   r  r   r   r   r    s    

r  ) )znp.random.betar/   )znp.random.binomialr/   )znp.random.chisquarer-   )znp.random.exponentialr-   )znp.random.fr/   )znp.random.gammar/   )znp.random.geometricr-   )znp.random.gumbelr/   )znp.random.hypergeometricr   )znp.random.laplacer/   )znp.random.logisticr/   )znp.random.lognormalr/   )znp.random.logseriesr-   )znp.random.negative_binomialr/   )znp.random.normalr/   )znp.random.paretor-   )znp.random.poissonr-   )znp.random.powerr-   )znp.random.randomr+   )znp.random.randintr/   )znp.random.rayleighr-   )znp.random.standard_cauchyr+   )znp.random.standard_exponentialr+   )znp.random.standard_gammar-   )znp.random.standard_normalr+   )znp.random.standard_tr-   )znp.random.triangularr   )znp.random.uniformr/   )znp.random.vonmisesr/   )znp.random.waldr/   )znp.random.weibullr-   )znp.random.zipfr-   c          	   C   s   ddl m} |j}|j}t|f|jd d  }|d d }	|| ||jd |d }
|| |||
}| ||}t	
||j4}|||	}t	||j|j}|| |||| W d Q R X t| ||j| S )Nr+   )arrayobj) r  rb   dtyper   r3   Z_parse_shapeZ_empty_nd_implZget_functionr   Z	for_rangeZnitemsZgepdataindexZ
store_itemr
   Z	_getvalue)r    r!   rf   r3   
typing_keyr  Zarrtyr  Z
scalar_sigZscalar_argsZshapesr  Zscalar_implZloopvalZptrr   r   r   
random_arr  s    
r  c              G   s"   t | dkrdd }ndd }|S )Nr   c              W   s
   t j S )N)r   rz   )sizer   r   r   	rand_impl  s    zrand.<locals>.rand_implc              W   s   t j| S )N)r   rz   )r  r   r   r   r    s    )re   )r  r  r   r   r   r    s    
r  c              G   s"   t | dkrdd }ndd }|S )Nr   c              W   s
   t j S )N)r   rz   r   )r  r   r   r   
randn_impl&  s    zrandn.<locals>.randn_implc              W   s   t j| S )N)r   rz   r   )r  r   r   r   r   +  s    )re   )r  r   r   r   r   randn"  s    
r!  Tc                s   t | tjrF| jdkst| jtdd tdd  tdd nFt | tjr~tj	tdd td	d  td
d nt
d| f |d tjfkrdfdd	}nd fdd	}|S )Nr+   c             S   s   t | S )N)re   )rJ   r   r   r   get_source_size<  s    zchoice.<locals>.get_source_sizec             S   s   |   S )N)r  )rJ   r   r   r   copy_source@  s    zchoice.<locals>.copy_sourcec             S   s   | | S )Nr   )rJ   a_ir   r   r   getitemD  s    zchoice.<locals>.getitemc             S   s   | S )Nr   )rJ   r   r   r   r"  L  s    c             S   s
   t | S )N)r   r  )rJ   r   r   r   r#  P  s    c             S   s   |S )Nr   )rJ   r$  r   r   r   r%  T  s    z@np.random.choice() first argument should be int or array, got %sTc                s     | }t jd|}| |S )zs
            choice() implementation returning a single sample
            (note *replace* is ignored)
            r   )r   rz   r  )rJ   r  replacer   r  )r"  r%  r   r   choice_impl]  s    zchoice.<locals>.choice_implc       	         s   | }|rTt |}|j}x0tt|D ] }t jd|}| |||< q,W |S t |}|j|krrtd | }|j}x:tt|D ]*}t j||}|| ||< || ||< qW |S dS )zO
            choice() implementation returning an array of samples
            r   z@Cannot take a larger sample than population when 'replace=False'N)	r   emptyflatrangere   rz   r  r  r   )	rJ   r  r&  r   outflr  r  src)r#  r  r"  r%  r   r   r'  g  s$    
)NT)NT)r	  r   r  r  r   r  r   r  r   intpr
  rm   )rJ   r  r&  r'  r   )r#  r  r"  r%  r   choice4  s"    

r/  c                s   t j tdd t| tjs,td| f t|tjtjfsLtd|f |d tj	fkrld
 fdd	}nJt|tjrd fdd	}n,t|tj
rd fdd	}ntd	|f |S )Nc             S   s   |j }|j}t|}xtd||D ]|}d}| }xVtd|d D ]D}	||	 }
tj||
|  }|||	 < ||8 }|dkrzP ||
8 }q>W |dkr"|||| d < q"W d S )Nr   g      ?r+   )r)  r  re   r*  r   rz   Zbinomial)r   pvalsr+  r,  Zszplenr  Zp_sumZn_experimentsr  Zp_jZn_jr   r   r   multinomial_inner  s    z&multinomial.<locals>.multinomial_innerz7np.random.multinomial(): n should be an integer, got %szEnp.random.multinomial(): pvals should be an array or sequence, got %sc                s    t t| }| || |S )z5
            multinomial(..., size=None)
            )r   zerosre   )r   r0  r  r+  )r  r2  r   r   multinomial_impl  s    z%multinomial.<locals>.multinomial_implc                s$   t |t|f }| || |S )z4
            multinomial(..., size=int)
            )r   r3  re   )r   r0  r  r+  )r  r2  r   r   r4    s    c                s&   t |t|f  }| || |S )z6
            multinomial(..., size=tuple)
            )r   r3  re   )r   r0  r  r+  )r  r2  r   r   r4    s    zDnp.random.multinomial(): size should be int or tuple or None, got %s)N)N)N)r   r.  r   r	  r   r  r
  Sequencer  rm   Z	BaseTuple)r   r0  r  r4  r   )r  r2  r   multinomial  s"    

	
r6  )NT)N)x__doc__Z
__future__r   r   r   rr   osrz   Znumpyr   Zllvmliter   Znumba.extendingr   r   Znumba.targets.imputilsr   r	   r
   Znumba.typingr   Znumbar   r   r   registrylowerZIntTyper   rW   r   Z
DoubleTyperG   r   r   r;   ZLiteralStructTypeZ	ArrayTypeZrnd_state_tZPointerTyper   r%   r&   r'   r*   r,   r.   r0   r4   rD   rL   r]   ri   Zuint32rl   rj   rn   ZFloatrp   rq   rx   ro   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int64r   r   r   r   r   r   r   r  r  r  r  Zpermutationr  r  ZarityZAnyr  r  r!  r/  r6  r   r   r   r   <module>   s  




)
$E

E

4;


=#
U
