
    bi0                       d Z ddlmZ ddlZddlmZmZ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 d	 Zej&                  Zej(                  Zej*                  Zej,                  Z eej.                        Z eej0                        Z eej2                        Z eej4                        Zej6                  Zej8                  Zej:                  Zej<                  Zej>                  Zej@                  Z ejB                  Z!ejD                  Z"ejF                  Z# ejH                  e%      5  ejL                  Z&ddd       ejN                  Z' ejH                  e%      5  ejP                  Z(ddd       ejR                  Z) ejH                  e%      5  ejT                  Z*ddd       dd
Z+ddZ,d Z-d Z.d Z/d Z0d Z1ddZ2ddZ3ddZ4ddZ5d Z6d Z7d Z8y# 1 sw Y   xY w# 1 sw Y   yxY w# 1 sw Y   RxY w)z+A set of NumPy functions to apply per chunk    )annotationsN)	ContainerIterableSequencewraps)Integral)concat)flattenc                0     t               d fd	       }|S )zU
    A wrapper for functions that don't provide keepdims to ensure that they do.
    c                    	| g|d|i|}|s|S |}|t        | j                        }t        |t        t        t
        f      s|g}t               }t        | j                        D ]  }||v r|dz  }|t        d       fz  } ||   }|S )NaxisN)rangendim
isinstancer   r   r   tupleslice)
xr   keepdimsargskwargsraxesr_slice	each_axis
a_callables
            K/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/dask/array/chunk.pykeepdims_wrapped_callablez3keepdims_wrapper.<locals>.keepdims_wrapped_callable   s    q545d5f5H<=D$Hh ?@6D'qvv 	*ID 7"E$K>)		* gJ    )NNr   )r   r   s   ` r   keepdims_wrapperr!      s$    
 : 2 %$r    c                   t        |j                        D ]  }|vsd|<    |r,t        fdt        |j                        D              }||   }t        t        t        |j                        D cg c]  }|j                  |   |   z  |   f c}            } | |j                  |      fdt        t        d|j                  dz  d            i|S c c}w )a  Coarsen array by applying reduction to fixed size neighborhoods

    Parameters
    ----------
    reduction: function
        Function like np.sum, np.mean, etc...
    x: np.ndarray
        Array to be coarsened
    axes: dict
        Mapping of axis to coarsening factor

    Examples
    --------
    >>> x = np.array([1, 2, 3, 4, 5, 6])
    >>> coarsen(np.sum, x, {0: 2})
    array([ 3,  7, 11])
    >>> coarsen(np.max, x, {0: 3})
    array([3, 6])

    Provide dictionary of scale per dimension

    >>> x = np.arange(24).reshape((4, 6))
    >>> x
    array([[ 0,  1,  2,  3,  4,  5],
           [ 6,  7,  8,  9, 10, 11],
           [12, 13, 14, 15, 16, 17],
           [18, 19, 20, 21, 22, 23]])

    >>> coarsen(np.min, x, {0: 2, 1: 3})
    array([[ 0,  3],
           [12, 15]])

    You must avoid excess elements explicitly

    >>> x = np.array([1, 2, 3, 4, 5, 6, 7, 8])
    >>> coarsen(np.min, x, {0: 3}, trim_excess=True)
    array([1, 4])
       c              3  r   K   | ].  \  }}||   z  rt        d ||   z         nt        dd       0 yw)r   Nr   ).0idr   s      r   	<genexpr>zcoarsen.<locals>.<genexpr>   sD      
1 )*DGE!q47{^$tT9JJ
s   47r      )r   r   r   	enumerateshaper
   reshape)	reductionr   r   trim_excessr   r'   indnewshapes     `     r   coarsenr2   U   s    P 166] D=DG  
