o
    Õ0 i¹¹  ã                   @   sø   d dl Z d dlZd dlZd dlZd dlZd dl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 d dlmZ d dlmZ d dlmZ d dlZdZd	ZG d
d„ deƒZddd„Zi ae jdd„ ƒZdd„ Zdd„ Zdd„ ZdS )é    N)ÚLinAlgError)Ú_core)Úcuda)Údevice)Ú_kernels)Ú_utill   ÿÿ l   ÿÿÿÿ c                   @   s@  e Zd ZdZdŽdd„Zdd„ Zdd„ Zdefd	d
„Zde	fdd„Z
defdd„Zdefdd„Zddefdd„Zdefdd„Zddefdd„Zde	fdd„Zde	fdd„Ze dddd¡Zd ddefd!d"„Zd ddefd#d$„Zd ddefd%d&„Zde	fd'd(„Zdd)d*d+efd,d-„Zde	fd.d/„Zd ddefd0d1„Zdefd2d3„Zdefd4d5„Zdefd6d7„Zdde	fd8d9„Zdefd:d;„Z d<d=„ Z!d>d?„ Z"e d@dAdBdC¡Z#dDdE„ Z$defdFdG„Z%ddefdHdI„Z&e dJdKdLdM¡Z'e dJdNdOdP¡Z(dQdR„ Z)dSdT„ Z*dUdV„ Z+e dWdXdYdZ¡Z,dd[d\„Z-defd]d^„Z.defd_d`„Z/defdadb„Z0defdcdd„Z1defdedf„Z2ddgdh„Z3e didAdjdk¡Z4defdldm„Z5e dndAdodp¡Z6d ddefdqdr„Z7defdsdt„Z8e dudvdwdx¡Z9defdydz„Z:defd{d|„Z;de	fd}d~„Z<dd€d„Z=d‚dƒ„ Z>d„d…„ Z?d†d‡„ Z@e dddˆd‰¡ZAd ddefdŠd‹„ZBdde	fdŒd„ZCdS )‘ÚRandomStateaV  Portable container of a pseudo-random number generator.

    An instance of this class holds the state of a random number generator. The
    state is available only on the device which has been current at the
    initialization of the instance.

    Functions of :mod:`cupy.random` use global instances of this class.
    Different instances are used for different devices. The global state for
    the current device can be obtained by the
    :func:`cupy.random.get_random_state` function.

    Args:
        seed (None or int): Seed of the random number generator. See the
            :meth:`~cupy.random.RandomState.seed` method for detail.
        method (int): Method of the random number generator. Following values
            are available::

               cupy.cuda.curand.CURAND_RNG_PSEUDO_DEFAULT
               cupy.cuda.curand.CURAND_RNG_PSEUDO_XORWOW
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MRG32K3A
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MTGP32
               cupy.cuda.curand.CURAND_RNG_PSEUDO_MT19937
               cupy.cuda.curand.CURAND_RNG_PSEUDO_PHILOX4_32_10

    Nc                 C   sN   ddl m} |d u r|j}| |¡| _t | |j| j¡| _|| _	|  
|¡ d S )Nr   ©Úcurand)Úcupy_backends.cuda.libsr
   ZCURAND_RNG_PSEUDO_DEFAULTZcreateGeneratorÚ
_generatorÚweakrefÚfinalizeZdestroyGeneratorÚ
_finalizerÚmethodÚseed)Úselfr   r   r
   © r   úb/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/cupy/random/_generator.pyÚ__init__8   s   
ÿzRandomState.__init__c                 C   s   | j | t | _ d S ©N)Ú_rk_seedÚ_UINT64_MAX)r   Úsizer   r   r   Ú_update_seedC   s   zRandomState._update_seedc                 G   s’   t  |¡}t j |¡}|d dkr(tj||d}|| j|jj|j	g|¢R Ž  |S tj|d f|d}|| j|jj|j	g|¢R Ž  |d |…  
|¡S )Né   r   ©Údtypeé   )r   Úget_sizeZinternalÚprodÚcupyÚemptyr   ÚdataÚptrr   Úreshape)r   Úfuncr   r   ÚargsZelement_sizeÚoutr   r   r   Ú_generate_normalF   s   
zRandomState._generate_normalc                 C   ó\   t  |¡t  |¡}}|du rt  ||¡j}t j||d}t ||| j|¡ |  |j	¡ |S )zÎReturns an array of samples drawn from the beta distribution.

        .. seealso::
            - :func:`cupy.random.beta` for full documentation
            - :meth:`numpy.random.RandomState.beta`
        N©Úshaper   )
r!   ÚasarrayÚ	broadcastr,   r"   r   Zbeta_kernelr   r   r   )r   ÚaÚbr   r   Úyr   r   r   ÚbetaY   ó   zRandomState.betac                 C   r*   )zÚReturns an array of samples drawn from the binomial distribution.

        .. seealso::
            - :func:`cupy.random.binomial` for full documentation
            - :meth:`numpy.random.RandomState.binomial`
        Nr+   )
