o
    *ήc+                     @   s  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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mZ d dlmZ d dlmZ d dlmZmZm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' d dl(m)Z)m*Z* dddZ+dd Z,dS )    )defaultdict)Function)
_af_invert)Sum)Add)Mul)Integer)Pow)default_sort_key)KroneckerDelta)ArrayElementwiseApplyFunc)IndexedIndexedBase)Permutation)MatrixElement)
ArrayDiagonal	get_shapeArrayElement_array_tensor_product_array_diagonal_array_contraction
_array_add_permute_dimsOneArrayArrayAdd)_get_argindex_get_diagonal_indicesNc                    s   t | \}}tdd |D rt||}g }s|S dd  dd |D fddD D ]} ||s<| q0 fd	d|D  d
d tfdd|D t|trktfdd|j	D  S t
|S )a	  
    Parse indexed expression into a form useful for code generation.

    Examples
    ========

    >>> from sympy.tensor.array.expressions.conv_indexed_to_array import convert_indexed_to_array
    >>> from sympy import MatrixSymbol, Sum, symbols

    >>> i, j, k, d = symbols("i j k d")
    >>> M = MatrixSymbol("M", d, d)
    >>> N = MatrixSymbol("N", d, d)

    Recognize the trace in summation form:

    >>> expr = Sum(M[i, i], (i, 0, d-1))
    >>> convert_indexed_to_array(expr)
    ArrayContraction(M, (0, 1))

    Recognize the extraction of the diagonal by using the same index `i` on
    both axes of the matrix:

    >>> expr = M[i, i]
    >>> convert_indexed_to_array(expr)
    ArrayDiagonal(M, (0, 1))

    This function can help perform the transformation expressed in two
    different mathematical notations as:

    `\sum_{j=0}^{N-1} A_{i,j} B_{j,k} \Longrightarrow \mathbf{A}\cdot \mathbf{B}`

    Recognize the matrix multiplication in summation form:

    >>> expr = Sum(M[i, j]*N[j, k], (j, 0, d-1))
    >>> convert_indexed_to_array(expr)
    ArrayContraction(ArrayTensorProduct(M, N), (1, 2))

    Specify that ``k`` has to be the starting index:

    >>> convert_indexed_to_array(expr, first_indices=[k])
    ArrayContraction(ArrayTensorProduct(N, M), (0, 3))
    c                 s   s    | ]
}t |ttfV  qd S N)
isinstanceintr   .0i r#   [/tmp/pip-target-vg8gfxp4/lib/python/sympy/tensor/array/expressions/conv_indexed_to_array.py	<genexpr>D   s    z+convert_indexed_to_array.<locals>.<genexpr>c                    s*    |v rdS t  fdd|D rdS dS )NTc                 3   s"    | ]}t |tr |v V  qd S r   r   	frozensetr    elemr#   r$   r%   N   s     zAconvert_indexed_to_array.<locals>._check_is_in.<locals>.<genexpr>F)any)r)   indicesr#   r(   r$   _check_is_inK   s
   z.convert_indexed_to_array.<locals>._check_is_inc                 S   &   i | ]}t |tr|D ]}||qqS r#   r&   r!   r"   jr#   r#   r$   
<dictcomp>R      & z,convert_indexed_to_array.<locals>.<dictcomp>c                       g | ]}  ||qS r#   getr    )replr#   r$   
<listcomp>S       z,convert_indexed_to_array.<locals>.<listcomp>c                    s   g | ]	} |s|qS r#   r#   r    )r,   first_indicesr#   r$   r6   W   s    c                 S   sH   | |v r	| | S t|D ]\}}t|tsq| |v r|  S qtd)Nz	not found)index	enumerater   r'   
ValueError)r)   r+   r"   er#   r#   r$   _get_posY   s   

z*convert_indexed_to_array.<locals>._get_posc                    s   g | ]} |qS r#   r#   r    )r=   r8   r#   r$   r6   c       c                    s   g | ]}t | qS r#   )r   r!   arg)permutationr#   r$   r6   e   r>   )_convert_indexed_to_arrayr*   r   removeextendr   r   r   r   argsr   )exprr8   resultr+   r"   r#   )r,   r=   r8   rA   r5   r$   convert_indexed_to_array   s&   ,





