
    hM                        S r SSKJr  SSKJrJrJr  SSKJrJ	r	  SSK
rSSKJr  SSKrSSKJr  SS jrSS	 jr " S
 S\\\      5      rg)zJImplementation of a space that represents closed boxes in euclidean space.    )annotations)IterableMappingSequence)AnySupportsFloatN)NDArray)Spacec                    U R                   S:w  aM  [        R                  " U 5      [        R                  " U 5      :X  a  [	        [        R                  " U 5      5      $ [	        U 5      $ )a3  Create a shortened string representation of a numpy array.

If arr is a multiple of the all-ones vector, return a string representation of the multiplier.
Otherwise, return a string representation of the entire array.

Args:
    arr: The array to represent

Returns:
    A short representation of the array
r   )sizenpminmaxstr)arrs    N/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/spaces/box.pyarray_short_reprr      sB     xx1}s3266#;s8O    c                    [         R                  " [        U 5      [         R                  5      =(       d.    [         R                  " [        U 5      [         R                  5      $ )zKChecks if a scalar variable is an integer or float (does not include bool).)r   
issubdtypetypeintegerfloating)vars    r   is_float_integerr       s3    ==cBJJ/X2==cBKK3XXr   c                     ^  \ rS rSrSrS\R                  S4         SU 4S jjjrSS jrSS jr	\
SS j5       r\
S 5       rSSS	 jjrSSS
 jjrSS jrSS jrSS jrSS jrSS jrSU 4S jjrSrU =r$ )Box%   aX  A (possibly unbounded) box in :math:`\mathbb{R}^n`.

Specifically, a Box represents the Cartesian product of n closed intervals.
Each interval has the form of one of :math:`[a, b]`, :math:`(-\infty, b]`,
:math:`[a, \infty)`, or :math:`(-\infty, \infty)`.

There are two common use cases:

* Identical bound for each dimension::

    >>> Box(low=-1.0, high=2.0, shape=(3, 4), dtype=np.float32)
    Box(-1.0, 2.0, (3, 4), float32)

* Independent bound for each dimension::

    >>> Box(low=np.array([-1.0, -2.0]), high=np.array([2.0, 4.0]), dtype=np.float32)
    Box([-1. -2.], [2. 4.], (2,), float32)