r!   r-   r.   r,   r"   r   Zbinomial_kernelr   r   r   ©r   ÚnÚpr   r   r1   r   r   r   Úbinomialh   r3   zRandomState.binomialc                 C   óF   t  |¡}|du r|j}t j||d}t || j|¡ |  |j¡ |S )zÞReturns an array of samples drawn from the chi-square distribution.

        .. seealso::
            - :func:`cupy.random.chisquare` for full documentation
            - :meth:`numpy.random.RandomState.chisquare`
        Nr+   )	r!   r-   r,   r"   r   Zchisquare_kernelr   r   r   ©r   Údfr   r   r1   r   r   r   Ú	chisquarew   ó   
zRandomState.chisquarec                 C   s‚   t  |¡}|du r|j}nt|tt jfƒr|f|j }n||j7 }t j||d}t || j	|¡ ||j
ddd }|  |j¡ |S )zÝReturns an array of samples drawn from the dirichlet distribution.

        .. seealso::
            - :func:`cupy.random.dirichlet` for full documentation
            - :meth:`numpy.random.RandomState.dirichlet`
        Nr+   éÿÿÿÿT)ÚaxisZkeepdims)r!   r-   r,   Ú
isinstanceÚintÚintegerr"   r   Ústandard_gamma_kernelr   Úsumr   r   )r   Úalphar   r   r1   r   r   r   Ú	dirichlet†   s   

zRandomState.dirichletç      ð?c                 C   sF   t  ||¡}|dk  ¡ rtdƒ‚|du r|j}|  ||¡}||9 }|S )a.  Returns an array of samples drawn from a exponential distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.exponential` for full documentation
            - :meth:`numpy.random.RandomState.exponential`
        r   ú	scale < 0N)r!   r-   ÚanyÚ
ValueErrorr,   Ústandard_exponential©r   Úscaler   r   Úxr   r   r   Úexponentialš   s   zRandomState.exponentialc                 C   r*   )zÅReturns an array of samples drawn from the f distribution.

        .. seealso::
            - :func:`cupy.random.f` for full documentation
            - :meth:`numpy.random.RandomState.f`
        Nr+   )
r!   r-   r.   r,   r"   r   Zf_kernelr   r   r   )r   ÚdfnumÚdfdenr   r   r1   r   r   r   Úf®   r3   zRandomState.fc                 C   sb   t  |¡t  |¡}}|du rt  ||¡j}t j||d}t || j|¡ ||9 }|  |j	¡ |S )zÏReturns an array of samples drawn from a gamma distribution.

        .. seealso::
            - :func:`cupy.random.gamma` for full documentation
            - :meth:`numpy.random.RandomState.gamma`
        Nr+   )
r!   r-   r.   r,   r"   r   rB   r   r   r   )r   r,   rL   r   r   r1   r   r   r   Úgamma½   s   zRandomState.gammac                 C   r8   )zÝReturns an array of samples drawn from the geometric distribution.

        .. seealso::
            - :func:`cupy.random.geometric` for full documentation
            - :meth:`numpy.random.RandomState.geometric`
        Nr+   )	r!   r-   r,   r"   r   Zgeometric_kernelr   r   r   ©r   r6   r   r   r1   r   r   r   Ú	geometricÍ   r<   zRandomState.geometricc                 C   sl   t  |¡t  |¡t  |¡}}}|du rt  |||¡j}t j||d}t |||| j|¡ |  |j	¡ |S )zìReturns an array of samples drawn from the hypergeometric distribution.

        .. seealso::
            - :func:`cupy.random.hypergeometric` for full documentation
            - :meth:`numpy.random.RandomState.hypergeometric`
        Nr+   )
r!   r-   r.   r,   r"   r   Zhypergeometric_kernelr   r   r   )r   ZngoodZnbadZnsampler   r   r1   r   r   r   ÚhypergeometricÜ   s   ÿzRandomState.hypergeometriczT x, T loc, T scalezT yz>y = loc + scale * ((x <= 0.5) ? log(x + x): -log(x + x - 1.0))Zcupy_laplace_kernelç        c                 C   sN   t  ||¡}t  ||¡}|du rt  ||¡j}|  ||¡}t ||||¡ |S )z×Returns an array of samples drawn from the laplace distribution.

        .. seealso::
            - :func:`cupy.random.laplace` for full documentation
            - :meth:`numpy.random.RandomState.laplace`
        N)r!   r-   r.   r,   Ú_random_sample_rawr   Ú_laplace_kernel©r   ÚlocrL   r   r   rM   r   r   r   Úlaplaceñ   s   zRandomState.laplacec                 C   s’   t  |¡t  |¡}}|du rt  ||¡j}t j||d}t | j|¡ |  |j	¡ d| | }t j
||d t j|||d t j|||d |S )zÚReturns an array of samples drawn from the logistic distribution.

        .. seealso::
            - :func:`cupy.random.logistic` for full documentation
            - :meth:`numpy.random.RandomState.logistic`
        Nr+   rF   ©r(   )r!   r-   r.   r,   r"   r   Zopen_uniform_kernelr   r   r   ÚlogÚmultiplyÚaddrY   r   r   r   Úlogistic   s   zRandomState.logisticc                 C   s‚   ddl m} tdd„ ||fD ƒƒr"|  ||||¡}tj||d |S |du r(d}t|ƒ}|jdkr5|j}n|j	}|  
|||||¡S )	zÝReturns an array of samples drawn from a log normal distribution.

        .. seealso::
            - :func:`cupy.random.lognormal` for full documentation
            - :meth:`numpy.random.RandomState.lognormal`

        r   r	   c                 s   s    | ]	}t |tjƒV  qd S r   )r?   r!   Úndarray)Ú.0Úargr   r   r   Ú	<genexpr>  s   € z(RandomState.lognormal.<locals>.<genexpr>r\   Nr   rQ   )r   r
   rH   Únormalr!   ÚexpÚ_check_and_get_dtypeÚcharZgenerateLogNormalZgenerateLogNormalDoubler)   )r   ÚmeanÚsigmar   r   r
   rM   r&   r   r   r   Ú	lognormal  s   
zRandomState.lognormalc                 C   sr   t  |¡}t  |dk¡rtdƒ‚t  |dk¡rtdƒ‚|du r"|j}t j||d}t || j|¡ |  	|j
¡ |S )a*  Returns an array of samples drawn from a log series distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.logseries` for full documentation
            - :meth:`numpy.random.RandomState.logseries`

        r   zp <= 0.0r   zp >= 1.0Nr+   )r!   r-   rH   rI   r,   r"   r   Zlogseries_kernelr   r   r   rS   r   r   r   Ú	logseries*  s   
