o
    Nrf                     @  s  U d dl mZ d dlZd dlZd dlZd dlmZmZ d dlmZ d dl	m
Z
 d dlmZ d dl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 d d
lmZ d dlmZ d dlmZ d dl m!Z!m"Z"m#Z# G dd dZ$dTddZ%G dd dZ&dd Z'dUddZ(dd Z)dd Z*dd Z+dd Z,d d! Z-d"d# Z.dd$d%d&d'd(Z/	 i Z0d)e1d*< e Z2d+d, Z3	 e3d-Z4e3d.Z5e3d/Z6e3d0Z7e3d1Z8e3d2Z9e3d3Z:e3d4Z;e3d5Z<e3d6Z=e3d7Z>e3d8Z?e3d9Z@e3d:ZAe3d;ZBe3d<ZCe3d=ZDe3d>ZEe3d?ZFe3d@ZGe3dAZHe3dBZIe3dCZJe3dDZKe3dEZLe3dEZMe3dFZNe3dGZOe3dHZPe3dIZQe3dJZRe3dKZSe3dLZTe3dMZUe3dNZVe3dOZWe3dPZXe3dQZYe3dRZZe3dSZ[dS )V    )annotationsN)chainproduct)Integral)getitem)Lock)array_creation_dispatch)Arrayasarraybroadcast_shapesbroadcast_tonormalize_chunksslices_from_chunks)arange)asarray_safe)tokenize)HighLevelGraph)derived_fromrandom_state_datatypenamec                   @  s6  e Zd ZdZdd Zdd Zedd Zedd	 Ze	e
jjd
dd`ddZe	e
jjd
dd`ddZe	e
jjd
dd`ddZe	e
jjd
d						daddZe	e
jjd
ddbddZe	e
jjd
dd`ddZe	e
jjd
ddbddZe	e
jjd
dd`dd Ze	e
jjd
ddcd"d#Ze	e
jjd
dd`d$d%Ze	e
jjd
ddde
jd&dfd'd(Ze	e
jjd
ddcd)d*Ze	e
jjd
ddcd+d,Ze	e
jjd
ddcd-d.Ze	e
jjd
dd`d/d0Ze	e
jjd
dd`d1d2Ze	e
jjd
d	ddd4d5Ze	e
jjd
dd`d6d7Ze	e
jjd
dd`d8d9Z e	e
jjd
dd`d:d;Z!e	e
jjd
ddcd<d=Z"e	e
jjd
dd`d>d?Z#e	e
jjd
dd@dA Z$e	e
jjd
ddbdBdCZ%e	e
jjd
dd`dDdEZ&e	e
jjd
dde
j'ddfdFdGZe	e
jjd
ddbdHdIZ(e	e
jjd
dd`dJdKZ)e	e
jjd
dd`dLdMZ*e	e
jjd
dd`dNdOZ+e	e
jjd
dd`dPdQZ,e	e
jjd
dd`dRdSZ-e	e
jjd
dd`dTdUZ.e	e
jjd
ddcdVdWZ/e	e
jjd
dd`dXdYZ0e	e
jjd
dd`dZd[Z1e	e
jjd
dd`d\d]Z2e	e
jjd
dd`d^d_Z3dS )e	Generatora
  
    Container for the BitGenerators.

    ``Generator`` exposes a number of methods for generating random
    numbers drawn from a variety of probability distributions and serves
    as a replacement for ``RandomState``. The main difference between the
    two is that ``Generator`` relies on an additional ``BitGenerator`` to
    manage state and generate the random bits, which are then transformed
    into random values from useful distributions. The default ``BitGenerator``
    used by ``Generator`` is ``PCG64``. The ``BitGenerator`` can be changed
    by passing an instantiated ``BitGenerator`` to ``Generator``.

    The function :func:`dask.array.random.default_rng` is the recommended way
    to instantiate a ``Generator``.

    .. warning::

       No Compatibility Guarantee.

       ``Generator`` does not provide a version compatibility guarantee. In
       particular, as better algorithms evolve the bit stream may change.

    Parameters
    ----------
    bit_generator : BitGenerator
        BitGenerator to use as the core generator.

    Notes
    -----
    In addition to the distribution-specific arguments, each ``Generator``
    method takes a keyword argument `size` that defaults to ``None``. If
    `size` is ``None``, then a single value is generated and returned. If
    `size` is an integer, then a 1-D array filled with generated values is
    returned. If `size` is a tuple, then an array with that shape is
    filled and returned.

    The Python stdlib module `random` contains pseudo-random number generator
    with a number of methods that are similar to the ones available in
    ``Generator``. It uses Mersenne Twister, and this bit generator can
    be accessed using ``MT19937``. ``Generator``, besides being
    Dask-aware, has the advantage that it provides a much larger number
    of probability distributions to choose from.

    All ``Generator`` methods are identical to ``np.random.Generator`` except
    that they also take a `chunks=` keyword argument.

    ``Generator`` does not guarantee parity in the generated numbers
    with any third party library. In particular, numbers generated by
    `Dask` and `NumPy` will differ even if they use the same seed.

    Examples
    --------
    >>> from numpy.random import PCG64
    >>> from dask.array.random import Generator
    >>> rng = Generator(PCG64())
    >>> rng.standard_normal().compute() # doctest: +SKIP
    array(0.44595957)  # random

    See Also
    --------
    default_rng : Recommended constructor for `Generator`.
    np.random.Generator
    c                 C  s
   || _ d S N)_bit_generator)selfbit_generator r   Z/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/dask/array/random.py__init__^   s   
zGenerator.__init__c                 C  s"   | j j}|d| jj j d 7 }|S )N())	__class____name__r   )r   _strr   r   r   __str__a   s   zGenerator.__str__c                 C  s   t | jdd S N.r   )r   r   splitr   r   r   r   _backend_namef   s   zGenerator._backend_namec                 C  s   t | jS r   )	importlibimport_moduler(   r'   r   r   r   _backendl   s   zGenerator._backend   Z
skipblocksNautoc                 K     t | d||f||d|S Nbetasizechunks
_wrap_funcr   abr3   r4   kwargsr   r   r   r1   r      zGenerator.betac                 K  r/   Nbinomialr2   r5   r   npr3   r4   r:   r   r   r   r=   v   r;   zGenerator.binomialc                 K     t | d|f||d|S N	chisquarer2   r5   r   dfr3   r4   r:   r   r   r   rC   z      zGenerator.chisquareTr   c              
     s   t |  ||\ }}}}	tt| }
t| jt|
}dt|||  }t|ggdd |D R  } fddt|||
D }tj	|||	d}t
||||dS )Nda.random.choice-%sc                 s      | ]	}t t|V  qd S r   rangelen.0Zbdr   r   r   	<genexpr>       z#Generator.choice.<locals>.<genexpr>c                   s(   i | ]\}}}|t | |fqS r   )_choice_rng)rM   kbitgenr3   r8   axisr@   replaceshuffler   r   
<dictcomp>   s    z$Generator.choice.<locals>.<dictcomp>dependenciesmeta)_choice_validate_paramslistr   _spawn_bitgensr   rK   r   zipr   from_collectionsr	   )r   r8   r3   rU   r@   rT   rV   r4   r[   rY   sizesbitgensnamekeysdskgraphr   rS   r   choice~   s*   
zGenerator.choice      ?c                 K  rA   Nexponentialr2   r5   r   scaler3   r4   r:   r   r   r   rj         zGenerator.exponentialc                 K  r/   Nfr2   r5   r   dfnumdfdenr3   r4   r:   r   r   r   ro      r;   zGenerator.fc                 K  r/   Ngammar2   r5   r   shaperl   r3   r4   r:   r   r   r   rt         zGenerator.gammac                 K  rA   N	geometricr2   r5   r   r@   r3   r4   r:   r   r   r   ry      rF   zGenerator.geometric        c                 K  r/   Ngumbelr2   r5   r   locrl   r3   r4   r:   r   r   r   r}      rw   zGenerator.gumbelc                 K     t | d|||f||d|S Nhypergeometricr2   r5   r   ZngoodZnbadnsampler3   r4   r:   r   r   r   r         zGenerator.hypergeometricFc                 K  s    t | d|f|||||d|S )Nintegers)highr3   dtypeendpointr4   r5   )r   lowr   r3   r   r   r4   r:   r   r   r   r      s   	zGenerator.integersc                 K  r/   Nlaplacer2   r5   r~   r   r   r   r      rw   zGenerator.laplacec                 K  r/   Nlogisticr2   r5   r~   r   r   r   r      rw   zGenerator.logisticc                 K  r/   N	lognormalr2   r5   r   meansigmar3   r4   r:   r   r   r   r      rw   zGenerator.lognormalc                 K  rA   N	logseriesr2   r5   rz   r   r   r   r      rF   zGenerator.logseriesc                 K  &   t | d||f||t|ffd|S Nmultinomialr3   r4   extra_chunksr6   rK   r   r?   Zpvalsr3   r4   r:   r   r   r   r         
zGenerator.multinomial	marginalsc                 K     t | d||f|||d|S )Nmultivariate_hypergeometric)r3   methodr4   r5   )r   colorsr   r3   r   r4   r:   r   r   r   r     s   z%Generator.multivariate_hypergeometricc                 K  r/   Nnegative_binomialr2   r5   r>   r   r   r   r     rw   zGenerator.negative_binomialc                 K  r/   Nnoncentral_chisquarer2   r5   r   rE   noncr3   r4   r:   r   r   r   r     rw   zGenerator.noncentral_chisquarec                 K  r   Nnoncentral_fr2   r5   r   rq   rr   r   r3   r4   r:   r   r   r   r        
zGenerator.noncentral_fc                 K  r/   Nnormalr2   r5   r~   r   r   r   r   %  rw   zGenerator.normalc                 K  rA   Nparetor2   r5   r   r8   r3   r4   r:   r   r   r   r   +  rF   zGenerator.paretoc                 C  s\   ddl m} | jdkrtdt|tjrt|dd}| jt	|}t
| j| |||S )Nr   shuffle_slicecupyz`Generator.permutation` not supported for cupy-backed Generator objects. Use the 'numpy' array backend to call `dask.array.random.default_rng`, or pass in  `numpy.random.PCG64()`.r.   r4   )dask.array.slicingr   r(   NotImplementedError
isinstancenumbersNumberr   r+   rK   _shuffler   r   xr   indexr   r   r   permutation/  s   

zGenerator.permutationc                 K  rA   Npoissonr2   r5   r   Zlamr3   r4   r:   r   r   r   r   B  rF   zGenerator.poissonc                 K  rA   Npowerr2   r5   r   r   r   r   r   F  rF   zGenerator.powerc                 K  s   t | df||||d|S )Nrandom)r3   r   outr4   r5   )r   r3   r   r   r4   r:   r   r   r   r   J  s   zGenerator.randomc                 K  rA   Nrayleighr2   r5   rk   r   r   r   r   P  rF   zGenerator.rayleighc                 K     t | df||d|S Nstandard_cauchyr2   r5   r   r3   r4   r:   r   r   r   r   T     zGenerator.standard_cauchyc                 K  r   Nstandard_exponentialr2   r5   r   r   r   r   r   X     zGenerator.standard_exponentialc                 K  rA   Nstandard_gammar2   r5   r   rv   r3   r4   r:   r   r   r   r   ^  rm   zGenerator.standard_gammac                 K  r   Nstandard_normalr2   r5   r   r   r   r   r   d  r   zGenerator.standard_normalc                 K  rA   N
standard_tr2   r5   rD   r   r   r   r   h  rF   zGenerator.standard_tc                 K  r   N
triangularr2   r5   r   leftmoderightr3   r4   r:   r   r   r   r   l  r   zGenerator.triangularc                 K  r/   Nuniformr2   r5   r   r   r   r3   r4   r:   r   r   r   r   r  rw   zGenerator.uniformc                 K  r/   Nvonmisesr2   r5   r   mukappar3   r4   r:   r   r   r   r   x  rw   zGenerator.vonmisesc                 K  r/   Nwaldr2   r5   r   r   rl   r3   r4   r:   r   r   r   r   ~  r;   zGenerator.waldc                 K  rA   Nweibullr2   r5   r   r   r   r   r     rF   zGenerator.weibullc                 K  rA   Nzipfr2   r5   r   r   r   r   r     rF   zGenerator.zipfNr.   )NTNr   Tr.   rh   Nr.   r{   rh   Nr.   )Nr   r.   )4r!   
__module____qualname____doc__r   r#   propertyr(   r+   r   npr   r   r1   r=   rC   rg   rj   ro   rt   ry   r}   r   Zint64r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   float64r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r      s    @

$
r   c                 C  sB   t | dr	t| S t| tr| S t | drt| jS tt| S )af
  
    Construct a new Generator with the default BitGenerator (PCG64).

    Parameters
    ----------
    seed : {None, int, array_like[ints], SeedSequence, BitGenerator, Generator}, optional
        A seed to initialize the `BitGenerator`. If None, then fresh,
        unpredictable entropy will be pulled from the OS. If an ``int`` or
        ``array_like[ints]`` is passed, then it will be passed to
        `SeedSequence` to derive the initial `BitGenerator` state. One may
        also pass in a `SeedSequence` instance.
        Additionally, when passed a `BitGenerator`, it will be wrapped by
        `Generator`. If passed a `Generator`, it will be returned unaltered.

    Returns
    -------
    Generator
        The initialized generator object.

    Notes
    -----
    If ``seed`` is not a `BitGenerator` or a `Generator`, a new
    `BitGenerator` is instantiated. This function does not manage a default
    global instance.

    Examples
    --------
    ``default_rng`` is the recommended constructor for the random number
    class ``Generator``. Here are several ways we can construct a random
    number generator using ``default_rng`` and the ``Generator`` class.

    Here we use ``default_rng`` to generate a random float:

    >>> import dask.array as da
    >>> rng = da.random.default_rng(12345)
    >>> print(rng)
    Generator(PCG64)
    >>> rfloat = rng.random().compute()
    >>> rfloat
    array(0.86999885)
    >>> type(rfloat)
    <class 'numpy.ndarray'>

    Here we use ``default_rng`` to generate 3 random integers between 0
    (inclusive) and 10 (exclusive):

    >>> import dask.array as da
    >>> rng = da.random.default_rng(12345)
    >>> rints = rng.integers(low=0, high=10, size=3).compute()
    >>> rints
    array([2, 8, 7])
    >>> type(rints[0])
    <class 'numpy.int64'>

    Here we specify a seed so that we have reproducible results:

    >>> import dask.array as da
    >>> rng = da.random.default_rng(seed=42)
    >>> print(rng)
    Generator(PCG64)
    >>> arr1 = rng.random((3, 3)).compute()
    >>> arr1
    array([[0.91674416, 0.91098667, 0.8765925 ],
           [0.30931841, 0.95465607, 0.17509458],
           [0.99662814, 0.75203348, 0.15038118]])

    If we exit and restart our Python interpreter, we'll see that we
    generate the same random numbers again:

    >>> import dask.array as da
    >>> rng = da.random.default_rng(seed=42)
    >>> arr2 = rng.random((3, 3)).compute()
    >>> arr2
    array([[0.91674416, 0.91098667, 0.8765925 ],
           [0.30931841, 0.95465607, 0.17509458],
           [0.99662814, 0.75203348, 0.15038118]])

    See Also
    --------
    np.random.default_rng
    Zcapsuler   )hasattrr   r   r   r   Zdefault_bit_generator)seedr   r   r   default_rng  s   
R


r   c                   @  sR  e Zd ZdZd^ddZedd Zd_ddZee	j
jd	d
d`ddZee	j
jd	d
d`ddZee	j
jd	d
d`ddZee ee	j
jd	d
daddZW d   n1 sZw   Y  ee	j
jd	d
dbddZee	j
jd	d
d`ddZee	j
jd	d
dbddZee	j
jd	d
d`ddZee	j
jd	d
dcdd Zee	j
jd	d
d`d!d"Zee	j
jd	d
dcd#d$Zee	j
jd	d
dcd%d&Zee	j
jd	d
dcd'd(Zee	j
jd	d
d`d)d*Zee	j
jd	d
d`d+d,Zee	j
jd	d
d`d-d.Zee	j
jd	d
d`d/d0Zee	j
jd	d
d`d1d2Z ee	j
jd	d
dcd3d4Z!ee	j
jd	d
d`d5d6Z"ee	j
jd	d
d7d8 Z#ee	j
jd	d
dbd9d:Z$ee	j
jd	d
d`d;d<Z%ee	j
jd	d
ddd>d?Z&ee	j
jd	d
ded@dAZ'ee	j
jd	d
d`dBdCZ(e(Z
ee	j
jd	d
dbdDdEZ)ee	j
jd	d
d`dFdGZ*ee	j
jd	d
d`dHdIZ+ee	j
jd	d
d`dJdKZ,ee	j
jd	d
d`dLdMZ-ee	j
jd	d
d`dNdOZ.ee	j
jd	d
d`dPdQZ/ee	j
jd	d
d`dRdSZ0ee	j
jd	d
dcdTdUZ1ee	j
jd	d
d`dVdWZ2ee	j
jd	d
d`dXdYZ3ee	j
jd	d
d`dZd[Z4ee	j
jd	d
d`d\d]Z5dS )fRandomStatea  
    Mersenne Twister pseudo-random number generator

    This object contains state to deterministically generate pseudo-random
    numbers from a variety of probability distributions.  It is identical to
    ``np.random.RandomState`` except that all functions also take a ``chunks=``
    keyword argument.

    Parameters
    ----------
    seed: Number
        Object to pass to RandomState to serve as deterministic seed
    RandomState: Callable[seed] -> RandomState
        A callable that, when provided with a ``seed`` keyword provides an
        object that operates identically to ``np.random.RandomState`` (the
        default).  This might also be a function that returns a
        ``mkl_random``, or ``cupy.random.RandomState`` object.

    Examples
    --------
    >>> import dask.array as da
    >>> state = da.random.RandomState(1234)  # a seed
    >>> x = state.normal(10, 0.1, size=3, chunks=(2,))
    >>> x.compute()
    array([10.01867852, 10.04812289,  9.89649746])

    See Also
    --------
    np.random.RandomState
    Nc                 C  s,   t j|| _|d u rtj| _d S || _d S r   )r   r   r   _numpy_stater   _RandomState)r   r   r   r   r   r   r   
  s
   zRandomState.__init__c                 C  s   t | jdd }t|S r$   )r   r   r&   r)   r*   )r   r(   r   r   r   r+     s   
zRandomState._backendc                 C  s   | j | d S r   )r   r   )r   r   r   r   r   r     s   zRandomState.seedr,   r-   r.   c                 K  r/   r0   r5   r7   r   r   r   r1     r;   zRandomState.betac                 K  r/   r<   r5   r>   r   r   r   r=     r;   zRandomState.binomialc                 K  rA   rB   r5   rD   r   r   r   rC   "  rF   zRandomState.chisquareTc                   s   t |  |d|\ }}}}}tt| }	tt|	| j}
dt|
||  }t|ggdd |D R  } fddt||
|	D }tj	|||d}t
||||dS )	Nr   rG   c                 s  rH   r   rI   rL   r   r   r   rN   ;  rO   z%RandomState.choice.<locals>.<genexpr>c              	     s$   i | ]\}}}|t | |fqS r   )
_choice_rs)rM   rQ   stater3   r8   r@   rU   r   r   rW   <  s    z&RandomState.choice.<locals>.<dictcomp>rX   rZ   )r\   r]   r   r   rK   r   r   r_   r   r`   r	   )r   r8   r3   rU   r@   r4   rT   r[   rY   ra   
state_datarc   rd   re   rf   r   r   r   rg   (  s.   
zRandomState.choicerh   c                 K  rA   ri   r5   rk   r   r   r   rj   F  rm   zRandomState.exponentialc                 K  r/   rn   r5   rp   r   r   r   ro   L  r;   zRandomState.fc                 K  r/   rs   r5   ru   r   r   r   rt   P  rw   zRandomState.gammac                 K  rA   rx   r5   rz   r   r   r   ry   V  rF   zRandomState.geometricr{   c                 K  r/   r|   r5   r~   r   r   r   r}   Z  rw   zRandomState.gumbelc                 K  r   r   r5   r   r   r   r   r   `  r   zRandomState.hypergeometricc                 K  r/   r   r5   r~   r   r   r   r   m  rw   zRandomState.laplacec                 K  r/   r   r5   r~   r   r   r   r   s  rw   zRandomState.logisticc                 K  r/   r   r5   r   r   r   r   r   y  rw   zRandomState.lognormalc                 K  rA   r   r5   rz   r   r   r   r     rF   zRandomState.logseriesc                 K  r   r   r   r   r   r   r   r     r   zRandomState.multinomialc                 K  r/   r   r5   r>   r   r   r   r     rw   zRandomState.negative_binomialc                 K  r/   r   r5   r   r   r   r   r     rw   z RandomState.noncentral_chisquarec                 K  r   r   r5   r   r   r   r   r     r   zRandomState.noncentral_fc                 K  r/   r   r5   r~   r   r   r   r     rw   zRandomState.normalc                 K  rA   r   r5   r   r   r   r   r     rF   zRandomState.paretoc                 C  sH   ddl m} t|tjrt|dd}tt|}| j	| |||S )Nr   r   r.   r   )
r   r   r   r   r   r   r   rK   r   rV   r   r   r   r   r     s   
zRandomState.permutationc                 K  rA   r   r5   r   r   r   r   r     rF   zRandomState.poissonc                 K  rA   r   r5   r   r   r   r   r     rF   zRandomState.powerlc                 K  r   )Nrandint)r3   r4   r   r5   )r   r   r   r3   r4   r   r:   r   r   r   r    s   zRandomState.randintc                 K  r/   )Nrandom_integersr2   r5   r   r   r   r   r    rw   zRandomState.random_integersc                 K  r   )Nrandom_sampler2   r5   r   r   r   r   r    r   zRandomState.random_samplec                 K  rA   r   r5   rk   r   r   r   r     rF   zRandomState.rayleighc                 K  r   r   r5   r   r   r   r   r     r   zRandomState.standard_cauchyc                 K  r   r   r5   r   r   r   r   r     r   z RandomState.standard_exponentialc                 K  rA   r   r5   r   r   r   r   r     rm   zRandomState.standard_gammac                 K  r   r   r5   r   r   r   r   r     r   zRandomState.standard_normalc                 K  rA   r   r5   rD   r   r   r   r     rF   zRandomState.standard_tc                 K  r   )Ntomaxintr2   r5   r   r   r   r   r    r   zRandomState.tomaxintc                 K  r   r   r5   r   r   r   r   r     r   zRandomState.triangularc                 K  r/   r   r5   r   r   r   r   r     rw   zRandomState.uniformc                 K  r/   r   r5   r   r   r   r   r     rw   zRandomState.vonmisesc                 K  r/   r   r5   r   r   r   r   r     r;   zRandomState.waldc                 K  rA   r   r5   r   r   r   r   r     rF   zRandomState.weibullc                 K  rA   r   r5   r   r   r   r   r     rF   zRandomState.zipf)NNr   r   )NTNr.   r   r   )NNr.   r   )NNr.   )6r!   r   r   r   r   r   r+   r   r   r   r   r   r1   r=   rC   
contextlibsuppressAttributeErrorrg   rj   ro   rt   ry   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     s    


 

