
    Qi,                      d dl mZ d dlZd dlZd dlmZmZ d dlmZ d dl	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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' d dl(m)Z) d dl*m+Z+ d dl,m-Z-m.Z.m/Z/m0Z0 d dl1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7 d dl(m8Z8 d dl9m:Z:m;Z;m<Z<m=Z=m>Z>m?Z? d dl@mAZA d dlBmCZC d dlDmEZE  G d de          ZF G d  d!eF          ZG G d" d#e          ZH G d$ d%eF          ZI G d& d'eF          ZJ G d( d)e          ZK G d* d+eK          ZL G d, d-eK          ZM G d. d/eK          ZN G d0 d1eK          ZO G d2 d3eK          ZP G d4 d5eK          ZQ G d6 d7eK          ZR G d8 d9          ZS G d: d;          ZT G d< d=          ZUd> ZVd? ZWd@ ZXdA ZYdB ZZdC Z[dD Z\dE Z]dF Z^dG Z_dH Z`dS )I    )annotationsN)defaultdictCounter)reduce)
accumulate)Integer)EqualityKroneckerDelta)Basic)Tuple)Expr)FunctionLambda)Mul)Sdefault_sort_key)DummySymbol)
MatrixBase)diagonalize_vector)
MatrixExpr)
ZeroMatrix)permutedimstensorcontractiontensordiagonaltensorproduct)ImmutableDenseNDimArray)	NDimArray)IndexedIndexedBase)MatrixElement)$_apply_recursively_over_nested_lists_sort_contraction_indices_get_mapping_from_subranks*_build_push_indices_up_func_transformation_get_contraction_links,_build_push_indices_down_func_transformationPermutation)
_af_invert_sympifyc                  &    e Zd ZU ded<   d Zd ZdS )
_ArrayExprztuple[Expr, ...]shapec                    t          |t          j        j                  s|f}t                              | |           |                     |          S N)
isinstancecollectionsabcIterableArrayElement_check_shape_getselfitems     /var/www/development/aibuddy-work/election-extract/venv/lib/python3.11/site-packages/sympy/tensor/array/expressions/array_expressions.py__getitem__z_ArrayExpr.__getitem__*   sF    $ 899 	7D!!$---yy    c                "    t          | |          S r3   )_get_array_element_or_slicer;   s     r>   r:   z_ArrayExpr._get0   s    *4666r@   N)__name__
__module____qualname____annotations__r?   r:    r@   r>   r0   r0   '   s@           7 7 7 7 7r@   r0   c                  P    e Zd ZdZdZddZed             Zed	             Zd
 Z	dS )ArraySymbolz1
    Symbol representing an array expression
    Fr1   typing.Iterablereturn'ArraySymbol'c                    t          |t                    rt          |          }t          t	          t
          |           }t          j        | ||          }|S r3   )r4   strr   r   mapr.   r   __new__)clssymbolr1   objs       r>   rP   zArraySymbol.__new__;   sK    fc"" 	$F^^Fs8U++,l3..
r@   c                    | j         d         S Nr   _argsr<   s    r>   namezArraySymbol.nameC       z!}r@   c                    | j         d         S N   rV   rX   s    r>   r1   zArraySymbol.shapeG   rZ   r@   c                     t          d  j        D                       st          d           fdt          j        d  j        D              D             } t          |          j         j         S )Nc              3  $   K   | ]}|j         V  d S r3   
is_Integer.0is     r>   	<genexpr>z*ArraySymbol.as_explicit.<locals>.<genexpr>L   $      44A1<444444r@   z1cannot express explicit array with symbolic shapec                     g | ]
}|         S rG   rG   )rc   rd   r<   s     r>   
<listcomp>z+ArraySymbol.as_explicit.<locals>.<listcomp>N   s    TTTAQTTTr@   c                ,    g | ]}t          |          S rG   rangerc   js     r>   rh   z+ArraySymbol.as_explicit.<locals>.<listcomp>N   s    4R4R4R!U1XX4R4R4Rr@   )allr1   
ValueError	itertoolsproductr   reshape)r<   datas   ` r>   as_explicitzArraySymbol.as_explicitK   s    4444444 	RPQQQTTTT!24R4Rtz4R4R4R!STTT4&t,,4djAAr@   N)r1   rJ   rK   rL   )
rC   rD   rE   __doc__	_iterablerP   propertyrY   r1   rt   rG   r@   r>   rI   rI   4   s          I      X   XB B B B Br@   rI   c                  l    e Zd ZdZdZdZdZd Zed             Z	e
d             Ze
d             Zd ZdS )	r8   z!
    An element of an array.
    Tc                @   t          |t                    rt          |          }t          |          }t          |t          j        j                  s|f}t          t          |                    }|                     ||           t          j
        | ||          }|S r3   )r4   rN   r   r.   r5   r6   r7   tupler9   r   rP   )rQ   rY   indicesrS   s       r>   rP   zArrayElement.__new__[   s    dC   	 $<<D~~';?#;<< 	!jG5>>**w'''l3g..
r@   c                v   t          |          }t          |d          rqt          d          }t          |          t          |j                  k    r|t          d t          ||j                  D                       rt          d          t          d |D                       rt          d          d S )Nr1   z3number of indices does not match shape of the arrayc              3  0   K   | ]\  }}||k    d k    V  dS )TNrG   )rc   rd   ss      r>   re   z,ArrayElement._check_shape.<locals>.<genexpr>m   s/      II1AFt#IIIIIIr@   zshape is out of boundsc              3  *   K   | ]}|d k     dk    V  dS )r   TNrG   rb   s     r>   re   z,ArrayElement._check_shape.<locals>.<genexpr>o   s*      001A$000000r@   zshape contains negative values)rz   hasattr
IndexErrorlenr1   anyzipro   )rQ   rY   r{   index_errors       r>   r9   zArrayElement._check_shapef   s    ..4!! 	;$%Z[[K7||s4:..!!IIGTZ0H0HIIIII ; !9:::0000000 	?=>>>	? 	?r@   c                    | j         d         S rU   rV   rX   s    r>   rY   zArrayElement.namer   rZ   r@   c                    | j         d         S r\   rV   rX   s    r>   r{   zArrayElement.indicesv   rZ   r@   c                   t          |t                    st          j        S || k    rt          j        S |j        | j        k    rt          j        S t          j        d t          | j	        |j	                  D                       S )Nc              3  <   K   | ]\  }}t          ||          V  d S r3   r
   rc   rd   rm   s      r>   re   z0ArrayElement._eval_derivative.<locals>.<genexpr>   s0      ZZTQN1a00ZZZZZZr@   )
r4   r8   r   ZeroOnerY   r   fromiterr   r{   )r<   r~   s     r>   _eval_derivativezArrayElement._eval_derivativez   sn    !\** 	6M995L6TY6M|ZZSqy=Y=YZZZZZZr@   N)rC   rD   rE   ru   	_diff_wrt	is_symbolis_commutativerP   classmethodr9   rw   rY   r{   r   rG   r@   r>   r8   r8   R   s          IIN	 	 	 	? 	? [	?   X   X
[ 
[ 
[ 
[ 
[r@   r8   c                  :    e Zd ZdZd Zed             Zd Zd ZdS )	ZeroArrayzM
    Symbolic array of zeros. Equivalent to ``ZeroMatrix`` for matrices.
    c                    t          |          dk    rt          j        S t          t          |          }t          j        | g|R  }|S rU   )r   r   r   rO   r.   r   rP   rQ   r1   rS   s      r>   rP   zZeroArray.__new__   sC    u::??6MHe$$l3''''
r@   c                    | j         S r3   rV   rX   s    r>   r1   zZeroArray.shape   
    zr@   c                    t          d | j        D                       st          d          t          j        | j         S )Nc              3  $   K   | ]}|j         V  d S r3   r`   rb   s     r>   re   z(ZeroArray.as_explicit.<locals>.<genexpr>   rf   r@   /Cannot return explicit form for symbolic shape.)rn   r1   ro   r   zerosrX   s    r>   rt   zZeroArray.as_explicit   sC    4444444 	PNOOO&,dj99r@   c                    t           j        S r3   )r   r   r;   s     r>   r:   zZeroArray._get   s	    vr@   N	rC   rD   rE   ru   rP   rw   r1   rt   r:   rG   r@   r>   r   r      sf              X: : :
    r@   r   c                  :    e Zd ZdZd Zed             Zd Zd ZdS )OneArrayz!
    Symbolic array of ones.
    c                    t          |          dk    rt          j        S t          t          |          }t          j        | g|R  }|S rU   )r   r   r   rO   r.   r   rP   r   s      r>   rP   zOneArray.__new__   sC    u::??5LHe$$l3''''
r@   c                    | j         S r3   rV   rX   s    r>   r1   zOneArray.shape   r   r@   c           
         t          d | j        D                       st          d           t          d t	          t          t          j        | j                            D                       j        | j         S )Nc              3  $   K   | ]}|j         V  d S r3   r`   rb   s     r>   re   z'OneArray.as_explicit.<locals>.<genexpr>   rf   r@   r   c                &    g | ]}t           j        S rG   r   r   rb   s     r>   rh   z(OneArray.as_explicit.<locals>.<listcomp>   s    '_'_'_!'_'_'_r@   )	rn   r1   ro   r   rk   r   operatormulrr   rX   s    r>   rt   zOneArray.as_explicit   sw    4444444 	PNOOOh&'_'_uVHLRVR\=]=]7^7^'_'_'_``hjnjtuur@   c                    t           j        S r3   r   r;   s     r>   r:   zOneArray._get   s	    ur@   Nr   rG   r@   r>   r   r      si              Xv v v
    r@   r   c                  F    e Zd Zed             Zd Zed             Zd ZdS )_CodegenArrayAbstractc                     | j         dd         S )a  
        Returns the ranks of the objects in the uppermost tensor product inside
        the current object.  In case no tensor products are contained, return
        the atomic ranks.

        Examples
        ========

        >>> from sympy.tensor.array import tensorproduct, tensorcontraction
        >>> from sympy import MatrixSymbol
        >>> M = MatrixSymbol("M", 3, 3)
        >>> N = MatrixSymbol("N", 3, 3)
        >>> P = MatrixSymbol("P", 3, 3)

        Important: do not confuse the rank of the matrix with the rank of an array.

        >>> tp = tensorproduct(M, N, P)
        >>> tp.subranks
        [2, 2, 2]

        >>> co = tensorcontraction(tp, (1, 2), (3, 4))
        >>> co.subranks
        [2, 2, 2]
        N)	_subranksrX   s    r>   subranksz_CodegenArrayAbstract.subranks   s    4 ~aaa  r@   c                *    t          | j                  S )z*
        The sum of ``subranks``.
        )sumr   rX   s    r>   subrankz_CodegenArrayAbstract.subrank   s     4=!!!r@   c                    | j         S r3   _shaperX   s    r>   r1   z_CodegenArrayAbstract.shape   
    {r@   c                                         dd          }|r- | j        fd| j        D                                              S |                                 S )NdeepTc                *    g | ]} |j         d i S )rG   )doit)rc   arghintss     r>   rh   z._CodegenArrayAbstract.doit.<locals>.<listcomp>   s+    FFFSxsx00%00FFFr@   )getfuncargs_canonicalize)r<   r   r   s    ` r>   r   z_CodegenArrayAbstract.doit   sb    yy&& 	(49FFFFDIFFFGUUWWW%%'''r@   N)rC   rD   rE   rw   r   r   r1   r   rG   r@   r>   r   r      sf        ! ! X!6" " "   X( ( ( ( (r@   r   c                  :    e Zd ZdZd Zd Zed             Zd ZdS )ArrayTensorProductzF
    Class to represent the tensor product of array-like objects.
    c                V   d |D             }|                     dd          }d |D             }t          j        | g|R  }||_        d |D             }t	          d |D                       rd |_        nt          d |D                       |_        |r|                                S |S )Nc                ,    g | ]}t          |          S rG   r-   rc   r   s     r>   rh   z.ArrayTensorProduct.__new__.<locals>.<listcomp>       ...#...r@   canonicalizeFc                ,    g | ]}t          |          S rG   get_rankr   s     r>   rh   z.ArrayTensorProduct.__new__.<locals>.<listcomp>       ///3#///r@   c                ,    g | ]}t          |          S rG   	get_shaperb   s     r>   rh   z.ArrayTensorProduct.__new__.<locals>.<listcomp>   s    ---1)A,,---r@   c              3     K   | ]}|d u V  	d S r3   rG   rb   s     r>   re   z-ArrayTensorProduct.__new__.<locals>.<genexpr>   &      ))QqDy))))))r@   c              3  $   K   | ]}|D ]}|V  d S r3   rG   r   s      r>   re   z-ArrayTensorProduct.__new__.<locals>.<genexpr>   s/      <<Q!<<Qq<<<<<<<r@   )popr   rP   r   r   r   rz   r   )rQ   r   kwargsr   ranksrS   shapess          r>   rP   zArrayTensorProduct.__new__   s    .....zz.%88//$///mC'$'''-----))&))))) 	=CJJ<<&<<<<<CJ 	'$$&&&
r@   c           	        | j         }|                     |          }d |D             g }t          |          D ]Q\  }t          |t                    s|                    fd|j        j        D                        |j        |<   R|rDt          t          | t          t                    dz
            t          |          z            S t          |          dk    r|d         S t          d |D                       r.t          t           j        d |D             d          }t%          | S d t          |          D             }|rtd	 |D             t'          t)          dgz                       d d
         t          d |D              }fd|                                D             }t-          |g|R  S d t          |          D             }|rg }	g }
d |D             t'          t)          dgz                       d d
         t          |          D ]\  }t          |t.                    rt1          |          t          |j                  z
  }t          |j                  }|	                    fdt5          |          D                        |
                    fdt5          |||z             D                        |	                    fdt5          t1          |                    D                        |	                    |
           t          d |D              }d |D             }t'          t)          dg|z                       d d
         fd|                                D             }t          t7          |g|R  t9          |	                    S  | j        |ddiS )Nc                ,    g | ]}t          |          S rG   r   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  r   r@   c                .    g | ]}fd |D             S )c                D    g | ]}|t          d                    z   S r3   )r   )rc   krd   r   s     r>   rh   z?ArrayTensorProduct._canonicalize.<locals>.<listcomp>.<listcomp>  s,    'F'F'FqCbqb	NN(:'F'F'Fr@   rG   )rc   rm   rd   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  s1    &l&l&l1'F'F'F'F'FA'F'F'F&l&l&lr@   r]   r   c              3  N   K   | ] }t          |t          t          f          V  !d S r3   r4   r   r   r   s     r>   re   z3ArrayTensorProduct._canonicalize.<locals>.<genexpr>  s1      HHCz#	:677HHHHHHr@   c                ,    g | ]}t          |          S rG   r   rb   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  s    *F*F*FA9Q<<*F*F*Fr@   rG   c                D    i | ]\  }}t          |t                    ||S rG   )r4   ArrayContractionrc   rd   r   s      r>   