zRandomState.logseriesÚignoreg:Œ0âŽyE>Úcholeskyc                 C   s>  t  d¡ tj||d}tj||d}|du rg }nt|ttjfƒr&|g}n|}t|jƒdkr3t	dƒ‚t|jƒdksD|jd |jd krHt	dƒ‚|jd |jd krVt	d	ƒ‚t
|dd… ƒ}	|	 |jd ¡ |d
vrnt	dƒ‚|dkr~|dkr~|dkr~t	dƒ‚|dkrtjdd‡ ztj |¡}
W nv ty   tjdd] |dkrê|dkrºtj |¡\}}t || k ¡ }|dkr×tj |¡\}}}tjt |j| |¡|||d}|t t |¡¡ }
|sét dt¡ nt dt¡ tj |¡}
W d  ƒ n	1 sw   Y  Y nw W d  ƒ n	1 sw   Y  nbtj|dS z>|dkr.tj |¡}
n0|dkrFtj |¡\}}|t t |¡¡ }
n|dkr^tj |¡\}}}|t t |¡¡ }
W n tyk   tdƒ‚w W d  ƒ n	1 sww   Y  | j|	|d d|jd ¡}t |
|j¡}|j}||7 }t|	ƒ|_|S )ae  Returns an array of samples drawn from the multivariate normal
        distribution.

        .. warning::
            This function calls one or more cuSOLVER routine(s) which may yield
            invalid results if input conditions are not met.
            To detect these invalid results, you can set the `linalg`
            configuration to a value that is not `ignore` in
            :func:`cupyx.errstate` or :func:`cupyx.seterr`.

        .. seealso::
            - :func:`cupy.random.multivariate_normal` for full documentation
            - :meth:`numpy.random.RandomState.multivariate_normal`
        z+cupy.random.RandomState.multivariate_normalr   Nr   zmean must be 1 dimensionalr   r   z$cov must be 2 dimensional and squarez"mean and cov must have same length>   Úeighrn   Úsvdz1method must be one of {'eigh', 'svd', 'cholesky'}rm   ÚwarnÚraisez3check_valid must equal 'warn', 'raise', or 'ignore')Úlinalgrn   ro   rp   )ZrtolZatolz?covariance is not positive-semidefinite, output may be invalid.z=covariance is not positive-semidefinite, output *is* invalid.z_Matrix is not positive definite; if matrix is positive-semidefinite, set'check_valid' to 'warn'r=   )r   Zexperimentalr!   r-   r?   r@   rA   Úlenr,   rI   ÚlistÚappendÚcupyxZerrstaters   rn   r   ro   rH   rp   ÚallcloseÚdotÚTÚsqrtÚabsÚwarningsrq   ÚRuntimeWarningÚstandard_normalr%   Útuple)r   ri   Zcovr   Zcheck_validZtolr   r   r,   Zfinal_shapeÚdecompÚsÚuZpsdZvhrM   r   r   r   Úmultivariate_normalB  s¦   
"ÿÿ
ÿþ€þ€í€ÿ€ý€