rH   c           $         s  t | tr_| j}| j}t|\}dd |D 	tt	fdd|D td}tg t |trQ|j	D ]}t |t
s<q4tt|jtd t dkrP  q4ttdt}|r}| jD ]\}}}t||}	|dksv|d ||	 kr|td	| q`g }
t|}t trtj}|t| d  }|d t|  }|D ]}||v r||}|
||  d ||< qd
d |D }t|D ]	\}	}||v r	 q|rtjg|R  njtt}t|D ]+\}	}t |trtfdd|D n|v}||v r|r|| |	 d ||	< q| D ]&\}}t |tr+tfdd|D r2n|v r2q|
t| qdd |D t}|j fddd t!g|
R dit|fS t | trt"dd | j	D  \}}i |D ];}t |t
squ|j\}	}t|j}|	v r||	  |v r||  t|}|D ]}||< qqug }g }t"||D ]\}}t |t
rƐq|| || qfdd|D }t#|\}}t$| }|rt|g|R  |fS ||fS t | t%r | j	dd  }t#|\}}|rt| j	d g|R  |fS | j	d |fS t | t&rB| j}t#|\}}|r=t| j'g|R  |fS | j'|fS t | t(rf| j}t#|\}}|r_t| j)g|R  |fS | j	d |fS t | t*rnt+t | t
ry| | jfS t | t,r&t"dd | j	D  \}}t|}g g t"||D ]-\} t }|-.fdd D  t|.fddt D  qtt"||D ]P\}	\} t tk r fddtD }fdd|D } tfdd|D    t$t/|  ||	 ||	< t0 fddD }!t1||	 |!||	< qt2| tfS t | t3r`t| j)\}t | j4t5t6fr`t"dd t7| j4D  }"tt$fddt7| j4D  g|"R  }#|#|fS t | t8rxt| j	d \}t9t:| |fS | dfS )Nc                 S   r-   r#   r&   r.   r#   r#   r$   r0   o   r1   z-_convert_indexed_to_array.<locals>.<dictcomp>c                    r2   r#   r3   r    )subindicessetsr#   r$   r6   p   r7   z-_convert_indexed_to_array.<locals>.<listcomp>)key   r      z0summation index and array dimension mismatch: %sc                 S      g | ]}|d ur|qS r   r#   r    r#   r#   r$   r6      r7   c                 3   s    | ]}| vV  qd S r   r#   r!   r/   kronecker_indicesr#   r$   r%          z,_convert_indexed_to_array.<locals>.<genexpr>c                 3   s    | ]}| v V  qd S r   r#   r    rO   r#   r$   r%      rQ   c                 S   rM   r   r#   r    r#   r#   r$   r6      r7   c                    s
     | S r   r9   )x)free_indicesr#   r$   <lambda>   s   
 z+_convert_indexed_to_array.<locals>.<lambda>rT   c                 S      g | ]}t |qS r#   rB   r?   r#   r#   r$   r6          c                    s"   g | ]}|D ]}  ||qqS r#   r3   r.   )kronecker_delta_replr#   r$   r6      s   " c                 S   rV   r#   rW   r?   r#   r#   r$   r6      rX   c                    s   g | ]}| v r|qS r#   r#   r    )arg_indices_missingr#   r$   r6      r7   c                    s    g | ]\}}| v r| qS r#   r#   r!   r"   r<   )rZ   	arg_shaper#   r$   r6           c                    s   g | ]
\}}| vr|qS r#   r#   r[   arg_indicesr#   r$   r6      s    c                    s   g | ]} | qS r#   r#   r    )shape0r#   r$   r6      rX   c                 3   s    | ]} | V  qd S r   r#   rN   )index0r#   r$   r%      rQ   c                    s   g | ]}  |qS r#   rR   rN   r^   r#   r$   r6      r>   c                 S   s    g | ]}d | d | d fqS )rK   rL   r#   r    r#   r#   r$   r6      r]   c                    s   g | ]} qS r#   r#   r    )subexprr#   r$   r6      s    r#   );r   r   function	variablesrB   sortedsetr
   r   rE   r   r+   lenupdater   limitsr   r;   listr   diagonal_indicesr9   appendr:   r   rF   r   r'   allitemsr*   tuplesortr   zipr   r   r   r   namer   baser   NotImplementedErrorr   
differencerD   r   r   r   r   r	   expr   r   ranger   r   type)$rF   rc   summation_indices
subindicesr@   shapeindistartiendr"   contraction_indicesrk   dindicesr9   positionaxes_contractionincludekvindices_retrE   r+   r/   kindicesnewargs
newindicesloc_indicesflattened_indicesret_indicestparg_indices_setmissing_indices_posmissing_shaperA   diagsarrr#   )
r_   rZ   r\   rT   ra   rY   rP   r`   rb   rI   r$   rB   j   s&  







(0







"(rB   r   )-collectionsr   sympyr    sympy.combinatorics.permutationsr   sympy.concrete.summationsr   sympy.core.addr   sympy.core.mulr   sympy.core.numbersr   sympy.core.powerr	   sympy.core.sortingr
   (sympy.functions.special.tensor_functionsr   sympy.tensor.array.expressionsr   sympy.tensor.indexedr   r   sympy.combinatoricsr   "sympy.matrices.expressions.matexprr   0sympy.tensor.array.expressions.array_expressionsr   r   r   r   r   r   r   r   r   r   $sympy.tensor.array.expressions.utilsr   r   rH   rB   r#   r#   r#   r$   <module>   s$    0
T