<dictcomp>z4ArrayTensorProduct._canonicalize.<locals>.<dictcomp>  s.    bbb61c
3P`@a@ab3bbbr@   c                t    g | ]5}t          |t                    rt          |          nt          |          6S rG   )r4   r   _get_subrankr   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  s@    ooocf*S:J*K*K^\#&&&QYZ]Q^Q^ooor@   c                J    g | ] }t          |t                    r|j        n|!S rG   )r4   r   exprr   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  s0    (p(p(pdgZEU5V5V)_\_(p(p(pr@   c                d    g | ]+\  }|j         D ]}t          fd |D                       ,S )c              3  .   K   | ]}         |z   V  d S r3   rG   )rc   r   cumulative_ranksrd   s     r>   re   z>ArrayTensorProduct._canonicalize.<locals>.<listcomp>.<genexpr>  s.      (L(LQ)9!)<q)@(L(L(L(L(L(Lr@   )contraction_indicesrz   )rc   r   rm   rd   r   s      @r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>  sr      #R  #R  #RQWQRTWy|  zQ  #R  #Rtu5(L(L(L(L(L!(L(L(L#L#L  #R  #R  #R  #Rr@   c                D    i | ]\  }}t          |t                    ||S rG   )r4   ArrayDiagonalr   s      r>   r   z4ArrayTensorProduct._canonicalize.<locals>.<dictcomp>"  s-    \\\3Z]=[=[\Q\\\r@   c                ,    g | ]}t          |          S rG   r   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>&  s    333sXc]]333r@   c                &    g | ]}         |z   S rG   rG   rc   rm   r   rd   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>,  s$    /[/[/[A0@0Ca0G/[/[/[r@   c                &    g | ]}         |z   S rG   rG   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>-  s$    %Z%Z%Z!&6q&9A&=%Z%Z%Zr@   c                &    g | ]}         |z   S rG   rG   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>/  s$    /f/f/fA0@0Ca0G/f/f/fr@   c                J    g | ] }t          |t                    r|j        n|!S rG   )r4   r   r   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>1  s/    (m(m(madZ]5S5S)\Y\(m(m(mr@   c                t    g | ]5}t          |t                    rt          |          nt          |          6S rG   )r4   r   r   r   r   s     r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>2  s<    mmmad:c=+I+I\l3'''xX[}}mmmr@   c                d    g | ]+\  }|j         D ]}t          fd |D                       ,S )c              3  .   K   | ]}         |z   V  d S r3   rG   )rc   r   cumulative_ranks2rd   s     r>   re   z>ArrayTensorProduct._canonicalize.<locals>.<listcomp>.<genexpr>4  s.      %J%J1&7&:Q&>%J%J%J%J%J%Jr@   )diagonal_indicesrz   )rc   r   rm   rd   r   s      @r>   rh   z4ArrayTensorProduct._canonicalize.<locals>.<listcomp>4  sp       J   J   JvqRUtw  uI   J   Jop%J%J%J%J%J%J%J%J J J   J   J   J   Jr@   r   F)r   _flatten	enumerater4   PermuteDimsextendpermutationcyclic_formr   _permute_dims_array_tensor_productr+   r   r   r   r   r   addr   listr   items_array_contractionr   r   r   rk   _array_diagonalr,   r   )r<   r   permutation_cyclesr   r   contractionstpr   	diagonalsinverse_permutation	last_permi1i2ranks2r   r   r   rd   r   s                  @@@@r>   r   z ArrayTensorProduct._canonicalize   ss   y}}T""//$///  oo 	 	FAsc;// %%&l&l&l&l&lPSP_Pk&l&l&lmmmhDGG 	z !6!={3u::VW<?X?XYdewYxYx?xyyyt99>>7N HH4HHHHH 	&HL*F*F*F*F*FKKFf%% cbYt__bbb 	@oojnoooE#JsU{$;$;<<SbSA&(p(pko(p(p(pqB #R  #R  #R  #R[g[m[m[o[o  #R  #R  #R%b?+>????\\)D//\\\	 	j"$I33d333E#JsU{$;$;<<SbSA#D// h h3c=11 h!#S-A)B)BBBS122B'../[/[/[/[/[QVWYQZQZ/[/[/[\\\$$%Z%Z%Z%Z%ZuRQSVXQXGYGY%Z%Z%Z[[[['../f/f/f/f/fQVW_`cWdWdQeQe/f/f/fgggg&&y111&(m(mhl(m(m(mnBmmhlmmmF $Zf%=%= > >ss C  J   J   J   JYbYhYhYjYj   J   J   J !G6F!G!G!GTgIhIhiiity$3U333r@   c                $      fd|D             }|S )Nc                N    g | ]!}t          |          r|j        n|gD ]}|"S rG   )r4   r   )rc   r   rd   rQ   s      r>   rh   z/ArrayTensorProduct._flatten.<locals>.<listcomp>;  s?    YYYc
38L8L,WCHHSVRWYYaYYYYr@   rG   )rQ   r   s   ` r>   r   zArrayTensorProduct._flatten9  s!    YYYYTYYYr@   c                2    t          d | j        D              S )Nc                Z    g | ](}t          |d           r|                                n|)S rt   r   rt   r   s     r>   rh   z2ArrayTensorProduct.as_explicit.<locals>.<listcomp>?  s8    nnn]`GC4O4OXs000UXnnnr@   )r   r   rX   s    r>   rt   zArrayTensorProduct.as_explicit>  s     nndhdmnnnoor@   N)	rC   rD   rE   ru   rP   r   r   r   rt   rG   r@   r>   r   r      sl           &74 74 74r   [p p p p pr@   r   c                  :    e Zd ZdZd Zd Zed             Zd ZdS )ArrayAddz0
    Class for elementwise array additions.
    c                   d |D             }d |D             }t          t          |                    }t          |          dk    rt          d          d |D             }t          d |D                       dk    rt          d          |                    dd	          }t          j        | g|R  }||_        t          d
 |D                       rd |_	        n|d         |_	        |r|
                                S |S )Nc                ,    g | ]}t          |          S rG   r-   r   s     r>   rh   z$ArrayAdd.__new__.<locals>.<listcomp>H  r   r@   c                ,    g | ]}t          |          S rG   r   r   s     r>   rh   z$ArrayAdd.__new__.<locals>.<listcomp>I  r   r@   r]   z!summing arrays of different ranksc                    g | ]	}|j         
S rG   r1   r   s     r>   rh   z$ArrayAdd.__new__.<locals>.<listcomp>M  s    ,,,#),,,r@   c                    h | ]}||S r3   rG   rb   s     r>   	<setcomp>z#ArrayAdd.__new__.<locals>.<setcomp>N  s    333aQ]]]]r@   zmismatching shapes in additionr   Fc              3     K   | ]}|d u V  	d S r3   rG   rb   s     r>   re   z#ArrayAdd.__new__.<locals>.<genexpr>U  r   r@   r   )r   setr   ro   r   r   rP   r   r   r   r   )rQ   r   r   r   r   r   rS   s          r>   rP   zArrayAdd.__new__G  s    .....//$///SZZ  u::??@AAA,,t,,,33633344q88=>>>zz.%88mC'$'''))&))))) 	#CJJCJ 	'$$&&&
r@   c                N   | j         }|                     |          }d |D             }d |D             }t          |          dk    r7t          d |D                       rt	          d          t          |d          S t          |          dk    r|d         S  | j        |ddiS )	Nc                ,    g | ]}t          |          S rG   r   r   s     r>   rh   z*ArrayAdd._canonicalize.<locals>.<listcomp>c  s    111S)C..111r@   c                J    g | ] }t          |t          t          f          |!S rG   r   r   s     r>   rh   z*ArrayAdd._canonicalize.<locals>.<listcomp>d  s,    TTT:cIz;R+S+STTTTr@   r   c              3     K   | ]}||V  	d S r3   rG   rb   s     r>   re   z)ArrayAdd._canonicalize.<locals>.<genexpr>f  s"      22	1				22r@   zIcannot handle addition of ZeroMatrix/ZeroArray and undefined shape objectr]   r   F)r   _flatten_argsr   r   NotImplementedErrorr   r   )r<   r   r   s      r>   r   zArrayAdd._canonicalize]  s    y !!$''11D111TTtTTTt99>>22f22222 w)*uvvvfQi((YY!^^7Nty$3U333r@   c                    g }|D ]G}t          |t                    r|                    |j                   2|                    |           H|S r3   )r4   r  r   r   append)rQ   r   new_argsr   s       r>   r"  zArrayAdd._flatten_argsm  sY     	% 	%C#x(( %))))$$$$r@   c                T    t          t          j        d | j        D                       S )Nc                Z    g | ](}t          |d           r|                                n|)S r  r  r   s     r>   rh   z(ArrayAdd.as_explicit.<locals>.<listcomp>z  s6    \\\3'#}"="=FS__3\\\r@   )r   r   r   r   rX   s    r>   rt   zArrayAdd.as_explicitw  s1    L\\RVR[\\\^ ^ 	^r@   N)	rC   rD   rE   ru   rP   r   r   r"  rt   rG   r@   r>   r  r  B  sk           ,4 4 4    [^ ^ ^ ^ ^r@   r  c                      e Zd ZdZddZd Zed             Zed             Ze	d             Z
e	d             Ze	d	             Ze	d
             Zd Ze	d             Zd Ze	d             Ze	d             ZdS )r   a  
    Class to represent permutation of axes of arrays.

    Examples
    ========

    >>> from sympy.tensor.array import permutedims
    >>> from sympy import MatrixSymbol
    >>> M = MatrixSymbol("M", 3, 3)
    >>> cg = permutedims(M, [1, 0])

    The object ``cg`` represents the transposition of ``M``, as the permutation
    ``[1, 0]`` will act on its indices by switching them:

    `M_{ij} \Rightarrow M_{ji}`

    This is evident when transforming back to matrix form:

    >>> from sympy.tensor.array.expressions.from_array_to_matrix import convert_array_to_matrix
    >>> convert_array_to_matrix(cg)
    M.T

    >>> N = MatrixSymbol("N", 3, 2)
    >>> cg = permutedims(N, [1, 0])
    >>> cg.shape
    (2, 3)

    There are optional parameters that can be used as alternative to the permutation:

    >>> from sympy.tensor.array.expressions import ArraySymbol, PermuteDims
    >>> M = ArraySymbol("M", (1, 2, 3, 4, 5))
    >>> expr = PermuteDims(M, index_order_old="ijklm", index_order_new="kijml")
    >>> expr
    PermuteDims(M, (0 2 1)(3 4))
    >>> expr.shape
    (3, 1, 2, 5, 4)

    Permutations of tensor products are simplified in order to achieve a
    standard form:

    >>> from sympy.tensor.array import tensorproduct
    >>> M = MatrixSymbol("M", 4, 5)
    >>> tp = tensorproduct(M, N)
    >>> tp.shape
    (4, 5, 3, 2)
    >>> perm1 = permutedims(tp, [2, 3, 1, 0])

    The args ``(M, N)`` have been sorted and the permutation has been
    simplified, the expression is equivalent:

    >>> perm1.expr.args
    (N, M)
    >>> perm1.shape
    (3, 2, 5, 4)
    >>> perm1.permutation
    (2 3)

    The permutation in its array form has been simplified from
    ``[2, 3, 1, 0]`` to ``[0, 1, 3, 2]``, as the arguments of the tensor
    product `M` and `N` have been switched:

    >>> perm1.permutation.array_form
    [0, 1, 3, 2]

    We can nest a second permutation:

    >>> perm2 = permutedims(perm1, [1, 0, 2, 3])
    >>> perm2.shape
    (2, 3, 5, 4)
    >>> perm2.permutation.array_form
    [1, 0, 3, 2]
    Nc                &   ddl m} t          |          }t          |          }|                     |||           |          j        }||k    rt          d          |                    dd          }	t          j	        | |          }
t          |          g|
_
        t          |          d |
_        n;t          fdt          t                              D                       |
_        |	r|
                                S |
