o
    *ήc                  
   @   s  d dl Z d dlmZ d dlmZmZmZm	Z
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 d dlmZ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$m%Z%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l0m1Z1 d dl!m2Z2 d dl3m4Z4m5Z5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z?m@Z@mAZAmBZBmCZCmDZDmEZEmFZFmGZGmHZH d dlImJZJ deeeK  deeB deeeB eLeKf fddZMdeAdeBdeBdeLdeLf
d d!ZNd"d# ZOd$e6fd%d&ZPd$e6fd'd(ZQed)d* ZReRSe:d$e:fd+d,ZTeRSe6d$e6fd-d,ZTeRSe;d$e;fd.d,ZTeRSe5d$e5fd/d,ZTeRSe4d$e4fd0d,ZTeRSe<d$e<fd1d,ZTeRSe?d$e?fd2d,ZTeRSeCd$eCfd3d,ZTed4d5 ZUeUSe6d$e6fd6d,ZTeUSe<d$e<fd7d,ZTeUSe4d$e4fd8d,ZTeUSe;d$e;fd9d,ZTd$e5fd:d;ZVeUSe5d$e5fd<d,ZTeUSe1d$e1fd=d,ZTeUSe?d$e?fd>d,ZTd?d@ ZWd$e5fdAdBZXdCdD ZYdEdF ZZdGdH Z[dIdJ Z\dKdL Z]d$ee;e5f fdMdNZ^dOdP Z_d$e;fdQdRZ`dSeKdTeeK dUeeK deeK fdVdWZad$e;fdXdYZbdS )Z    N)defaultdict)TupleUnion	FrozenSetDictListOptional)singledispatch)
accumulate)MatMulBasicWildKroneckerProduct)Qask)Mul)S)
DiagMatrix)hadamard_productHadamardPower)
MatrixExpr)Identity
ZeroMatrix	OneMatrixTrace	Transpose)
_af_invertPermutation)MatrixCommon)ElementwiseApplyFunction)MatrixElement)PermuteDimsArrayDiagonalArrayTensorProductOneArrayget_rank_get_subrank	ZeroArrayArrayContractionArrayAdd_CodegenArrayAbstract	get_shapeArrayElementwiseApplyFunc
_ArrayExpr_EditArrayContraction_ArgEArrayElement_array_tensor_product_array_contraction_array_diagonal
_array_add_permute_dims)_get_mapping_from_subranksscan_indicesremaining_argsreturnc                 C   s   dd | D }t |dkrdS d}d }d}|D ]<}t|jts q|D ]0}|dkr-||kr-q"||jv rRt|j|hkr>d } n|d u rN|}|}||jd k}q"d } nq"q|||fS )Nc                 S      g | ]}|d ur|qS N .0ir>   r>   Z/tmp/pip-target-vg8gfxp4/lib/python/sympy/tensor/array/expressions/conv_array_to_matrix.py
<listcomp>       z>_get_candidate_for_matmul_from_contraction.<locals>.<listcomp>r   )NFFrE      )len
isinstanceelementr   indicesset)r9   r:   scan_indices_int	transpose	candidatecandidate_indexarg_with_ind2indexr>   r>   rB   *_get_candidate_for_matmul_from_contraction   s2   

