B
    T\*                 @   s   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d	l
mZ dd
lmZ ddlmZ ddlmZ dd Zdd Zdd Zdd ZdS )    )absolute_importdivisionprint_function)product)mulN   )Array   )tokenize)flatten)reduce)HighLevelGraph)Mc                s  t dd |D stt| d }t|d }dd tt| D }dd tt|D }x|dksp|dkr| | || kr|| ||< || ||< |d8 }|d8 }q^| | }|| }|dkrd||< |d8 }q^|dkrd||< |d8 }q^||k r|d }	x4|	dkr4tt| |	|d  |k r4|	d8 }	qW tt| |	|d  |krZtd	x*t|	d |d D ]}
| |
 f||
< qnW tttt||	d |d  }t||	 |||	< tt| |	d |d  t	fd
d||	 D ||< |d8 }|	d }q^||kr^|d }x4|dkrFtt|||d  |k rF|d8 }qW tt|||d  |krltd	tt||d |d   t
||  ||< x*t|d |d D ]}
||
 f||
< qW t	 fdd|| D ||< |d }|d8 }q^W t	|t	|fS )Nc             s   s   | ]}t |tV  qd S )N)
isinstancetuple).0c r   1lib/python3.7/site-packages/dask/array/reshape.py	<genexpr>   s    z"reshape_rechunk.<locals>.<genexpr>r   c             S   s   g | ]}d qS )Nr   )r   ir   r   r   
<listcomp>   s    z#reshape_rechunk.<locals>.<listcomp>c             S   s   g | ]}d qS )Nr   )r   r   r   r   r   r      s    r   )r   zShapes not compatiblec             3   s   | ]} | V  qd S )Nr   )r   r   )prodr   r   r   4   s    c             3   s   | ]}|  V  qd S )Nr   )r   r   )csr   r   r   G   s    )allAssertionErrorlenranger   r   
ValueErrormapexpand_tupler   contract_tuple)ZinshapeZoutshapeinchunksZiiZoiZresult_inchunksZresult_outchunksZdinZdoutZileftr   Zchunk_reductionZoleftr   )r   r   r   reshape_rechunk   s`    


( 
(r#   c             C   s   |dkr| S g }xX| D ]P}|}t || d}x*|d| krV|t| |t|8 }q.W |r|| qW t| t|ks~tt|S )z

    >>> expand_tuple((2, 4), 2)
    (1, 1, 2, 2)

    >>> expand_tuple((2, 4), 3)
    (1, 1, 1, 1, 2)

    >>> expand_tuple((3, 4), 2)
    (1, 2, 2, 2)

    >>> expand_tuple((7, 4), 3)
    (2, 2, 3, 1, 1, 2)
    r   r	   )maxappendintsumr   r   )chunksfactoroutr   xpartr   r   r   r    O   s    
r    c             C   s`   t | | dkstg }d}x:| D ]2}||7 }|| }|| }|| }|r"|| q"W t|S )z Return simple chunks tuple such that factor divides all elements

    Examples
    --------

    >>> contract_tuple((2, 2, 8, 4), 4)
    (4, 8, 4)
    r   )r'   r   r%   r   )r(   r)   r*   ZresidualchunkZdivZgoodr   r   r   r!   n   s    	
r!   c                s  ddl m} tt||}dd |D }t|t|k rt|t| dkrTtdt|dkrn| jdkrn| S || jtt	|d  t fdd|D }t
t| jrtd| jtt	|d| jkrtd	| j|kr| S d
t| | }| jdkr\tt|  }|fdt|  tj||fi}tdd |D }tj||| gd}t|||| jdS t| j|| j\}	}
| |	}tt|jgfdd |	D  }tt|gfdd |
D  }tt|
 }dd t|||D }tj|||gd}t|||
| jdS )a/   Reshape array to new shape

    This is a parallelized version of the ``np.reshape`` function with the
    following limitations:

    1.  It assumes that the array is stored in C-order
    2.  It only allows for reshapings that collapse or merge dimensions like
        ``(1, 2, 3, 4) -> (1, 6, 4)`` or ``(64,) -> (4, 4, 4)``

    When communication is necessary this algorithm depends on the logic within
    rechunk.  It endeavors to keep chunk sizes roughly the same when possible.

    See Also
    --------
    dask.array.rechunk
    numpy.reshape
    r   )sanitize_indexc             S   s   g | ]}|d kr|qS )r   )r   sr   r   r   r      s    zreshape.<locals>.<listcomp>z&can only specify one unknown dimensionc             3   s   | ]}|d kr n|V  qdS )r/   Nr   )r   r0   )missing_sizer   r   r      s    zreshape.<locals>.<genexpr>z/Array chunk size or shape is unknown. shape: %sz)total size of new array must be unchangedzreshape-)r   c             s   s   | ]}|fV  qd S )Nr   )r   dr   r   r   r      s    )Zdependencies)dtypec             S   s   g | ]}t t|qS r   )r   r   )r   r   r   r   r   r      s    c             S   s   g | ]}t t|qS r   )r   r   )r   r   r   r   r   r      s    c             S   s    i | ]\}}}t j||f|qS r   )r   reshape)r   abshaper   r   r   
<dictcomp>   s    zreshape.<locals>.<dictcomp>) Zslicingr.   r   r   r   r   ndimsizer   r   npZisnanr'   r7   r
   Znpartitionsnextr   Z__dask_keys__r   r4   r   Zfrom_collectionsr   r3   r#   r(   Zrechunklistr   namezip)r+   r7   r.   Zknown_sizesr>   keyZdskr(   Zgraphr"   Z	outchunksZx2Zin_keysZout_keysZshapesr   )r1   r   r4      s>    

 r4   )Z
__future__r   r   r   	itertoolsr   operatorr   Znumpyr;   Zcorer   baser
   r   Zcompatibilityr   Zhighlevelgraphr   Zutilsr   r#   r    r!   r4   r   r   r   r   <module>   s   ?