€ÿ€õÿÿ
zRandomState.multivariate_normalc                 C   sz   t  |¡}t  |¡}t  |dk¡rtdƒ‚t  |dk ¡r tdƒ‚t  |dk¡r+tdƒ‚|  |d| | |¡}| j||dS )aB  Returns an array of samples drawn from the negative binomial distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.negative_binomial` for full documentation
            - :meth:`numpy.random.RandomState.negative_binomial`
        r   zn <= 0zp < 0r   zp > 1r   )r!   r-   rH   rI   rR   Úpoissonr4   r   r   r   Únegative_binomial¢  s   

zRandomState.negative_binomialc                 C   sÌ   ddl m} t|ƒ}|du rt ||¡j}|jdkr|j}n|j}t	|tj
ƒrB|  |||dd¡}tj|||d tj|||d |S t	|tj
ƒr[|  |||d|¡}tj|||d |S |  |||||¡}|S )zÇReturns an array of normally distributed samples.

        .. seealso::
            - :func:`cupy.random.normal` for full documentation
            - :meth:`numpy.random.RandomState.normal`

        r   r	   NrQ   rV   rF   r\   )r   r
   rg   r!   r.   r,   rh   ZgenerateNormalZgenerateNormalDoubler?   ra   r)   r^   r_   )r   rZ   rL   r   r   r
   r&   rM   r   r   r   re   ¸  s$   
ûÿzRandomState.normalc                 C   sN   t  |¡}|du r|j}|  ||¡}t j||d t j| | |d |d S )z×Returns an array of samples drawn from the pareto II distribution.

        .. seealso::
            - :func:`cupy.random.pareto` for full documentation
            - :meth:`numpy.random.RandomState.pareto`
        Nr\   r   )r!   r-   r,   rW   r]   rf   ©r   r/   r   r   rM   r   r   r   ÚparetoÔ  s   
zRandomState.paretoc                 C   sˆ   t  |¡t  |¡}}t  |dk¡rtdƒ‚t  |dk ¡r!tdƒ‚|du r,t  ||¡j}t j||d}t ||| j	|¡ |  
|j¡ |S )aT  Returns an array of samples drawn from the noncentral chi-square
        distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.noncentral_chisquare` for full documentation
            - :meth:`numpy.random.RandomState.noncentral_chisquare`
        r   zdf <= 0únonc < 0Nr+   )r!   r-   rH   rI   r.   r,   r"   r   Znoncentral_chisquare_kernelr   r   r   )r   r:   Únoncr   r   r1   r   r   r   Únoncentral_chisquareã  s   z RandomState.noncentral_chisquarec                 C   s®   t  |¡t  |¡t  |¡}}}t  |dk¡rtdƒ‚t  |dk¡r'tdƒ‚t  |dk ¡r2tdƒ‚|du r>t  |||¡j}t j||d}t |||| j	|¡ |  
|j¡ |S )a3  Returns an array of samples drawn from the noncentral F distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.noncentral_f` for full documentation
            - :meth:`numpy.random.RandomState.noncentral_f`
        r   z
dfnum <= 0z
dfden <= 0r‰   Nr+   )r!   r-   rH   rI   r.   r,   r"   r   Znoncentral_f_kernelr   r   r   )r   rO   rP   rŠ   r   r   r1   r   r   r   Únoncentral_fû  s   ÿzRandomState.noncentral_fc                 C   r8   )z×Returns an array of samples drawn from the poisson distribution.

        .. seealso::
            - :func:`cupy.random.poisson` for full documentation
            - :meth:`numpy.random.RandomState.poisson`
        Nr+   )	r!   r-   r,   r"   r   Zpoisson_kernelr   r   r   )r   Zlamr   r   r1   r   r   r   r…     r<   zRandomState.poissonc                 C   sv   t  |¡}t  |dk ¡rtdƒ‚|du r|j}| j||d}t j| |d t jd| |d t j|d| |d |S )a  Returns an array of samples drawn from the power distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.power` for full documentation
            - :meth:`numpy.random.RandomState.power`
        r   úa < 0N©r   r   r\   r   rF   )	r!   r-   rH   rI   r,   rJ   rf   r_   Úpowerr‡   r   r   r   r   $  s   
zRandomState.powerc                 O   ó4   |  dt¡}|rtdd | ¡ ¡ ƒ‚| j||dS )zÍReturns uniform random values over the interval ``[0, 1)``.

        .. seealso::
            - :func:`cupy.random.rand` for full documentation
            - :meth:`numpy.random.RandomState.rand`

        r   z*rand() got unexpected keyword arguments %sú, rŽ   )ÚpopÚfloatÚ	TypeErrorÚjoinÚkeysÚrandom_sample©r   r   Úkwargr   r   r   r   Úrand:  ó   ÿzRandomState.randc                 O   r   )zÆReturns an array of standard normal random values.

        .. seealso::
            - :func:`cupy.random.randn` for full documentation
            - :meth:`numpy.random.RandomState.randn`

        r   z+randn() got unexpected keyword arguments %sr‘   rŽ   )r’   r“   r”   r•   r–   re   r˜   r   r   r   ÚrandnH  r›   zRandomState.randnÚ zT xzx = (x == (T)1) ? 0 : xZcupy_random_x_mod_1c                 C   sR   ddl m} t|ƒ}tj||d}|jdkr|j}n|j}|| j|j	j
