ó
¦–Õ\c           @` së  d  d l  m Z m Z m Z d  d l m Z d  d l Z d  d l Z y¿ e j	 ƒ  ­ e j
 e j d d d d ƒe j d d d d d e j ƒƒ sØ e j
 e j d d	 d d
 ƒd ƒ sØ e j
 e j d d ƒ d ƒ rç e d ƒ ‚ n  e j Z e j j Z Wd QXWnJ e k
 rOd d d „ Z e j j j e e j j j ƒ  d  d ƒ Z n Xe e j ƒ d k  rzd „  Z d „  Z n  d „  Z d „  Z e e j ƒ e d ƒ k sÂe e j ƒ e d ƒ k rËe Z n e Z d e f d „  ƒ  YZ d S(   i    (   t   absolute_importt   divisiont   print_function(   t   LooseVersionNgš™™™™™Ù?i   t   castingt   unsafet   dtypeg      à?t   i8i   sI   Divide not working with dtype: https://github.com/numpy/numpy/issues/3484c         C` s7   t  j |  | | ƒ } | d k	 r3 | j | ƒ } n  | S(   sÍ   Implementation of numpy.divide that works with dtype kwarg.

        Temporary compatibility fix for a bug in numpy's version. See
        https://github.com/numpy/numpy/issues/3484 for the relevant issue.N(   t   npt   dividet   Nonet   astype(   t   x1t   x2t   outR   t   x(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyR	      s    s   1.15.0c   	      C` s  t  j | j t  j ƒ s' t d ƒ ‚ n  t |  ƒ | j k rK t d ƒ ‚ n  d | j } t t	 | ƒ ƒ d  g t t	 | d | j ƒ ƒ } g  } xr t | |  ƒ D]a \ } } | d  k rÉ | j | ƒ q¡ | |  d | | d } | j t  j | ƒ j | ƒ ƒ q¡ Wt | ƒ S(   Ns"   `indices` must be an integer arrays;   `indices` and `arr` must have the same number of dimensionsi   iÿÿÿÿ(   i   (   iÿÿÿÿ(   R   t
   issubdtypeR   t   integert
   IndexErrort   lent   ndimt
   ValueErrort   listt   rangeR
   t   zipt   appendt   aranget   reshapet   tuple(	   t	   arr_shapet   indicest   axist
   shape_onest	   dest_dimst   fancy_indext   dimt   nt	   ind_shape(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   _make_along_axis_idx*   s    #c         C` sf   | d k r- |  j }  t |  ƒ f } d } n% | d k  rI |  j | } n  |  j } |  t | | | ƒ S(   sŸ  
        Take values from the input array by matching 1d index and data slices.
        This iterates over matching 1d slices oriented along the specified axis in
        the index and data arrays, and uses the former to look up values in the
        latter. These slices can be different lengths.
        Functions returning an index along an axis, like `argsort` and
        `argpartition`, produce suitable indices for this function.
        .. versionadded:: 1.15.0
        Parameters
        ----------
        arr: ndarray (Ni..., M, Nk...)
            Source array
        indices: ndarray (Ni..., J, Nk...)
            Indices to take along each 1d slice of `arr`. This must match the
            dimension of arr, but dimensions Ni and Nj only need to broadcast
            against `arr`.
        axis: int
            The axis to take 1d slices along. If axis is None, the input array is
            treated as if it had first been flattened to 1d, for consistency with
            `sort` and `argsort`.
        Returns
        -------
        out: ndarray (Ni..., J, Nk...)
            The indexed result.
        Notes
        -----
        This is equivalent to (but faster than) the following use of `ndindex` and
        `s_`, which sets each of ``ii`` and ``kk`` to a tuple of indices::
            Ni, M, Nk = a.shape[:axis], a.shape[axis], a.shape[axis+1:]
            J = indices.shape[axis]  # Need not equal M
            out = np.empty(Nk + (J,) + Nk)
            for ii in ndindex(Ni):
                for kk in ndindex(Nk):
                    a_1d       = a      [ii + s_[:,] + kk]
                    indices_1d = indices[ii + s_[:,] + kk]
                    out_1d     = out    [ii + s_[:,] + kk]
                    for j in range(J):
                        out_1d[j] = a_1d[indices_1d[j]]
        Equivalently, eliminating the inner loop, the last two lines would be::
                    out_1d[:] = a_1d[indices_1d]
        See Also
        --------
        take : Take along an axis, using the same indices for every 1d slice
        put_along_axis :
            Put values into the destination array by matching 1d index and data slices
        Examples
        --------
        For this sample array
        >>> a = np.array([[10, 30, 20], [60, 40, 50]])

        We can sort either by using sort directly, or argsort and this function
        >>> np.sort(a, axis=1)
        array([[10, 20, 30],
               [40, 50, 60]])
        >>> ai = np.argsort(a, axis=1); ai
        array([[0, 2, 1],
               [1, 2, 0]])
        >>> take_along_axis(a, ai, axis=1)
        array([[10, 20, 30],
               [40, 50, 60]])

        The same works for max and min, if you expand the dimensions:
        >>> np.expand_dims(np.max(a, axis=1), axis=1)
        array([[30],
               [60]])
        >>> ai = np.expand_dims(np.argmax(a, axis=1), axis=1)
        >>> ai
        array([[1],
               [0]])
        >>> take_along_axis(a, ai, axis=1)
        array([[30],
               [60]])

        If we want to get the max and min at the same time,
        we can stack the indices first:
        >>> ai_min = np.expand_dims(np.argmin(a, axis=1), axis=1)
        >>> ai_max = np.expand_dims(np.argmax(a, axis=1), axis=1)
        >>> ai = np.concatenate([ai_min, ai_max], axis=1)
        >>> ai
        array([[0, 1],
               [1, 0]])
        >>> take_along_axis(a, ai, axis=1)
        array([[10, 30],
               [40, 60]])
        i    N(   R
   t   flatR   R   t   shapeR&   (   t   arrR   R   R   (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   take_along_axisA   s    W			c         C` sn   i | d 6g  | D] } |  j  | d ^ q d 6g  | D] } |  j  | d ^ q6 d 6|  j d 6} t j | ƒ S(   Nt   namesi    t   formatsi   t   offsetst   itemsize(   t   fieldsR.   R   R   (   R   t   indext   namet   new(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   _make_sliced_dtype_np_ge_16¥   s    %%c         C` s0   t  j g  | D] } | |  | f ^ q ƒ } | S(   N(   R   R   (   R   R0   R1   t   dt(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   _make_sliced_dtype_np_lt_14¶   s    ,s   1.16.0s   1.14.0t	   _Recurserc           B` s>   e  Z d  Z d „  Z d „  d „  d „  d „ Z d d „ Z RS(   s;   
    Utility class for recursing over nested iterables
    c         C` s   | |  _  d  S(   N(   t
   recurse_if(   t   selfR7   (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   __init__Ì   s    c         K` s   |  S(   N(    (   R   t   kwargs(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   <lambda>Ñ   t    c         K` s   |  S(   N(    (   R   R:   (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyR;   Ò   R<   c          K` s   |  S(   N(    (   R:   (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyR;   Ó   R<   c         ` s(   ‡  ‡ ‡ ‡ ‡ f d †  ‰  ˆ  | |  S(   s{  
        Iterate over the nested list, applying:
        * ``f_map`` (T -> U) to items
        * ``f_reduce`` (Iterable[U] -> U) to mapped items

        For instance, ``map_reduce([[1, 2], 3, 4])`` is::

            f_reduce([
              f_reduce([
                f_map(1),
                f_map(2)
              ]),
              f_map(3),
              f_map(4)
            ]])


        State can be passed down through the calls with `f_kwargs`,
        to iterables of mapped items. When kwargs are passed, as in
        ``map_reduce([[1, 2], 3, 4], **kw)``, this becomes::

            kw1 = f_kwargs(**kw)
            kw2 = f_kwargs(**kw1)
            f_reduce([
              f_reduce([
                f_map(1), **kw2)
                f_map(2,  **kw2)
              ],      **kw1),
              f_map(3, **kw1),
              f_map(4, **kw1)
            ]],     **kw)
        c         ` sL   ˆ j  |  ƒ s ˆ |  |  Sˆ |   ‰  ˆ ‡ ‡  f d †  |  Dƒ |  Sd  S(   Nc         3` s   |  ] } ˆ  | ˆ  Vq d  S(   N(    (   t   .0t   xi(   t   ft   next_kwargs(    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pys	   <genexpr>û   s   (   R7   (   R   R:   (   R?   t   f_kwargst   f_mapt   f_reduceR8   (   R@   s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyR?   õ   s    (    (   R8   R   RB   RC   RA   R:   (    (   R?   RA   RB   RC   R8   s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt
   map_reduceÏ   s    &	c         c` sq   |  j  | ƒ } | | | f V| s' d SxC t | ƒ D]5 \ } } x& |  j | | | f ƒ D] } | VqZ Wq4 Wd S(   sB  
        Iterate over x, yielding (index, value, entering), where

        * ``index``: a tuple of indices up to this point
        * ``value``: equal to ``x[index[0]][...][index[-1]]``. On the first iteration, is
                     ``x`` itself
        * ``entering``: bool. The result of ``recurse_if(value)``
        N(   R7   t	   enumeratet   walk(   R8   R   R0   t
   do_recurset   iR>   t   v(    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyRF      s    	 (    (   t   __name__t
   __module__t   __doc__R9   RD   RF   (    (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyR6   Ã   s   	-(   t
   __future__R    R   R   t   distutils.versionR   t   numpyR   t   warningst   catch_warningst   allcloseR	   t   floatt	   TypeErrort   mat	   ma_divideR
   t   coret   _DomainedBinaryOperationt   _DomainSafeDividet   __version__R&   R*   R3   R5   t   _make_sliced_dtypet   objectR6   (    (    (    s6   lib/python2.7/site-packages/dask/array/numpy_compat.pyt   <module>   s6   %%	
	d			