S )Nr   r*   z8Permutation size must be the length of the shape of exprr   Fc              3  :   K   | ]} |                   V  d S r3   rG   )rc   rd   r   r1   s     r>   re   z&PermuteDims.__new__.<locals>.<genexpr>  s0      PPu[[^^4PPPPPPr@   )sympy.combinatoricsr+   r.   r   _get_permutation_from_argumentssizero   r   r   rP   r   r   r   rz   rk   r   r   )rQ   r   r   index_order_oldindex_order_newr   r+   	expr_rankpermutation_sizer   rS   r1   s     `        @r>   rP   zPermuteDims.__new__  s   333333~~TNN	99+Xgirss!k+..&+y((WXXXzz.%88mC{33!$($=CJJPPPPPeCJJ>O>OPPPPPCJ 	'$$&&&
r@   c                    | j         | j        }t          t                    rj         }j        }||z  }|t          t                    r|                     |          \  }t          t                    r|                     |          \  }t          t          t          f          rt          fd|j
        D              S |j
        }|t          |          k    rS |                     |d          S )Nc                *    g | ]}j         |         S rG   r  rc   rd   r   s     r>   rh   z-PermuteDims._canonicalize.<locals>.<listcomp>  s    MMMtz!}MMMr@   F)r   )r   r   r4   r   r   '_PermuteDims_denestarg_ArrayContractionr   )_PermuteDims_denestarg_ArrayTensorProductr   r   
array_formsortedr   )r<   r   subexprsubpermplistr   s        @r>   r   zPermuteDims._canonicalize  s   y&dK(( 	iG&G%/KDd,-- 	` $ L LTS^ _ _D+d.// 	b $ N NtU` a aD+dY
344 	OMMMMk6LMMMNN&F5MM!!Kyy{y???r@   c                    | j         d         S rU   r   rX   s    r>   r   zPermuteDims.expr      y|r@   c                    | j         d         S r\   r>  rX   s    r>   r   zPermuteDims.permutation  r?  r@   c                  	
 t          |j                  
t          |j                  t          t	          dg|j        z                       		
fdt          t                              D             d t                    D             }|	                    d            d |D             }fd|D             }fd|D             }t          t          d	 |D                                 }t          | |fS )
Nr   c                B    g | ]}|         |d z                     S r]   rG   )rc   rd   cumulperm_image_forms     r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>  s0    (h(h(hRSq%!*9L)M(h(h(hr@   c                6    g | ]\  }}|t          |          fS rG   )r9  )rc   rd   comps      r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>  s'    XXXGAtq&,,XXXr@   c                    | d         S r\   rG   xs    r>   <lambda>zGPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<lambda>  s
    ad r@   keyc                    g | ]
}|d          S r   rG   rb   s     r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>
  s    111!111r@   c                     g | ]
}|         S rG   rG   rc   rd   r   s     r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>  s    ===1tAw===r@   c                     g | ]
}|         S rG   rG   )rc   rd   perm_image_form_in_componentss     r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>  s    &f&f&fA'DQ'G&f&f&fr@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zIPermuteDims._PermuteDims_denestarg_ArrayTensorProduct.<locals>.<listcomp>  s'    1d1d1dbc1d1d]^!1d1d1d1dr@   )r,   r8  r   r   r   r   rk   r   r   sortr+   r   )rQ   r   r   psperm_args_image_formargs_sortedperm_image_form_sorted_argsnew_permutationr   rD  rE  rS  s           @@@@r>   r7  z5PermuteDims._PermuteDims_denestarg_ArrayTensorProduct  s(    %[%;<<DIZdm 34455 )i(h(h(h(hW\]`ae]f]fWgWg(h(h(h%XXy9V/W/WXXX 	NN###11b111====(<===&f&f&f&fQe&f&f&f#%j1d1d=X1d1d1d&e&eff$k2OCCr@   c                   t          |t                    s||fS t          |j        t                    s||fS |j        j        d |j        j        D             }|j        }d |D             }t          t          dg|z                       g t          |j	                  }d}t          t          |                    D ]`}g }	t          |         |dz                      D ]'}
|
|v r|	                    ||                    |dz  }(                    |	           afdt          |j                  D             |                    |j                  }|dz  fd|D             }t          t          |                    }|                    d 	           d
 |D             }fd|D             }t          d |D                       fd|D             }fd|D             }t#          t%          | g|R  }t'          t          d fd|D             D                                 }||fS )Nc                ,    g | ]}t          |          S rG   r   r   s     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>  s    <<<cHSMM<<<r@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>  %    #N#N#N!A#N#NqA#N#N#N#Nr@   r   r]   c           
     n    g | ]1\  }}t          t          |         |d z                                2S rC  r   rk   )rc   rd   erD  s      r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>.  s;    ___daU58U1Q3Z8899___r@   r   c                ,    g | ]}fd |D             S )c                *    g | ]}| |          S r3   rG   )rc   rm   r  s     r>   rh   zRPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>.<listcomp>1  s&    $X$X$X!-%8%8%;%;---r@   rG   )rc   rd   r  s     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>1  s/    #r#r#r]^$X$X$X$XQ$X$X$X#r#r#rr@   c                    | d         S r\   rG   rI  s    r>   rK  zEPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<lambda>6  s
    ! r@   rL  c                    g | ]
}|d          S rO  rG   rb   s     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>9  s    :::qt:::r@   c                     g | ]
}|         S rG   rG   )rc   rd   index_blockss     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>;  s    IIILOIIIr@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp><  s'    /W/W/WaUV/W/WPQ/W/W/W/Wr@   c                     g | ]
}|         S rG   rG   rQ  s     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>=  s    999DG999r@   c                F    g | ]}t          fd |D                       S )c              3  (   K   | ]}|         V  d S r3   rG   )rc   rm   new_index_perm_array_forms     r>   re   zQPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>.<genexpr>>  s)      (Q(Q!)B1)E(Q(Q(Q(Q(Q(Qr@   rz   )rc   rd   rl  s     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>>  s7    "o"o"oVW5(Q(Q(Q(Qq(Q(Q(Q#Q#Q"o"o"or@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>@  sJ      2G  2G  2G  EF  2G  2G  @A!  2G  2G  2G  2Gr@   c                     g | ]
}|         S rG   rG   )rc   r   permutation_array_blocks_ups     r>   rh   zGPermuteDims._PermuteDims_denestarg_ArrayContraction.<locals>.<listcomp>@  s!    =z=z=zab>YZ[>\=z=z=zr@   )r4   r   r   r   r   r   r   r   r,   r8  rk   r   r%  r   r   _push_indices_uprU  r  r   r+   )rQ   r   r   r   r   contraction_indices_flat
image_formcounterrd   currentrm   index_blocks_upindex_blocks_up_permutedsorting_keysnew_perm_image_formnew_index_blocksr&  new_contraction_indicesnew_exprrZ  r   rD  rg  r  rl  rp  s                       @@@@@@r>   r6  z3PermuteDims._PermuteDims_denestarg_ArrayContraction  s   $ 011 	%$$$)%788 	%$$y~<<TY^<<<"6#N#N/B#N#N#N Zh//00 ')# 677
s8}}%% 	8 	8AG58U1Q3Z00  000z'23331'..w7777 `___iPTP]F^F^___//0H,WW)B/#r#r#r#rbq#r#r#r  I&>??@@nn--- ;:\:::IIII5HIII$./W/W;K/W/W/W$X$X!9999%8999"o"o"o"o[n"o"o"o%&;X&FaI`aaa%j  2G  2G=z=z=z=zfy=z=z=z  2G  2G  2G  'H  'H  I  I((r@   c           	        j         }fdt          j                  D             fdt                                                    D             }t          j                  |d                  }g g t                      }t          |          D ]\  }}|         |k    r                               g |         }                    |           ||         }	t                    |	k    ru                    t                               fdD             }
|         }t          |         t          |
                    |<   |                    |           g ։                               t          t          t                                        }i }dgt          t          |                    z   t          t          |                    D ]i}fdt          |         |dz                      D             }t          |          dk    rBt          t!          |                    }||k    r|||<   jg }g }|rt          |          dk    r-|                                \  }}|                    |           n$|d         }||vrg }Q|                    |          }||v r|                    |           g }|                    |           ||D ]5}t          |          D ]#\  }}||||dz   t          |          z           <   $6fdt          |          D             fd	|D             fd
|D             }d |D             }t'           t          |          fS )Nc                T    g | ]$\  }}t          j        |                   D ]}|%S rG   )rk   r   )rc   rd   r   rm   r   s       r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>F  s:    [[[61c5WXIYCZCZ[[aQ[[[[r@   c                &    g | ]} |          S rG   rG   rc   rd   r   s     r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>G  s!    JJJqKKNNJJJr@   r   c                4    g | ]}|t                    z
  S rG   min)rc   rm   current_indicess     r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>V  s&    ([([([aS-A-A)A([([([r@   c                ,    h | ]}|                  S rG   rG   )rc   rm   	index2argrZ  s     r>   r  z9PermuteDims._check_permutation_mapping.<locals>.<setcomp>d  s#    ppp1?1-.pppr@   r]   r   c                R    g | ]"\  }fd t          |          D             #S )c                2    g | ]}         |z            S rG   rG   )rc   rm   cumulative_subranksrd   rZ  s     r>   rh   zEPermuteDims._check_permutation_mapping.<locals>.<listcomp>.<listcomp>  s)    ]]]q/B1/E/IJ]]]r@   rj   )rc   ra  rd   r  rZ  s     @r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>  sF    ~~~bfbcef]]]]]]TYZ[T\T\]]]~~~r@   c                     g | ]
}|         S rG   rG   )rc   rd   r&  s     r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>  s    888AHQK888r@   c                     g | ]
}|         S rG   rG   )rc   rd   permutation_blockss     r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>  s    !P!P!PA"4Q"7!P!P!Pr@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z:PermuteDims._check_permutation_mapping.<locals>.<listcomp>  s%    III!qII!AIIIIr@   )r   r   r   rk   r   r   r  r   r%  r   r9  r   r+   r   r   nextiterpopitemr   r   )rQ   r   r   r   permuted_indicesarg_candidate_indexinserted_arg_cand_indicesrd   idxarg_candidate_ranklocal_current_indicesr
  args_positionsmapsr~   elemlinescurrent_liner   vlinera  new_permutation_blocksnew_permutation2r  r  r  r&  rZ  r  s    ``                     @@@@@@r>   _check_permutation_mappingz&PermuteDims._check_permutation_mappingC  s   =[[[[Yty%9%9[[[	JJJJE$,,..4I4IJJJ	??'(8(;<$'EE! 011 	% 	%FAs~!444&&777"$&/n#""3'''!)*=!>?##'999&&vo'>'>???([([([([?([([([%q\,Xb\;G\;];]^^)--.ABBB"$/// eCMM2233 cDH)=)=$>$>>s8}}%% 	 	Appppp>QRS>TVijklmjmVn8o8opppA1vv{{Q==DDyyQ  	#<  A%%||~~1##A&&&& $D==#%LHHQKKL  \***!"""  	#  	> 	>D!$ > >1<=tQUc$ii$7899> ~~~~jst|j}j}~~~8888888!P!P!P!P!P!P!PII'=III$h/=M1N1NNNr@   c           	     Z   t          |j                  }|j        }|j        }dgt          t	          |                    z   d |D             }d |D             }g }t          |          D ]\  }	}
d}t          t                    dz
            D ]a||	                  k    rM||	         dz            k     r8t          |         t          fd|
D             g                    |<   d} nb|r|
                    |
           t          | t          ||j                  fS )	Nr   c                ,    g | ]}t          |          S rG   r  rb   s     r>   rh   zAPermuteDims._check_if_there_are_closed_cycles.<locals>.<listcomp>      222c!ff222r@   c                ,    g | ]}t          |          S rG   maxrb   s     r>   rh   zAPermuteDims._check_if_there_are_closed_cycles.<locals>.<listcomp>  r  r@   Tr]   c                &    g | ]}|         z
  S rG   rG   )rc   r   r  rm   s     r>   rh   zAPermuteDims._check_if_there_are_closed_cycles.<locals>.<listcomp>  s&    BmBmBmbc1GZ[\G]C]BmBmBmr@   F)r.  )r   r   r   r   r   r   rk   r   r   r+   r%  r   r.  )rQ   r   r   r   r   r   
cyclic_min
cyclic_maxcyclic_keeprd   cycleflagr  rm   s               @@r>   !_check_if_there_are_closed_cyclesz-PermuteDims._check_if_there_are_closed_cycles  s`   DI=!- cDH)=)=$>$>>22k222
22k222
!+.. 		* 		*HAuD3233a788  a=$7$:::z!}ObcdefcfOg?g?g+DG[BmBmBmBmBmglBmBmBmAn5o5oppDG DE *""5)))$d+[;K[-\-\-\\\r@   c                N    |                      | j        | j                  }|| S |S )z
        DEPRECATED.
        )_nest_permutationr   r   )r<   rets     r>   nest_permutationzPermuteDims.nest_permutation  s-     $$TY0@AA;K
r@   c                   t          |t                    rt          |                     |           S t          |t                    r[j        }t	          j        |g|R  }t          |          fd|j        D             }t          t          |j                  g|R  S t          |t                    rt          fd|j        D              S d S )Nc                F    g | ]}t          fd |D                       S )c              3  .   K   | ]} |          V  d S r3   rG   )rc   rm   newpermutations     r>   re   z;PermuteDims._nest_permutation.<locals>.<listcomp>.<genexpr>  s-      &D&DQ~~a'8'8&D&D&D&D&D&Dr@   rm  )rc   rd   r  s     r>   rh   z1PermuteDims._nest_permutation.<locals>.<listcomp>  s6     g g g&D&D&D&D!&D&D&D!D!D g g gr@   c                0    g | ]}t          |          S rG   r   )rc   r   r   s     r>   rh   z1PermuteDims._nest_permutation.<locals>.<listcomp>  s#    SSS#C = =SSSr@   )r4   r   r   r  r   r   '_convert_outer_indices_to_inner_indicesr+   r   r  r   r   r  
_array_addr   )rQ   r   r   cycles	newcyclesnew_contr_indicesr  s     `   @r>   r  zPermuteDims._nest_permutation  s    d.// 
	U #"G"Gk"Z"Z[[.// 	U ,F(PQU_X^___I(33N g g g gdNf g g g%k$)^&L&LaO`aaaah'' 	USSSSSSSTTtr@   c                    | j         }t          |d          r|                                }t          || j                  S Nrt   )r   r   rt   r   r   r<   r   s     r>   rt   zPermuteDims.as_explicit  s?    y4'' 	&##%%D4!1222r@   c                    |/||t          d          t                              |||          S |t          d          |t          d          |S )NzPermutation not definedz2index_order_new cannot be defined with permutationz2index_order_old cannot be defined with permutation)ro   r   "_get_permutation_from_index_orders)rQ   r   r/  r0  dims        r>   r-  z+PermuteDims._get_permutation_from_arguments  sl    &/*A !:;;;AA/Sbdghhh* !UVVV* !UVVVr@   c                   t          t          |                    |k    rt          d          t          t                              |k    rt          d          t          t                              t          |          t                                        dk    rt          d          fd|D             }|S )Nz*wrong number of indices in index_order_newz*wrong number of indices in index_order_oldr   z>index_order_new and index_order_old must have the same indicesc                :    g | ]}                     |          S rG   index)rc   rd   r/  s     r>   rh   zBPermuteDims._get_permutation_from_index_orders.<locals>.<listcomp>  s'    IIIA,,Q//IIIr@   )r   r  ro   symmetric_difference)rQ   r/  r0  r  r   s    `   r>   r  z.PermuteDims._get_permutation_from_index_orders  s    s?##$$++IJJJs?##$$++IJJJs''O(<(<c/>R>RSSTTWXXX]^^^IIIIIIIr@   )NNN)rC   rD   rE   ru   rP   r   rw   r   r   r   r7  r6  r  r  r  r  rt   r-  r  rG   r@   r>   r   r   }  sf       G GR   .@ @ @&   X   X D D [D0 .) .) [.)` BO BO [BOH ] ] [](     [3 3 3 
 
 [
   [  r@   r   c                  $   e Zd ZdZd Zd Zed             Zed             Ze	d             Z
e	d             Zed             Zed	             Zed
             Zedd            Zd Zd Zed             Zed             Zed             Zd ZdS )r   a  
    Class to represent the diagonal operator.

    Explanation
    ===========

    In a 2-dimensional array it returns the diagonal, this looks like the
    operation:

    `A_{ij} \rightarrow A_{ii}`

    The diagonal over axes 1 and 2 (the second and third) of the tensor product
    of two 2-dimensional arrays `A \otimes B` is

    `\Big[ A_{ab} B_{cd} \Big]_{abcd} \rightarrow \Big[ A_{ai} B_{id} \Big]_{adi}`

    In this last example the array expression has been reduced from
    4-dimensional to 3-dimensional. Notice that no contraction has occurred,
    rather there is a new index `i` for the diagonal, contraction would have
    reduced the array to 2 dimensions.

    Notice that the diagonalized out dimensions are added as new dimensions at
    the end of the indices.
    c                   t          |          }d |D             }|                    dd          }t          |          }|+ | j        |g|R i | |                     ||          \  }}nd }t          |          dk    r|S t          j        | |g|R  }||_        t          |          |_
        ||_        |r|                                S |S )Nc                :    g | ]}t          t          |           S rG   )r   r9  rb   s     r>   rh   z)ArrayDiagonal.__new__.<locals>.<listcomp>  s#    HHH!E6!99-HHHr@   r   Fr   )r.   r   r   	_validate_get_positions_shaper   r   rP   
