o
    &j                     @   s6  d Z ddlmZmZmZ ddlZddlZddl	m
Z dZdZeeeejddd Zed dks9ed dkrOd	ZejjZed dkrKejjjZnejjZdadZd
ZG dd d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 Z%dd Z&dd  Z'd!d" Z(d#d$ Z)d%d& Z*d'd( Z+d)d* Z,d+d, Z-d-d. Z.d/d0 Z/d1d2 Z0d3d4 Z1d5d6 Z2d7d8 Z3d9d: Z4d;d< Z5d=d> Z6d?d@ Z7dAdB Z8dCdD Z9dEdF Z:dGdH Z;dIdJ Z<dKdL Z=dMdN Z>dOdP Z?dQdR Z@dSdT ZAdUdV ZBdWdX ZCdYdZ ZDd[d\ ZEd]d^ ZFd_d` ZG	a	didbdcZHdjdedfZIG dgdh dheZJdS )ka  Classes and functions related to pseudo-random number generation.

This module deals with the generation of pseudo-random numbers.
It provides the :class:`~imgaug.random.RNG` class, which is the primary
random number generator in ``imgaug``. It also provides various utility
functions related random number generation, such as copying random number
generators or setting their state.

The main benefit of this module is to hide the actually used random number
generation classes and methods behin imgaug-specific classes and methods.
This allows to deal with numpy using two different interfaces (one old
interface in numpy <=1.16 and a new one in numpy 1.17+). It also allows
to potentially switch to a different framework/library in the future.

Definitions
-----------

- *numpy generator* or *numpy random number generator*: Usually an instance
  of :class:`numpy.random.Generator`. Can often also denote an instance
  of :class:`numpy.random.RandomState` as both have almost the same interface.
- *RandomState*: An instance of `numpy.random.RandomState`.
  Note that outside of this module, the term "random state" often roughly
  translates to "any random number generator with numpy-like interface
  in a given state", i.e. it can then include instances of
  :class:`numpy.random.Generator` or :class:`~imgaug.random.RNG`.
- *RNG*: An instance of :class:`~imgaug.random.RNG`.

Examples
--------

>>> import imgaug.random as iarandom
>>> rng = iarandom.RNG(1234)
>>> rng.integers(0, 1000)

Initialize a random number generator with seed ``1234``, then sample
a single integer from the discrete interval ``[0, 1000)``.
This will use a :class:`numpy.random.Generator` in numpy 1.17+ and
automatically fall back to :class:`numpy.random.RandomState` in numpy <=1.16.

    )print_functiondivisionabsolute_importNF.         Tic                   @   s  e Zd ZdZdd Zedd Zejdd Zdd Zd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd  Zd!d" Zed#d$ Zed%d& Z	(	)dd*d+Zdd-d.Zdd0d1Zd2d3 Zd4d5 Zd6d7 Zdd8d9Zdd:d;Z dd<d=Z!dd>d?Z"ddAdBZ#ddCdDZ$ddEdFZ%ddGdHZ&ddJdKZ'ddLdMZ(ddNdOZ)ddPdQZ*ddRdSZ+ddTdUZ,ddVdWZ-	X	YddZd[Z.dd\d]Z/dd^d_Z0dd`daZ1ddbdcZ2ddddeZ3ddfdgZ4ddhdiZ5ddjdkZ6ddldmZ7	n	'ddodpZ8ddqdrZ9ddsdtZ:ddudvZ;ddwdxZ<ddydzZ=dd{d|Z>dd}d~Z?dddZ@dddZAdd ZBdddZCdd ZDdddZEdd ZFdddZGd'S )RNGa  
    Random number generator for imgaug.

    This class is a wrapper around ``numpy.random.Generator`` and
    automatically falls back to ``numpy.random.RandomState`` in case of
    numpy version 1.16 or lower. It allows to use numpy 1.17's sampling
    functions in 1.16 too and supports a variety of useful functions on
    the wrapped sampler, e.g. gettings its state or copying it.

    Not supported sampling functions of numpy <=1.16:

    * :func:`numpy.random.RandomState.rand`
    * :func:`numpy.random.RandomState.randn`
    * :func:`numpy.random.RandomState.randint`
    * :func:`numpy.random.RandomState.random_integers`
    * :func:`numpy.random.RandomState.random_sample`
    * :func:`numpy.random.RandomState.ranf`
    * :func:`numpy.random.RandomState.sample`
    * :func:`numpy.random.RandomState.seed`
    * :func:`numpy.random.RandomState.get_state`
    * :func:`numpy.random.RandomState.set_state`

    In :func:`~imgaug.random.RNG.choice`, the `axis` argument is not yet
    supported.

    Parameters
    ----------
    generator : None or int or RNG or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState
        The numpy random number generator to use. In case of numpy
        version 1.17 or later, this shouldn't be a ``RandomState`` as that
        class is outdated.
        Behaviour for different datatypes:

          * If ``None``: The global RNG is wrapped by this RNG (they are then
            effectively identical, any sampling on this RNG will affect the
            global RNG).
          * If ``int``: In numpy 1.17+, the value is used as a seed for a
            ``Generator`` wrapped by this RNG. I.e. it will be provided as the
            entropy to a ``SeedSequence``, which will then be used for an
            ``SFC64`` bit generator and wrapped by a ``Generator``.
            In numpy <=1.16, the value is used as a seed for a ``RandomState``,
            which is then wrapped by this RNG.
          * If :class:`RNG`: That RNG's ``generator`` attribute will be used
            as the generator for this RNG, i.e. the same as
            ``RNG(other_rng.generator)``.
          * If :class:`numpy.random.Generator`: That generator will be wrapped.
          * If :class:`numpy.random.BitGenerator`: A numpy
            generator will be created (and wrapped by this RNG) that contains
            the bit generator.
          * If :class:`numpy.random.SeedSequence`: A numpy
            generator will be created (and wrapped by this RNG) that contains
            an ``SFC64`` bit generator initialized with the given
            ``SeedSequence``.
          * If :class:`numpy.random.RandomState`: In numpy <=1.16, this
            ``RandomState`` will be wrapped and used to sample random values.
            In numpy 1.17+, a seed will be derived from this ``RandomState``
            and a new ``numpy.generator.Generator`` based on an ``SFC64``
            bit generator will be created and wrapped by this RNG.

    c                 C   s6   t |tr