!!''*
 
 cF VuQVV}U!aggajDG3T!W=UVWHQYYx(XuU1affqj!5L/MXQWXX Vs   5!Cc                    t        |t              r|g| j                  z  }t        |t              r2t	        | j                        D cg c]  }|j                  |d       }}| t        d |D                 S c c}w )aC  Trim boundaries off of array

    >>> x = np.arange(24).reshape((4, 6))
    >>> trim(x, axes={0: 0, 1: 1})
    array([[ 1,  2,  3,  4],
           [ 7,  8,  9, 10],
           [13, 14, 15, 16],
           [19, 20, 21, 22]])

    >>> trim(x, axes={0: 1, 1: 1})
    array([[ 7,  8,  9, 10],
           [13, 14, 15, 16]])
    r   c              3  >   K   | ]  }t        ||r| nd         y wr   r%   )r&   axs     r   r)   ztrim.<locals>.<genexpr>   s     Ab5BbSD1As   )r   r	   r   dictr   getr   )r   r   r'   s      r   trimr8      sg     $!v$(-aff61A66UADAABB 7s   A8c                   |du sJ d   t        |      | j                     k\  r| S t        j                  | |       } |dkD  rt	        | d      nt	        |       | t        fdt        | j                        D                 S )a  Chunk and combine function of topk

    Extract the k largest elements from a on the given axis.
    If k is negative, extract the -k smallest elements instead.
    Note that, unlike in the parent function, the returned elements
    are not sorted internally.
    Tr   r   Nc              3  B   K   | ]  }|k(  rn
t        d         y wr   r%   r&   r'   r   k_slices     r   r)   ztopk.<locals>.<genexpr>   s      PQa4i7U4[8P   )absr,   np	partitionr   r   r   r   )akr   r   r=   s     ` @r   topkrD      s     t7D
1v
Q&A!"QeQBoE1"IGUP%-PPQQr    c                    |du sJ t        | ||      } d   t        j                  |       } |dk  r| S | t        fdt	        | j
                        D                 S )zmFinal aggregation function of topk

    Invoke topk one final time and then sort the results internally.
    Tr   r:   c              3  X   K   | ]!  }|k(  rt        d d d      n
t        d        # y wNr%   r&   r'   r   s     r   r)   z!topk_aggregate.<locals>.<genexpr>   .      
DEQ$YE$b!E$K?
   '*)rD   r@   sortr   r   r   )rB   rC   r   r   s     ` r   topk_aggregaterM      sr    
 tQ4"A7D
A1u 
INqvv
 	
 r    c                
    | |fS )z^Preparatory step for argtopk

    Put data together with its original indices in a tuple.
     )rB   idxs     r   argtopk_preprocessrQ      s    
 c6Mr    c           
       
 |du sJ d   t        | t              rt        t        |             } t        j                  | D cg c]  \  }}|	 c}}      }t        j                  | D cg c]%  \  }}t        j
                  ||j                        ' c}}      }n| \  }}t        |      |j                     k\  r| S t        j                  ||       }	|dkD  rt        | d      nt        |       
|	t        
fdt        |j                        D                 }	t        j                  ||	      t        j                  ||	      fS c c}}w c c}}w )a)  Chunk and combine function of argtopk

    Extract the indices of the k largest elements from a on the given axis.
    If k is negative, extract the indices of the -k smallest elements instead.
    Note that, unlike in the parent function, the returned elements
    are not sorted internally.
    Tr   r:   Nc              3  B   K   | ]  }|k(  rn
t        d         y wr   r%   r<   s     r   r)   zargtopk.<locals>.<genexpr>   s      Sdgd;Sr>   )r   listr   r@   concatenatebroadcast_tor,   r?   argpartitionr   r   r   r   take_along_axis)
a_plus_idxrC   r   r   ai_rB   idxirP   idx2r=   s     `       @r   argtopkr^      s'    t7D*d#'*-.
NNJ752qB7>nn=GHTR__T288,H$
 3
1v??1qbt,D!"QeQBoE1"IGSU166]SSTDat,b.@.@dD.QQQ 8Hs   E
/*E
c                $   |du sJ t        |       dkD  r| n| d   } t        | ||      \  }}d   t        j                  |      }t        j                  ||      }|dk  r|S |t        fdt        |j                        D                 S )zFinal aggregation function of argtopk

    Invoke argtopk one final time, sort the results internally, drop the data
    and return the index only.
    Tr#   r   r:   c              3  X   K   | ]!  }|k(  rt        d d d      n
t        d        # y wrG   r%   rI   s     r   r)   z$argtopk_aggregate.<locals>.<genexpr>   rJ   rK   )lenr^   r@   argsortrX   r   r   r   )rY   rC   r   r   rB   rP   r]   s     `    r   argtopk_aggregaterc      s     t":2
1JZD(3FAs7D::ad#D


S$
-C1u
 
INsxx
 	
 r    c                R    ddl m}  || ||||      }t        |      |kD  r|d d S |S )Nr   )arange_safelikerH   )dask.array.utilsre   ra   )startstopsteplengthdtyperg   re   ress           r   arangero     s3    ,