r   c                 C  s(   t | dd }t|}|j| S r$   )r   r&   r)   r*   r   r   )rR   backend_nameZbackend_libr   r   r   _rng_from_bitgen  s   
r	  c                 C  s,   | j }t|  } || _ t| }|j||dS )N)rT   )r   typer	  rV   )r   r   rT   r   r   r   r   r   r     s
   
r   c                   s"    j |} fdd|D }|S )Nc                   s   g | ]}t  |qS r   )r
  )rM   r   rR   r   r   
<listcomp>"      z"_spawn_bitgens.<locals>.<listcomp>)	_seed_seqZspawn)rR   Z	n_bitgensZseedsrb   r   r  r   r^      s   r^   c                 C  s:   t |tjjr| |}t|} t| |}||d|i|S )z$Apply random module method with seedr3   )r   r   r   ZSeedSequencer	  getattr)rngfuncnamerR   r3   argsr:   funcr   r   r   _apply_random_func&  s
   
r  c                 C  s2   | du rt j} | |}t||}||d|i|S )z"Apply RandomState method with seedNr3   )r   r   r  )r   r  r   r3   r  r:   r   r  r   r   r   _apply_random/  s
   
r  c                 C  s   t | }|j||||||dS )N)r3   rU   r@   rT   rV   )r	  rg   )r   r8   r3   rU   r@   rT   rV   r   r   r   r   rP   8  s   rP   c                 C  s   t | }|j||||dS )N)r3   rU   r@   )r   r   rg   )r   r8   r3   rU   r@   r   r   r   r   r   =  s   
r   c                 C  s  g }t |trPt | tr"| jdkrtd| jj jddd d}n#t | t	rA|d ur2| j
dgn|}	| jj	 jdd|	d}ntd|}
|dk rOtdn%t|}||j}|j}|jdkrftd	t|}
|| | d }|d urt |tst||d
}tj| ddddstdt|}n||j}|jdkrtdt||
krtd|| | d }|d u rd}n
t |ttfs|f}|dkrtdt||tjd}|st|d dkrd}t|||||||||fS )Nr   z3`choice` not supported for cupy-backed `Generator`.r,   r   )r3   r@   zUnknown generator classr   za must be greater than 0za must be one dimensional)likegHz>)ZrtolZatolzprobabilities do not sum to 1zp must be one dimensionalza and p must have the same sizez)axis must be 0 since a is one dimensionalr   z]replace=False is not currently supported for dask.array.choice with multi-chunk output arrays)r   r   r   r(   r   r+   r   r   rg   r   array
ValueErrorr
   rechunkrv   _metandimrK   appendZ__dask_keys__r	   r   r   isclosesumtupler]   r   r   )r   r8   r3   rU   r@   rT   r4   rY   r[   Zdummy_pZlen_aerr_msgr   r   r   r\   B  sb   









r\   r.   r   r   c          %   
   O  s2  |durt |ttfs|f}tdd t|| D }|dur%|| t| }t|||dt	j