|jƒ |S )Nr   r	   r   rQ   )r   r
   rg   r!   r"   rh   ZgenerateUniformZgenerateUniformDoubler   r#   r$   r   )r   r   r   r
   r(   r&   r   r   r   rW   Y  s   
zRandomState._random_sample_rawc                 C   s&   |du rd}|   ||¡}t |¡ |S )zãReturns an array of random values over the interval ``[0, 1)``.

        .. seealso::
            - :func:`cupy.random.random_sample` for full documentation
            - :meth:`numpy.random.RandomState.random_sample`

        Nr   )rW   r   Ú_mod1_kernel)r   r   r   r(   r   r   r   r—   e  s
   
zRandomState.random_samplec                 C   sz   t  |¡}|du r|j}t  |dk ¡rtdƒ‚|  ||¡}t j||d}t j|d|d}t j||d}t j|||d}|S )a%  Returns an array of samples drawn from a rayleigh distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.rayleigh` for full documentation
            - :meth:`numpy.random.RandomState.rayleigh`
        Nr   rG   r\   g       À)	r!   r-   r,   rH   rI   rW   r]   r^   r{   rK   r   r   r   Úrayleighs  s   
zRandomState.rayleighzT max, T mxzT outz3out = max - (mx != max ? (max - mx) % (mx + 1) : 0)Z cupy_random_interval_upper_limitzT samplez$if (mx != max) { sample %= mx + 1; }Z"cupy_random_interval_sample_moduloc                 C   s¾  |du rd}nt |tƒr|f}t |¡}|rX|dkr"tj|tjdS |dk r-td |¡ƒ‚|t	kr?tj}|t	d|d   ƒ}nY|t
krQtj}|t
d|d   ƒ}nGtd	 |¡ƒ‚|j}|tjkse|tjkrvtj}|j|d
d}|  t	|¡}n"|tjks€|tjkr‘tj}|j|d
d}|  t
|¡}ntd |¡ƒ‚t tj|d¡}|dkr«tj||dS |  ||¡}|rÒ|d }|d| ¡ d > krÒd| ¡ > d }	||	M }| |¡S |  ||d
¡}
|
j}|dkrét |¡sé||
 }|dkr=|r÷t|d dƒn|j}|  ||¡}|  ||d¡}|j}||kr||d|…  ||
< d}n|| ||
d|… < |
|d… }
|s5||d… }||8 }|dksî|rE||; }n|tjkrS|  t	||¡}n|  t
||¡}| |¡S )a`  Generate multiple integers independently sampled uniformly from ``[0, mx]``.

        Args:
            mx (int): Upper bound of the interval
            size (None or int or tuple): Shape of the array or the scalar
                returned.
        Returns:
            int or cupy.ndarray: If ``None``, an :class:`cupy.ndarray` with
            shape ``()`` is returned.
            If ``int``, 1-D array of length size is returned.
            If ``tuple``, multi-dimensional array with shape
            ``size`` is returned.
            Currently, only 32 bit or 64 bit integers can be sampled.
        Nr   r   r   z$mx must be non-negative (actual: {})ì        r   ì            z+mx must be within uint64 range (actual: {})F©Úcopyzdtype must be integer, got: {}r   i   T)r?   r@   ÚnumpyÚisscalarr!   ZzerosÚuint32rI   ÚformatÚ_UINT32_MAXr   Úuint64r   Úint32ÚastypeÚ_interval_upper_limitÚint64Ú	functoolsÚreduceÚoperatorÚmulr"   Ú_curand_generateÚ
bit_lengthr%   Ú_get_indicesr   ÚmaxÚ_interval_sample_modulo)r   Zmxr   Zis_mx_scalarr   Úupper_limitZn_sampleÚsampleZmx1ÚmaskZ
ng_indicesZn_ngZn_supplementZ
supplementZ
ok_indicesZn_okr   r   r   Ú	_interval”  sŒ   

ÿÿÿ

ÿÿ
î

zRandomState._intervalc                 C   sD   ddl m} tj|f|d}|jtjdj}| | j	|j
j|¡ |S )Nr   r	   r   )r   r
   r!   r"   Úviewr¤   r¦   r   Úgenerater   r#   r$   )r   Únumr   r
   r¸   Zsize32r   r   r   r²   ÷  s
   zRandomState._curand_generatec                 C   sh   |j dk rtjntj}|r||kn||k}tj||d}~tjt|d ƒf|d}| j|||j d |S )Nr    r   r=   ©r   )	r   r¤   r¦   r©   r!   Zcumsumr"   r@   Ú_kernel_get_indices)r   r¸   r·   Zcondr   ÚflagsZcsumÚindicesr   r   r   r´      s   zRandomState._get_indicesz
raw U csumzraw U indiceszo
        int j = 0;
        if (i > 0) { j = csum[i-1]; }
        if (csum[i] > j) { indices[j] = i; }
        Zcupy_get_indicesc                 C   sú   ddl m} |du r+zt t d¡¡}t|dƒ}W nG ty*   t ¡ d t	 }Y n7w t