_positions_get_subranksr   r   r   )rQ   r   r   r   r   r1   	positionsrS   s           r>   rP   zArrayDiagonal.__new__  s    ~~HH7GHHHzz.%88$CM$<!1<<<V<<<"77?OPPIuuI  A%%KmC9(8999"%d++
 	'$$&&&
r@   c                   | j         }| j        }d |D             }t          |          dk    rrd t          |          D             }d t          |          D             }d |D             }t	          |           }t          |          }||z
  }	g }
d}t
                              |t          t          |                    t	          |                    }|D ]z}||v r|
	                    |	||         z              %t          |t          t          f          r|
	                    |           |dz  }\|
	                    |	||         z              {t          |
          }t          |          dk    rt          t          |g|R  |          S t          ||          S t          |t                     r | j        |g|R  S t          |t
                    r | j        |g|R  S t          |t&                    r | j        |g|R  S t          |t*          t,          f          r'|                     |j        |          \  }}t+          | S  | j        |g|R ddiS )	Nc                8    g | ]}t          |          d k    |S rC  r   rb   s     r>   rh   z/ArrayDiagonal._canonicalize.<locals>.<listcomp>  s#    DDDqA!r@   r   c                L    i | ]!\  }}t          |          d k    |d         |"S r]   r   r  rc   rd   ra  s      r>   r   z/ArrayDiagonal._canonicalize.<locals>.<dictcomp>	  s/    ZZZtq!cRSffXYkk1Q4kkkr@   c                @    i | ]\  }}t          |          d k    ||S rC  r  r  s      r>   r   z/ArrayDiagonal._canonicalize.<locals>.<dictcomp>
  s*    SSSAAQR

1


r@   c                8    g | ]}t          |          d k    |S rC  r  rb   s     r>   rh   z/ArrayDiagonal._canonicalize.<locals>.<listcomp>  s#    %P%P%PASVVaZZaZZZr@   r]   r   F)r   r   r   r   r   r   _push_indices_downr   rk   r%  r4   r   intr,   r   r  r  _ArrayDiagonal_denest_ArrayAdd#_ArrayDiagonal_denest_ArrayDiagonalr   !_ArrayDiagonal_denest_PermuteDimsr   r   r  r1   r   )r<   r   r   trivial_diagstrivial_posdiag_posdiagonal_indices_shortrank1rank2rank3inv_permutationcounter1indices_downrd   r   r  r1   s                    r>   r   zArrayDiagonal._canonicalize  s   y0DD$4DDD}!!ZZy9I/J/JZZZKSS3C)D)DSSSH%P%P1A%P%P%P"TNNE())EEME OH(;;<RTXY^_dYeYeTfTfhpquhvhvwwL! @ @###**5;q>+ABBBBGS>22 @#**8444MHH#**58A;+>????$_55K)**Q..$_T%S<R%S%S%SU`aaa$T;777dH%% 	P646tO>NOOOOdM** 	U;4;DTCSTTTTdK(( 	S949$RAQRRRRdY
344 	%#88EUVVIue$$tyE 0EEEuEEEr@   c                   t          |           |D ]}t          fd|D                       rt          d          t          fd|D                       dk    rt          d          |                    dd          s"t          |          dk    rt          d          t          t          |                    t          |          k    rt          d	          d S )
Nc              3  >   K   | ]}|t                    k    V  d S r3   r  rc   rm   r1   s     r>   re   z*ArrayDiagonal._validate.<locals>.<genexpr>0  s-      ..q1E

?......r@   z%index is larger than expression shapec                     h | ]
}|         S rG   rG   r  s     r>   r  z*ArrayDiagonal._validate.<locals>.<setcomp>2  s    (((E!H(((r@   r]   z-diagonalizing indices of different dimensionsallow_trivial_diagsFz%need at least two axes to diagonalizezaxis index cannot be repeated)r   r   ro   r   r   r  )r   r   r   rd   r1   s       @r>   r  zArrayDiagonal._validate*  s     $! 	B 	BA....A..... J !HIII((((a((())Q.. !PQQQ::3U;; JA! !HIII3q66{{c!ff$$ !@AAA %	B 	Br@   c                       fd|D             S )Nc                f    g | ]-}|d                   dk    t          d |D                       .S )r   r]   c              3     K   | ]}|V  d S r3   rG   rl   s     r>   re   zFArrayDiagonal._remove_trivial_dimensions.<locals>.<listcomp>.<genexpr>;  s      ^^Aa^^^^^^r@   rm  rc   rd   r1   s     r>   rh   z<ArrayDiagonal._remove_trivial_dimensions.<locals>.<listcomp>;  s>    RRRqtPQAQAQ^^^^^##AQAQAQr@   rG   )r1   r   s   ` r>   _remove_trivial_dimensionsz(ArrayDiagonal._remove_trivial_dimensions9  s    RRRR-=RRRRr@   c                    | j         d         S rU   r>  rX   s    r>   r   zArrayDiagonal.expr=  r?  r@   c                     | j         dd          S r\   r>  rX   s    r>   r   zArrayDiagonal.diagonal_indicesA      y}r@   c                   | j         }d |D             }|                                 t          |           }t          |          }||z
  }d t	          |          D             d}d}t	          |          D ]E}	||k     r(|||         k    r|dz  }|dz  }||k     r|||         k    |	xx         |z  cc<   |dz  }Ft          fd|D                       }||z   }
t          | j        g|
R  S )Nc                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z*ArrayDiagonal._flatten.<locals>.<listcomp>H  s%    BBB1BB1QBBBBr@   c                    g | ]}d S rO  rG   rb   s     r>   rh   z*ArrayDiagonal._flatten.<locals>.<listcomp>N      ///!///r@   r   r]   c              3  N   K   | ]}t          fd |D                       V   dS )c              3  .   K   | ]}|         |z   V  d S r3   rG   rc   rm   shiftss     r>   re   z3ArrayDiagonal._flatten.<locals>.<genexpr>.<genexpr>W  s+      ,F,FqVAY],F,F,F,F,F,Fr@   Nrm  rc   rd   r  s     r>   re   z)ArrayDiagonal._flatten.<locals>.<genexpr>W  s@      &g&g1u,F,F,F,FA,F,F,F'F'F&g&g&g&g&g&gr@   )r   rU  r   r   rk   rz   r  r   )r   outer_diagonal_indicesinner_diagonal_indices	all_inner
total_rank
inner_rank
outer_rankrt  pointerrd   r   r  s              @r>   r   zArrayDiagonal._flattenE  sB   !%!6BB 6BBB	!$''
^^
*,
//U:..///z"" 	 	AJ&&7i6H+H+H11 J&&7i6H+H+H 1III IIIqLGG!&&g&g&g&gPf&g&g&g!g!g14JJty<+;<<<<r@   c                8    t          fd|j        D              S )Nc                *    g | ]}t          |gR  S rG   )r  )rc   r   r   s     r>   rh   z@ArrayDiagonal._ArrayDiagonal_denest_ArrayAdd.<locals>.<listcomp>]  s*    YYYOCC2BCCCYYYr@   r  r   rQ   r   r   s     `r>   r  z,ArrayDiagonal._ArrayDiagonal_denest_ArrayAdd[  s%    YYYYtyYYYZZr@   c                     | j         |g|R  S r3   r   r  s      r>   r  z1ArrayDiagonal._ArrayDiagonal_denest_ArrayDiagonal_  s    s|D4#34444r@   r   r   c                  	
 fdD             }fdt          t                              D             }fd|D             }d t          t          |                    D             		fd|D             }t	          |          

fdt          t	          |                    D             }||z   }t          t          j        g|R  |          S )Nc                ,    g | ]}fd |D             S )c                :    g | ]}                     |          S rG   r   )rc   rm   r   s     r>   rh   zNArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>.<listcomp>e  s'    !A!A!A!$"2"21"5"5!A!A!Ar@   rG   r5  s     r>   rh   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>e  s.     \ \ \a!A!A!A!Aq!A!A!A \ \ \r@   c                L    g | ]t          fd D                        S )c              3      K   | ]}|v V  	d S r3   rG   rc   rm   rd   s     r>   re   zMArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>.<genexpr>f  s'      >`>`!qAv>`>`>`>`>`>`r@   r   )rc   rd   r   s    @r>   rh   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>f  s=    aaa3>`>`>`>`O_>`>`>`;`;`a1aaar@   c                :    g | ]}                     |          S rG   r  r5  s     r>   rh   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>g  s'    ===((++===r@   c                    i | ]\  }}||	S rG   rG   r  s      r>   r   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<dictcomp>h  s    BBB$!QABBBr@   c                     g | ]
}|         S rG   rG   )rc   rd   remaps     r>   rh   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>i  s    ;;;E!H;;;r@   c                    g | ]}|z   S rG   rG   )rc   rd   shifts     r>   rh   zCArrayDiagonal._ArrayDiagonal_denest_PermuteDims.<locals>.<listcomp>k  s    PPP1u9PPPr@   )rk   r   r   r9  r   r   r  r   )rQ   r   r   back_diagonal_indicesnondiagback_nondiagnew_permutation1diag_block_permrZ  r  r  s    ``      @@r>   r  z/ArrayDiagonal._ArrayDiagonal_denest_PermuteDimsc  s    \ \ \ \K[ \ \ \aaaaeHTNN33aaa====W===BB)F<,@,@"A"ABBB;;;;l;;;$%%PPPPeC8M4N4N.O.OPPP*_<	&   
 
 	
r@   c                .      fd}t          ||          S )Nc                R    | t          j                  k     rj        |          nd S r3   )r   r  )rJ  r<   s    r>   rK  z<ArrayDiagonal._push_indices_down_nonstatic.<locals>.<lambda>v  s(    ADO8L8L4L4Ldoa00RV r@   r$   r<   r{   	transforms   `  r>   _push_indices_down_nonstaticz*ArrayDiagonal._push_indices_down_nonstaticu  s!    VVVV	3IwGGGr@   c                .      fd}t          ||          S )Nc                    t          j                  D ]=\  }}t          |t                    r| |k    st          |t                    r| |v r|c S >d S r3   )r   r  r4   r  rz   )rJ  rd   ra  r<   s      r>   r!  z;ArrayDiagonal._push_indices_up_nonstatic.<locals>.transform{  sh    !$/22  1q#&& 166z!U7K7K6PQUVPVPVHHH r@   r  r   s   `  r>   _push_indices_up_nonstaticz(ArrayDiagonal._push_indices_up_nonstaticy  s.    	 	 	 	 	
 4IwGGGr@   c                z    |                      t          |          |          \  }fd}t          ||          S )Nc                >    | t                    k     r|          nd S r3   r  )rJ  r  s    r>   rK  z2ArrayDiagonal._push_indices_down.<locals>.<lambda>  s    a#i...@.@illd r@   r  rk   r$   rQ   r   r{   rankr1   r!  r  s         @r>   r  z ArrayDiagonal._push_indices_down  sB    33E$KKAQRR	5JJJJ	3IwGGGr@   c                z    |                      t          |          |          \  }fd}t          ||          S )Nc                    t                    D ]D\  }}t          |t                    r| |k    s t          |t          t          f          r| |v r|c S Ed S r3   )r   r4   r  rz   r   )rJ  rd   ra  r  s      r>   r!  z1ArrayDiagonal._push_indices_up.<locals>.transform  sj    !),,  1q#&& 166z!eU^7T7T6Z[_`Z`Z`HHH r@   r(  r)  s         @r>   rq  zArrayDiagonal._push_indices_up  sO    33E$KKAQRR	5	 	 	 	 	
 4IwGGGr@   c                    t          fdt                    D                       }|r	t          | nd\  }}t          fdD                       }|r	t          | nd\  }}||z   }	||z   |	fS )Nc              3  ^   K   | ]&\  }t          fd D                        |fV  'dS )c              3      K   | ]}|v V  	d S r3   rG   r  s     r>   re   z?ArrayDiagonal._get_positions_shape.<locals>.<genexpr>.<genexpr>  s(      HjHjTUaHjHjHjHjHjHjr@   Nr  )rc   shprd   r   s     @r>   re   z5ArrayDiagonal._get_positions_shape.<locals>.<genexpr>  sO      kk61cSHjHjHjHjYiHjHjHjEjEjkq#hkkkkkkr@   )rG   rG   c              3  8   K   | ]}||d                   fV  dS )r   NrG   r  s     r>   re   z5ArrayDiagonal._get_positions_shape.<locals>.<genexpr>  s0      AA1q%!+&AAAAAAr@   )rz   r   r   )
