a
    tDf#                     @  sn   d dl mZ d dlZd dlmZmZmZ d dlm	Z	 dZ
ee
Zdd Zdd	 Ze	edd
ddddZdS )    )annotationsN)asarray	blockwiseeinsum_lookup)derived_from4abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZc                  O  s^   | d}| d}| d}tt| d }||g| R d|i|}||jd|  S )N
subscriptsncontract_indskernel_dtyper   dtype   )popr   dispatchtypeZreshapeshape)operandskwargsr   r	   r   einsumchunk r   c/nfs/NAS7/SABIOD/METHODE/ermites/ermites_venv/lib/python3.9/site-packages/dask/array/einsumfuncs.pychunk_einsum   s    


r   c                 C  s  t | dkrtdt| d trt| d dd}dd | dd D } |D ]"}|d	v rZqL|tvrLtd
| qLn0t| }g }g }tt | d D ]$}||	d ||	d qt |r|d nd}dd |D } d}t |d }t
|D ]Z\}	}
|
D ]<}|tu r|d7 }n"t|tr2|t| 7 }ntdq |	|kr|d7 }q|dur|d7 }|D ]<}|tu r~|d7 }n"t|tr|t| 7 }ntdqfd|v sd|v r|ddkp|ddk}|s|ddkrtdd|v r|dddddd}ttt| }d|}d}d|v r`|d\}}|d}d}n|d}d}t
|D ]\}	}
d|
v rv|
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|||	< qvd|}|dkr`d}n|| d }|r|d|d| 7 }n|d}|dd}tt|D ]4}|tvrtd
| ||dkr||7 }qdtt|t| }|d| | 7 }d|v r |d\}}nV|}|dd}d}tt|D ]4}|tvrZtd
| ||dkr@||7 }q@|D ]}||vrztd| qzt |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>9       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   K   r    z...z=For this input type lists must contain either int or Ellipsis,->->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
isinstancestr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_Zoutput_listlastnumsubinvalidusedZunusedZellipse_inds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    











 









rH   F)r   optimizesplit_everyc              	   O  s"  | }t |\}}}d||f}	| du r<tjdd |D  } |durndd |D }
tj|	g|
R d|i\}}dd |d	D }d
d |D }|t| }t|}tt	t
|t
| gdd t||D R dd |D | |	|||d|}|dkrt|}|jtt||| |dS |S )a  Dask added an additional keyword-only argument ``split_every``.

    split_every: int >= 2 or dict(axis: int), optional
        Determines the depth of the recursive aggregation.
        Defaults to ``None`` which would let dask heuristically
        decide a good default.
    r%   Nc                 S  s   g | ]
}|j qS r   )r   r   r   r   r   r      r    zeinsum.<locals>.<listcomp>Fc                 S  s$   g | ]}t j|jd |jdqS )r   )r   )npZbroadcast_tor   r   r   r   r   r   r   r      r    rI   c                 S  s   g | ]}t |qS r   )tuple)r   ir   r   r   r      r    r$   c                 S  s   h | ]}|D ]}|qqS r   r   )r   rM   ar   r   r   	<setcomp>   r    zeinsum.<locals>.<setcomp>c                 s  s   | ]}|D ]
}|V  q
qd S )Nr   )r   ZaprN   r   r   r   	<genexpr>   r    zeinsum.<locals>.<genexpr>c                 S  s   i | ]
}|d qS r   r   )r   indr   r   r   
<dictcomp>   r    zeinsum.<locals>.<dictcomp>)Zadjust_chunksr   r   r
   r	   rI   r   )ZaxisrJ   )rH   r:   rK   Zresult_typeZeinsum_pathr;   r9   r*   r   r   rL   zipsumr0   r1   )r   rI   rJ   r   r   Zeinsum_dtypeinputsoutputsopsr   Zfake_opsr@   Zall_indsZcontract_indsr	   resultsizer   r   r   r      sB    

r   )
__future__r   numpyrK   Zdask.array.corer   r   r   Z
dask.utilsr   r6   r9   r/   r   rH   r   r   r   r   r   <module>   s    +