rR   editorarg_with_indrN   
transpose1
transpose2c           	      C   s\   |j }|rt|}|jd }n|jd }|rt|j n|j | }| j| t|}||fS Nr   rF   )rI   r   rJ   args_with_indremover1   )	rS   rT   rN   rU   rV   otherother_indexnew_elementnew_arger>   r>   rB   _insert_candidate_into_editor=   s   
r^   c                 C   s  t | dkr
t| S tt| g| R  }t|}|  	 d}t|jD ]\}}t|j	t
s/q$|jd }|jd }||}	||}
|d ur^|	dkr^||kr^d}t|j	 |_	g |_ nog }|	dkri|| |
dkrr|| t||j|d d  \}}}|d urd}||| ||k}t|||||\}}||kr||g|_n||g|_t|j}t |dkr|d hkrt|j	 |_	g |_||j|<  nq$|rnq|  | S )Nr   TrF   F   )rG   _a2m_tensor_productr4   r3   r0   track_permutation_start	enumeraterX   rH   rI   r   rJ   count_args_with_indexr   
_normalizeappendrR   track_permutation_merger^   rK   refresh_indicesto_array_contraction)contraction_indicesargsacrS   	flag_stoprA   rT   first_indexsecond_indexfirst_frequencysecond_frequencyr9   rN   rM   found_indexrU   r]   r[   set_indicesr>   r>   rB   _support_function_tp1_recognizeK   sZ   








.rs   exprc                 C   sB  g }d }d }d }g }d}dd | j D }t| j D ]b\}}	t|	tru|	jdkr:||	 d ||< |||d g n;|d u rut|	tru|	j }
t|
D ]*\}}t|trt|jd dkrt|}t|
d |d  }t|
|d d  } nqJ|t	|	7 }q|d u r| g fS |tdd |D  | 
 ||< tdd |D  |fS )	Nr   c                 S   s   g | ]}|qS r>   r>   r?   r>   r>   rB   rC          z2_find_trivial_matrices_rewrite.<locals>.<listcomp>rF   rF   rF   c                 s   s    | ]}|V  qd S r=   r>   r?   r>   r>   rB   	<genexpr>   s    z1_find_trivial_matrices_rewrite.<locals>.<genexpr>c                 S   r<   r=   r>   r?   r>   r>   rB   rC      rD   )rj   rb   rH   r   shapere   extendr   fromiterr'   doitr3   )rt   trivial_matricesposfirstsecondremovedcounterrj   rA   argmargsjer>   r>   rB   _find_trivial_matrices_rewrite   s6   	


$r   c                    s&  g }g d t | jD ]\}} t|7  t|} fddtt|ddD }|dkrUt|dkrUdt|d vrUt|d trUt|trUt|d ||d< 	| qd|vrt|dkrt|d dkrt|d ||d< fddtt
|D }	|dd   q|| qt| fS )	Nr   c                    s   g | ]} | qS r>   r>   r?   )
count_dimsr>   rB   rC          z>_find_trivial_kronecker_products_broadcast.<locals>.<listcomp>rE   rv   rF   c                       g | ]}| vr|qS r>   r>   r?   r   r>   rB   rC      rD   )rb   rj   r'   r-   rangerG   rH   r   r   ry   minre   r3   )rt   newargsrA   r   rx   current_range
prev_ranger>   )r   r   rB   *_find_trivial_kronecker_products_broadcast   s(   $$r   c                 C   s   | S r=   r>   rt   r>   r>   rB   _array2matrix   s   r   c                 C   s   t | dkrt| j S | S )Nr_   )r'   r   rx   r   r>   r>   rB   _   s   
r   c                 C   s   t dd | jD  S )Nc                 S      g | ]}t |qS r>   r   r@   r   r>   r>   rB   rC      r   _.<locals>.<listcomp>)r`   rj   r   r>   r>   rB   r      s   c                 C   s  |   } t| } |  } t| } t| tst| S | j}| j}|dks9|dkr.|j	d dks9|dkrU|j	d dkrU|j	}t|}t|t
rUtd|d | t|d d S t|trtt|g|R  }|j}tdd |jD rtdd	 tjd
d	 | jjD  D  }t|g|R  }t|trt|}|S t|tsJ t|t|jj}|S t|tst|}t|t
r| jdksJ t|S t|g| jR  S d S )N)r   rF   )r   rF   )r   r   c                 s   s    | ]}|d kV  qdS )r_   Nr>   r?   r>   r>   rB   rw      s    z_.<locals>.<genexpr>c                 S   s   g | ]}t | qS r>   )r`   r@   r   r>   r>   rB   rC      r   r   c                 S   s"   g | ]}t |tr|jn|gqS r>   )rH   r+   rj   r?   r>   r>   rB   rC      s    
)r   rF   )flatten_contraction_of_diagonal$identify_removable_identity_matricessplit_multiple_contractionsidentify_hadamard_productsrH   r*   r   rt   ri   rx   r   r   r%   r4   anysubranksr6   	itertoolsproductrj   r+   rs   listr,   
_a2m_trace)rt   subexprri   rx   newexpraddendsretr>   r>   rB   r      sT   

 