rQ   r1   r   data1pos1shp1data2pos2shp2r  s
    ``       r>   r  z"ArrayDiagonal._get_positions_shape  s    kkkkYu-=-=kkkkk$)7S%[[x
dAAAA0@AAAAA$)7S%[[x
d4K	t%r@   c                |    | j         }t          |d          r|                                }t          |g| j        R  S r  )r   r   rt   r   r   r  s     r>   rt   zArrayDiagonal.as_explicit  sE    y4'' 	&##%%Dd;T%:;;;;r@   N)r   r   )rC   rD   rE   ru   rP   r   staticmethodr  r  rw   r   r   r   r   r  r  r  r"  r%  r  rq  r  rt   rG   r@   r>   r   r     s        2  ,$F $F $FL B B \B S S \S   X   X = = \=* [ [ [[ 5 5 [5 
 
 
 [
"H H HH H H H H [H
 H H [H     [ < < < < <r@   r   c                  b    e Zd Zd Zed             Zed             Zed             Zd Zd Z	dS )ArrayElementwiseApplyFuncc                    t          |t                    s(t          d          }t          | ||                    }t                              | ||          }t          |          |_        |S Nd)r4   r   r   r   rP   r  r   )rQ   functionelementr>  rS   s        r>   rP   z!ArrayElementwiseApplyFunc.__new__  sa    (F++ 	.c

Aa!--H#++C7CC%g..
r@   c                    | j         d         S rU   r>  rX   s    r>   r?  z"ArrayElementwiseApplyFunc.function  r?  r@   c                    | j         d         S r\   r>  rX   s    r>   r   zArrayElementwiseApplyFunc.expr  r?  r@   c                    | j         j        S r3   r   r1   rX   s    r>   r1   zArrayElementwiseApplyFunc.shape  s    yr@   c                    t          d          }|                     |          }|                    |          }t          |t                    rt          |          }nt          ||          }|S r=  )r   r?  diffr4   r   typer   )r<   r>  r?  fdiffs       r>   _get_function_fdiffz-ArrayElementwiseApplyFunc._get_function_fdiff  sb    #JJ==##a  eX&& 	%KKEE1e$$Er@   c                    | j         }t          |d          r|                                }|                    | j                  S r  )r   r   rt   	applyfuncr?  r  s     r>   rt   z%ArrayElementwiseApplyFunc.as_explicit  s@    y4'' 	&##%%D~~dm,,,r@   N)
rC   rD   rE   rP   rw   r?  r   r1   rI  rt   rG   r@   r>   r;  r;    s             X   X   X  - - - - -r@   r;  c                     e Zd ZdZd Zd Zd Zd Zed             Z	e
d             Ze
d             Ze
d	             Zd
 Zd Zed             Zed             Zed             Zed             Ze
d             Ze
d             Ze
d             Ze
d             Ze
d#d            Ze
d             Zd Zed             Zed             Zed             Zed             Zed             Z d Z!d Z"d  Z#d! Z$d"S )$r   zx
    This class is meant to represent contractions of arrays in a form easily
    processable by the code printers.
    c                    t                    t          |          }|                    dd          }t          j        | |gR  }t          |          |_        t          |j                  |_        fdt          t          |j                            D             }||_        t          |          } | j        |gR   |r(t          fdt          |          D                       }||_        |r|                                S |S )Nr   Fc                N    i | ] t          fd D                       !S )c              3      K   | ]}|vV  	d S r3   rG   )rc   cindrd   s     r>   re   z6ArrayContraction.__new__.<locals>.<dictcomp>.<genexpr>  sK        SB  SBeiST\`S`  SB  SB  SB  SB  SB  SBr@   )rn   rc   rd   r   s    @r>   r   z,ArrayContraction.__new__.<locals>.<dictcomp>  s|      $C  $C  $CQs  SB  SB  SB  SB  nA  SB  SB  SB  PB  PB  $CAq  $C  $C  $Cr@   c              3  Z   K   | ]$\  }t          fd D                        |V  %dS )c              3      K   | ]}|v V  	d S r3   rG   r  s     r>   re   z5ArrayContraction.__new__.<locals>.<genexpr>.<genexpr>  s(      GlGlSTQGlGlGlGlGlGlr@   Nr  )rc   r0  rd   r   s     @r>   re   z+ArrayContraction.__new__.<locals>.<genexpr>  sK      mm&!SCGlGlGlGlXkGlGlGlDlDlm#mmmmmmr@   )r%   r.   r   r   rP   r  r   r&   _mappingrk   r   _free_indices_to_positionr   r  rz   r   r   r   )rQ   r   r   r   r   rS   free_indices_to_positionr1   s     `     r>   rP   zArrayContraction.__new__  s2   78KLL~~zz.%88mC<(;<<<%d++1#-@@ $C  $C  $C  $C%CM8J8J2K2K  $C  $C  $C (@%$d101111 	nmmmmIe,<,<mmmmmE
 	'$$&&&
