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mZmZ dZeeZd	d
 Zdd Zee	jedkZee	jdd ZdS )    )divisionprint_functionabsolute_import)LooseVersion)wrapsN)
basestring   )	blockwiseasarrayeinsum_lookupZ4abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZc              O   s\   | d}| d}| d}tt| d }||f| d|i|}||jd|  S )N
subscriptsncontract_indskernel_dtyper   dtype)r   )popr   dispatchtypeZreshapeshape)operandskwargsr   r   r   einsumchunk r   5lib/python3.7/site-packages/dask/array/einsumfuncs.pychunk_einsum   s    


r   c             C   s  t | dkrtdt| d trx| d dd}dd | dd D } x*|D ]"}|d	kr\qN|tkrNtd
| qNW n@t| }g }g }x8tt | d D ]$}||	d ||	d qW t |r|d nd}dd |D } d}t |d }xjt
|D ]^\}	}
xD|
D ]<}|tkr$|d7 }n"t|tr>|t| 7 }ntdqW |	|kr|d7 }qW |dk	r|d7 }xD|D ]<}|tkr|d7 }n"t|tr|t| 7 }ntdqxW d|ksd|kr|ddkp|ddk}|s |ddkrtdd|kr"|dddddd}ttt| }d|}d}d|krt|d\}}|d}d}n|d}d}xt
|D ]\}	}
d|
kr|
ddks|
ddkrtd| |	 jdkrd}n t| |	 jd}|t |
d 8 }||kr
|}|dk rtdn:|dkr:|
dd||	< n|| d }|
d|||	< qW d|}|dkrxd}n|| d }|r|d|d| 7 }nd}|dd}xDtt|D ]4}|tkrtd
| ||dkr||7 }qW dtt|t| }|d| | 7 }d|kr<|d\}}nZ|}|dd}d}xDtt|D ]4}|tkrxtd
| ||dkr^||7 }q^W x$|D ]}||krtd| qW t |dt | krtd||| fS )a  
    A reproduction of numpy's _parse_einsum_input()
    which in itself is a reproduction of
    c side einsum parsing in python.

    Returns
    -------
    input_strings : str
        Parsed input strings
    output_string : str
        Parsed output string
    operands : list of array_like
        The operands to use in the numpy contraction
    Examples
    --------
    The operand list is simplified to reduce printing:
    >> a = np.random.rand(4, 4)
    >> b = np.random.rand(4, 4, 4)
    >> __parse_einsum_input(('...a,...a->...', a, b))
    ('za,xza', 'xz', [a, b])
    >> __parse_einsum_input((a, [Ellipsis, 0], b, [Ellipsis, 0]))
    ('za,xza', 'xz', [a, b])
    r   zNo input operands  c             S   s   g | ]}t |qS r   )r
   ).0or   r   r   
<listcomp><   s    z&parse_einsum_input.<locals>.<listcomp>r   Nz.,->z#Character %s is not a valid symbol.   c             S   s   g | ]}t |qS r   )r
   )r   vr   r   r   r   N   s    z...z=For this input type lists must contain either int or Ellipsis,z->->z%Subscripts can only contain one '->'..TF   zInvalid Ellipses.r   zEllipses lengths do not match.z/Output character %s did not appear in the inputzDNumber of einsum subscripts must be equal to the number of operands.)len
ValueError
isinstancer   replaceeinsum_symbols_setlistrangeappendr   	enumerateEllipsisinteinsum_symbols	TypeErrorcountsetjoinsplitr   maxndimsorted)r   r   sZtmp_operandsZoperand_listZsubscript_listpZoutput_listZlastZnumsubZinvalidZusedZunusedZellipse_indsZlongestZ	input_tmpZ
output_subZsplit_subscriptsZout_subZellipse_countZrep_indsZout_ellipseZoutput_subscriptZtmp_subscriptsZnormal_indsZinput_subscriptscharr   r   r   parse_einsum_input   s    













 










r@   z1.12.0c           
   O   s  | dd}| dd }| dd}| dd}| dd }|rRtd	d
| |}t| \}}	}
d||	f}|d krtjdd |
D  }tr|dk	rdd |
D }tj|f|d|i\}}d|i}ni }dd |d
D }t	dd |D }|t	|	 }t
|}ttt|	t| fdd t|
|D dd |D ||||||d|}|dkrt
|	}|jtt||| |dS |S )NcastingZsafer   optimizeForderKsplit_everyz.einsum() got unexpected keyword argument(s) %sr#   z->c             S   s   g | ]
}|j qS r   )r   )r   r   r   r   r   r      s    zeinsum.<locals>.<listcomp>c             S   s$   g | ]}t j|jd |jdqS )r   )r   )npZbroadcast_tor   r   r   )r   r   r   r   r   r      s   c             S   s   g | ]}t |qS r   )tuple)r   ir   r   r   r      s    c             s   s   | ]}|D ]
}|V  q
qd S )Nr   )r   rH   ar   r   r   	<genexpr>   s    zeinsum.<locals>.<genexpr>c             s   s   | ]}|D ]
}|V  q
qd S )Nr   )r   ZaprI   r   r   r   rJ      s    c             S   s   i | ]
}d |qS )r   r   )r   Zindr   r   r   
<dictcomp>   s    zeinsum.<locals>.<dictcomp>)Zadjust_chunksr   r   r   r   rC   rA   r   )ZaxisrE   )r   r4   r7   r@   rF   Zresult_typeeinsum_can_optimizeZeinsum_pathr8   r6   r(   r	   r   rG   zipsumr-   r.   )r   r   rA   r   rB   rC   rE   Zeinsum_dtypeZinputsZoutputsZopsr   Zfake_ops_Zall_indsZcontract_indsr   resultsizer   r   r   r      sH    

r   )Z
__future__r   r   r   Zdistutils.versionr   	functoolsr   ZnumpyrF   Znumpy.compatr   Zcorer	   r
   r   r3   r6   r,   r   r@   __version__rL   r   r   r   r   r   <module>   s    (