c                 C   sF   t t| jg| jR  }t|}t|trt|}| |kr| S t|S r=   )r5   r   rt   diagonal_indicesr   rH   r$   _array_diag2contr_diagmatrix)rt   pexprr>   r>   rB   r      s   
c                    sb  | j jddgkrtt| jS t| jtr| jj}| j d   fddtt	|D }g }d}|D ]}|
||||   ||7 }q1g }g }g }t|| jjD ]F\}	}
t|	dkrb|
t|
 qP|	t|	kry|
t|
|	d f ||	 qPt|	dkr|
tt|
|	d f |t|	 qPt dd |D }ttg ||R  t|S t| jtr/t| j}t|tst|| j S tdt|j d | j  fddtdt|j D }d	d |jD }tt|jD ]:}|d|  }|d| d  }|d |d krt|  S ||kr!t|j|d  ||< q|j|d  ||< qt| S | S )
NrF   r   rE   c                       g | ]} |qS r>   r>   r?   )inv_permutationr>   rB   rC     r   r   r_   c                 S   s   g | ]}|d  qS r   r>   r?   r>   r>   rB   rC   "  r   c                    r   r>   r>   r?   )permutationr>   rB   rC   *  r   c                 S      g | ]}d qS r=   r>   r?   r>   r>   rB   rC   +  ru   )r   
array_form_a2m_transposer   rt   rH   r%   r   r   sumre   ziprj   rG   sortedry   reversedNotImplementedErrorr7   r`   r   r*   r   )rt   ranksnewrangenewposr   rankr   newpermscalarsr}   r   mat_mul_linespermuted
args_arrayrA   p1p2r>   )r   r   rB   r     sV   



 
c                 C   s   dd | j D }t| S )Nc                 S   r   r>   r   r   r>   r>   rB   rC   <  r   r   )rj   _a2m_add)rt   r   r>   r>   rB   r   :  s   c                 C   s   t | j}t|trC|jdkr=| jjd }td|gd}td|gd}| jj|||  }|d ur=|| t	|||  S t
| j|S t| j|S )Nrv   r   w)excludep)r   rt   rH   r   rx   functionbound_symbolsr   matchr   r!   r.   )rt   r   dr   r   mr>   r>   rB   r   @  s   


c                 C   s2   t | j}t|trt|g| jR  S t|| jS r=   )r   namerH   r   r"   rJ   r2   )rt   r   r>   r>   rB   r   P  s   

c                 C   s   | g fS r=   r>   r   r>   r>   rB   _remove_trivial_dimsX  s   r   c                 C   s  g }g }t tdgdd | jD  }d }d }t| jD ]\}}t t|| ||d  }t|tr9|| qt|tt	fsQt
|\}	}
||
 ||	 qt|ddrg|jdkrg|jdkrf|| q|jdkrt
|\}}t|dkr~|| qdt|d v r|d jd dkr|d | |d< n||d  |d< || q|| qd|jv rd	d |jD d }|d u r|}|}|| q||kr|d }|jd dkr|| }t|}n|| d }|jd dkr|| d }t|}n|| }|| |d< d }|||g q|| |}|}q|| d }qt| t|}}t|tr<t|\}}td||}t|trNt|\}}td||}||fS )
Nr   c                 S   r   r>   r'   r   r>   r>   rB   rC   f  r   r   rF   is_IdentityFrv   rE   c                 S   s   g | ]}|d kr|qS r   r>   r?   r>   r>   rB   rC     rD   )r   r
   rj   rb   r   rH   r&   ry   r   r    r   re   getattrrx   rG   r-   r   r`   r   r%   r   _combine_removedr   )rt   r   r   cumulpendingprev_irA   r   r   rargremr   kprevd1d2r   
newremovednewremoved2r>   r>   rB   r   ]  sz   