r@   c                   | j         | j        }t          |          dk    rS t          t                    r | j        g|R  S t          t          t          f          r | j        g|R  S t          t                    r | j
        g|R  S t          t                    rG|                     |          \  }|                     |          \  }t          |          dk    rS t          t                    r | j        g|R  S t          t                     r | j        g|R  S fd|D             }t          |          dk    rS  | j        g|R ddiS )Nr   c                x    g | ]6}t          |          d k    st                    |d                  d k    4|7S r  )r   r   r5  s     r>   rh   z2ArrayContraction._canonicalize.<locals>.<listcomp>  sE    jjjQQ!yY]_`ab_cOdhiOiOiqOiOiOir@   r   F)r   r   r   r4   r   )_ArrayContraction_denest_ArrayContractionr   r   "_ArrayContraction_denest_ZeroArrayr   $_ArrayContraction_denest_PermuteDimsr   _sort_fully_contracted_args_lower_contraction_to_addendsr   &_ArrayContraction_denest_ArrayDiagonalr  !_ArrayContraction_denest_ArrayAddr   )r<   r   r   s     @r>   r   zArrayContraction._canonicalize  s   y"6"##q((Kd,-- 	^A4A$]I\]]]]dY
344 	W:4:4VBUVVVVdK(( 	Y<4<TXDWXXXXd.// 	(,(H(HOb(c(c%D%(,(J(J4Qd(e(e%D%&''1,,dM** 	[>4>tZFYZZZZdH%% 	V949$UATUUUU kjjj*=jjj"##q((KtyH 3HHH%HHHr@   c                0    |dk    r| S t          d          Nr]   zDProduct of N-dim arrays is not uniquely defined. Use another method.r#  r<   others     r>   __mul__zArrayContraction.__mul__      A::K%&lmmmr@   c                0    |dk    r| S t          d          ra  rb  rc  s     r>   __rmul__zArrayContraction.__rmul__  rf  r@   c                    t          |           d S |D ]0}t          fd|D                       dk    rt          d          1d S )Nc                8    h | ]}|         d k    |         S )r   rG   r  s     r>   r  z-ArrayContraction._validate.<locals>.<setcomp>   s&    :::58r>>E!H>>>r@   r]   z+contracting indices of different dimensions)r   r   ro   )r   r   rd   r1   s      @r>   r  zArrayContraction._validate  st    $=F % 	P 	PA::::a:::;;q@@ !NOOO A	P 	Pr@   c                    d |D             }|                                  t          |          }t          ||          S )Nc                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z7ArrayContraction._push_indices_down.<locals>.<listcomp>%  &    (S(S(SqQR(S(SA(S(S(S(Sr@   )rU  r)   r$   rQ   r   r{   flattened_contraction_indicesr!  s        r>   r  z#ArrayContraction._push_indices_down#  sG    (S(S4G(S(S(S%%**,,,@A^__	3IwGGGr@   c                    d |D             }|                                  t          |          }t          ||          S )Nc                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z5ArrayContraction._push_indices_up.<locals>.<listcomp>,  rm  r@   )rU  r'   r$   rn  s        r>   rq  z!ArrayContraction._push_indices_up*  sG    (S(S4G(S(S(S%%**,,,>?\]]	3IwGGGr@   c                  	
 t          |t                    rt                      t          |t                    s||fS |j        }t          t          dg|z                       
g }d |j        D             }t                      	|D ]}t          t          |j                            D ]~t          |j                 t                    s#t          
fd|D                       r?|                             
fd|D                        	                    |            n|                    |           t          |          t          |          k    r||fS t          |          }t          t          	fdt          |          D                                 fd|D             }t          d t!          |j        |          D              }||fS )Nr   c                    g | ]}g S rG   rG   rb   s     r>   rh   zBArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>:  s    #:#:#:1B#:#:#:r@   c              3  V   K   | ]#}         |cxk    od z            k     nc V  $dS )r]   NrG   rc   r   cumranksrm   s     r>   re   zAArrayContraction._lower_contraction_to_addends.<locals>.<genexpr>@  sK      SSAx{a7777(1Q3-7777SSSSSSr@   c                &    g | ]}|         z
  S rG   rG   ru  s     r>   rh   zBArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>A  s!    7c7c7cAHQK7c7c7cr@   c                     g | ]
}|v rd ndS r  rG   )rc   rd   	backshifts     r>   rh   zBArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>I  s%    !X!X!XqI~~!!1!X!X!Xr@   c                P    g | ]"}t          j        fd |D                       #S )c              3  .   K   | ]}||         z
  V  d S r3   rG   r  s     r>   re   zLArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>.<genexpr>J  s+      7Q7Q!F1I7Q7Q7Q7Q7Q7Qr@   )r   r   r  s     r>   rh   zBArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>J  s9    (y(y(yVW7Q7Q7Q7Qq7Q7Q7Q)Q)Q(y(y(yr@   c                .    g | ]\  }}t          |g|R  S rG   r  )rc   r   contrs      r>   rh   zBArrayContraction._lower_contraction_to_addends.<locals>.<listcomp>K  s:     &
 &
 &
0:Us+U+++&
 &
 &
r@   )r4   r  r#  r   r   r   r   r   r  rk   r   rn   r%  updater   r   r   )rQ   r   r   r   contraction_indices_remainingcontraction_indices_argscontraction_groupr   r  ry  rv  rm   r  s            @@@@r>   r]  z.ArrayContraction._lower_contraction_to_addends1  s,   dH%% 	(%'''$ 233 	-,,,=
A3>2233(*%#:#:	#:#:#: EE	!4 		H 		H3ty>>** H H!$)A,99 SSSSSARSSSSS ,Q/667c7c7c7c7cQb7c7c7cddd$$%6777E
 .445FGGG,--5H1I1III,,,d^^
j!X!X!X!XeJFWFW!X!X!XYYZZ(y(y(y(y[x(y(y(y%# &
 &
>A$)Me>f>f&
 &
 &
  111r@   c           	        t          |           }| j        }g }t          |          D ] \  }t          |          dk    r|                              }| j        j        |d                  }g }g }|D ]\  }	}
|j        |	         }|j        }|	                    |          \  }}d|
z
  }||z   d|j        vs<|dk    du r|j        dk    s)t          fdt          |          D                       r|                    ||
f           |                    ||
f           t          |          dk    r|D ]\  }}
t          |j                  |_        |dd         |z   |dd         z   }|d         \  }}
|j        |
         }|dd         D ]}\  }}
||j        |
<   |                                }|j                            d          d|
z
  k    sJ ||j        |j                            d          <   |                    |           ~|d         \  }}
||j        |
<   |D ]4}|                    |t#          t%          d          dg                     5|                                S )	a`  
        Recognize multiple contractions and attempt at rewriting them as paired-contractions.

        This allows some contractions involving more than two indices to be
        rewritten as multiple contractions involving two indices, thus allowing
        the expression to be rewritten as a matrix multiplication line.

        Examples:

        * `A_ij b_j0 C_jk` ===> `A*DiagMatrix(b)*C`

        Care for:
        - matrix being diagonalized (i.e. `A_ii`)
        - vectors being diagonalized (i.e. `a_i0`)

        Multiple contractions can be split into matrix multiplications if
        not more than two arguments are non-diagonals or non-vectors.
        Vectors get diagonalized while diagonal matrices remain diagonal.
        The non-diagonal matrices can be at the beginning or at the end
        of the final matrix multiplication line.
           r   r]   T)r]   r]   c              3  2   K   | ]\  }}|k    |v V  d S r3   rG   )rc   lilindlother_arg_abss      r>   re   z?ArrayContraction.split_multiple_contractions.<locals>.<genexpr>  s8      eeur1Z\`dZdZd*ZdZdZdZdeer@   Nr   )_EditArrayContractionr   r   r   get_mapping_for_indexr   r1   args_with_indr@  get_absolute_ranger   r%  r   r{   get_new_contraction_indexr  insert_after_ArgEr   to_array_contraction)r<   editorr   onearray_insertlinksr  current_dimensionnot_vectorsvectorsarg_indrel_indr   matabs_arg_startabs_arg_endother_arg_posr  vectors_to_loopfirst_not_vector	new_indexlast_vecr  r  s                        @@r>   split_multiple_contractionsz,ArrayContraction.split_multiple_contractionsP  s   . 't,,"6$%899 @	2 @	2KD%5zzQ& 44T::I !%	a 9KG$- 3 3 *73k-3-F-Fs-K-K*{ !'	 - =ci'''1,55#)v:M:Meeeee	BU8V8Veeeee ;N  &&W~6666NNC>2222;!## 
 & : :
7.qy99		)"1"o7+abb/IO(7(:%g(09I-ad3 * *
7%.	'""<<>>	yt,,G;;;;3<	!)//$//0&&q)))) / 3Hg(1HW%%  	? 	?A5!tf#=#=>>>>**,,,r@   c                >   t          | j        t                    s| S | j                            | j        j        | j                  }g }| j        j        d d          }|D ]}t          |          }|D ]=fd|D             |                    d D                        fd|D             }>|                    t          t          |                               t                              ||          }t          t          | j        j        g|R  g|R  S )Nc                    g | ]}|v |	S rG   rG   )rc   r   rm   s     r>   rh   zDArrayContraction.flatten_contraction_of_diagonal.<locals>.<listcomp>  s     G G GqQr@   c                    g | ]	}|D ]}|
S rG   rG   )rc   r   r  s      r>   rh   zDArrayContraction.flatten_contraction_of_diagonal.<locals>.<listcomp>  s%    )N)N)NA)N)Nq!)N)N)N)Nr@   c                    g | ]}|v|	S rG   rG   )rc   r   diagonal_withs     r>   rh   zDArrayContraction.flatten_contraction_of_diagonal.<locals>.<listcomp>  s#    #Z#Z#Z!1MCYCYACYCYCYr@   )r4   r   r   r  r   r   r   r   r%  r9  r  rq  r  r  )r<   contraction_downr{  r   rd   r  r  rm   s         @@r>   flatten_contraction_of_diagonalz0ArrayContraction.flatten_contraction_of_diagonal  sc   $)]33 	K977	8RTXTlmm"$95aaa8! 	K 	KA $Q [ [ G G G G,< G G G!(()N)N])N)N)NOOO#Z#Z#Z#Z/?#Z#Z#Z  #**6#6G2H2H+I+IJJJJ"/"@"@AQSj"k"k!	!  

 %
 
 
 	
r@   c                ^    i }d |D             }d}| D ]}||v r	|dz  }||v 	|||<   |dz  }|S )Nc                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zFArrayContraction._get_free_indices_to_position_map.<locals>.<listcomp>  rm  r@   r   r]   rG   )free_indicesr   rV  ro  rt  inds         r>   !_get_free_indices_to_position_mapz2ArrayContraction._get_free_indices_to_position_map  sp    #% (S(S4G(S(S(S% 	 	C:::1 :::,3$S)qLGG''r@   c                ~   | j         }d |D             }|                                 t          |           }t          |          }||z
  }d t	          |          D             }d}d}t	          |          D ]E}	||k     r(|||         k    r|dz  }|dz  }||k     r|||         k    ||	xx         |z  cc<   |dz  }F|S )a  
        Get the mapping of indices at the positions before the contraction
        occurs.

        Examples
        ========

        >>> from sympy.tensor.array import tensorproduct, tensorcontraction
        >>> from sympy import MatrixSymbol
        >>> M = MatrixSymbol("M", 3, 3)
        >>> N = MatrixSymbol("N", 3, 3)
        >>> cg = tensorcontraction(tensorproduct(M, N), [1, 2])
        >>> cg._get_index_shifts(cg)
        [0, 2]

        Indeed, ``cg`` after the contraction has two dimensions, 0 and 1. They
        need to be shifted by 0 and 2 to get the corresponding positions before
        the contraction (that is, 0 and 3).
        c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z6ArrayContraction._get_index_shifts.<locals>.<listcomp>  s%    EEE11EEaQEEEEr@   c                    g | ]}d S rO  rG   rb   s     r>   rh   z6ArrayContraction._get_index_shifts.<locals>.<listcomp>  r  r@   r   r]   )r   rU  r   r   rk   )
r   inner_contraction_indicesr  r   r  r  r  rt  r  rd   s
             r>   _get_index_shiftsz"ArrayContraction._get_index_shifts  s    * %)$<!EE 9EEE	!$''
^^
*,
//U:..///z"" 	 	AJ&&7i6H+H+H11 J&&7i6H+H+H 1III IIIqLGGr@   c                r    t                               |           t          fd|D                       }|S )Nc              3  N   K   | ]}t          fd |D                       V   dS )c              3  .   K   | ]}|         |z   V  d S r3   rG   r  s     r>   re   zUArrayContraction._convert_outer_indices_to_inner_indices.<locals>.<genexpr>.<genexpr>  s+      /I/I!q	A/I/I/I/I/I/Ir@   Nrm  r  s     r>   re   zKArrayContraction._convert_outer_indices_to_inner_indices.<locals>.<genexpr>  s@      )m)ma%/I/I/I/Iq/I/I/I*I*I)m)m)m)m)m)mr@   )r   r  rz   )r   outer_contraction_indicesr  s     @r>   r  z8ArrayContraction._convert_outer_indices_to_inner_indices  s@    !33D99$))m)m)m)mSl)m)m)m$m$m!((r@   c                b    | j         }t          j        | g|R  }||z   }t          | j        g|R  S r3   )r   r   r  r  r   )r   r  r  r   s       r>   r   zArrayContraction._flatten  sK    $($<!$4$\]a$~d}$~$~$~!7:SS!$)B.ABBBBr@   c                     | j         |g|R  S r3   r	  rQ   r   r   s      r>   rY  z:ArrayContraction._ArrayContraction_denest_ArrayContraction  s    s|D7#67777r@   c                n    d |D             fdt          |j                  D             }t          | S )Nc                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   zGArrayContraction._ArrayContraction_denest_ZeroArray.<locals>.<listcomp>  r^  r@   c                "    g | ]\  }}|v	|S rG   rG   )rc   rd   ra  rr  s      r>   rh   zGArrayContraction._ArrayContraction_denest_ZeroArray.<locals>.<listcomp>  s(    ZZZtq!AY8Y8Y8Y8Y8Yr@   )r   r1   r   )rQ   r   r   r1   rr  s       @r>   rZ  z3ArrayContraction._ArrayContraction_denest_ZeroArray  sF    #N#N/B#N#N#N ZZZZy44ZZZ%  r@   c                8    t          fd|j        D              S )Nc                *    g | ]}t          |gR  S rG   r}  rQ  s     r>   rh   zFArrayContraction._ArrayContraction_denest_ArrayAdd.<locals>.<listcomp>  s+    [[[A.qG3FGGG[[[r@   r  r  s     `r>   r_  z2ArrayContraction._ArrayContraction_denest_ArrayAdd  s'    [[[[QUQZ[[[\\r@   c                    |j         j        }fd|D             fd|D             }|                     |          }t          t	          |j        gR  t          |                    S )Nc                F    g | ]}t          fd |D                       S )c              3  .   K   | ]} |          V  d S r3   rG   )rc   rm   r   s     r>   re   zSArrayContraction._ArrayContraction_denest_PermuteDims.<locals>.<listcomp>.<genexpr>  s+      (C(CAQ(C(C(C(C(C(Cr@   rm  r  s     r>   rh   zIArrayContraction._ArrayContraction_denest_PermuteDims.<locals>.<listcomp>  s6    "a"a"a5(C(C(C(C(C(C(C#C#C"a"a"ar@   c                L    g | ]t          fd D                        S )c              3      K   | ]}|v V  	d S r3   rG   r  s     r>   re   zSArrayContraction._ArrayContraction_denest_PermuteDims.<locals>.<listcomp>.<genexpr>  s'      0Y0YAa0Y0Y0Y0Y0Y0Yr@   r  )rc   rd   r{  s    @r>   rh   zIArrayContraction._ArrayContraction_denest_PermuteDims.<locals>.<listcomp>  s=    ZZZ1S0Y0Y0Y0YAX0Y0Y0Y-Y-YZQZZZr@   )r   r8  rq  r   r  r   r+   )rQ   r   r   r<  	new_plistr{  r   s        @@r>   r[  z5ArrayContraction._ArrayContraction_denest_PermuteDims  s    &&"a"a"a"aM`"a"a"aZZZZZZZ	(()@)LL	tyC+BCCC	""
 
 	
r@   r   'ArrayDiagonal'c                B   t          |j                  }|                    |j        |t          |j                            }d |D             }g }|D ]}|d d          }t          |          D ]=\  }t          fd|D                       r|                               d ||<   >|                    t          t          |                               d |D             }	t                              ||	          }
t          t          |j        g|R  g|
R  S )Nc                &    g | ]}d  |D             S )c                Z    g | ](}t          |t          t          f          r|n|gD ]}|)S rG   )r4   rz   r   )rc   rm   r   s      r>   rh   zVArrayContraction._ArrayContraction_denest_ArrayDiagonal.<locals>.<listcomp>.<listcomp>*  sB    $i$i$i1APUW\~A^A^<gAAefdg$i$iaQ$i$i$i$ir@   rG   rb   s     r>   rh   zKArrayContraction._ArrayContraction_denest_ArrayDiagonal.<locals>.<listcomp>*  s:      $M  $M  $Mno$i$i$i$i$i  $M  $M  $Mr@   c              3      K   | ]}|v V  	d S r3   rG   )rc   rd   diag_indgrps     r>   re   zJArrayContraction._ArrayContraction_denest_ArrayDiagonal.<locals>.<genexpr>1  s(      >>AqK'>>>>>>r@   c                    g | ]}||S r3   rG   rb   s     r>   rh   zKArrayContraction._ArrayContraction_denest_ArrayDiagonal.<locals>.<listcomp>6  s    $R$R$R1AMQMMMr@   )r   r   r  r   r   r   r   r   r%  r9  r  r   rq  r  r  )rQ   r   r   r   down_contraction_indicesr{  contr_indgrpr  rm   new_diagonal_indices_downnew_diagonal_indicesr  s              @r>   r^  z7ArrayContraction._ArrayContraction_denest_ArrayDiagonal%  sv    566#'#:#:4;PRegoptpygzgz#{#{  $M  $M  tL  $M  $M  $M "$4 	= 	=Lqqq/C"+,<"="= / /;&>>>>>>>>> /JJ{+++*.$Q'#**6#c((+;+;<<<<$R$R0@$R$R$R!/@@AXZstttyC+BCCC
!
 
 
 	
r@   c                0  	
 j         |fS t          t          dgj        z                       fdt	          t          j                            D             
d |D             fdt          j                  D             	t          t	          t          j                            	fd          }fd|D             }
fd|D             }t          |          fd	|D             }t          |          }t          | |fS )
Nr   c           
     h    g | ].}t          t          |         |d z                                /S rC  r`  )rc   rd   rD  s     r>   rh   z@ArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>B  s7    YYYaU58U1Q3Z8899YYYr@   c                    h | ]	}|D ]}|