|j| _nt|| _t | jtjj | _d S N)
isinstancer	   	generatornormalize_generator_nprandomRandomState_is_new_rng_style)selfr    r   N/var/www/html/Deteccion_Ine/venv/lib/python3.10/site-packages/imgaug/random.py__init__   s
   


zRNG.__init__c                 C   
   t | jS )aq  Get the state of this RNG.

        Returns
        -------
        tuple or dict
            The state of the RNG.
            In numpy 1.17+, the bit generator's state will be returned.
            In numpy <=1.16, the ``RandomState`` 's state is returned.
            In both cases the state is a copy. In-place changes will not affect
            the RNG.

        )get_generator_stater   r   r   r   r   state      
z	RNG.statec                 C   s   |  | dS )zSet the state if the RNG in-place.

        Parameters
        ----------
        value : tuple or dict
            The new state of the RNG.
            Should correspond to the output of the ``state`` property.

        N)
set_state_r   valuer   r   r   r         c                 C   s   t | j| | S )a'  Set the state if the RNG in-place.

        Parameters
        ----------
        value : tuple or dict
            The new state of the RNG.
            Should correspond to the output of the ``state`` property.

        Returns
        -------
        RNG
            The RNG itself.

        )set_generator_state_r   r   r   r   r   r      s   zRNG.set_state_c                 C   s   |  |jS )a  Copy and use (in-place) the state of another RNG.

        .. note::

            It is often sensible to first verify that neither this RNG nor
            `other` are identical to the global RNG.

        Parameters
        ----------
        other : RNG
            The other RNG, which's state will be copied.

        Returns
        -------
        RNG
            The RNG itself.

        )r   r   r   otherr   r   r   use_state_of_      zRNG.use_state_of_c                 C   s   t  j| ju S )ac  Estimate whether this RNG is identical to the global RNG.

        Returns
        -------
        bool
            ``True`` is this RNG's underlying generator is identical to the
            global RNG's underlying generator. The RNGs themselves may
            be different, only the wrapped generator matters.
            ``False`` otherwise.

        )get_global_rngr   r   r   r   r   is_global_rng   s   zRNG.is_global_rngc                 C   s   t  | S )a  Estimate whether this RNG has the same state as the global RNG.

        Returns
        -------
        bool
            ``True`` is this RNG has the same state as the global RNG, i.e.
            it will lead to the same sampled values given the same sampling
            method calls. The RNGs *don't* have to be identical object
            instances, which protects against e.g. copy effects.
            ``False`` otherwise.

        )r$   equalsr   r   r   r   equals_global_rng   s   zRNG.equals_global_rngc                 C   r   )zSample a random seed.

        This advances the underlying generator's state.

        See ``SEED_MIN_VALUE`` and ``SEED_MAX_VALUE`` for the seed's value
        range.

        Returns
        -------
        int
            The sampled seed.

        )generate_seed_r   r   r   r   r   r(     r   zRNG.generate_seed_c                 C   s   t | j|S )av  Generate `n` random seed values.

        This advances the underlying generator's state.

        See ``SEED_MIN_VALUE`` and ``SEED_MAX_VALUE`` for the seed's value
        range.

        Parameters
        ----------
        n : int
            Number of seeds to sample.

        Returns
        -------
        ndarray
            1D-array of ``int32`` seeds.

        )generate_seeds_r   r   nr   r   r   r)     r#   zRNG.generate_seeds_c                 C      t | j | S )zoReset all cache of this RNG.

        Returns
        -------
        RNG
            The RNG itself.

        )reset_generator_cache_r   r   r   r   r   reset_cache_'  s   
	zRNG.reset_cache_c                 C   s   |  dd S )zCreate a child RNG.

        This advances the underlying generator's state.

        Returns
        -------
        RNG
            A child RNG.

        r   r   )derive_rngs_r   r   r   r   derive_rng_3  r   zRNG.derive_rng_c                 C   s   dd t | j|D S )a	  Create `n` child RNGs.

        This advances the underlying generator's state.

        Parameters
        ----------
        n : int
            Number of child RNGs to derive.

        Returns
        -------
        list of RNG
            Child RNGs.

        c                 S      g | ]}t |qS r   )r	   ).0genr   r   r   