c                 C   sf   dd | j D }t| \}}ttdd |D dkr| g fS t|dkr)| |fS |d }t| |fS )Nc                 S   r   r>   )r   r   r>   r>   rB   rC     r   r   c                 S   r   r>   )r-   r?   r>   r>   rB   rC     r   rF   r   )rj   r   rG   rK   r   )rt   recr   r   removed1r>   r>   rB   r     s   c                    s   t | j\}| jj}t| jj ttfddtt|D  fddD }fddt	|D }t
||}t|}|| krRt t|\}}td||}||fS )Nc                       g | ]
}| v r
d ndqS rF   r   r>   r?   )
subremovedr>   rB   rC         r   c                       g | ]} | qS r>   r>   r?   )pinvr>   rB   rC     r   c                    s$   g | ]\}}|vr| |  qS r>   r>   r@   rA   r   )shiftr   r>   rB   rC        $ rE   )r   rt   r   r   r   r   r
   r   rG   rb   r7   r   r   r   )rt   r   r   premovedr   r   removed2r>   )r   r   r   rB   r     s   "
c           
         s,  t | \}}|| krtt|\}}td||}||fS t| }t| \} }t| ts9t| \}|t||fS t| j\}t	t
fddtt| jD fdd| jD }	dd |	D }	dd | jD   fddD fdd|	D }	t| jt||}t|g|	R  t	|fS )	NrE   c                    r   r   r>   r?   r   r>   rB   rC     r   r   c                    "   g | ]}t  fd d|D qS )c                 3       | ]	}| vr|V  qd S r=   r>   r   r   r>   rB   rw         _.<locals>.<listcomp>.<genexpr>tupler?   r   r>   rB   rC        " c                 S      g | ]
}t |d kr|qS r   rG   r?   r>   r>   rB   rC     r   c                 S   s   g | ]	}|D ]}|qqS r>   r>   )r@   rA   r   r>   r>   rB   rC         c                    r   r>   r>   r?   )contraction_indices_flatr>   rB   rC     rD   c                    r   )c                 3       | ]	}| |  V  qd S r=   r>   r   shiftsr>   rB   rw     r   r   r   r?   r   r>   rB   rC     r   )0_array_contraction_to_diagonal_multiple_identityr   r   r   r'   remove_identity_matricesrH   r*   rt   r   r
   r   ri   _push_indices_upr4   )
rt   new_exprremoved0	new_expr2r   r   rank1expr2r   new_contraction_indicesr>   )r   r   r   rB   r     s(   
$c           	         sV  t | tsJ t| fddtddj dD }g }d}tjD ]l\} |t j7 }t  j	t
rd  jv rtdd  jD rdd  jD d } fd	d|| D d }t |j	tsbq$d
|j	jvriq$d |jvroq$d j| _	|jd }t|j	|_	|}||d | g q$dd jD _t| j|t| j} |fS )Nc                    s"   i | ]   fd dj D qS )c                    s   h | ]	} |j v r|qS r>   rJ   r   rA   r>   rB   	<setcomp>  r   zD_remove_diagonalized_identity_matrices.<locals>.<dictcomp>.<setcomp>)rX   )r@   )rS   r  rB   
<dictcomp>  r   z:_remove_diagonalized_identity_matrices.<locals>.<dictcomp>rE   r   c                 s   s$    | ]}|d uo|dk dkV  qd S )Nr   Tr>   r?   r>   r>   rB   rw     s   " z9_remove_diagonalized_identity_matrices.<locals>.<genexpr>c                 S   r<   r=   r>   r   r>   r>   rB   rC     rD   z:_remove_diagonalized_identity_matrices.<locals>.<listcomp>c                       g | ]}| kr|qS r>   r>   r   rT   r>   rB   rC     rD   rF   c                 S      g | ]	}|j d ur|qS r=   rI   r?   r>   r>   rB   rC     r   )rH   r$   r0   r   number_of_diagonal_indicesrb   rX   rG   rJ   rI   r   r   r   rx   rQ   r   get_absolute_rangery   r   r   r'   rt   rh   )	rt   mappingr   r   rA   diag_indrZ   
none_indexother_ranger>   )rT   rS   rB   &_remove_diagonalized_identity_matrices  s4    

r  c           	         s&  t | j\}ttdgfddtt| jD  fdd| jD }| D ]\ }t|dkr= fddD q*fdd|	 D }t| j}t
| j|td	d
 D dd |D }t|dkrxt|g|R ddi}n|}t|t