S rG   rG   r   s      r>   r  z?ArrayContraction._sort_fully_contracted_args.<locals>.<setcomp>C  r^  r@   c                    g | ]=\  }}t          fd t          |         |dz                      D                       >S )c              3      K   | ]}|v V  	d S r3   rG   )rc   rm   rr  s     r>   re   zJArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>.<genexpr>D  s)      cc!%= =ccccccr@   r]   )rn   rk   )rc   rd   r   rr  rD  s      r>   rh   z@ArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>D  sk      H  H  HhnhiknCccccuUSTXW\]^_`]`WaGbGbccccc  H  H  Hr@   c                P    |          rdt          j        |                    fndS )Nr   rC  )r   r   )rJ  r   fully_contracteds    r>   rK  z>ArrayContraction._sort_fully_contracted_args.<locals>.<lambda>E  s8    euvwex  ?CqBRSWS\]^S_B`B`>a>a  C r@   rL  c                *    g | ]}j         |         S rG   r>  r5  s     r>   rh   z@ArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>F  s    222QDIaL222r@   c                *    g | ]}|         D ]}|S rG   rG   )rc   rd   rm   rg  s      r>   rh   z@ArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>G  s*     M M Mq\!_ M M M M M Mr@   c                F    g | ]}t          fd |D                       S )c              3  (   K   | ]}|         V  d S r3   rG   )rc   rm   index_permutation_array_forms     r>   re   zJArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>.<genexpr>I  s)      (T(TQ)Ea)H(T(T(T(T(T(Tr@   rm  )rc   rd   r  s     r>   rh   z@ArrayContraction._sort_fully_contracted_args.<locals>.<listcomp>I  s8    "r"r"rYZ5(T(T(T(TRS(T(T(T#T#T"r"r"rr@   )r1   r   r   r   rk   r   r   r   r9  r,   r%   r   )rQ   r   r   new_posr&  new_index_blocks_flatr{  rr  rD  r  rg  r  s    `     @@@@@r>   r\  z,ArrayContraction._sort_fully_contracted_args=  s   :,,,Zdm 34455YYYY5TYCXCXYYY#N#N/B#N#N#N  H  H  H  H  Hr{  }A  }F  sG  sG  H  H  Hs49~~..  5C  5C  5C  5C  5C  D  D  D2222'222 M M M MG M M M'12G'H'H$"r"r"r"r^q"r"r"r";<S"T"T$h/1HHHr@   c                8    | j         fd| j        D             S )a  
        Return tuples containing the argument index and position within the
        argument of the index position.

        Examples
        ========

        >>> from sympy import MatrixSymbol
        >>> from sympy.abc import N
        >>> from sympy.tensor.array import tensorproduct, tensorcontraction
        >>> A = MatrixSymbol("A", N, N)
        >>> B = MatrixSymbol("B", N, N)

        >>> cg = tensorcontraction(tensorproduct(A, B), (1, 2))
        >>> cg._get_contraction_tuples()
        [[(0, 1), (1, 0)]]

        Notes
        =====

        Here the contraction pair `(1, 2)` meaning that the 2nd and 3rd indices
        of the tensor product `A\otimes B` are contracted, has been transformed
        into `(0, 1)` and `(1, 0)`, identifying the same indices in a different
        notation. `(0, 1)` is the second index (1) of the first argument (i.e.
                0 or `A`). `(1, 0)` is the first index (i.e. 0) of the second
        argument (i.e. 1 or `B`).
        c                ,    g | ]}fd |D             S )c                     g | ]
}|         S rG   rG   )rc   rm   mappings     r>   rh   zGArrayContraction._get_contraction_tuples.<locals>.<listcomp>.<listcomp>j  s    ''''''r@   rG   )rc   rd   r  s     r>   rh   z<ArrayContraction._get_contraction_tuples.<locals>.<listcomp>j  s.    JJJA''''Q'''JJJr@   )rT  r   )r<   r  s    @r>   _get_contraction_tuplesz(ArrayContraction._get_contraction_tuplesM  s)    8 -JJJJ1IJJJJr@   c                n    | j         }dgt          t          |                    z   fd|D             S )Nr   c                F    g | ]}t          fd |D                       S )c              3  4   K   | ]\  }}|         |z   V  d S r3   rG   )rc   rm   r   r   s      r>   re   zYArrayContraction._contraction_tuples_to_contraction_indices.<locals>.<listcomp>.<genexpr>q  s2      ::1&q)!+::::::r@   rm  )rc   rd   r   s     r>   rh   zOArrayContraction._contraction_tuples_to_contraction_indices.<locals>.<listcomp>q  s6    WWWq:::::::::WWWr@   )r   r   r   )r   contraction_tuplesr   r   s      @r>   *_contraction_tuples_to_contraction_indicesz;ArrayContraction._contraction_tuples_to_contraction_indicesl  sD     3j&7&7!8!88WWWWDVWWWWr@   c                     | j         d d          S r3   )_free_indicesrX   s    r>   r  zArrayContraction.free_indicess  s    !!!!$$r@   c                *    t          | j                  S r3   )dictrU  rX   s    r>   rV  z)ArrayContraction.free_indices_to_positionw  s    D2333r@   c                    | j         d         S rU   r>  rX   s    r>   r   zArrayContraction.expr{  r?  r@   c                     | j         dd          S r\   r>  rX   s    r>   r   z$ArrayContraction.contraction_indices  r  r@   c                    | j         }t          |t                    st          d          |j        }i }d}t          |          D ]#\  }}t          |          D ]}||f||<   |dz  }$|S )Nz(only for contractions of tensor productsr   r]   )r   r4   r   r#  r   r   rk   )r<   r   r   r  rt  rd   r*  rm   s           r>   "_contraction_indices_to_componentsz3ArrayContraction._contraction_indices_to_components  s    y$ 233 	R%&PQQQ '' 	 	GAt4[[  $%q6 1 r@   c                x  	 | j         }t          |t                    s| S |j        }t	          t          |          d           }t          | \  }fdt          |          D             	|                                 }	fd|D             }t          | }| 	                    ||          }t          |g|R  S )a  
        Sort arguments in the tensor product so that their order is lexicographical.

        Examples
        ========

        >>> from sympy.tensor.array.expressions.from_matrix_to_array import convert_matrix_to_array
        >>> from sympy import MatrixSymbol
        >>> from sympy.abc import N
        >>> A = MatrixSymbol("A", N, N)
        >>> B = MatrixSymbol("B", N, N)
        >>> C = MatrixSymbol("C", N, N)
        >>> D = MatrixSymbol("D", N, N)

        >>> cg = convert_matrix_to_array(C*D*A*B)
        >>> cg
        ArrayContraction(ArrayTensorProduct(A, D, C, B), (0, 3), (1, 6), (2, 5))
        >>> cg.sort_args_by_name()
        ArrayContraction(ArrayTensorProduct(A, D, B, C), (0, 3), (1, 4), (2, 7))
        c                ,    t          | d                   S r\   r   rI  s    r>   rK  z4ArrayContraction.sort_args_by_name.<locals>.<lambda>  s    <LQqT<R<R r@   rL  c                B    i | ]\  }}|                     |          S rG   r  )rc   rd   r   
pos_sorteds      r>   r   z6ArrayContraction.sort_args_by_name.<locals>.<dictcomp>  s-    OOOVQ!Z--a00OOOr@   c                ,    g | ]}fd |D             S )c                *    g | ]\  }}|         |fS rG   rG   )rc   rm   r   reordering_maps      r>   rh   zAArrayContraction.sort_args_by_name.<locals>.<listcomp>.<listcomp>  s'    DDD$!Qq 115DDDr@   rG   )rc   rd   r  s     r>   rh   z6ArrayContraction.sort_args_by_name.<locals>.<listcomp>  s.    aaaDDDD!DDDaaar@   )r   r4   r   r   r9  r   r   r  r   r  r  )
r<   r   r   sorted_datarX  r  c_tpr  r  r  s
           @@r>   sort_args_by_namez"ArrayContraction.sort_args_by_name  s    * y$ 233 	KyYt__2R2RSSS"%{"3
KOOOOyOOO!99;;aaaaN`aaa$k2 KK"
 
 "$;):;;;;r@   c                >    t          | g| j        g| j        R  \  }}|S )ao  
        Returns a dictionary of links between arguments in the tensor product
        being contracted.

        See the example for an explanation of the values.

        Examples
        ========

        >>> from sympy import MatrixSymbol
        >>> from sympy.abc import N
        >>> from sympy.tensor.array.expressions.from_matrix_to_array import convert_matrix_to_array
        >>> A = MatrixSymbol("A", N, N)
        >>> B = MatrixSymbol("B", N, N)
        >>> C = MatrixSymbol("C", N, N)
        >>> D = MatrixSymbol("D", N, N)

        Matrix multiplications are pairwise contractions between neighboring
        matrices:

        `A_{ij} B_{jk} C_{kl} D_{lm}`

        >>> cg = convert_matrix_to_array(A*B*C*D)
        >>> cg
        ArrayContraction(ArrayTensorProduct(B, C, A, D), (0, 5), (1, 2), (3, 6))

        >>> cg._get_contraction_links()
        {0: {0: (2, 1), 1: (1, 0)}, 1: {0: (0, 1), 1: (3, 0)}, 2: {1: (0, 0)}, 3: {0: (1, 1)}}

        This dictionary is interpreted as follows: argument in position 0 (i.e.
        matrix `A`) has its second index (i.e. 1) contracted to `(1, 0)`, that
        is argument in position 1 (matrix `B`) on the first index slot of `B`,
        this is the contraction provided by the index `j` from `A`.

        The argument in position 1 (that is, matrix `B`) has two contractions,
        the ones provided by the indices `j` and `k`, respectively the first
        and second indices (0 and 1 in the sub-dict).  The link `(0, 1)` and
        `(2, 0)` respectively. `(0, 1)` is the index slot 1 (the 2nd) of
        argument in position 0 (that is, `A_{\ldot j}`), and so on.
        )r(   r   r   )r<   r   dlinkss      r>   r(   z'ArrayContraction._get_contraction_links  s,    R .tfdm_dF^___fr@   c                |    | j         }t          |d          r|                                }t          |g| j        R  S r  )r   r   rt   r   r   r  s     r>   rt   zArrayContraction.as_explicit  sE    y4'' 	&##%%D A(@AAAAr@   N)r   r  )%rC   rD   rE   ru   rP   r   re  rh  r9  r  r   r  rq  r]  r  r  r  r  r  r   rY  rZ  r_  r[  r^  r\  r  r  rw   r  rV  r   r   r  r  r(   rt   rG   r@   r>   r   r     s        
  ,!I !I !IFn n nn n n P P \P H H [H H H [H 2 2 [2<b- b- b-H
 
 
. 	( 	( \	( $ $ \$L ) ) \)
 C C \C 8 8 [8 ! ! [!
 ] ] [] 	
 	
 [	
 
 
 
 [
. I I [IK K K> X X \X % % X% 4 4 X4   X   X  #< #< #<J* * *XB B B B Br@   r   c                  P    e Zd ZdZd Zed             Zed             Zd Zd Z	dS )Reshapea  
    Reshape the dimensions of an array expression.

    Examples
    ========

    >>> from sympy.tensor.array.expressions import ArraySymbol, Reshape
    >>> A = ArraySymbol("A", (6,))
    >>> A.shape
    (6,)
    >>> Reshape(A, (3, 2)).shape
    (3, 2)

    Check the component-explicit forms:

    >>> A.as_explicit()
    [A[0], A[1], A[2], A[3], A[4], A[5]]
    >>> Reshape(A, (3, 2)).as_explicit()
    [[A[0], A[1]], [A[2], A[3]], [A[4], A[5]]]

    c                Z   t          |          }t          |t                    s	t          | }t          t	          j        |j                  t	          j        |                    dk    rt          d          t          j	        | ||          }t          |          |_        ||_        |S )NFzshape mismatch)r.   r4   r   r	   r   r   r1   ro   r   rP   rz   r   _expr)rQ   r   r1   rS   s       r>   rP   zReshape.__new__  s    ~~%'' 	"5MECL,,cl5.A.ABBeKK-...l3e,,5\\
	
r@   c                    | j         S r3   r   rX   s    r>   r1   zReshape.shape
  r   r@   c                    | j         S r3   )r  rX   s    r>   r   zReshape.expr  r   r@   c                    |                     dd          r | j        j        |i |}n| j        }t          |t          t
          f          r |j        | j         S t          || j                  S )Nr   T)	r   r   r   r4   r   r    rr   r1   r  )r<   r   r   r   s       r>   r   zReshape.doit  ss    ::fd## 	!49>42622DD9DdZ344 	-4<,,tTZ(((r@   c                    | j         }t          |d          r|                                }t          |t                    rddlm}  ||          }nt          |t                    r| S  |j        | j	         S )Nrt   r   )Array)
r   r   rt   r4   r   sympyr  r   rr   r1   )r<   eer  s      r>   rt   zReshape.as_explicit  s    Y2}%% 	"!!Bb*%% 	######rBBJ'' 	Krz4:&&r@   N)
rC   rD   rE   ru   rP   rw   r1   r   r   rt   rG   r@   r>   r  r    s         ,	 	 	   X   X) ) )	' 	' 	' 	' 	'r@   r  c                  2    e Zd ZU dZded<   dd	dZd ZeZdS )
r  al  
    The ``_ArgE`` object contains references to the array expression
    (``.element``) and a list containing the information about index
    contractions (``.indices``).

    Index contractions are numbered and contracted indices show the number of
    the contraction. Uncontracted indices have ``None`` value.

    For example:
    ``_ArgE(M, [None, 3])``
    This object means that expression ``M`` is part of an array contraction
    and has two indices, the first is not contracted (value ``None``),
    the second index is contracted to the 4th (i.e. number ``3``) group of the
    array contraction object.
    zlist[int | None]r{   Nlist[int | None] | Nonec                    || _         |-d t          t          |                    D             | _        d S || _        d S )Nc                    g | ]}d S r3   rG   rb   s     r>   rh   z"_ArgE.__init__.<locals>.<listcomp><  s    CCCQDCCCr@   )r@  rk   r   r{   )r<   r@  r{   s      r>   __init__z_ArgE.__init__9  sB    ?CC%0A0A*B*BCCCDLLL"DLLLr@   c                (    d| j         d| j        dS )Nz_ArgE(z, ))r@  r{   rX   s    r>   __str__z_ArgE.__str__@  s     "&,,,==r@   r3   )r{   r
  )rC   rD   rE   ru   rF   r  r  __repr__rG   r@   r>   r  r  '  sW           # # # # #> > > HHHr@   r  c                  *    e Zd ZdZd	dZd ZeZd ZdS )
_IndPosz
    Index position, requiring two integers in the constructor:

    - arg: the position of the argument in the tensor product,
    - rel: the relative position of the index inside the argument.
    r   r  relc                "    || _         || _        d S r3   r   r  )r<   r   r  s      r>   r  z_IndPos.__init__M  s    r@   c                $    d| j         | j        fz  S )Nz_IndPos(%i, %i)r  rX   s    r>   r  z_IndPos.__str__Q  s     DHdh#777r@   c              #  2   K   | j         | j        gE d {V  d S r3   r  rX   s    r>   __iter__z_IndPos.__iter__V  s-      Hdh''''''''''r@   N)r   r  r  r  )rC   rD   rE   ru   r  r  r  r  rG   r@   r>   r  r  F  sW            8 8 8 H( ( ( ( (r@   r  c                      e Zd ZdZd"dZd#dZd	 Zd
 Zd Zd Z	d$dZ
d%dZd&dZd'dZd(dZed             Zd Zd)dZd*dZd*d Zd!S )+r  a  
    Utility class to help manipulate array contraction objects.

    This class takes as input an ``ArrayContraction`` object and turns it into
    an editable object.

    The field ``args_with_ind`` of this class is a list of ``_ArgE`` objects
    which can be used to easily edit the contraction structure of the
    expression.

    Once editing is finished, the ``ArrayContraction`` object may be recreated
    by calling the ``.to_array_contraction()`` method.
    
base_arrayAtyping.Union[ArrayContraction, ArrayDiagonal, ArrayTensorProduct]c                &   t          |t                    r%t          |j                  }|j        }|j        }d}nt          |t                    rt          |j        t                    r\t          |j        j                  }|j        j        }t                              |j        j        |j                  }|j        j        }njt          |j        t                    ri }|j        }|j        }g }n=i }|j        }|j        }g }n*t          |t                    r|}g }d}nt                      t          |t                    rt          |j                  }n|g}d |D             }t          |          D ]%\  }}	|	D ]}
||
         \  }}|||         j        |<   &|| _        t!          |          | _        d | _        t          |j                  }t          |          D ]-\  }}|D ]%}
||
         \  }}d|z
  | j        |         j        |<   &.d S )NrG   c                ,    g | ]}t          |          S rG   )r  r   s     r>   rh   z2_EditArrayContraction.__init__.<locals>.<listcomp>  s    %A%A%ASeCjj%A%A%Ar@   r   )r4   r   r&   r   r   r   r   r  r   r   r#  r   r   r   r{   r  r   number_of_contraction_indices_track_permutation)r<   r  r  r   r   diagonalizedr   r  rd   contraction_tuplerm   arg_posrel_posra  s                 r>   r  z_EditArrayContraction.__init__i  sg   
 j"233 	(01DEEG?D","@LL