eT4T
:C3x&(3s81c1r    c                    ddl m} t        | |      r| j                         } t        ||      r|j                         }t	        j
                  | ||||      S )Nr   )Array)endpointrm   )dask.array.corerq   r   computer@   linspace)ri   rj   numrr   rm   rq   s         r   ru   ru   
  sF    %%$||~;;udC(%HHr    c                (     | j                   |fi |S r   )astype)r   astype_dtyper   s      r   rx   rx     s    188L+F++r    c                h   |dk(  r)	 t        j                  | |       } | j                  |      S 	 t        j                  | |       } | j
                  j                  |      j
                  S # t        $ r t        j                  |       } Y nw xY w# t        $ r t        j                  |       } Y iw xY w)NCrf   )r@   ascontiguousarray	TypeErrorviewasfortranarrayT)r   rm   orders      r   r~   r~     s    |	($$QQ/A vve}	%!!!!,A ssxx     	($$Q'A	(  	%!!!$A	%s"   A, B ,BBB10B1c                H   ddl m}m}  | ||             j                  t        j
                        t	        j                  dk  |z         |z
  dk\  | j                     k  z  }|   | t        fdt        | j                        D                 S )a  Chunk function of `slice_with_int_dask_array_on_axis`.
    Slice one chunk of x by one chunk of idx.

    Parameters
    ----------
    x: ndarray, any dtype, any shape
        i-th chunk of x
    idx: ndarray, ndim=1, dtype=any integer
        j-th chunk of idx (cartesian product with the chunks of x)
    offset: ndarray, shape=(1, ), dtype=int64
        Index of the first element along axis of the current chunk of x
    x_size: int
        Total size of the x da.Array along axis
    axis: int
        normalized axis to take elements from (0 <= axis < x.ndim)

    Returns
    -------
    x sliced along axis, using only the elements of idx that fall inside the
    current chunk.
    r   )asarray_safemeta_from_arrayrf   c              3  B   K   | ]  }|k(  rn
t        d         y wr   r%   )r&   r'   r   rP   s     r   r)   z,slice_with_int_dask_array.<locals>.<genexpr>T  s      L!t)3t4Lr>   )rh   r   r   rx   r@   int64wherer,   r   r   r   )r   rP   offsetx_sizer   r   r   
idx_filters    `  `   r   slice_with_int_dask_arrayr   )  s    , ?
s!3
4C **RXX
C ((37C&L#
.C
 ,C (sQWWT]23J
j/C ULeAFFmLLMMr    c                  	 | j                  t        j                        } t        j                  | dk  | t	        |      z   |       } d}d}t        j
                  |       	|D ]b  }| |k\  | ||z   k  z  }t        j                  |      }	t        j                  ||dz
  |z   d      z  	||z  }|j                  dkD  s[||d   z  }d |t        	fdt        |j                        D                 S )aS  Final aggregation function of `slice_with_int_dask_array_on_axis`.
    Aggregate all chunks of x by one chunk of idx, reordering the output of
    `slice_with_int_dask_array`.

    Note that there is no combine function, as a recursive aggregation (e.g.
    with split_every) would not give any benefit.

    Parameters
    ----------
    idx: ndarray, ndim=1, dtype=any integer
        j-th chunk of idx
    chunk_outputs: ndarray
        concatenation along axis of the outputs of `slice_with_int_dask_array`
        for all chunks of x and the j-th chunk of idx
    x_chunks: tuple
        dask chunks of the x da.Array along axis, e.g. ``(3, 3, 2)``
    axis: int
        normalized axis to take elements from (0 <= axis < x.ndim)

    Returns
    -------
    Selection from all chunks of x for the j-th chunk of idx, in the correct
    order
    r   r#   rH   c              3  B   K   | ]  }|k(  rn
t        d         y wr   r%   )r&   r'   r   	idx_finals     r   r)   z6slice_with_int_dask_array_aggregate.<locals>.<genexpr>  s%      
89dId3
r>   )rx   r@   r   r   sum
zeros_likecumsumsizer   r   r   )
rP   chunk_outputsx_chunksr   x_chunk_offsetchunk_output_offsetx_chunkr   idx_cumr   s
      `     @r   #slice_with_int_dask_array_aggregater   W  s    4 **RXX
C ((37C#h-/
5CN c"I /^+nw6N0NO
))J'RXXj'A+8K*KQOO	'!<<!72;./  
=B=CUCU=V
 	
 r    c                    	 | |   }	 |j                  j                  s,| j                  d|j                  z  k\  r|j                         }|S # t         $ r}t        d      |d}~ww xY w# t        $ r Y |S w xY w)af  Getitem function

    This function creates a copy of the desired selection for array-like
    inputs when the selection is smaller than half of the original array. This
    avoids excess memory usage when extracting a small portion from a large array.
    For more information, see
    https://numpy.org/doc/stable/reference/arrays.indexing.html#basic-slicing-and-indexing.

    Parameters
    ----------
    obj: ndarray, string, tuple, list
        Object to get item from.
    index: int, list[int], slice()
        Desired selection to extract from obj.

    Returns
    -------
    Selection obj[index]

    zTArray chunk size or shape is unknown. Possible solution with x.compute_chunk_sizes()Nr*   )
IndexError
ValueErrorflagsowndatar   copyAttributeError)objindexresultes       r   getitemr     s    *U||##AO(C[[]F M  =
 	  Ms)   A AA) 	A&A!!A&)	A65A6)Fr   )TN)r{   )9__doc__
__future__r   
contextlibcollections.abcr   r   r   	functoolsr   numbersr	   numpyr@   tlzr
   	dask.corer   r!   r   prodminmaxargmin	nanargminargmax	nanargmaxanyallnansumnanprod
nancumprod	nancumsumnanminnanmaxmeansuppressr   nanmeanvarnanvarstdnanstdr2   r8   rD   rM   rQ   r^   rc   ro   ru   rx   r~   r   r   r   rO   r    r   <module>r      s   1 "  9 9     %F 	ff	wwffff	"))	$R\\*		"))	$R\\*	ffff	
**]]
LL				wwZ( jjG 	ffZ( YYF 	ffZ( YYF6YrC,R$$R:,2	I,!+N\5p#Q
 
 
 s$   ,GG$G0G!$G-0G9