rt|\}}td||fS |fS )Nr   c                    r   r   r>   r?   r   r>   rB   rC     r   r   c                    s$   i | ]}|t  fd d|D qS )c                 3   r   r=   r>   r   r   r>   rB   rw     r   z_.<locals>.<dictcomp>.<genexpr>r   r?   r   r>   rB   r    r   z_.<locals>.<dictcomp>rF   c                    r   r>   r>   r?   )old_diag_tupler>   rB   rC     rD   c                    r   )c                 3   r   r=   r>   r   r   r>   rB   rw     r   r   r   r?   r   r>   rB   rC     r   c                 S   s   h | ]}|qS r>   r>   r?   r>   r>   rB   r  	  ru   z_.<locals>.<setcomp>c                 S   r   r   r   r?   r>   r>   rB   rC     r   allow_trivial_diagsTrE   )r   rt   r   r
   r   r'   r   itemsrG   valuesr$   r   r   r5   rH   r  r   )	rt   r   new_diag_indices_mapnew_diag_tuplenew_diag_indicesr   newexpr2newexpr3r   r>   )r  r   r   rB   r     s(   *

c                 C   s>   t | j\}}|jdkr| ||ddg fS t| j|g fS )Nrv   r   rF   )r   rt   rx   r   r!   rt   r   r   r>   r>   rB   r     s   
c                 C   s   t | j\}}t| j||fS r=   )r   rt   r.   r   r  r>   r>   rB   r   "  s   c                 C   s   t | }t|\}}|S )a	  
    Recognize matrix expressions in codegen objects.

    If more than one matrix multiplication line have been detected, return a
    list with the matrix expressions.

    Examples
    ========

    >>> from sympy.tensor.array.expressions.conv_indexed_to_array import convert_indexed_to_array
    >>> from sympy.tensor.array import tensorcontraction, tensorproduct
    >>> from sympy import MatrixSymbol, Sum
    >>> from sympy.abc import i, j, k, l, N
    >>> from sympy.tensor.array.expressions.conv_matrix_to_array import convert_matrix_to_array
    >>> from sympy.tensor.array.expressions.conv_array_to_matrix import convert_array_to_matrix
    >>> A = MatrixSymbol("A", N, N)
    >>> B = MatrixSymbol("B", N, N)
    >>> C = MatrixSymbol("C", N, N)
    >>> D = MatrixSymbol("D", N, N)

    >>> expr = Sum(A[i, j]*B[j, k], (j, 0, N-1))
    >>> cg = convert_indexed_to_array(expr)
    >>> convert_array_to_matrix(cg)
    A*B
    >>> cg = convert_indexed_to_array(expr, first_indices=[k])
    >>> convert_array_to_matrix(cg)
    B.T*A.T

    Transposition is detected:

    >>> expr = Sum(A[j, i]*B[j, k], (j, 0, N-1))
    >>> cg = convert_indexed_to_array(expr)
    >>> convert_array_to_matrix(cg)
    A.T*B
    >>> cg = convert_indexed_to_array(expr, first_indices=[k])
    >>> convert_array_to_matrix(cg)
    B.T*A

    Detect the trace:

    >>> expr = Sum(A[i, i], (i, 0, N-1))
    >>> cg = convert_indexed_to_array(expr)
    >>> convert_array_to_matrix(cg)
    Trace(A)

    Recognize some more complex traces:

    >>> expr = Sum(A[i, j]*B[j, i], (i, 0, N-1), (j, 0, N-1))
    >>> cg = convert_indexed_to_array(expr)
    >>> convert_array_to_matrix(cg)
    Trace(A*B)

    More complicated expressions:

    >>> expr = Sum(A[i, j]*B[k, j]*A[l, k], (j, 0, N-1), (k, 0, N-1))
    >>> cg = convert_indexed_to_array(expr)
    >>> convert_array_to_matrix(cg)
    A*B.T*A.T

    Expressions constructed from matrix expressions do not contain literal
    indices, the positions of free indices are returned instead:

    >>> expr = A*B
    >>> cg = convert_matrix_to_array(expr)
    >>> convert_array_to_matrix(cg)
    A*B

    If more than one line of matrix multiplications is detected, return
    separate matrix multiplication factors embedded in a tensor product object:

    >>> cg = tensorcontraction(tensorproduct(A, B, C, D), (1, 2), (5, 6))
    >>> convert_array_to_matrix(cg)
    ArrayTensorProduct(A*B, C*D)

    The two lines have free indices at axes 0, 3 and 4, 7, respectively.
    )r   r   )rt   r   r   r>   r>   rB   convert_array_to_matrix(  s   Mr  c                    sX  t | jtr*t| jj}t| j}tdd |D fdd|D }g }t| }dd |D }tt	||D ]\}\}}	t