M22 	(*/+;<< )4Z_5MNN!+/BB:?Cfhr  iD   E   E&0o&I##JO-?@@ 	)!):&(##!):&(##
$677 	(D"$LL%'''d.// 		??DD6D%A%AD%A%A%A$-.A$B$B 	< 	< A & < <#*1: :;g&.w77< +8256I2J2J*:>,Z-@AA l++ 	F 	FDAq F F#*1: ?AAv"7+3G<<F	F 	Fr@   r   r  new_argc                v    | j                             |          }| j                             |dz   |           d S r\   )r  r  insert)r<   r   r%  poss       r>   r  z"_EditArrayContraction.insert_after  s;     &&s++!!#'733333r@   c                6    | xj         dz  c_         | j         dz
  S r\   )r  rX   s    r>   r  z/_EditArrayContraction.get_new_contraction_index  s$    **a/**1A55r@   c                "   i | j         D ]&}                    d |j        D                        't          t	                              D ]
\  }}||<   t                    | _        | j         D ]}fd|j        D             |_        d S )Nc                    i | ]}||dS )Nr   rG   rb   s     r>   r   z9_EditArrayContraction.refresh_indices.<locals>.<dictcomp>  s    QQQa1=Ar===r@   c                <    g | ]}                     |d           S r3   )r   )rc   rd   updatess     r>   rh   z9_EditArrayContraction.refresh_indices.<locals>.<listcomp>  s'    #W#W#WQGKK4$8$8#W#W#Wr@   )r  r  r{   r   r9  r   r  )r<   arg_with_indrd   ra  r-  s       @r>   refresh_indicesz%_EditArrayContraction.refresh_indices  s     . 	S 	SLNNQQ<+?QQQRRRRfWoo.. 	 	DAqGAJJ-0\\* . 	X 	XL#W#W#W#W,BV#W#W#WL  	X 	Xr@   c                   g }| j         D ]/}t          |j                  dk    r|                    |           0|D ]}| j                             |           t          j        d |D                       }t          | j                   dk    r)| j                             t          |                     d S ddlm	}  ||| j         d         j
                  | j         d         _
        d S )Nr   c                    g | ]	}|j         
S rG   r@  rb   s     r>   rh   z7_EditArrayContraction.merge_scalars.<locals>.<listcomp>  s    :::Qqy:::r@   )_a2m_tensor_product)r  r   r{   r%  remover   r   r  3sympy.tensor.array.expressions.from_array_to_matrixr3  r@  )r<   scalarsr.  rd   scalarr3  s         r>   merge_scalarsz#_EditArrayContraction.merge_scalars  s    . 	- 	-L<'((A--|,,, 	) 	)A%%a((((::':::;;t!""a''%%eFmm44444______,?,?HZ[\H]He,f,fDq!)))r@   c                   d}t          t                    }t                      }| j        D ])}|                    t          |j                             *|d          }g }g }t                      }d}	| j        D ]
}d}
|j        D ]}| |                    |	           |
dz  }
|	dz  }	$|dk    r+|d|z
                               ||
z              ||         dk    r5||vr1|                    |dz
  |z
             |                    |           n4||vr0|                    |dz
  |z
             |                    |           |
dz  }
d |j        D             |_        |t          d |j        D                       z  }||z   }t          |          }d |                                D             }|                                  |                                  d | j        D             }|                                 }t          t!          | g|R  }t#          |g|R  }| j        .t          d | j        D                       }t'          ||          }t'          ||          }|S )	Nr   r]   r   c                &    g | ]}||dk    r|nd S rU   rG   rb   s     r>   rh   z>_EditArrayContraction.to_array_contraction.<locals>.<listcomp>  s)    #j#j#jPQ166AAt#j#j#jr@   c                "    g | ]}||dk     
|S rU   rG   rb   s     r>   rh   z>_EditArrayContraction.to_array_contraction.<locals>.<listcomp>  s"    RRR!qyAPQEEAEEEr@   c                R    g | ]$}t          |          d k    t          |          %S rC  )r   rz   )rc   r  s     r>   rh   z>_EditArrayContraction.to_array_contraction.<locals>.<listcomp>  s+     W W WaCPQFFUVJJqJJJr@   c                    g | ]	}|j         
S rG   r2  r   s     r>   rh   z>_EditArrayContraction.to_array_contraction.<locals>.<listcomp>  s    ::::::r@   c                    g | ]	}|D ]}|
S rG   rG   r   s      r>   rh   z>_EditArrayContraction.to_array_contraction.<locals>.<listcomp>  s&    &U&U&UQST&U&Uaq&U&U&U&Ur@   )r   r   r   r  r  r{   r  r%  r   r   r,   valuesr8  r/  get_contraction_indicesr  r   r  r   r   )r<   rt  diag_indicescount_index_freqr.  free_index_count	inv_perm1	inv_perm2donecounter4counter2rd   r  r   diag_indices_filteredr   r   r   expr2permutation2expr3s                        r>   r  z*_EditArrayContraction.to_array_contraction  s    "4(("99 . 	C 	CL##GL,@$A$ABBBB+D1 		uu  . 	T 	TL H!)  9$$X...MHMH66R!V$++Gh,>???#A&!++$$%5%9A%=>>>HHQKKKKd]]$$%5%9A%=>>>HHQKKKA#j#jUaUi#j#j#jL sRR|';RRRSSSGG')3 !455 !X W<3F3F3H3H W W W::t'9:::"::<<!"7">UATUUU='<===".%&U&U$2I&U&U&UVVL!%66Ee[11r@   rK   list[list[int]]c                    d t          | j                  D             }d}| j        D ].}|j        D ]$}|||                             |           |dz  }%/|S )Nc                    g | ]}g S rG   rG   rb   s     r>   rh   zA_EditArrayContraction.get_contraction_indices.<locals>.<listcomp>  s    /f/f/fq/f/f/fr@   r   r]   )rk   r  r  r{   r%  )r<   r   current_positionr.  rm   s        r>   r@  z-_EditArrayContraction.get_contraction_indices  s    /f/fE$Bd<e<e/f/f/f ! . 	& 	&L!) & &='*112BCCC A%  & #"r@   list[_IndPos]c                    || j         k    rt          d          g }t          | j                  D ]H\  }}t          |j                  D ].\  }}||k    r#|                    t          ||                     /I|S )Nz%index value exceeding the index range)r  ro   r   r  r{   r%  r  )r<   r  r  rd   r.  rm   r  s          r>   r  z+_EditArrayContraction.get_mapping_for_index  s    $444DEEE#%	();<< 	4 	4OA|'(<== 4 4
7'>>$$WQ]]3334 r@   list[list[_IndPos]]c                    d t          | j                  D             }t          | j                  D ]J\  }}t          |j                  D ]0\  }}|)||                             t          ||                     1K|S )Nc                    g | ]}g S rG   rG   rb   s     r>   rh   zP_EditArrayContraction.get_contraction_indices_to_ind_rel_pos.<locals>.<listcomp>  s    3j3j3j1B3j3j3jr@   )rk   r  r   r  r{   r%  r  )r<   r   rd   r.  rm   r  s         r>   &get_contraction_indices_to_ind_rel_posz<_EditArrayContraction.get_contraction_indices_to_ind_rel_pos  s    3j3jdFh@i@i3j3j3j();<< 	C 	COA|#L$899 C C3?',33GAqMMBBBC #"r@   r  r  c                :    d}| j         D ]}||j        v r|dz  }|S )zJ
        Count the number of arguments that have the given index.
        r   r]   )r  r{   )r<   r  rt  r.  s       r>   count_args_with_indexz+_EditArrayContraction.count_args_with_index!  s8      . 	 	L,,,1r@   list[_ArgE]c                .    fd| j         D             }|S )zA
        Get a list of arguments having the given index.
        c                &    g | ]}|j         v |S rG   )r{   )rc   rd   r  s     r>   rh   z=_EditArrayContraction.get_args_with_index.<locals>.<listcomp>/  s%    PPP!Uai=O=OA=O=O=Or@   )r  )r<   r  r  s    ` r>   get_args_with_indexz)_EditArrayContraction.get_args_with_index+  s'     QPPPt'9PPP
r@   c                    t                      }| j        D ]&}|                    d |j        D                        't	          |          S )Nc                "    h | ]}||dk     
|S rU   rG   rb   s     r>   r  zC_EditArrayContraction.number_of_diagonal_indices.<locals>.<setcomp>6  s!    KKKq1=QUUUUUr@   )r  r  r  r{   r   )r<   rs   r   s      r>   number_of_diagonal_indicesz0_EditArrayContraction.number_of_diagonal_indices2  sQ    uu% 	M 	MCKKKKCKKKKLLLL4yyr@   c                T   g }g }d}d}| j         D ]`}g }|j        D ]?}|!|dk     r|                    |           |dz  }%|                    |           |dz  }@|                    |           a|rt          d |D                       ndfd|D             }||gz   | _        d S )Nr   r   r]   c              3  <   K   | ]}|rt          |          nd V  dS )r   Nr  rb   s     r>   re   z@_EditArrayContraction.track_permutation_start.<locals>.<genexpr>I  s1      ??a)c!fffr??????r@   c                    g | ]}|z
  S rG   rG   )rc   rd   max_inds     r>   rh   zA_EditArrayContraction.track_permutation_start.<locals>.<listcomp>J  s    444QWq[444r@   )r  r{   r%  r  r   )	r<   r   	perm_diagrt  rH  r.  permrd   rc  s	           @r>   track_permutation_startz-_EditArrayContraction.track_permutation_start9  s    	 . 
	% 
	%LD!)  =1uu!((222 AG$$$1t$$$$CNV#??;??????TV4444)444	"-";r@   destinationfrom_elementc                    | j                             |          }| j                             |          }| j        |                             | j        |                    | j                            |           d S r3   )r  r  r   r   r   )r<   rg  rh  index_destinationindex_elements        r>   track_permutation_mergez-_EditArrayContraction.track_permutation_mergeM  sr     .44[AA*00>> 1299$:QR_:`aaa##M22222r@   typing.Tuple[int, int]c                    d}| j         D ]4}t          d |j        D                       }||k    r	|||z   fc S ||z  }5t          d          )zw
        Return the range of the free indices of the arg as absolute positions
        among all free indices.
        r   c                    g | ]}||S r3   rG   rb   s     r>   rh   zA_EditArrayContraction.get_absolute_free_range.<locals>.<listcomp>Z  s    &T&T&TQ!)q)))r@   argument not foundr  r   r{   r   )r<   r   rt  r.  number_free_indicess        r>   get_absolute_free_rangez-_EditArrayContraction.get_absolute_free_rangeS  sy    
  . 	+ 	+L"%&T&T,2F&T&T&T"U"Us""*= =====**GG-...r@   c                    d}| j         D ]*}t          |j                  }||k    r	|||z   fc S ||z  }+t          d          )zc
        Return the absolute range of indices for arg, disregarding dummy
        indices.
        r   rp  rq  )r<   r   rt  r.  number_indicess        r>   r  z(_EditArrayContraction.get_absolute_range`  sg    
  . 	& 	&L !566Ns"". 88888~%GG-...r@   N)r  r  )r   r  r%  r  )rK   rM  )rK   rQ  )rK   rS  )r  r  rK   r  )r  r  rK   rY  )rg  r  rh  r  )r   r  rK   rm  )rC   rD   rE   ru   r  r  r  r/  r8  r  r@  r  rV  rX  r\  rw   r_  rf  rl  rs  r  rG   r@   r>   r  r  Z  s[        7F 7F 7F 7Fr4 4 4 46 6 6X X Xg g gA A AF# # # #   # # # #         X< < <(3 3 3 3/ / / // / / / / /r@   r  c                   t          | t          t          f          rdS t          | t                    rt	          | j                  S t          | t                    r|                                 S t          | t                    r| j        S t          | t                    r| j        }|dS t	          |          S t          | d          rt	          | j                  S dS )Nr  r   r1   r   )r4   r   r#   r   r   r1   r    r*  r!   r"   r   rD  s     r>   r   r   n  s    $]344 q$-.. 4:$	"" yy{{$   y$$$ 
=2u::tW 4:1r@   c                r    t          | t                    r|                                 S t          |           S r3   )r4   r   r   r   r   s    r>   r   r     s/    $-.. ||~~D>>r@   c                Z    t          | t                    r| j        S t          |           gS r3   )r4   r   r   r   rx  s    r>   r  r    s,    $-..  }r@   c                4    t          | d          r| j        S dS )Nr1   rG   )r   r1   rx  s    r>   r   r     s!    tW z2r@   c                X    t          | t                    r|                                 S | S r3   )r4   r   r  rx  s    r>   r  r    s+    $$$ $$&&&r@   c                     t          | ddi|S Nr   T)r   r   r   s     r>   r   r     s    tA$A&AAAr@   c                &    t          | g|R ddi|S r}  )r   )r   r   r   s      r>   r  r    s&    DT#6TTTTTVTTTr@   c                &    t          | g|R ddi|S r}  )r   )r   r   r   s      r>   r  r    s&    N 0NNNtNvNNNr@   c                "    t          | |fddi|S r}  r  )r   r   r   s      r>   r   r     s    t[FFtFvFFFr@   c                     t          | ddi|S r}  )r  r~  s     r>   r  r    s    T77777r@   c                "    t          | |          S r3   )r8   )r   r{   s     r>   rB   rB     s    g&&&r@   )a
__future__r   collections.abcr5   r   r   r   	functoolsr   rp   r   typingsympy.core.numbersr   sympy.core.relationalr	   (sympy.functions.special.tensor_functionsr   sympy.core.basicr   sympy.core.containersr   sympy.core.exprr   sympy.core.functionr   r   sympy.core.mulr   sympy.core.singletonr   sympy.core.sortingr   sympy.core.symbolr   r   sympy.matrices.matrixbaser   #sympy.matrices.expressions.diagonalr   "sympy.matrices.expressions.matexprr   "sympy.matrices.expressions.specialr   sympy.tensor.array.arrayopr   r   r   r   #sympy.tensor.array.dense_ndim_arrayr   sympy.tensor.array.ndim_arrayr    sympy.tensor.indexedr!   r"   r#   $sympy.tensor.array.expressions.utilsr$   r%   r&   r'   r(   r)   r,  r+    sympy.combinatorics.permutationsr,   sympy.core.sympifyr.   r0   rI   r8   r   r   r   r   r  r   r   r;  r   r  r  r  r  r   r   r  r   r  r   r  r  r   r  rB   rG   r@   r>   <module>r     sG   " " " " " "      , , , , , , , ,                        & & & & & & * * * * * * C C C C C C " " " " " " ' ' ' ' ' '             2 2 2 2 2 2 2 2       " " " " " " / / / / / / - - - - - - - - 0 0 0 0 0 0 B B B B B B 9 9 9 9 9 9 9 9 9 9 9 9 f f f f f f f f f f f f G G G G G G 3 3 3 3 3 3 7 7 7 7 7 7 7 7 < < < < < <1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 , + + + + + 7 7 7 7 7 7 ' ' ' ' ' '
7 
7 
7 
7 
7 
7 
7 
7B B B B B* B B B<2[ 2[ 2[ 2[ 2[4 2[ 2[ 2[j    
   2    z   2-( -( -( -( -(E -( -( -(^Wp Wp Wp Wp Wp. Wp Wp Wpt8^ 8^ 8^ 8^ 8^$ 8^ 8^ 8^vT T T T T' T T Tn
M< M< M< M< M<) M< M< M<`&- &- &- &- &- 5 &- &- &-RXB XB XB XB XB, XB XB XBv<' <' <' <' <'# <' <' <'~       >( ( ( ( ( ( ( ((Q/ Q/ Q/ Q/ Q/ Q/ Q/ Q/h  (           B B BU U UO O OG G G8 8 8' ' ' ' 'r@   