|tjƒrBttj|dd ¡ dd… dƒ}nt |¡}|jjd	vrQtd
ƒ‚t|ƒ}|dk s]|dkratdƒ‚| | j|¡ | j|j|jfvrx| | jd¡ || _dS )zÎResets the state of the random number generator with a seed.

        .. seealso::
            - :func:`cupy.random.seed` for full documentation
            - :meth:`numpy.random.RandomState.seed`

        r   r	   Né   é   i@B F)ÚusedforsecurityZbiuzSeed must be an integer.r¡   z/Seed must be an integer between 0 and 2**64 - 1)r   r
   ÚbinasciiÚhexlifyÚosÚurandomr@   ÚNotImplementedErrorÚtimer   r?   r¤   ra   ÚhashlibÚmd5Ú	hexdigestr-   r   Úkindr”   rI   ZsetPseudoRandomGeneratorSeedr   r   ZCURAND_RNG_PSEUDO_MT19937ZCURAND_RNG_PSEUDO_MTGP32ZsetGeneratorOffsetr   )r   r   r
   Zseed_strZseed_arrr   r   r   r     s<   ÿÿ
ÿÿ
ÿÿ
zRandomState.seedc                 C   s"   | j ||d}t tj|d  ¡S )zïReturns an array of samples drawn from the standard cauchy distribution.

        .. seealso::
            - :func:`cupy.random.standard_cauchy` for full documentation
            - :meth:`numpy.random.RandomState.standard_cauchy`
        rŽ   g      à?)Úuniformr!   ÚtanÚpi©r   r   r   rM   r   r   r   Ústandard_cauchy7  s   zRandomState.standard_cauchyc                 C   s(   |du rd}|   ||¡}tj||d S )z÷Returns an array of samples drawn from the standard exp distribution.

         .. seealso::
            - :func:`cupy.random.standard_exponential` for full documentation
            - :meth:`numpy.random.RandomState.standard_exponential`
        Nr   r\   )rW   r!   r]   rÒ   r   r   r   rJ   A  s   z RandomState.standard_exponentialc                 C   r8   )zêReturns an array of samples drawn from a standard gamma distribution.

        .. seealso::
            - :func:`cupy.random.standard_gamma` for full documentation
            - :meth:`numpy.random.RandomState.standard_gamma`
        Nr+   )	r!   r-   r,   r"   r   rB   r   r   r   )r   r,   r   r   r1   r   r   r   Ústandard_gammaM  r<   zRandomState.standard_gammac                 C   s   | j ||dS )zäReturns samples drawn from the standard normal distribution.

        .. seealso::
            - :func:`cupy.random.standard_normal` for full documentation
            - :meth:`numpy.random.RandomState.standard_normal`

        rŽ   )re   )r   r   r   r   r   r   r   \  s   zRandomState.standard_normalc                 C   r8   )zàReturns an array of samples drawn from the standard t distribution.

        .. seealso::
            - :func:`cupy.random.standard_t` for full documentation
            - :meth:`numpy.random.RandomState.standard_t`
        Nr+   )	r!   r-   r,   r"   r   Zstandard_t_kernelr   r   r   r9   r   r   r   Ú
standard_tf  r<   zRandomState.standard_tc                 C   sd   ddl m} |du rd}tj|tjd}|jjd }| | j|j	j
|j| ¡ |t tj¡jM }|S )aî  Draws integers between 0 and max integer inclusive.

        Return a sample of uniformly distributed random integers in the
        interval [0, ``np.iinfo(np.int_).max``]. The `np.int_` type translates
        to the C long integer type and its precision is platform dependent.

        Args:
            size (int or tuple of ints): Output shape.

        Returns:
            cupy.ndarray: Drawn samples.

        .. seealso::
            :meth:`numpy.random.RandomState.tomaxint`

        r   r	   Nr   r   é   )r   r
   r!   r"   Úint_r   Úitemsizer¼   r   r#   r$   r   Úiinforµ   )r   r   r
   r¸   Zsize_in_intr   r   r   Útomaxintu  s   ÿzRandomState.tomaxintzL left, M mode, R righta  
        T base, leftbase, ratio, leftprod, rightprod;

        base = right - left;
        leftbase = mode - left;
        ratio = leftbase / base;
        leftprod = leftbase*base;
        rightprod = (right - mode)*base;

        if (x <= ratio)
        {
            x = left + sqrt(x*leftprod);
        } else
        {
            x = right - sqrt((1.0 - x) * rightprod);
        }
        Zcupy_triangular_kernelc                 C   sš   t  |¡t  |¡t  |¡}}}t  ||k¡rtdƒ‚t  ||k¡r'tdƒ‚t  ||k¡r2tdƒ‚|du r>t  |||¡j}| j||d}t ||||¡S )a-  Returns an array of samples drawn from the triangular distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.triangular` for full documentation
            - :meth:`numpy.random.RandomState.triangular`
        zleft > modezmode > rightzleft == rightNrŽ   )	r!   r-   rH   rI   r.   r,   r—   r   Ú_triangular_kernel)r   ÚleftÚmodeÚrightr   r   rM   r   r   r   Ú
triangularª  s   ÿzRandomState.triangularzT low, T highzx = T(low) + x * T(high - low)Z
cupy_scalec                 C   sh   t  |¡st ||¡}t  |¡st ||¡}|du r!t ||¡j}t  |¡}| j||d}t 	|||¡S )zÛReturns an array of uniformly-distributed samples over an interval.

        .. seealso::
            - :func:`cupy.random.uniform` for full documentation
            - :meth:`numpy.random.RandomState.uniform`

        NrŽ   )