|dkrEq8|	\\}
}\}}||
 }|| }t|dksat|dkrr||
 rid ||< || rqd ||< q8d| }d| }|j| dkr|j| dkrt|}n|}|| |||ft
|d |ff |d7 }d ||< t|j| ||
< d||
< q8|j| dkr|j| dkrt|}n|}|| ||
|ft
|d |ff |d7 }d ||< t|j| ||< d||< q8dd |D }ttd	gd
d |D    fdd|D }tt| g|R  }t|g|R  }|S | S )Nc                 S   r   r>   )r(   r   r>   r>   rB   rC   ~  r   z0_array_diag2contr_diagmatrix.<locals>.<listcomp>c                       g | ]} fd d|D qS )c                    r   r>   r>   r   r  r>   rB   rC     r   z;_array_diag2contr_diagmatrix.<locals>.<listcomp>.<listcomp>r>   r?   r  r>   rB   rC         c                 S   r   )Fr>   r   r>   r>   rB   rC     ru   r_   rF   Tc                 S   r<   r=   r>   r?   r>   r>   rB   rC     rD   r   c                 S   r   r>   r   r   r>   r>   rB   rC     r   c                    r   )c                 3   s     | ]\}} | | V  qd S r=   r>   )r@   abr   r>   rB   rw     s    z:_array_diag2contr_diagmatrix.<locals>.<listcomp>.<genexpr>r   r?   r"  r>   rB   rC     r   )rH   rt   r%   r   rj   r   r8   r'   rb   r   rG   rx   r   re   r&   r
   r4   r3   r5   )rt   rj   diag_indicestuple_linkscontr_indices
total_rankreplacedrA   abs_posrel_pos
pos1_outer
pos1_inner
pos2_outer
pos2_innerarg1arg2pos1_in2pos2_in2darg1darg2diag_indices_newcontr_indices2tctdr>   )r   r  rB   r   z  sl   





r   c                  G   sR   t dd | D sddlm} ||   S tt|  gdd tdt| D R  S )Nc                 s       | ]}t |tV  qd S r=   rH   r,   r?   r>   r>   rB   rw         z_a2m_mul.<locals>.<genexpr>r   )r   c                 S   s    g | ]}d | d d | fqS )r_   rF   r>   r?   r>   r>   rB   rC          z_a2m_mul.<locals>.<listcomp>rF   )r   !sympy.matrices.expressions.matmulr   r{   r4   r3   r   rG   )rj   r   r>   r>   rB   _a2m_mul  s   r=  c                  G   s   g }g }| D ]}t |tttfr|| q|| qt|}t|dkr)|S |dkrEt |d tr=|g| }t| S |d  |9  < t| S rW   )	rH   r   r/   r,   re   r   rz   rG   r3   )rj   r   arraysr   scalarr>   r>   rB   r`     s   

r`   c                  G   s2   t dd | D sddlm} ||   S t|  S )Nc                 s   r8  r=   r9  r?   r>   r>   rB   rw     r:  z_a2m_add.<locals>.<genexpr>r   )MatAdd)r   !sympy.matrices.expressions.mataddr@  r{   r6   )rj   r@  r>   r>   rB   r     s   r   c                 C   s(   t | tr
t| dS ddlm} || S )Nr   r   r   )rH   r,   r4    sympy.matrices.expressions.tracer   )r   r   r>   r>   rB   r     s   