<listcomp>P  s    z$RNG.derive_rngs_.<locals>.<listcomp>)derive_generators_r   r*   r   r   r   r/   @  s   zRNG.derive_rngs_c                 C   s*   t |tsJ dt|f t| j|jS )zEstimate whether this RNG and `other` have the same state.

        Returns
        -------
        bool
            ``True`` if this RNG's generator and the generator of `other`
            have equal internal states. ``False`` otherwise.

        zExpected 'other' to be an RNG, got type %s. Use imgaug.random.is_generator_equal_to() to compare numpy generators or RandomStates.)r   r	   typeis_generator_equal_tor   r    r   r   r   r&   R  s   
z
RNG.equalsc                 C   r,   )a  Advance the RNG's internal state in-place by one step.

        This advances the underlying generator's state.

        .. note::

            This simply samples one or more random values. This means that
            a call of this method will not completely change the outputs of
            the next called sampling method. To achieve more drastic output
            changes, call :func:`~imgaug.random.RNG.derive_rng_`.

        Returns
        -------
        RNG
            The RNG itself.

        )advance_generator_r   r   r   r   r   advance_b  s   
zRNG.advance_c                 C   s   t t| jS )zCreate a copy of this RNG.

        Returns
        -------
        RNG
            Copy of this RNG. The copy will produce the same random samples.

        )r	   copy_generatorr   r   r   r   r   copyw  s   	zRNG.copyc                 C   s   |   r| S |  S )a  Create a copy of this RNG unless it is the global RNG.

        Returns
        -------
        RNG
            Copy of this RNG unless it is the global RNG. In the latter case
            the RNG instance itself will be returned without any changes.

        )r%   r;   r   r   r   r   copy_unless_global_rng  s   
zRNG.copy_unless_global_rngc                    s    fddt |D S )a  Create a list containing `n` times this RNG.

        This method was mainly introduced as a replacement for previous
        calls of :func:`~imgaug.random.RNG.derive_rngs_`. These calls
        turned out to be very slow in numpy 1.17+ and were hence replaced
        by simple duplication (except for the cases where child RNGs
        absolutely *had* to be created).
        This RNG duplication method doesn't help very much against code
        repetition, but it does *mark* the points where it would be desirable
        to create child RNGs for various reasons. Once deriving child RNGs
        is somehow sped up in the future, these calls can again be
        easily found and replaced.

        Parameters
        ----------
        n : int
            Length of the output list.

        Returns
        -------
        list of RNG
            List containing `n` times this RNG (same instances, no copies).

        c                    s   g | ]} qS r   r   )r2   _r   r   r   r4     s    z!RNG.duplicate.<locals>.<listcomp>)smxranger*   r   r   r   	duplicate  s   zRNG.duplicatec                 C   s
   t t S )a  Create a new RNG, based on entropy provided from the OS.

        Returns
        -------
        RNG
            A new RNG. It is not derived from any other previously created
            RNG, nor does it depend on the seeding of imgaug or numpy.

        )r	   create_fully_random_generatorclsr   r   r   create_fully_random  s   
zRNG.create_fully_randomc                 C   s
   t   S )a4  Create a new RNG in pseudo-random fashion.

        A seed will be sampled from the current global RNG and used to
        initialize the new RNG.

        This advandes the global RNG's state.

        Returns
        -------
        RNG
            A new RNG, derived from the current global RNG.

        )r$   r0   rB   r   r   r   create_pseudo_random_  s   
zRNG.create_pseudo_random_Nint32Fc                 C   s   t | j|||||dS )zCall numpy's ``integers()`` or ``randint()``.

        .. note::

            Changed `dtype` argument default value from numpy's ``int64`` to
            ``int32``.

        lowhighsizedtypeendpoint)polyfill_integersr   )r   rH   rI   rJ   rK   rL   r   r   r   integers  s   
zRNG.integersfloat32c                 C   s   t | j|||dS )zCall numpy's ``random()`` or ``random_sample()``.

        .. note::

            Changed `dtype` argument default value from numpy's ``d`` to
            ``float32``.

        rJ   rK   out)polyfill_randomr   )r   rJ   rK   rQ   r   r   r   r     s   	