Nc                (
  > Uc  [        S5      e[        R                  " U5      U l        [        R                  " U R                  [        R                  5      (       dk  [        R                  " U R                  [        R
                  5      (       d7  U R                  [        R                  :X  d  [        SU R                   S35      eUbu  [        U[        5      (       d  [        S[        U5       35      e[        S U 5       5      (       d  [        S[        S U 5       5       35      e[        S	 U 5       5      nGO([        U[        R                  5      (       ak  [        U[        R                  5      (       aL  UR                  UR                  :w  a%  [        S
UR                   SUR                   35      eUR                  nO[        U[        R                  5      (       a  UR                  nOr[        U[        R                  5      (       a  UR                  nOF[        U5      (       a  [        U5      (       a  SnO#[        S[        U5       S[        U5       35      eX0l        U R                  [        R                  :X  a  Su  pgGO[        R                  " U R                  [        R
                  5      (       ag  [#        [        R$                  " U R                  5      R&                  5      n[#        [        R$                  " U R                  5      R(                  5      nOf[+        [        R,                  " U R                  5      R&                  5      n[+        [        R,                  " U R                  5      R(                  5      nU R/                  X5      u  U l        U l        U R5                  X'5      u  U l        U l        U R0                  R                  U:w  a/  [        SU R0                  R                   SU R                   35      eU R6                  R                  U:w  a/  [        SU R6                  R                   SU R                   35      e[        R:                  " U R0                  U R6                  :  5      (       a%  [        SU R0                   SU R6                   35      e[=        U R0                  5      U l        [=        U R6                  5      U l         [B        TU ]  U R                  U R                  U5        g)a  Constructor of :class:`Box`.

The argument ``low`` specifies the lower bound of each dimension and ``high`` specifies the upper bounds.
I.e., the space that is constructed will be the product of the intervals :math:`[\text{low}[i], \text{high}[i]]`.

If ``low`` (or ``high``) is a scalar, the lower bound (or upper bound, respectively) will be assumed to be
this value across all dimensions.

Args:
    low (SupportsFloat | np.ndarray): Lower bounds of the intervals. If integer, must be at least ``-2**63``.
    high (SupportsFloat | np.ndarray]): Upper bounds of the intervals. If integer, must be at most ``2**63 - 2``.
    shape (Optional[Sequence[int]]): The shape is inferred from the shape of `low` or `high` `np.ndarray`s with
        `low` and `high` scalars defaulting to a shape of (1,)
    dtype: The dtype of the elements of the space. If this is an integer type, the :class:`Box` is essentially a discrete space.
    seed: Optionally, you can use this argument to seed the RNG that is used to sample from the space.

Raises:
    ValueError: If no shape information is provided (shape is None, low is None and high is None) then a
        value error is raised.
Nz6Box dtype must be explicitly provided, cannot be None.zInvalid Box dtype (z.), must be an integer, floating, or bool dtypez2Expected Box shape to be an iterable, actual type=c              3  ~   #    U  H3  n[         R                  " [        U5      [         R                  5      v   M5     g 7fN)r   r   r   r   .0dims     r   	<genexpr>Box.__init__.<locals>.<genexpr>j   s&     O#tCy"**==s   ;=z;Expected all Box shape elements to be integer, actual type=c              3  8   #    U  H  n[        U5      v   M     g 7fr!   )r   r"   s     r   r%   r&   l   s     WsmrfiX\]`XaXamr   c              3  8   #    U  H  n[        U5      v   M     g 7fr!   )intr"   s     r   r%   r&   p   s     4es#c((er(   z4Box low.shape and high.shape don't match, low.shape=z, high.shape=)   zBox shape is not specified, therefore inferred from low and high. Expected low and high to be np.ndarray, integer, or float.Actual types low=z, high=)r   r+   z6Box low.shape doesn't match provided shape, low.shape=z, shape=z8Box high.shape doesn't match provided shape, high.shape=zTBox all low values must be less than or equal to high (some values break this), low=)#
ValueErrorr   dtyper   r   r   bool_
isinstancer   	TypeErrorr   alltuplendarrayshaper   _shapefloatfinfor   r   r*   iinfo	_cast_lowlowbounded_below
_cast_highhighbounded_aboveanyr   low_repr	high_reprsuper__init__)	selfr:   r=   r4   r-   seed	dtype_min	dtype_max	__class__s	           r   rC   Box.__init__9   s   : =UVVXXe_
 MM$**bjj11}}TZZ55zzRXX%%djj\1_` 
 eX..HeV  OOOOQRWWsmrWsRsQtu 
 4e44ERZZ((Zbjj-I-IyyDJJ& J399+Ubcgcmcmbno  IIERZZ((IIEbjj))JJEc""'7'='=E$$(I;gd4j\C  (- ::!#' Iy]]4::r{{33bhhtzz2667Ibhhtzz2667IBHHTZZ0445IBHHTZZ0445I (,~~c'E$$$(,(H%	4% 88>>U"HHXX`aeakak`lm  99??e#J499??J[[cdhdndncop 
 66$((TYY&''fgkgogofppwx|  yB  yB  xC  D  )2)$))4TZZ6r   c                @   [        U5      (       Ga  [        R                  * [        R                  " U R                  U[
        S9:  n[        R                  " U5      (       a  [        SU 35      e[        R                  " U5      (       aF  U R                  R                  S:X  a  UnO?U R                  R                  S;   a  [        SU 35      eOX:  a  [        SU SU 35      e[        R                  " U R                  XR                  S9nX4$ [        U[        R                  5      (       d  [        S[        U5       35      e[        R                  " UR                  [        R                  5      (       dj  [        R                  " UR                  [        R                   5      (       d6  UR                  [        R"                  :X  d  [        S	UR                   35      e[        R$                  " [        R                  " U5      5      (       a  [        SU 35      e[        R                  * U:  n[        R$                  " [        R                  " U5      5      (       a\  U R                  R                  S:X  a  X![        R                  " U5      '   OqU R                  R                  S;   a  [        SU 35      eOHUR                  U R                  :w  a.  [        R$                  " X:  5      (       a  [        SU SU 35      e[        R                  " UR                  [        R                  5      (       a  [        R                  " U R                  [        R                  5      (       a  [        R&                  " U R                  5      R(                  [        R&                  " UR                  5      R(                  :  a9  [*        R,                  R/                  S
U R                   SUR                   35        UR1                  U R                  5      U4$ )zCasts the input Box low value to ndarray with provided dtype.

Args:
    low: The input box low value
    dtype_min: The dtype's minimum value

Returns:
    The updated low value and for what values the input is bounded (below)
r-   z+No low value can be equal to `np.nan`, low=i   buz4Box unsigned int dtype don't support `-np.inf`, low=z1Box low is out of bounds of the dtype range, low=z, min dtype=z=Box low must be a np.ndarray, integer, or float, actual type=zABox low must be a floating, integer, or bool dtype, actual dtype=z*Box low's precision lowered by casting to z, current low.dtype=)r   r   inffullr4   r6   isnanr,   isneginfr-   kindr/   r3   r   r   r   r   r.   r?   r7   	precisiongymloggerwarnastype)rD   r:   rF   r;   s       r   r9   Box._cast_low   s    C  VVGbggdjj#U&KKMxx}} #Nse!TUUS!!::??c)#CZZ__
2$NseT  3  GuLYbXcd  ''$**c<C%%c2::.. STXY\T]S^_  cii55==BJJ7799( WX[XaXaWbc  && #Nse!TUUVVGcMMvvbkk#&''::??c),5C()ZZ__
2$NseT  3 djj(RVVCO-D-D GuLYbXcd 
 cii55MM$**bkk::HHTZZ(22RXXcii5H5R5RR

@L`adajaj`kl ::djj)=88r   c                   [        U5      (       Ga  [        R                  " U R                  U[        S9[        R
                  :  n[        R                  " U5      (       a  [        SU 35      e[        R                  " U5      (       aF  U R                  R                  S:X  a  UnO?U R                  R                  S;   a  [        SU 35      eOX:  a  [        SU SU 35      e[        R                  " U R                  XR                  S9nX4$ [        U[        R                  5      (       d  [        S[        U5       35      e[        R                  " UR                  [        R                  5      (       dj  [        R                  " UR                  [        R                   5      (       d6  UR                  [        R"                  :X  d  [        S	UR                   35      e[        R$                  " [        R                  " U5      5      (       a  [        SU 35      eU[        R
                  :  n[        R                  " U5      n[        R$                  " U5      (       aH  U R                  R                  S:X  a  X!U'   OqU R                  R                  S;   a  [        SU 35      eOHUR                  U R                  :w  a.  [        R$                  " X!:  5      (       a  [        SU SU 35      e[        R                  " UR                  [        R                  5      (       a  [        R                  " U R                  [        R                  5      (       a  [        R&                  " U R                  5      R(                  [        R&                  " UR                  5      R(                  :  a9  [*        R,                  R/                  S
U R                   SUR                   35        UR1                  U R                  5      U4$ )zCasts the input Box high value to ndarray with provided dtype.

Args:
    high: The input box high value
    dtype_max: The dtype's maximum value

Returns:
    The updated high value and for what values the input is bounded (above)
rK   z-No high value can be equal to `np.nan`, high=rL   rM   z4Box unsigned int dtype don't support `np.inf`, high=z3Box high is out of bounds of the dtype range, high=z, max dtype=z>Box high must be a np.ndarray, integer, or float, actual type=z;Box high must be a floating or integer dtype, actual dtype=z+Box high's precision lowered by casting to z, current high.dtype=)r   r   rQ   r4   r6   rP   rR   r,   isposinfr-   rT   r/   r3   r   r   r   r   r.   r?   r7   rU   rV   rW   rX   rY   )rD   r=   rG   r>   posinfs        r   r<   Box._cast_high   s    D!!GGDJJEBRVVKMxx~~ #PQUPV!WXXT""::??c)$DZZ__
2$NtfU  3 ! I$|\e[fg  774::t::>D&&dBJJ// TUYZ^U_T`a  djj"++66==RZZ88::) QRVR\R\Q]^  '' #PQUPV!WXX 266MM[[&Fvvf~~::??c)#,LZZ__
2$NtfU  3 tzz)bffY5E.F.F I$|\e[fg 
 djj"++66MM$**bkk::HHTZZ(22RXXdjj5I5S5SS

A$**Mbcgcmcmbno ;;tzz*M99r   c                    U R                   $ )z.Has stricter type than gym.Space - never None.)r5   rD   s    r   r4   	Box.shape7  s     {{r   c                    g)zDChecks whether this space can be flattened to a :class:`spaces.Box`.T r`   s    r   is_np_flattenableBox.is_np_flattenable<  s     r   c                   [        [        R                  " U R                  5      5      n[        [        R                  " U R                  5      5      nUS:X  a  U=(       a    U$ US:X  a  U$ US:X  a  U$ [        SU 35      e)zChecks whether the box is bounded in some sense.

Args:
    manner (str): One of ``"both"``, ``"below"``, ``"above"``.

Returns:
    If the space is bounded

Raises:
    ValueError: If `manner` is neither ``"both"`` nor ``"below"`` or ``"above"``
bothbelowabovez;manner is not in {'below', 'above', 'both'}, actual value: )boolr   r1   r;   r>   r,   )rD   mannerrh   ri   s       r   
is_boundedBox.is_boundedA  sz     RVVD../0RVVD../0V?U"wLwLOPVxX r   c                <   Ub"  [         R                  R                  SU 35      eUb"  [         R                  R                  SU 35      eU R                  R                  S:X  a  U R
                  OU R
                  R                  S5      S-   n[        R                  " U R                  5      nU R                  ) U R                  ) -  nU R                  ) U R                  -  nU R                  U R                  ) -  nU R                  U R                  -  nU R                  R                  XU   R                  S9XE'   U R                  R                  Xw   R                  S9U R                  U   -   XG'   U R                  R                  Xf   R                  S9* X6   -   XF'   U R                  R!                  U R                  U   X8   X   R                  S9XH'   U R                  R                  S;   a  [        R"                  " U5      n[        R$                  " U R                  [        R&                  5      (       aj  [        R(                  " U R                  5      R*                  S	-   n	[        R(                  " U R                  5      R,                  S	-
  n
UR/                  XS
9nO[        R$                  " U R                  [        R0                  5      (       ac  [        R(                  " U R                  5      R*                  n	[        R(                  " U R                  5      R,                  n
UR/                  XS
9nUR                  U R                  5      nU R                  [        R2                  :X  a$  UR/                  U R                  U R
                  S
9nU$ )a  Generates a single random sample inside the Box.

In creating a sample of the box, each coordinate is sampled (independently) from a distribution
that is chosen according to the form of the interval:

* :math:`[a, b]` : uniform distribution
* :math:`[a, \infty)` : shifted exponential distribution
* :math:`(-\infty, b]` : shifted negative exponential distribution
* :math:`(-\infty, \infty)` : normal distribution

Args:
    mask: A mask for sampling values from the Box space, currently unsupported.
    probability: A probability mask for sampling values from the Box space, currently unsupported.

Returns:
    A sampled value from the Box
z4Box.sample cannot be provided a mask, actual value: z@Box.sample cannot be provided a probability mask, actual value: fint64r+   )r   )r:   r=   r   )rL   rO   rN      )r   r   )rV   errorErrorr-   rT   r=   rY   r   emptyr4   r;   r>   	np_randomnormalexponentialr:   uniformfloorr   signedintegerr8   r   r   clipunsignedintegerrp   )rD   maskprobabilityr=   sample	unboundedupp_boundedlow_boundedboundedrF   rG   s              r   r   
Box.sampleZ  s   $ ))//FtfM  $))//RS^R_`  !JJOOs2tyy		8H8H8QTU8U$**% '''4+=+=*==	)))D,>,>>((D,>,>+>>$$t'9'99 !NN11y7K7Q7Q1R NN&&K,D,J,J&Khh{#$ 	 ^^''[-E-K-K'LL  	
 ..00!G<L<R<R 1 
 ::??o-XXf%F ==R%5%566,0014I,0014I[[Y[>F]]4::r'9'9::,00I,00I[[Y[>Ftzz* ::![[TXX499[=Fr   c                4   [        U[        R                  5      (       d>  [        R                  R                  S5         [        R                  " XR                  S9n[        [        R                  " UR                  U R                  5      =(       ak    UR                  U R                  :H  =(       aK    [        R                  " XR                  :  5      =(       a"    [        R                  " XR                  :*  5      5      $ ! [        [        4 a     gf = f)z?Return boolean specifying if x is a valid member of this space.zCasting input x to numpy array.rK   F)r/   r   r3   rV   rW   rX   asarrayr-   r,   r0   rj   can_castr4   r1   r:   r=   )rD   xs     r   containsBox.contains  s    !RZZ((JJOO=>JJq

3 KK, '4::%'qHH}%' qII~&	
 	
 	* s    D DDc                L    U Vs/ s H  o"R                  5       PM     sn$ s  snf )zCConvert a batch of samples from this space to a JSONable data type.)tolistrD   sample_nr   s      r   to_jsonableBox.to_jsonable  s    .67hFh777s   !c                j    U Vs/ s H!  n[         R                  " X R                  S9PM#     sn$ s  snf )zCConvert a JSONable data type to a batch of samples from this space.rK   )r   r   r-   r   s      r   from_jsonableBox.from_jsonable  s'    CKL8

648LLLs   (0c           	     p    SU R                    SU R                   SU R                   SU R                   S3	$ )zA string representation of this space.

The representation will include bounds, shape and dtype.
If a bound is uniform, only the corresponding scalar will be given to avoid redundant and ugly strings.

Returns:
    A representation of the space
zBox(z, ))r@   rA   r4   r-   r`   s    r   __repr__Box.__repr__  s7     dmm_Bt~~&6bBtzzlRSTTr   c                j   [        U[        5      =(       a    U R                  UR                  :H  =(       a}    U R                  UR                  :H  =(       a]    [        R
                  " U R                  UR                  5      =(       a+    [        R
                  " U R                  UR                  5      $ )zVCheck whether `other` is equivalent to this instance. Doesn't check dtype equivalence.)r/   r   r4   r-   r   allcloser:   r=   )rD   others     r   __eq__
Box.__eq__  sw     uc" 3u{{*3u{{*3 DHHeii03 DIIuzz2	
r   c                   > [         TU ]  U5        [        U S5      (       d  [        U R                  5      U l        [        U S5      (       d  [        U R                  5      U l        gg)zCSets the state of the box for unpickling a box with legacy support.r@   rA   N)rB   __setstate__hasattrr   r:   r@   r=   rA   )rD   staterH   s     r   r   Box.__setstate__  sQ    U# tZ((,TXX6DMt[))-dii8DN *r   )r5   r>   r;   r-   r=   rA   r:   r@   )
r:   SupportsFloat | NDArray[Any]r=   r   r4   zSequence[int] | Noner-   z.type[np.floating[Any]] | type[np.integer[Any]]rE   z int | np.random.Generator | None)returnztuple[np.ndarray, np.ndarray])r   ztuple[int, ...])rg   )rk   r   r   rj   )NN)r}   Noner~   r   r   NDArray[Any])r   r   r   rj   )r   zSequence[NDArray[Any]]r   z
list[list])r   zSequence[float | int]r   zlist[NDArray[Any]])r   r   )r   r   r   rj   )r   z-Iterable[tuple[str, Any]] | Mapping[str, Any])__name__
__module____qualname____firstlineno____doc__r   float32rC   r9   r<   propertyr4   rd   rl   r   r   r   r   r   r   r   __static_attributes____classcell__)rH   s   @r   r   r   %   s    . '+@B

15q7)q7 +q7 $	q7
 >q7 /q7 q7fC9JD:L    2IV
 8M	U
	9 	9r   r   )r   r   r   r   )r   r   r   rj   )r   
__future__r   collections.abcr   r   r   typingr   r   numpyr   numpy.typingr	   	gymnasiumrV   gymnasium.spaces.spacer
   r   r   r   rc   r   r   <module>r      sB    P " 7 7 %     ("Y
v9%
 v9r   