r   c                 C   s0   t | trt| ddgS ddlm} ||  S )NrF   r   r   )rH   r,   r7   $sympy.matrices.expressions.transposer   r{   )r   r   r>   r>   rB   r     s   
r   c                    s  t | }tt}tt|jD ] }|jD ]
}|  d7  < qd |jv r%q|t|j | q| D ]\d}t	dkr[t
tdkr[tfdd|D dkr[d}tj}nt	dkrbq4t	dkriq4D ]	}| dkrtqkqkdd	  tfd
dD rtdd D rd}d j} d js|j}dd  }n}t fdd|D  }d j}	 |d jstt|	}	|rt||j  }g }	|d t||	 D ]}
|j|
 qq4| S )NrF   Fr   c                    s   g | ]
}t t |v qS r>   )nextiterr?   )r   r>   rB   rC     r   z.identify_hadamard_products.<locals>.<listcomp>Tr_   c                 S   s   dd | D } | t | kS )Nc                 S   s    g | ]}|d kr
|nd| qS )r   rE   r>   r?   r>   r>   rB   rC   
  r;  zGidentify_hadamard_products.<locals>.check_transpose.<locals>.<listcomp>)r   )xr>   r>   rB   check_transpose	  s   z3identify_hadamard_products.<locals>.check_transposec                    s$   g | ]} | t ko|d kqS r   r   r   )map_ind_to_indsvr>   rB   rC     r   c                 S   s   g | ]}|d kqS r   r>   r   r>   r>   rB   rC     r   c                    s&   g | ]} |j r|jnt|jqS r>   )rJ   rI   r   r?   )rG  r>   rB   rC     s   & )r0   r   r   intrX   rJ   	frozensetre   r  rG   rD  rE  r   r   OneallrI   Tr   r   r   rd   insert_afterr1   rY   rh   )rt   rS   map_contr_to_argsrT   ind
make_tracefirst_elementhadamard_factorshp
hp_indicesrA   r>   )rG  r   rH  rI  rB   r     sT   


6*

r   c                    s  t | }d}|rd}|jD ] t jtrw jjd } jd d gkr#qd  jv rSdd  jD d |}|dkrM| t	| |j
  d} n|dkrRqq jd  jd krv jd |}|dkru|j
  d} nX	 qtt jr̈ jd d gkrqd  jv rq jd  jd kr̈ jd |}|dkr|  fd	d|jD }fd
d|d jD |d _g _d} nq|s| S )NTFr   c                 S   r<   r=   r>   r   r>   r>   rB   rC   6  rD   z8identify_removable_identity_matrices.<locals>.<listcomp>rF   r_      c                    r  r>   r>   r   r  r>   rB   rC   Z  rD   c                       g | ]
}| kr
n|qS r>   r>   r   )rQ  ind_newr>   rB   rC   [  r   )r0   rX   rH   rI   r   rx   rJ   rc   rO  r&   rY   r   r   diagonalget_new_contraction_indexrh   )rt   rS   flagr   counted
other_argsr>   )rT   rQ  rY  rB   r   (  s^   







 
4r   c              
      sr  t | }g i }ttdgdd |jD  }dd t|j|d d D  i }t|jD ]k|}dd |D }t|}|t|d ksK|dkrLq-d	d |D d t	d