r¤   r¥   r!   r-   r.   r,   r   r—   r   Ú_scale_kernel)r   ÚlowÚhighr   r   rš   r   r   r   rÏ   Ç  s   


zRandomState.uniformc                 C   r*   )zÛReturns an array of samples drawn from the von Mises distribution.

        .. seealso::
            - :func:`cupy.random.vonmises` for full documentation
            - :meth:`numpy.random.RandomState.vonmises`
        Nr+   )
r!   r-   r.   r,   r"   r   Zvonmises_kernelr   r   r   )r   ÚmuÚkappar   r   r1   r   r   r   ÚvonmisesÛ  r3   zRandomState.vonmiseszT mean, T scale, T UzT Xa	  
            T mu_2l;
            T Y;
            mu_2l = mean / (2*scale);
            Y = mean*X*X;
            X = mean + mu_2l*(Y - sqrt(4*scale*Y + Y*Y));
            if (U > mean/(mean+X))
            {
                X = mean*mean/X;
            }
        Zcupy_wald_scalec                 C   s`   t j||dt j||d}}|du rt  ||¡j}| j||d}| j||d}t ||||¡S )zÏReturns an array of samples drawn from the Wald distribution.

         .. seealso::
            - :func:`cupy.random.wald` for full documentation
            - :meth:`numpy.random.RandomState.wald`
        r   NrŽ   )r!   r-   r.   r,   re   r—   r   Ú_wald_kernel)r   ri   rL   r   r   rM   rƒ   r   r   r   Úwaldù  s   ÿzRandomState.waldc                 C   sR   t  |¡}t  |dk ¡rtdƒ‚|du r|j}|  ||¡}t j|d| |d |S )a$  Returns an array of samples drawn from the weibull distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.weibull` for full documentation
            - :meth:`numpy.random.RandomState.weibull`
        r   r   NrF   r\   )r!   r-   rH   rI   r,   rJ   r   r‡   r   r   r   Úweibull  s   
zRandomState.weibullc                 C   s\   t  |¡}t  |dk¡rtdƒ‚|du r|j}t j||d}t || j|¡ |  	|j
¡ |S )a  Returns an array of samples drawn from the Zipf distribution.

        .. warning::

            This function may synchronize the device.

        .. seealso::
            - :func:`cupy.random.zipf` for full documentation
            - :meth:`numpy.random.RandomState.zipf`
        rF   z'a' must be a valid float > 1.0Nr+   )r!   r-   rH   rI   r,   r"   r   Zzipf_kernelr   r   r   )r   r/   r   r   r1   r   r   r   Úzipf  s   
zRandomState.zipfTc           
      C   s0  |du rt dƒ‚t|tjƒr|jdkrt‚t|tƒr%|}|dk r$t dƒ‚ntj|dd}|jdkr5t dƒ‚t|ƒ}|durpt |¡}|jdkrKt dƒ‚t|ƒ|krUt d	ƒ‚|dk 	¡ s_t d
ƒ‚t 
|¡ ¡ }t |d¡spt dƒ‚|du rxtdƒ‚|}t |¡}|dkr‹|dkr‹t dƒ‚|s¸|du r¸||k r™t dƒ‚t|tƒr¦tj|dd}n| ¡ }|  |¡ |d|…  |¡S |s¼t‚|duræt |||f¡}tjt |¡| j||fd dd}	t|tƒsåt |	|¡}	n|dkrìd}| jd||d}	|	jtjdd}	t|tƒr|	S |	jdkrtj||	 |jdS ||	 S )zÃReturns an array of random values from a given 1-D array.

        .. seealso::
            - :func:`cupy.random.choice` for full documentation
            - :meth:`numpy.random.choice`

        Nz%a must be 1-dimensional or an integerr   z$a must be greater than or equal to 0Fr¢   r   zp must be 1-dimensionalza and p must have same sizez"probabilities are not non-negativezprobabilities do not sum to 1z5choice() without specifying size is not supported yetz-a cannot be empty unless no samples are takenz@Cannot take a larger sample than population when 'replace=False'Úlr   r¾   )r>   )rI   r?   r!   ra   ÚndimrÉ   r@   Úarrayrt   ÚallrC   Úgetr¤   rx   r    Zaranger£   Úshuffler%   Zbroadcast_toZargmaxr]   ÚgumbelÚrandintr«   r­   r   )
r   r/   r   Úreplacer6   Za_sizeZp_sumr,   rÁ   Úindexr   r   r   Úchoice3  s~   
ÿ


ÿ
ÿ

ÿþ
€zRandomState.choicec                 C   sD   t |tjƒs
tdƒ‚|jdkrtdƒ‚||  t|ƒ¡ |dd…< dS )z¥Returns a shuffled array.

        .. seealso::
            - :func:`cupy.random.shuffle` for full documentation
            - :meth:`numpy.random.shuffle`

        zThe array must be cupy.ndarrayr   z)An array whose ndim is 0 is not supportedN)r?   r!   ra   r”   rë   Ú_permutationrt   ©r   r/   r   r   r   rï   ƒ  s
   