d}t|}dd }	i }
i }g }g }t|D ]L\}}t |t	jtfr|	|||}t |trk|| |j||< nt |t	jrdt| }|||< ||
|< ||td	d
 |jD   qI|| qIi }| D ]J\}}t |t	jtfr|	|||}t |tr|| |j||< nt |t	jrdt| }|||< ||
|< |tdd
 |jD  ||< q|||< qtt| }t | trt| jt|}t|}dd |D }t}t| j}nt | tr&tt|| j}t|}t}| j}ntdt|||||}| d| }t|ggdd |D dggt|  R  }tdd |D  }g }t ||||D ]\}}}}g } t|D ]8\}}||vr}| | qmt |tr| || f|  qmt |t	jr| t!|| |f qmtdi }!| D ]5\}"}|"|vr||!|"< qt |tr||" f| |!|"< qt |t	jrt!||" |f|!|"< qtd||||||| |!f qa||||dt| ||}#|
"t#t || t$j%||
|d}$t|$||| |#dS )zWrap numpy random function to produce dask.array random function
    extra_chunks should be a chunks tuple to append to the end of chunks
    Nc                 S  s"   h | ]}t |ttjfr|jqS r   )r   r	   r   ndarrayrv   )rM   arr   r   r   	<setcomp>  s    z_wrap_func.<locals>.<setcomp>r   r  c                 S  s@   t | trt| ||S t | tjrtt| |S td)Nz!Unknown object type for broadcast)r   r	   r   r  r   r"  Zascontiguousarray	TypeError)r#  rv   r4   r   r   r   _broadcast_any  s
   