d |D r_q-|D ]}d |_
t |  | tdd |jD   qad}	jd d  ||	f< fddjD _q-  ttfddtt| D }
| D ]$\\}	} fddt|D }t|dksJ |D ]}|	||< qqdd |jD |_| }g }d}d}tt| D ]=}|v rq||v r|| }|||
|   |d7 }q|| v r |d7 }|| v s|| |d7 }|d7 }qt|t|}|fS )Nr   c                 S   s    g | ]}t d d |jD qS )c                 S   s   g | ]}|d u qS r=   r>   r?   r>   r>   rB   rC   i  r   z7remove_identity_matrices.<locals>.<listcomp>.<listcomp>)r   rJ   r   r>   r>   rB   rC   i  r;  z,remove_identity_matrices.<locals>.<listcomp>c                 S   s   i | ]\}}||qS r>   r>   )r@   r   rI  r>   r>   rB   r  j      z,remove_identity_matrices.<locals>.<dictcomp>rE   c                 S   s   g | ]
}t |jtr|qS r>   rH   rI   r   r?   r>   r>   rB   rC   p  r   rF   c                 S   s   g | ]
}t |jts|qS r>   r`  r?   r>   r>   rB   rC   v  r   c                 S   s   g | ]}d |j vqS r=   r  r?   r>   r>   rB   rC   y  r_  c                 S   s   g | ]}|d u r|qS r=   r>   r   r>   r>   rB   rC   ~  rD   c                    s   g | ]
}| kr
d n|qS r=   r>   r?   )rQ  r>   rB   rC     r   c                    r   r   r>   r?   r   r>   rB   rC     r   c                    s$   g | ]\}}|kr  | qS r>   r>   r   )free_maprQ  non_identityr>   rB   rC     r   c                 S   r	  r=   r
  r?   r>   r>   rB   rC     r   )r0   r   r
   rX   r   r   number_of_contraction_indicesget_args_with_indexrG   r   rI   ry   rJ   popsortr'   r  rb   rh   re   r  r7   r   )rt   rS   permutation_mapfree_indicesupdate_pairsrj   identity_matricesnumber_identity_matricesrA   last_removedr   non_identity_indicesr}   r   ret_exprr   r   counter2target	ret_expr2r>   )ra  rQ  rb  r   rB   r   c  sb   
.
"




r   dimr   r   c                 C   s   t |}t |}d}d}g }	 |t|kr/|t|k r,|||  |d7 }|t|k s	 |S |t|k rK|| |||  krK|||  |d7 }n||||   |d7 }q)Nr   TrF   )r   rG   re   )rr  r   r   rA   r   r   r>   r>   rB   r     s&    
r   c                    s  t | }|  g }d}t|jD ] g }g }t|jD ]\}} |jvr&qt|jt	r2|
| q|
| qt|dkr?qt|t| dk rJqd| |d7 }d}t|D ]%\}	}
d |
jvred} ntt||
 d }|jd 
| d |
_d} |rq|d |	 ||	d d   D ]}d |_|t||  q|D ]} fdd|jD |_qqt|jD ]\}}|jd u rd |j|< qd	d |jD |_d
d ttdd |jD D fdd|jD |_dd |jD |_| }||fS )Nr   rW  rE   rF   TFc                    rX  r>   r>   r   )rA   new_diag_indr>   rB   rC     r   zD_array_contraction_to_diagonal_multiple_identity.<locals>.<listcomp>c                 S   r<   r=   r>   r?   r>   r>   rB   rC     rD   c                 S   s   i | ]\}}||qS r>   r>   r   r>   r>   rB   r    r_  zD_array_contraction_to_diagonal_multiple_identity.<locals>.<dictcomp>c                 S   s   h | ]	}|D ]}|qqS r>   r>   )r@   r   r   r>   r>   rB   r    r   zC_array_contraction_to_diagonal_multiple_identity.<locals>.<setcomp>c                    r  )c                    r   r>   r>   r   remapr>   rB   rC     r   zO_array_contraction_to_diagonal_multiple_identity.<locals>.<listcomp>.<listcomp>r>   r?   rt  r>   rB   rC     r  c                 S   r	  r=   r
  r?   r>   r>   rB   rC     r   )r0   ra   r   rc  rb   rX   rJ   rH   rI   r   re   rG   r   get_absolute_free_range_track_permutationry   r   rh   )rt   rS   r   diag_index_counter
identitiesrj   r   r   r\  i1id1free_posr   r   r>   )rA   rs  ru  rB   r     s^   

 

"r   )cr   collectionsr   typingr   tTupler   tUnionr   r   tDictr   r   	functoolsr	   r
   sympyr   r   r   r   sympy.assumptions.askr   r   sympy.core.mulr   sympy.core.singletonr   #sympy.matrices.expressions.diagonalr   #sympy.matrices.expressions.hadamardr   r   "sympy.matrices.expressions.matexprr   "sympy.matrices.expressions.specialr   r   r   rB  r   rC  r    sympy.combinatorics.permutationsr   r   sympy.matrices.commonr    $sympy.matrices.expressions.applyfuncr!   r"   0sympy.tensor.array.expressions.array_expressionsr#   r$   r%   r&   r'   r(   r)   r*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r4   r5   r6   r7   $sympy.tensor.array.expressions.utilsr8   rJ  boolrR   r^   rs   r   r   r   registerr   r   r  r  r   r=  r`   r   r   r   r   r   r   r   r   r>   r>   r>   rB   <module>   s     \0!:%
(
2
MR8@;&A