z
RNG.randomTc                 C      | j j||||dS )z+Call :func:`numpy.random.Generator.choice`.)arJ   replacep)r   choice)r   rT   rJ   rU   rV   r   r   r   rW     s   z
RNG.choicec                 C      | j j|dS )z*Call :func:`numpy.random.Generator.bytes`.)length)r   bytes)r   rY   r   r   r   rZ        z	RNG.bytesc                 C   s   | j | dS )z,Call :func:`numpy.random.Generator.shuffle`.N)r   shuffler   xr   r   r   r\     s   zRNG.shufflec                 C   s   | j |S )z0Call :func:`numpy.random.Generator.permutation`.)r   permutationr]   r   r   r   r_     s   zRNG.permutationc                 C      | j j|||dS )z)Call :func:`numpy.random.Generator.beta`.)rT   brJ   )r   beta)r   rT   ra   rJ   r   r   r   rb        zRNG.betac                 C   r`   )z-Call :func:`numpy.random.Generator.binomial`.r+   rV   rJ   )r   binomialr   r+   rV   rJ   r   r   r   re        zRNG.binomialc                 C      | j j||dS )z.Call :func:`numpy.random.Generator.chisquare`.dfrJ   )r   	chisquarer   rj   rJ   r   r   r   rk        zRNG.chisquarec                 C   rh   )z.Call :func:`numpy.random.Generator.dirichlet`.)alpharJ   )r   	dirichlet)r   rn   rJ   r   r   r   ro        zRNG.dirichlet      ?c                 C   rh   )z0Call :func:`numpy.random.Generator.exponential`.scalerJ   )r   exponentialr   rs   rJ   r   r   r   rt     rp   zRNG.exponentialc                 C   r`   )z&Call :func:`numpy.random.Generator.f`.)dfnumdfdenrJ   )r   f)r   rv   rw   rJ   r   r   r   rx     rg   zRNG.fc                 C   r`   )z*Call :func:`numpy.random.Generator.gamma`.)shapers   rJ   )r   gamma)r   ry   rs   rJ   r   r   r   rz     rg   z	RNG.gammac                 C   rh   )z.Call :func:`numpy.random.Generator.geometric`.rV   rJ   )r   	geometricr   rV   rJ   r   r   r   r|      rp   zRNG.geometric        c                 C   r`   )z+Call :func:`numpy.random.Generator.gumbel`.locrs   rJ   )r   gumbelr   r   rs   rJ   r   r   r   r   $  rg   z
RNG.gumbelc                 C   rS   )z3Call :func:`numpy.random.Generator.hypergeometric`.)ngoodnbadnsamplerJ   )r   hypergeometric)r   r   r   r   rJ   r   r   r   r   (     zRNG.hypergeometricc                 C   r`   )z,Call :func:`numpy.random.Generator.laplace`.r   )r   laplacer   r   r   r   r   -  rg   zRNG.laplacec                 C   r`   )z-Call :func:`numpy.random.Generator.logistic`.r   )r   logisticr   r   r   r   r   1  rg   zRNG.logisticc                 C   r`   )z.Call :func:`numpy.random.Generator.lognormal`.)meansigmarJ   )r   	lognormal)r   r   r   rJ   r   r   r   r   5  rg   zRNG.lognormalc                 C   rh   )z.Call :func:`numpy.random.Generator.logseries`.r{   )r   	logseriesr}   r   r   r   r   9  rp   zRNG.logseriesc                 C   r`   )z0Call :func:`numpy.random.Generator.multinomial`.)r+   pvalsrJ   )r   multinomial)r   r+   r   rJ   r   r   r   r   =  rg   zRNG.multinomialwarn:0yE>c                 C   s   | j j|||||dS )z8Call :func:`numpy.random.Generator.multivariate_normal`.)r   covrJ   check_validtol)r   multivariate_normal)r   r   r   rJ   r   r   r   r   r   r   A  s   
zRNG.multivariate_normalc                 C   r`   )z6Call :func:`numpy.random.Generator.negative_binomial`.rd   )r   negative_binomialrf   r   r   r   r   G  rg   zRNG.negative_binomialc                 C   r`   )z9Call :func:`numpy.random.Generator.noncentral_chisquare`.)rj   noncrJ   )r   noncentral_chisquare)r   rj   r   rJ   r   r   r   r   K  rc   zRNG.noncentral_chisquarec                 C   rS   )z1Call :func:`numpy.random.Generator.noncentral_f`.)rv   rw   r   rJ   )r   noncentral_f)r   rv   rw   r   rJ   r   r   r   r   P  r   zRNG.noncentral_fc                 C   r`   )z+Call :func:`numpy.random.Generator.normal`.r   )r   normalr   r   r   r   r   U  rg   z
RNG.normalc                 C   rh   )z+Call :func:`numpy.random.Generator.pareto`.rT   rJ   )r   paretor   rT   rJ   r   r   r   r   Y  rm   z
RNG.paretoc                 C   rh   )z,Call :func:`numpy.random.Generator.poisson`.)lamrJ   )r   poisson)r   r   rJ   r   r   r   r   ^  rp   zRNG.poissonc                 C   rh   )z*Call :func:`numpy.random.Generator.power`.r   )r   powerr   r   r   r   r   b  rm   z	RNG.powerc                 C   rh   )z-Call :func:`numpy.random.Generator.rayleigh`.rr   )r   rayleighru   r   r   r   r   g  rp   zRNG.rayleighc                 C   rX   )z4Call :func:`numpy.random.Generator.standard_cauchy`.rJ   )r   standard_cauchyr   rJ   r   r   r   r   k  r[   zRNG.standard_cauchyzigc                 C   sj   | j r| jj||||dS | jj|d|}|dur3|jj|jjks/J d|jj|jjf ||d< |S )zCall :func:`numpy.random.Generator.standard_exponential`.

        .. note::

            Changed `dtype` argument default value from numpy's ``d`` to
            ``float32``.

        )rJ   rK   methodrQ   r   NzyExpected out array to have the same dtype as standard_exponential()'s result array. Got %s (out) and %s (result) instead..)r   r   standard_exponentialastyperK   name)r   rJ   rK   r   rQ   resultr   r   r   r   o  s   
zRNG.standard_exponentialc                 C   sl   | j r| jj||||dS | jj||d|}|dur4|jj|jjks0J d|jj|jjf ||d< |S )zCall :func:`numpy.random.Generator.standard_gamma`.

        .. note::

            Changed `dtype` argument default value from numpy's ``d`` to
            ``float32``.

        )ry   rJ   rK   rQ   )ry   rJ   NzsExpected out array to have the same dtype as standard_gamma()'s result array. Got %s (out) and %s (result) instead..)r   r   standard_gammar   rK   r   )r   ry   rJ   rK   rQ   r   r   r   r   r     s"   	zRNG.standard_gammac                 C   sh   | j r| jj|||dS | jj|d|}|dur2|jj|jjks.J d|jj|jjf ||d< |S )zCall :func:`numpy.random.Generator.standard_normal`.

        .. note::

            Changed `dtype` argument default value from numpy's ``d`` to
            ``float32``.

        rP   r   NztExpected out array to have the same dtype as standard_normal()'s result array. Got %s (out) and %s (result) instead..)r   r   standard_normalr   rK   r   )r   rJ   rK   rQ   r   r   r   r   r     s   	zRNG.standard_normalc                 C   rh   )z/Call :func:`numpy.random.Generator.standard_t`.ri   )r   
standard_trl   r   r   r   r     rm   zRNG.standard_tc                 C   rS   )z/Call :func:`numpy.random.Generator.triangular`.)leftmoderightrJ   )r   
triangular)r   r   r   r   rJ   r   r   r   r     r   zRNG.triangularc                 C   r`   )z,Call :func:`numpy.random.Generator.uniform`.)rH   rI   rJ   )r   uniformr   rH   rI   rJ   r   r   r   r     rg   zRNG.uniformc                 C   r`   )z-Call :func:`numpy.random.Generator.vonmises`.)mukapparJ   )r   vonmises)r   r   r   rJ   r   r   r   r     rc   zRNG.vonmisesc                 C   r`   )z)Call :func:`numpy.random.Generator.wald`.)r   rs   rJ   )r   wald)r   r   rs   rJ   r   r   r   r     rg   zRNG.waldc                 C   rh   )z,Call :func:`numpy.random.Generator.weibull`.r   )r   weibullr   r   r   r   r     rm   zRNG.weibullc                 C   rh   )z)Call :func:`numpy.random.Generator.zipf`.r   )r   zipfr   r   r   r   r     rm   zRNG.zipfc                 G      | j |dS )zCall :func:`numpy.random.RandomState.rand`.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.random` instead.

        Added in 0.4.0.

        r   )r   r   argsr   r   r   rand  s   
zRNG.randc                 C   s   | j ||||ddS )a8  Call :func:`numpy.random.RandomState.randint`.

        .. note::

            Changed `dtype` argument default value from numpy's ``I`` to
            ``int32``.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.integers`
            instead.

        Added in 0.4.0.

        FrG   rN   )r   rH   rI   rJ   rK   r   r   r   randint  s   zRNG.randintc                 G   r   )zCall :func:`numpy.random.RandomState.randn`.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.standard_normal`
            instead.

        Added in 0.4.0.

        r   )r   r   r   r   r   randn  s   z	RNG.randnc                 C   s,   |du r| j d||ddS | j |||ddS )zCall :func:`numpy.random.RandomState.random_integers`.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.integers`
            instead.

        Added in 0.4.0.

        Nr   T)rH   rI   rJ   rL   r   r   r   r   r   random_integers  s   zRNG.random_integersc                 C   s   | j dd|dS )zCall :func:`numpy.random.RandomState.random_sample`.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.uniform`
            instead.

        Added in 0.4.0.

        r~   rq   r   )r   r   r   r   r   random_sample  s   zRNG.random_samplec                 C   s4   ddl }|j}ttjj}| jdt|||ddS )zCall :func:`numpy.random.RandomState.tomaxint`.

        .. warning::

            This method is outdated in numpy. Use :func:`RNG.integers`
            instead.

        Added in 0.4.0.

        r   NT)rJ   rL   )sysmaxsizer   ZiinforF   maxrN   min)r   rJ   r   ZmaxintZint32maxr   r   r   tomaxint   s   zRNG.tomaxintNNrF   FrO   N)NTNr
   )rq   N)r~   rq   N)Nr   r   )NrO   r   N)NrO   N)NNrF   )NN)H__name__
__module____qualname____doc__r   propertyr   setterr   r"   r%   r'   r(   r)   r.   r0   r/   r&   r9   r;   r<   r@   classmethodrD   rE   rN   r   rW   rZ   r\   r_   rb   re   rk   ro   rt   rx   rz   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r	   V   s    ?











































r	   c                   C   s   t S )ap  
    Determine whether numpy supports the new ``random`` interface (v1.17+).

    Returns
    -------
    bool
        ``True`` if the new ``random`` interface is supported by numpy, i.e.
        if numpy has version 1.17 or later. Otherwise ``False``, i.e.
        numpy has version 1.16 or older and ``numpy.random.RandomState``
        should be used instead.

    )SUPPORTS_NEW_NP_RNG_STYLEr   r   r   r   supports_new_numpy_rng_style2  s   r   c                  C   s"   t du rttj} tt| a t S )z
    Get or create the current global RNG of imgaug.

    Note that the first call to this function will create a global RNG.

    Returns
    -------
    RNG
        The global RNG to use.

    N)
GLOBAL_RNGr(   r   r   r	   convert_seed_to_generator)seedr   r   r   r$   B  s   
r$   c                 C   s   t rt|  dS t|  dS )a
  Set the seed of imgaug's global RNG (in-place).

    The global RNG controls most of the "randomness" in imgaug.

    The global RNG is the default one used by all augmenters. Under special
    circumstances (e.g. when an augmenter is switched to deterministic mode),
    the global RNG is replaced with a local one. The state of that replacement
    may be dependent on the global RNG's state at the time of creating the
    child RNG.

    Parameters
    ----------
    entropy : int
        The seed value to use.

    N)r   _seed_np117__seed_np116_entropyr   r   r   r   _  s   r   c                 C   s   t | jt _d S r
   )BIT_GENERATORr   r$   r   r   r   r   r   v  s   r   c                 C   s   t  j|  d S r
   )r$   r   r   r   r   r   r   r   ~  s   r   c                 C   s   t t| S )a  Normalize various inputs to a numpy (random number) generator.

    This function will first copy the provided argument, i.e. it never returns
    a provided instance itself.

    Parameters
    ----------
    generator : None or int or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState
        The numpy random number generator to normalize. In case of numpy
        version 1.17 or later, this shouldn't be a ``RandomState`` as that
        class is outdated.
        Behaviour for different datatypes:

          * If ``None``: The global RNG's generator is returned.
          * If ``int``: In numpy 1.17+, the value is used as a seed for a
            ``Generator``, i.e. it will be provided as the entropy to a
            ``SeedSequence``, which will then be used for an ``SFC64`` bit
            generator and wrapped by a ``Generator``, which is then returned.
            In numpy <=1.16, the value is used as a seed for a ``RandomState``,
            which will then be returned.
          * If :class:`numpy.random.Generator`: That generator will be
            returned.
          * If :class:`numpy.random.BitGenerator`: A numpy
            generator will be created and returned that contains the bit
            generator.
          * If :class:`numpy.random.SeedSequence`: A numpy
            generator will be created and returned that contains an ``SFC64``
            bit generator initialized with the given ``SeedSequence``.
          * If :class:`numpy.random.RandomState`: In numpy <=1.16, this
            ``RandomState`` will be returned. In numpy 1.17+, a seed will be
            derived from this ``RandomState`` and a new
            ``numpy.generator.Generator`` based on an ``SFC64`` bit generator
            will be created and returned.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator`` (even if
        the input was a ``RandomState``).

    )r   copylibdeepcopyr   r   r   r   normalize_generator  s   *r   c                 C      t st| S t| S )a;  Normalize in-place various inputs to a numpy (random number) generator.

    This function will try to return the provided instance itself.

    Parameters
    ----------
    generator : None or int or numpy.random.Generator or numpy.random.BitGenerator or numpy.random.SeedSequence or numpy.random.RandomState
        See :func:`~imgaug.random.normalize_generator`.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator`` (even if
        the input was a ``RandomState``).

    )r   _normalize_generator_np116__normalize_generator_np117_r   r   r   r   r     s   r   c                 C   s   | d u rt  jS t| tjjrtjt| S t| tr(tj| } t	|  | S t| tjjr5t	|  | S t| tjj
rBtt| S | }t|S r
   )r$   r   r   r   r   SeedSequence	Generatorr   _BIT_GENERATOR_INTERFACEr-   r   r   r(   )r   seed_r   r   r   r     s"   
r   c                 C   s.   | d u rt  jS t| tjjr| S | }t|S r
   )r$   r   r   r   r   r   r   )random_stater   r   r   r   r     s   r   c                 C   r   )aZ  Convert a seed value to a numpy (random number) generator.

    Parameters
    ----------
    entropy : int
        The seed value to use.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        Both are initialized with the provided seed.

    )r    _convert_seed_to_generator_np116 _convert_seed_to_generator_np117r   r   r   r   r     s   r   c                 C   s   t j| }t|S r
   )r   r   r   "convert_seed_sequence_to_generator)r   seed_sequencer   r   r   r     s   r   c                 C   s   t j| S r
   r   r   r   r   r   r   r   r        r   c                 C   s   t jt| S )a"  Convert a seed sequence to a numpy (random number) generator.

    Parameters
    ----------
    seed_sequence : numpy.random.SeedSequence
        The seed value to use.

    Returns
    -------
    numpy.random.Generator
        Generator initialized with the provided seed sequence.

    )r   r   r   r   )r   r   r   r   r     s   r   c                  C   s   t t j} t| S )aX  Create a new numpy (random) generator, derived from the global RNG.

    This function advances the global RNG's state.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        Both are initialized with a seed sampled from the global RNG.

    )r(   r$   r   r   )Zrandom_seedr   r   r   create_pseudo_random_generator_  s   r   c                   C   s   t st S t S )an  Create a new numpy (random) generator, derived from OS's entropy.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        Both are initialized with entropy requested from the OS. They are
        hence independent of entered seeds or the library's global RNG.

    )r   $_create_fully_random_generator_np116$_create_fully_random_generator_np117r   r   r   r   rA   -  s   rA   c                   C   s   t jt j S r
   )r   r   r   SFC64r   r   r   r   r   =  rg   r   c                   C   s
   t j S r
   r   r   r   r   r   r   B  s   
r   c                 C   s   t | dd S )a  Sample a seed from the provided generator.

    This function advances the generator's state.

    See ``SEED_MIN_VALUE`` and ``SEED_MAX_VALUE`` for the seed's value
    range.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator from which to sample the seed.

    Returns
    -------
    int
        The sampled seed.

    r   r   )r)   r   r   r   r   r(   F  s   r(   c                 C   s   t | tt|fdS )aw  Sample `n` seeds from the provided generator.

    This function advances the generator's state.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator from which to sample the seed.

    n : int
        Number of seeds to sample.

    Returns
    -------
    ndarray
        1D-array of ``int32`` seeds.

    r   )rM   SEED_MIN_VALUESEED_MAX_VALUEr   r+   r   r   r   r)   \  s   r)   c                 C      t | tjjrt| S t| S )a|  Copy an existing numpy (random number) generator.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to copy.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        Both are copies of the input argument.

    )r   r   r   r   _copy_generator_np116_copy_generator_np117r   r   r   r   r:   s  s   r:   c                 C   s*   | j }|d}t|j|_tj|S Nr   )bit_generator	__class__r   r   r   r   r   r   )r   Zold_bit_genZnew_bit_genr   r   r   r     s   
r   c                 C   s"   t jd}|  }|| |S r   )r   r   r   	get_state	set_state)r   Zrs_copyr   r   r   r   r     s   
r   c                 C   s   | t  ju r| S t| S )a  Copy a numpy generator unless it is the current global generator.

    "global generator" here denotes the generator contained in the
    global RNG's ``.generator`` attribute.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to copy.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        Both are copies of the input argument, unless that input is
        identical to the global generator. If it is identical, the
        instance itself will be returned without copying it.

    )r$   r   r:   r   r   r   r   &copy_generator_unless_global_generator  s   r   c                 C   r   )a  Reset a numpy (random number) generator's internal cache.

    This function modifies the generator's state in-place.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator of which to reset the cache.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        In both cases the input argument itself.

    )r   r   r   r   _reset_generator_cache_np116__reset_generator_cache_np117_r   r   r   r   r-     s   r-   c                 C   s   t | }d|d< t| | | S )Nr   
has_uint32)_get_generator_state_np117_set_generator_state_np117_r   r   r   r   r   r     s   
r   c                 C   s&   t |  }d|d< | t| | S )Nr   )listr   r   tupler   r   r   r   r   r     s   r   c                 C   s   t | ddd S )a  Create a child numpy (random number) generator from an existing one.

    This advances the generator's state.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator from which to derive a new child generator.

    Returns
    -------
    numpy.random.Generator or numpy.random.RandomState
        In numpy <=1.16 a ``RandomState``, in 1.17+ a ``Generator``.
        In both cases a derived child generator.

    r   r+   r   )r5   r   r   r   r   derive_generator_  s   r  c                 C   s&   t | tjjrt| |dS t| |dS )a"  Create child numpy (random number) generators from an existing one.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator from which to derive new child generators.

    n : int
        Number of child generators to derive.

    Returns
    -------
    list of numpy.random.Generator or list of numpy.random.RandomState
        In numpy <=1.16 a list of  ``RandomState`` s,
        in 1.17+ a list of ``Generator`` s.
        In both cases lists of derived child generators.

    r  )r   r   r   r   _derive_generators_np116__derive_generators_np117_r   r   r   r   r5     s   r5   c                 C   s:   | j ttdddd }tj|}||}dd |D S )aL  
    advance_rng_(rng)
    rng = copylib.deepcopy(rng)
    reset_rng_cache_(rng)
    state = rng.bit_generator.state
    rngs = []
    for i in sm.xrange(n):
        state["state"]["state"] += (i * 100003 + 17)
        rng.bit_generator.state = state
        rngs.append(rng)
        rng = copylib.deepcopy(rng)
    return rngs
    rF   )r   )rK   rJ   c                 S   r1   r   )r   )r2   seed_seqr   r   r   r4   '  s    z-_derive_generators_np117_.<locals>.<listcomp>)rN   r   r   r   r   r   Zspawn)r   r+   r   r  Z	seed_seqsr   r   r   r
  	  s   

r
  c                    s$   |  tt  fddt|D S )Nc                    s   g | ]}t  | qS r   )r   )r2   ir   r   r   r4   -  s    z-_derive_generators_np116_.<locals>.<listcomp>)r   r   r   r>   r?   )r   r+   r   r  r   r	  +  s   r	  c                 C   r   )a  Get the state of this provided generator.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator, which's state is supposed to be extracted.

    Returns
    -------
    tuple or dict
        The state of the generator.
        In numpy 1.17+, the bit generator's state will be returned.
        In numpy <=1.16, the ``RandomState`` 's state is returned.
        In both cases the state is a copy. In-place changes will not affect
        the RNG.

    )r   r   r   r   _get_generator_state_np116r   r   r   r   r   r   0  s   r   c                 C   s   | j jS r
   r   r   r   r   r   r   r   G     r   c                 C   s   |   S r
   )r   )r   r   r   r   r  K  r  r  c                 C   s*   t | tjjrt| | dS t| | dS )a  Set the state of a numpy (random number) generator in-place.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator, which's state is supposed to be modified.

    state : tuple or dict
        The new state of the generator.
        Should correspond to the output of
        :func:`~imgaug.random.get_generator_state`.

    N)r   r   r   r   _set_generator_state_np116_r  r  r   r   r   r   O  s   r   c                 C   s   || j _d S r
   r  r  r   r   r   r  c  r   r  c                 C   s   |  | d S r
   )r   r  r   r   r   r  g  s   r  c                 C   s"   t | tjjrt| |S t| |S )a  Estimate whether two generator have the same class and state.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        First generator used in the comparison.

    other_generator : numpy.random.Generator or numpy.random.RandomState
        Second generator used in the comparison.

    Returns
    -------
    bool
        ``True`` if `generator` 's class and state are the same as the
        class and state of `other_generator`. ``False`` otherwise.

    )r   r   r   r   _is_generator_equal_to_np116_is_generator_equal_to_np117)r   other_generatorr   r   r   r7   k  s   

r7   c                 C   s   | j |j u sJ dt| t|f t| }t|}|d dks)J d|d f |d dks8J d|d f |d |d krBdS |d |d   krPdkr\n n
|d |d kr\dS t|d	 d	 |d	 d	 S )
NzCExpected both rngs to have the same class, got types '%s' and '%s'.r   r   zSCan currently only compare the states of numpy.random.SFC64 bit generators, got %s.r   Fr   Zuintegerr   )r   r6   r   r   array_equal)r   r  state1state2r   r   r   r    s.    r  c                 C   s@   t | }t |}tddD ]}t|| || s dS qdS )Nr      FT)r  r>   r?   r   r  )r   Zother_random_stater  r  r  r   r   r   r    s   r  c                 C   s&   t | tjjrt|  dS t|  dS )a:  Advance a numpy random generator's internal state in-place by one step.

    This advances the generator's state.

    .. note::

        This simply samples one or more random values. This means that
        a call of this method will not completely change the outputs of
        the next called sampling method. To achieve more drastic output
        changes, call :func:`~imgaug.random.derive_generator_`.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        Generator of which to advance the internal state.

    N)r   r   r   r   _advance_generator_np116__advance_generator_np117_r   r   r   r   r8     s   r8   c                 C      t |  |   d S r
   )r   r   r   r   r   r   r       r  c                 C   r  r
   )r   r   r   r   r   r   r    r  r  rF   c                 C   sR   t | dr|r|du r|d }d}n|d }| j||||dS | j|||||dS )a  Sample integers from a generator in different numpy versions.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to sample from. If it is a ``RandomState``,
        :func:`numpy.random.RandomState.randint` will be called,
        otherwise :func:`numpy.random.Generator.integers`.

    low : int or array-like of ints
        See :func:`numpy.random.Generator.integers`.

    high : int or array-like of ints, optional
        See :func:`numpy.random.Generator.integers`.

    size : int or tuple of ints, optional
        See :func:`numpy.random.Generator.integers`.

    dtype : {str, dtype}, optional
        See :func:`numpy.random.Generator.integers`.

    endpoint : bool, optional
        See :func:`numpy.random.Generator.integers`.

    Returns
    -------
    int or ndarray of ints
        See :func:`numpy.random.Generator.integers`.

    r   Nr   r   )rH   rI   rJ   rK   rG   )hasattrr   rN   )r   rH   rI   rJ   rK   rL   r   r   r   rM     s   
 rM   rO   c                 C   sh   t | dr,| j|d|}|dur*|jj|jjks&J d|jj|jjf ||d< |S | j|||dS )a  Sample random floats from a generator in different numpy versions.

    Parameters
    ----------
    generator : numpy.random.Generator or numpy.random.RandomState
        The generator to sample from. Both ``RandomState`` and ``Generator``
        support ``random()``, but with different interfaces.

    size : int or tuple of ints, optional
        See :func:`numpy.random.Generator.random`.

    dtype : {str, dtype}, optional
        See :func:`numpy.random.Generator.random`.

    out : ndarray, optional
        See :func:`numpy.random.Generator.random`.


    Returns
    -------
    float or ndarray of floats
        See :func:`numpy.random.Generator.random`.

    r   r   NzrExpected out array to have the same dtype as random_sample()'s result array. Got %s (out) and %s (result) instead..rP   )r  r   r   rK   r   r   )r   rJ   rK   rQ   r   r   r   r   rR     s   
rR   c                   @   s*   e Zd ZdZd	ddZdd Zdd ZdS )
temporary_numpy_seeda  Context to temporarily alter the random state of ``numpy.random``.

    The random state's internal state will be set back to the original one
    once the context finishes.

    Added in 0.4.0.

    Parameters
    ----------
    entropy : None or int
        The seed value to use.
        If `None` then the seed will not be altered and the internal state
        of ``numpy.random`` will not be reset back upon context exit (i.e.
        this context will do nothing).

    Nc                 C   s   d | _ || _d S r
   )	old_stater   )r   r   r   r   r   r   1  s   
ztemporary_numpy_seed.__init__c                 C   s,   | j d urtj | _tj| j  d S d S r
   )r   r   r   r   r   r   r   r   r   r   	__enter__5  s   
ztemporary_numpy_seed.__enter__c                 C   s    | j d urtj| j d S d S r
   )r   r   r   r   r   )r   exc_typeexc_valexc_tbr   r   r   __exit__:  s   
ztemporary_numpy_seed.__exit__r
   )r   r   r   r   r   r!  r%  r   r   r   r   r    s
    
r  r   r   )Kr   
__future__r   r   r   r;   r   numpyr   Z	six.movesZmovesr>   r   r   r  mapint__version__splitZ_NP_VERSIONr   r   r   ZBitGeneratorr   r   r   r   objectr	   r   r$   r   r   r   r   r   r   r   r   r   r   r   r   rA   r   r   r(   r)   r:   r   r   r   r-   r   r   r  r5   r
  r	  r   r   r  r   r  r  r7   r  r  r8   r  r  rM   rR   r  r   r   r   r   <module>   s    (     a-


"

,(