z"_wrap_func.<locals>._broadcast_anyzarray-c                 s      | ]}d V  qdS r   Nr   rM   _r   r   r   rN         z_wrap_func.<locals>.<genexpr>c                 s  r'  r(  r   r)  r   r   r   rN     r+  c                 S  s   g | ]}|j qS r   )r  )rM   Z_bitgenr   r   r   r    s    z_wrap_func.<locals>.<listcomp>z:Unknown object type: Not a Generator and Not a RandomState-c                 S     g | ]}t t|qS r   rI   rL   r   r   r   r    r  r   c                 S  r-  r   rI   rL   r   r   r   r    r  zUnknown object type in argszUnknown object type in kwargsr   rX   rZ   )&r   r   r]   r   valuesr  r   r   getr   r   r   	enumerater"  r	   rc   r   rv   itemsr   r   r^   r   rK   r  r
  r   r   r   r  r   r%  r_   r   updatedictr   r`   )%r  r  r3   r4   r   r  r:   ZshapesZslicesr&  re   lookupZ
small_argsrY   ir#  resrc   Zsmall_kwargskeyra   rb   Zbitgen_tokenZfunc_appliergentokenrd   blocksvalsrR   ZslcblockargZkwrgrQ   r[   rf   r   r   r   r6     s   



 





	r6   zdict[str, RandomState]_cached_statesc                   s,    fdd}t t j|_t t j|_|S )Nc               	     sl   t j}t zt| }W n ty   t  t|< }Y nw W d    n1 s'w   Y  t| | i |S r   )r   backend_cached_states_lockr?  KeyErrorr   r  )r  r:   r8  r   attrr   r   wrapper  s   z_make_api.<locals>.wrapper)r  r   r!   r   )rD  rE  r   rC  r   	_make_api  s   	rF  r   r1   r=   rC   rg   rj   ro   rt   ry   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.  )\
__future__r   r  r)   r   	itertoolsr   r   r   operatorr   	threadingr   numpyr   Zdask.array.backendsr   Zdask.array.corer	   r
   r   r   r   r   Zdask.array.creationr   Zdask.array.utilsr   Z	dask.baser   Zdask.highlevelgraphr   Z
dask.utilsr   r   r   r   r   r   r	  r   r^   r  r  rP   r   r\   r6   r?  __annotations__rA  rF  r   r1   r=   rC   rg   rj   ro   rt   ry   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   <module>   s       
p_  (
		G 	