zRandomState.shufflec                 C   s&   t |tƒr
|  |¡S ||  t|ƒ¡ S )z6Returns a permuted range or a permutation of an array.)r?   r@   rõ   rt   rö   r   r   r   Úpermutation“  s   

zRandomState.permutationc                 C   s@   ddl m} tj|ftjd}| | j|jj	|¡ t 
|¡}|S )zReturns a permuted range.r   r	   r   )r   r
   r!   r"   r¤   rª   r¼   r   r#   r$   Zargsort)r   r½   r
   r¸   rì   r   r   r   rõ   š  s
   
zRandomState._permutationz$y = T(loc) - log(-log(x)) * T(scale)Zcupy_gumbel_kernelc                 C   sd   t  |¡st ||¡}t  |¡st ||¡}|du r!t ||¡j}| j||d}t ||||¡ |S )zÒReturns an array of samples drawn from a Gumbel distribution.

        .. seealso::
            - :func:`cupy.random.gumbel` for full documentation
            - :meth:`numpy.random.RandomState.gumbel`
        NrŽ   )	r¤   r¥   r!   r-   r.   r,   rW   r   Ú_gumbel_kernelrY   r   r   r   rð   ¨  s   

zRandomState.gumbelc                 C   st  t  |¡s\t |¡}|du rt |¡}|d }n	|}t |¡d }|du r,t ||¡j}|| }t t	j
|d¡}|  | ¡ |¡}	|	 |¡}	t |	|¡}	|j|dd}tj|	||	d |	S |du rid}t|ƒd }
n
t|ƒ}t|ƒd }
||
kr{tdƒ‚|t |¡jk rŽtd t |¡j¡ƒ‚|
t |¡jkr¡td	 t |¡j¡ƒ‚|
| }|  ||¡j|dd}tj|||d |S )
zÛReturns a scalar or an array of integer values over ``[low, high)``.

        .. seealso::
            - :func:`cupy.random.randint` for full documentation
            - :meth:`numpy.random.RandomState.randint`
        Nr   Fr¢   r\   r   zlow >= highzlow is out of bounds for {}zhigh is out of bounds for {})r¤   r¥   r!   r-   Z
zeros_liker.   r,   r®   r¯   r°   r±   rº   Úflattenr«   r%   r_   r@   rI   rÙ   Úminr§   r   Únamerµ   )r   rá   râ   r   r   ÚloÚhiÚdiffZtotal_elemsr(   Zhi1rM   r   r   r   rñ   ¹  sP   





ÿÿ
ÿÿzRandomState.randint)NNr   )NTN)DÚ__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r)   r“   r2   r@   r7   r;   rE   rN   rQ   rR   rT   rU   r   ZElementwiseKernelrX   r[   r`   rk   rl   r„   r†   re   rˆ   r‹   rŒ   r…   r   rš   rœ   rž   rW   r—   rŸ   r¬   r¶   rº   r²   r´   r¿   r   rÓ   rJ   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      sÄ    
ý
ÿ`ÿýýc		ù
	%


íýó
P	ýr   c                 C   s   t ƒ  | ¡ dS )a÷  Resets the state of the random number generator with a seed.

    This function resets the state of the global random number generator for
    the current device. Be careful that generators for other devices are not
    affected.

    Args:
        seed (None or int): Seed for the random number generator. If ``None``,
            it uses :func:`os.urandom` if available or :func:`time.time`
            otherwise. Note that this function does not support seeding by
            an integer array.

    N)Úget_random_stater   )r   r   r   r   r   í  s   r   c                   C   s   i a d S r   )Ú_random_statesr   r   r   r   Úreset_states  s   r  c                  C   sX   t  ¡ } t | jd¡}|du r*t d¡}|durt t	|ƒ¡}t
|ƒ}t | j|¡}|S )aX  Gets the state of the random number generator for the current device.

    If the state for the current device is not created yet, this function
    creates a new one, initializes it, and stores it as the state for the
    current device.

    Returns:
        RandomState: The state of the random number generator for the
        device.

    NZ	CUPY_SEED)r   ZDevicer  rî   ÚidrÇ   Úgetenvr¤   r©   r@   r   Ú
setdefault)ÚdevÚrsr   r   r   r   r  	  s   
r  c                 C   s,   t | tƒstd t| ƒ¡ƒ‚| tt ¡ < dS )zSets the state of the random number generator for the current device.

    Args:
        state(RandomState): Random state to set for the current device.
    z;Random state must be an instance of RandomState. Actual: {}N)r?   r   r”   r§   Útyper  r   Zget_device_id)r
  r   r   r   Úset_random_state   s   

þr  c                 C   s    t  | ¡} | jdvrtdƒ‚| S )N)rQ   Údz-cupy.random only supports float32 and float64)r¤   r   rh   r”   r   r   r   r   rg   -  s   

rg   r   ) ÚatexitrÅ   r®   rË   r°   rÇ   rÊ   r   r¤   r}   Znumpy.linalgr   r!   r   r   Z	cupy.cudar   Zcupy.randomr   r   rw   r¨   r   Úobjectr   r   r  Úregisterr  r  r  rg   r   r   r   r   Ú<module>   sJ             
Z
