o
    *ήcj                     @   s  d dl mZ d dlmZ d dlmZmZmZm	Z	m
Z
 d dlmZ d dlmZ d dlmZmZ d dlmZ d dlmZmZmZmZ d d	lmZmZ d d
lmZ d dlmZ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+ d3ddZ,G dd deZ-e)e-edd Z.e)e-e-dd Z.dd Z/e/e	ge/e
gdej0e-< d4ddZ1dd  Z2G d!d" d"eZ3G d#d$ d$e-Z4d%d& Z5G d'd( d(Z6d)d* Z7d+d,l8m9Z9 d+d-l:m;Z; d+d.l<m=Z= d+d/l>m?Z? d+d0l@mAZA d+d1lBmCZCmDZD d+d2lEmFZF dS )5    )Tuplewraps)SIntegerBasicMulAdd)check_assumptions)call_highest_priority)ExprExprBuilder)	FuzzyBool)StrDummysymbolsSymbol)SympifyError_sympify)
SYMPY_INTS)	conjugateadjoint)KroneckerDelta)NonSquareMatrixError)
MatrixKind
MatrixBase)dispatch)
filldedentNc                    s    fdd}|S )Nc                    s   t   fdd}|S )Nc                    s,   z
t |} | |W S  ty    Y S w N)r   r   )ab)funcretval I/tmp/pip-target-vg8gfxp4/lib/python/sympy/matrices/expressions/matexpr.py__sympifyit_wrapper   s   z5_sympifyit.<locals>.deco.<locals>.__sympifyit_wrapperr   )r!   r%   r"   )r!   r$   deco   s   z_sympifyit.<locals>.decor#   )argr"   r'   r#   r&   r$   
_sympifyit   s   r)   c                       s.  e Zd ZU dZdZdZdZdZdZdZ	dZ
dZdZdZdZdZdZdZdZe Zeed< dd	 Zed
eeef fddZedd Zedd Zdd Zdd Zede e!ddd Z"ede e!ddd Z#ede e!ddd Z$ede e!dd d! Z%ede e!d"d#d$ Z&ede e!d"d%d& Z'ede e!d'd(d) Z(ede e!d'd*d+ Z)ede e!d,d-d. Z*ede e!d/d0d1 Z+ede e!d2d3d4 Z,ede e!d5d6d7 Z-ed8d9 Z.ed:d; Z/ed<d= Z0d>d? Z1dd@dAZ2dBdC Z3dDdE Z4dFdG Z5dHdI Z6dJdK Z7dLdM Z8dNdO Z9dPdQ Z: fdRdSZ;e<dTdU Z=dVdW Z>dXdY Z?ddZd[Z@d\d] ZAd^d_ ZBed`da ZCdbdc ZDddde ZEdfdg ZFedhdi ZGdjdk ZHdldm ZId
eJfdndoZKdpdq ZLdrds ZMdtdu ZNdvdw ZOdxdy ZPdzd{ ZQeRdd|d}ZSd~d ZT  ZUS )
MatrixExpra  Superclass for Matrix Expressions

    MatrixExprs represent abstract matrices, linear transformations represented
    within a particular basis.

    Examples
    ========

    >>> from sympy import MatrixSymbol
    >>> A = MatrixSymbol('A', 3, 3)
    >>> y = MatrixSymbol('y', 3, 1)
    >>> x = (A.T*A).I * A * y

    See Also
    ========

    MatrixSymbol, MatAdd, MatMul, Transpose, Inverse
    r#   Fg      &@TNkindc                 O   s"   t t|}tj| g|R i |S r   )mapr   r   __new__)clsargskwargsr#   r#   r$   r-   P   s   
zMatrixExpr.__new__returnc                 C      t r   NotImplementedErrorselfr#   r#   r$   shapeV      zMatrixExpr.shapec                 C      t S r   MatAddr5   r#   r#   r$   _add_handlerZ   r8   zMatrixExpr._add_handlerc                 C   r9   r   MatMulr5   r#   r#   r$   _mul_handler^   r8   zMatrixExpr._mul_handlerc                 C   s   t tj|  S r   )r>   r   NegativeOnedoitr5   r#   r#   r$   __neg__b      zMatrixExpr.__neg__c                 C   r2   r   r3   r5   r#   r#   r$   __abs__e      zMatrixExpr.__abs__other__radd__c                 C      t | | S r   r;   rA   r6   rF   r#   r#   r$   __add__h      zMatrixExpr.__add__rK   c                 C      t ||  S r   rI   rJ   r#   r#   r$   rG   m   rL   zMatrixExpr.__radd____rsub__c                 C   s   t | |  S r   rI   rJ   r#   r#   r$   __sub__r      zMatrixExpr.__sub__rO   c                 C   s   t ||   S r   rI   rJ   r#   r#   r$   rN   w   rP   zMatrixExpr.__rsub____rmul__c                 C   rH   r   r>   rA   rJ   r#   r#   r$   __mul__|   rL   zMatrixExpr.__mul__c                 C   rH   r   rR   rJ   r#   r#   r$   
__matmul__   rL   zMatrixExpr.__matmul__rS   c                 C   rM   r   rR   rJ   r#   r#   r$   rQ      rL   zMatrixExpr.__rmul__c                 C   rM   r   rR   rJ   r#   r#   r$   __rmatmul__   rL   zMatrixExpr.__rmatmul____rpow__c                 C   rH   r   )MatPowrA   rJ   r#   r#   r$   __pow__   rL   zMatrixExpr.__pow__rX   c                 C   s   t d)NzMatrix Power not definedr3   rJ   r#   r#   r$   rV         zMatrixExpr.__rpow____rtruediv__c                 C   s   | |t j  S r   )r   r@   rJ   r#   r#   r$   __truediv__   rL   zMatrixExpr.__truediv__r[   c                 C   s   t  r   r3   rJ   r#   r#   r$   rZ      s   zMatrixExpr.__rtruediv__c                 C   
   | j d S Nr   r7   r5   r#   r#   r$   rows      
zMatrixExpr.rowsc                 C   r\   N   r^   r5   r#   r#   r$   cols   r`   zMatrixExpr.colsc                 C   s   | j | jkS r   r_   rc   r5   r#   r#   r$   	is_square      zMatrixExpr.is_squarec                 C   s   ddl m} |t| S Nr   )Adjoint)"sympy.matrices.expressions.adjointrh   	Transposer6   rh   r#   r#   r$   _eval_conjugate   s   zMatrixExpr._eval_conjugatec                 K      |   S r   )_eval_as_real_imag)r6   deephintsr#   r#   r$   as_real_imag      zMatrixExpr.as_real_imagc                 C   s0   t j| |    }| |   dt j  }||fS N   )r   Halfrl   ImaginaryUnit)r6   realimr#   r#   r$   rn      s   zMatrixExpr._eval_as_real_imagc                 C      t | S r   Inverser5   r#   r#   r$   _eval_inverse   rr   zMatrixExpr._eval_inversec                 C   ry   r   Determinantr5   r#   r#   r$   _eval_determinant   rr   zMatrixExpr._eval_determinantc                 C   ry   r   rj   r5   r#   r#   r$   _eval_transpose   rr   zMatrixExpr._eval_transposec                 C   s
   t | |S )z
        Override this in sub-classes to implement simplification of powers.  The cases where the exponent
        is -1, 0, 1 are already covered in MatPow.doit(), so implementations can exclude these cases.
        rW   )r6   expr#   r#   r$   _eval_power   s   
zMatrixExpr._eval_powerc                    s2   | j r| S ddlm | j fdd| jD  S )Nr   )simplifyc                    s   g | ]
}|fi  qS r#   r#   ).0xr0   r   r#   r$   
<listcomp>       z-MatrixExpr._eval_simplify.<locals>.<listcomp>)is_Atomsympy.simplifyr   r!   r/   r6   r0   r#   r   r$   _eval_simplify   s   zMatrixExpr._eval_simplifyc                 C      ddl m} || S rg   )ri   rh   rk   r#   r#   r$   _eval_adjoint      zMatrixExpr._eval_adjointc                 C   s   t | ||S r   )r   _eval_derivative_n_times)r6   r   nr#   r#   r$   r         z#MatrixExpr._eval_derivative_n_timesc                    s    |  |rt |S t| j S r   )hassuper_eval_derivative
ZeroMatrixr7   r6   r   	__class__r#   r$   r      s   

zMatrixExpr._eval_derivativec                 C   s(   t |ddd}|du rtd|dS )z2Helper function to check invalid matrix dimensionsT)integernonnegativeFz?The dimension specification {} should be a nonnegative integer.N)r
   
ValueErrorformat)r.   dimokr#   r#   r$   
_check_dim   s   zMatrixExpr._check_dimc                 K   s   t d| jj )NzIndexing not implemented for %s)r4   r   __name__r6   ijr0   r#   r#   r$   _entry   s   
zMatrixExpr._entryc                 C   ry   r   )r   r5   r#   r#   r$   r      rr   zMatrixExpr.adjointc                 C   s
   t j| fS )z2Efficiently extract the coefficient of a product. )r   One)r6   rationalr#   r#   r$   as_coeff_Mul   r`   zMatrixExpr.as_coeff_Mulc                 C   ry   r   )r   r5   r#   r#   r$   r      rr   zMatrixExpr.conjugatec                 C   r   )Nr   	transpose)$sympy.matrices.expressions.transposer   )r6   r   r#   r#   r$   r      r   zMatrixExpr.transposec                 C   rm   )zMatrix transpositionr   r5   r#   r#   r$   T   rY   zMatrixExpr.Tc                 C   s   | j std|  S )NzInverse of non-square matrix)re   r   r|   r5   r#   r#   r$   inverse  s   zMatrixExpr.inversec                 C   rm   r   r   r5   r#   r#   r$   inv	  rr   zMatrixExpr.invc                 C   r   )Nr   )det)&sympy.matrices.expressions.determinantr   )r6   r   r#   r#   r$   r     r   zMatrixExpr.detc                 C   rm   r   r   r5   r#   r#   r$   I  s   zMatrixExpr.Ic                 C   s^   dd }||o.||o.| j d u p|| j  kdko|| j k dko.|| j kdko.|| jk dkS )Nc                 S   s   t | ttttfS r   )
isinstanceintr   r   r   )idxr#   r#   r$   is_valid     z(MatrixExpr.valid_index.<locals>.is_validFrd   )r6   r   r   r   r#   r#   r$   valid_index  s   
zMatrixExpr.valid_indexc                 C   sH  t |tst |trddlm} || |dS t |trZt|dkrZ|\}}t |ts/t |tr;ddlm} || ||S t|t|}}| ||dkrR| ||S t	d||f t |t
tfr| j\}}t |tsqt	tdt|}|| }|| }| ||dkr| ||S t	d| t |ttfrt	td	t	d
|  )Nr   )MatrixSlice)r   Nrb   rt   FzInvalid indices (%s, %s)zo
                    Single indexing is only supported when the number
                    of columns is known.zInvalid index %szj
                Only integers may be used when addressing the matrix
                with a single index.zInvalid index, wanted %s[i,j])r   tupleslice sympy.matrices.expressions.slicer   lenr   r   r   
IndexErrorr   r   r7   r   r   r   )r6   keyr   r   r   r_   rc   r#   r#   r$   __getitem__  s2   

zMatrixExpr.__getitem__c                 C   s$   t | jttf pt | jttf S r   )r   r_   r   r   rc   r5   r#   r#   r$   _is_shape_symbolic?  s   zMatrixExpr._is_shape_symbolicc                    s8      rtdddlm} | fddt jD S )a  
        Returns a dense Matrix with elements represented explicitly

        Returns an object of type ImmutableDenseMatrix.

        Examples
        ========

        >>> from sympy import Identity
        >>> I = Identity(3)
        >>> I
        I
        >>> I.as_explicit()
        Matrix([
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1]])

        See Also
        ========
        as_mutable: returns mutable Matrix type

        z<Matrix with symbolic shape cannot be represented explicitly.r   ImmutableDenseMatrixc                    s&   g | ]  fd dt jD qS )c                    s   g | ]} |f qS r#   r#   r   r   )r   r6   r#   r$   r   `  s    z5MatrixExpr.as_explicit.<locals>.<listcomp>.<listcomp>)rangerc   )r   r5   )r   r$   r   `  s
    
z*MatrixExpr.as_explicit.<locals>.<listcomp>)r   r   sympy.matrices.immutabler   r   r_   )r6   r   r#   r5   r$   as_explicitC  s   zMatrixExpr.as_explicitc                 C   s   |    S )a  
        Returns a dense, mutable matrix with elements represented explicitly

        Examples
        ========

        >>> from sympy import Identity
        >>> I = Identity(3)
        >>> I
        I
        >>> I.shape
        (3, 3)
        >>> I.as_mutable()
        Matrix([
        [1, 0, 0],
        [0, 1, 0],
        [0, 0, 1]])

        See Also
        ========
        as_explicit: returns ImmutableDenseMatrix
        )r   
as_mutabler5   r#   r#   r$   r   d  s   zMatrixExpr.as_mutablec                 C   sR   ddl m} || jtd}t| jD ]}t| jD ]}| ||f |||f< qq|S )Nr   )empty)dtype)numpyr   r7   objectr   r_   rc   )r6   r   r   r   r   r#   r#   r$   	__array__}  s   zMatrixExpr.__array__c                 C   s   |   |S )z
        Test elementwise equality between matrices, potentially of different
        types

        >>> from sympy import Identity, eye
        >>> Identity(3).equals(eye(3))
        True
        )r   equalsrJ   r#   r#   r$   r     s   	zMatrixExpr.equalsc                 C      | S r   r#   r5   r#   r#   r$   canonicalize  rE   zMatrixExpr.canonicalizec                 C   s   t jt| fS r   )r   r   r>   r5   r#   r#   r$   as_coeff_mmul  r   zMatrixExpr.as_coeff_mmulc                 C   sT   ddl m} ddlm} g }|dur|| |dur || || |d}||S )a  
        Parse expression of matrices with explicitly summed indices into a
        matrix expression without indices, if possible.

        This transformation expressed in mathematical notation:

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

        Optional parameter ``first_index``: specify which free index to use as
        the index starting the expression.

        Examples
        ========

        >>> from sympy import MatrixSymbol, MatrixExpr, Sum
        >>> from sympy.abc import i, j, k, l, N
        >>> A = MatrixSymbol("A", N, N)
        >>> B = MatrixSymbol("B", N, N)
        >>> expr = Sum(A[i, j]*B[j, k], (j, 0, N-1))
        >>> MatrixExpr.from_index_summation(expr)
        A*B

        Transposition is detected:

        >>> expr = Sum(A[j, i]*B[j, k], (j, 0, N-1))
        >>> MatrixExpr.from_index_summation(expr)
        A.T*B

        Detect the trace:

        >>> expr = Sum(A[i, i], (i, 0, N-1))
        >>> MatrixExpr.from_index_summation(expr)
        Trace(A)

        More complicated expressions:

        >>> expr = Sum(A[i, j]*B[k, j]*A[l, k], (j, 0, N-1), (k, 0, N-1))
        >>> MatrixExpr.from_index_summation(expr)
        A*B.T*A.T
        r   )convert_indexed_to_arrayconvert_array_to_matrixN)first_indices)4sympy.tensor.array.expressions.conv_indexed_to_arrayr   3sympy.tensor.array.expressions.conv_array_to_matrixr   append)exprfirst_index
last_index
dimensionsr   r   r   arrr#   r#   r$   from_index_summation  s   *

zMatrixExpr.from_index_summationc                 C   s   ddl m} ||| S )Nrb   )ElementwiseApplyFunction)	applyfuncr   )r6   r!   r   r#   r#   r$   r     s   
zMatrixExpr.applyfunc)TF)NNN)Vr   
__module____qualname____doc__	__slots__	_iterable_op_priority	is_Matrixis_MatrixExpris_Identity
is_Inverseis_Transposeis_ZeroMatrix	is_MatAdd	is_MatMulis_commutative	is_number	is_symbol	is_scalarr   r+   __annotations__r-   propertytTupler   r7   r<   r?   rB   rD   r)   NotImplementedr   rK   rG   rO   rN   rS   rT   rQ   rU   rX   rV   r[   rZ   r_   rc   re   rl   rq   rn   r|   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   boolr   r   r   r   r   r   r   staticmethodr   r   __classcell__r#   r#   r   r$   r*   $   s   
 






	


#!3r*   c                 C      dS )NFr#   lhsrhsr#   r#   r$   _eval_is_eq  r8   r  c                 C   s"   | j |j krdS | | jrdS d S )NFT)r7   r   r   r#   r#   r$   r    s
   
c                    s    fdd}|S )Nc                    s   t ttti  }g }g }| jD ]}t|tr|| q|| q|s) |S |r\ t krNt	t
|D ]}|| jsL||  |||< g } nq5n ||| jddg S |tkrh|| jddS | |g|R  jddS )NF)ro   )r   r>   r	   r;   r/   r   r*   r   
_from_argsr   r   r   rS   rA   )r   	mat_classnonmatricesmatricestermr   r.   r#   r$   _postprocessor  s,   



z)get_postprocessor.<locals>._postprocessorr#   )r.   r	  r#   r  r$   get_postprocessor  s   #r
  )r   r	   Fc           	      C   sh   t | ts
t |trd}|rt| |S ddlm} ddlm} ddlm} || }|||}||}|S )NTr   )convert_matrix_to_array)array_deriver   )	r   r    _matrix_derivative_old_algorithm3sympy.tensor.array.expressions.conv_matrix_to_arrayr  4sympy.tensor.array.expressions.arrayexpr_derivativesr  r   r   )	r   r   old_algorithmr  r  r   
array_exprdiff_array_exprdiff_matrix_exprr#   r#   r$   _matrix_derivative  s   

r  c                    s   ddl m} | |}dd |D }ddlm fdd|D }dd   fd	d
fdd|D }|d }dd |dkrLtfdd|D S || |S )Nr   )ArrayDerivativec                 S   s   g | ]}|  qS r#   )buildr   r   r#   r#   r$   r         z4_matrix_derivative_old_algorithm.<locals>.<listcomp>r   c                    s   g | ]} fd d|D qS )c                       g | ]} |qS r#   r#   r   r   r#   r$   r   "  r  z?_matrix_derivative_old_algorithm.<locals>.<listcomp>.<listcomp>r#   r  r   r#   r$   r   "  s    c                 S      t | tr| jS dS )Nrb   rb   r   r*   r7   elemr#   r#   r$   
_get_shape$     
z4_matrix_derivative_old_algorithm.<locals>._get_shapec                    s   t  fdd| D S )Nc                    s"   g | ]} |D ]}|d vqqS ))rb   Nr#   )r   r   r   r  r#   r$   r   *  s   " zF_matrix_derivative_old_algorithm.<locals>.get_rank.<locals>.<listcomp>)sum)partsr!  r#   r$   get_rank)  s   z2_matrix_derivative_old_algorithm.<locals>.get_rankc                    r  r#   r#   r  )r$  r#   r$   r   ,  r  c                 S   s   t | dkr
| d S | d d \}}|jr|j}|tdkr!|}n|tdkr*|}n|| }t | dkr6|S |jr=td|t| dd   S )Nrb   r   rt    )r   r   r   Identityr   r   fromiter)r#  p1p2pbaser#   r#   r$   contract_one_dims/  s   z;_matrix_derivative_old_algorithm.<locals>.contract_one_dimsrt   c                    r  r#   r#   r  )r+  r#   r$   r   D  r  )$sympy.tensor.array.array_derivativesr  _eval_derivative_matrix_linesr   r   r	   r'  )r   r   r  linesr#  ranksrankr#   )r  r+  r   r$  r$   r    s   

r  c                   @   sl   e Zd Zedd Zedd Zedd ZdZdZdZ	dd Z
edd	 Zd
d Zedd Zdd ZdS )MatrixElementc                 C   r\   r]   r/   r5   r#   r#   r$   <lambda>J     
 zMatrixElement.<lambda>c                 C   r\   ra   r2  r5   r#   r#   r$   r3  K  r4  c                 C   r\   rs   r2  r5   r#   r#   r$   r3  L  r4  Tc                 C   s   t t||f\}}ddlm} t|trt|}n3t||r/|jr*|jr*|||f S t|}nt|}t|jt	s=t
dt|ddd ||sLtdt| |||}|S )Nr   r   z2First argument of MatrixElement should be a matrixr   c                 S   r   )NTr#   )r   mr#   r#   r$   r3  _  s    z'MatrixElement.__new__.<locals>.<lambda>zindices out of range)r,   r   sympy.matrices.matricesr   r   strr   
is_Integerr+   r   	TypeErrorgetattrr   r   r-   )r.   namer   r6  r   objr#   r#   r$   r-   Q  s   



zMatrixElement.__new__c                 C   r\   r]   r2  r5   r#   r#   r$   symbold  r`   zMatrixElement.symbolc                    sD     dd}|r fdd| jD }n| j}|d |d |d f S )Nro   Tc                    s   g | ]
}|j d i  qS )r#   )rA   )r   r(   rp   r#   r$   r   k  r   z&MatrixElement.doit.<locals>.<listcomp>r   rb   rt   )getr/   )r6   rp   ro   r/   r#   r?  r$   rA   h  s
   zMatrixElement.doitc                 C   s   | j dd  S ra   r2  r5   r#   r#   r$   indicesp  s   zMatrixElement.indicesc                 C   sR  t |ts ddlm} t | j|r| j|| j| jf S tj	S | j
d }| jj\}}||j
d krRt| j
d |j
d d|d ft| j
d |j
d d|d f S t |trddlm} | j
dd  \}}tdtd\}	}
|j
d }|j\}}||||	f ||	|
f | ||
|f  |	d|d f|
d|d f S | |j
d rd S tj	S )Nr   r5  rb   rt   )Sumzz1, z2r  )r   r1  r7  r   parentdiffr   r   r   Zeror/   r7   r   r{   sympy.concrete.summationsrB  r   r   r   )r6   vr   Mr6  r   rB  r   r   i1i2Yr1r2r#   r#   r$   r   t  s*   




HzMatrixElement._eval_derivativeN)r   r   r   r   rC  r   r   	_diff_wrtr   r   r-   r>  rA   rA  r   r#   r#   r#   r$   r1  I  s    

r1  c                   @   sh   e Zd ZdZdZdZdZdd Zedd Z	edd	 Z
d
d Zedd Zdd Zdd Zdd ZdS )MatrixSymbola  Symbolic representation of a Matrix object

    Creates a SymPy Symbol to represent a Matrix. This matrix has a shape and
    can be included in Matrix Expressions

    Examples
    ========

    >>> from sympy import MatrixSymbol, Identity
    >>> A = MatrixSymbol('A', 3, 4) # A 3 by 4 Matrix
    >>> B = MatrixSymbol('B', 4, 3) # A 4 by 3 Matrix
    >>> A.shape
    (3, 4)
    >>> 2*A*B + Identity(3)
    I + 2*A*B
    FTc                 C   sL   t |t |}}| | | | t|trt|}t| |||}|S r   )r   r   r   r8  r   r   r-   )r.   r<  r   r6  r=  r#   r#   r$   r-     s   


zMatrixSymbol.__new__c                 C   s   | j d | j d fS )Nrb   rt   r2  r5   r#   r#   r$   r7     s   zMatrixSymbol.shapec                 C   s   | j d jS r]   )r/   r<  r5   r#   r#   r$   r<    rf   zMatrixSymbol.namec                 K   s   t | ||S r   )r1  r   r#   r#   r$   r     s   zMatrixSymbol._entryc                 C   s   | hS r   r#   r5   r#   r#   r$   free_symbols  s   zMatrixSymbol.free_symbolsc                 K   r   r   r#   r   r#   r#   r$   r     rE   zMatrixSymbol._eval_simplifyc                 C   s   t | jd | jd S Nr   rb   )r   r7   r   r#   r#   r$   r     s   zMatrixSymbol._eval_derivativec                 C   s   | |kr5| j d dkrt|j d | j d ntj}| j d dkr+t|j d | j d ntj}t||ggS | j d dkrCt| j d ntj}| j d dkrTt| j d ntj}t||ggS rQ  )r7   r   r   rE  _LeftRightArgsr&  r   )r6   r   firstsecondr#   r#   r$   r-    s   **""z*MatrixSymbol._eval_derivative_matrix_linesN)r   r   r   r   r   r   rN  r-   r   r7   r<  r   rP  r   r   r-  r#   r#   r#   r$   rO    s     


rO  c                 C   s   dd | j D S )Nc                 S   s   g | ]}|j r|qS r#   )r   )r   symr#   r#   r$   r         z"matrix_symbols.<locals>.<listcomp>)rP  r   r#   r#   r$   matrix_symbols  rC   rX  c                   @   s   e Zd ZdZejfddZedd Zej	dd Zedd Z
e
j	d	d Z
d
d Zdd Zedd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )rR  a  
    Helper class to compute matrix derivatives.

    The logic: when an expression is derived by a matrix `X_{mn}`, two lines of
    matrix multiplications are created: the one contracted to `m` (first line),
    and the one contracted to `n` (second line).

    Transposition flips the side by which new matrices are connected to the
    lines.

    The trace connects the end of the two lines.
    c                 C   sB   dd |D | _ | j | _d| _d| _| j | _d| _d| _|| _d S )Nc                 S      g | ]}|qS r#   r#   r  r#   r#   r$   r         z+_LeftRightArgs.__init__.<locals>.<listcomp>r   rb   )_lines_first_pointer_parent_first_pointer_index_first_line_index_second_pointer_parent_second_pointer_index_second_line_indexhigher)r6   r.  rb  r#   r#   r$   __init__  s   
z_LeftRightArgs.__init__c                 C      | j | j S r   r\  r]  r5   r#   r#   r$   first_pointer  rf   z_LeftRightArgs.first_pointerc                 C      || j | j< d S r   re  r6   valuer#   r#   r$   rf       c                 C   rd  r   r_  r`  r5   r#   r#   r$   second_pointer  rf   z_LeftRightArgs.second_pointerc                 C   rg  r   rk  rh  r#   r#   r$   rl    rj  c                    s"    fdd j D }d| jf S )Nc                       g | ]}  |qS r#   _buildr  r5   r#   r$   r     rV  z+_LeftRightArgs.__repr__.<locals>.<listcomp>z#_LeftRightArgs(lines=%s, higher=%s))r[  rb  )r6   builtr#   r5   r$   __repr__  s
   z_LeftRightArgs.__repr__c                 C   s:   | j | j| _| _ | j| j| _| _| j| j| _| _| S r   )r_  r\  r`  r]  ra  r^  r5   r#   r#   r$   r   
  s   z_LeftRightArgs.transposec                 C   sN   t | tr	|  S t | tr%t| dkr| d S | d dd | d D  S | S )Nrb   r   c                 S   s   g | ]}t |qS r#   )rR  ro  r  r#   r#   r$   r     rV  z)_LeftRightArgs._build.<locals>.<listcomp>)r   r   r  listr   rW  r#   r#   r$   ro    s   

z_LeftRightArgs._buildc                    sB    fdd j D } jdkr|  jg7 }dd |D }|S )Nc                    rm  r#   rn  r  r5   r#   r$   r     rV  z(_LeftRightArgs.build.<locals>.<listcomp>rb   c                 S   rY  r#   r#   r  r#   r#   r$   r      rZ  )r[  rb  ro  )r6   datar#   r5   r$   r    s
   
z_LeftRightArgs.buildc                 C   s   | j dkr| jdkrtddd }|| j d || jd krC|| jdkr/| j | jd  S || j dkr?| j d | jj S td| j dkrO| j | jj S | jS )Nrb   z.higher dimensional array cannot be representedc                 S   r  )N)NNr  r  r#   r#   r$   r  '  r   z._LeftRightArgs.matrix_form.<locals>._get_shaper  )r   r   zincompatible shapes)rS  rb  r   rT  r   )r6   r  r#   r#   r$   matrix_form#  s   
z_LeftRightArgs.matrix_formc                 C   sb   d}| j dkr|tdd | j jD 7 }| jdkr&|tdd | jjD 7 }| jdkr/|d7 }|S )zl
        Number of dimensions different from trivial (warning: not related to
        matrix rank).
        r   rb   c                 S      g | ]}|d kqS rb   r#   r  r#   r#   r$   r   @  r  z'_LeftRightArgs.rank.<locals>.<listcomp>c                 S   ru  rv  r#   r  r#   r#   r$   r   B  r  rt   )rS  r"  r7   rT  rb  )r6   r0  r#   r#   r$   r0  9  s   


z_LeftRightArgs.rankc                 C   s:   ddl m} ddl m} t|t|||gdg|jd}|S )N   )ArrayTensorProduct)ArrayContraction)rb   rt   )	validator)*tensor.array.expressions.array_expressionsrx  ry  r   	_validate)r6   pointerrF   rx  ry  subexprr#   r#   r$   _multiply_pointerG  s   
z _LeftRightArgs._multiply_pointerc                 C      |  j |9  _ d S r   )rf  rJ   r#   r#   r$   append_first\  r   z_LeftRightArgs.append_firstc                 C   r  r   )rl  rJ   r#   r#   r$   append_second_  r   z_LeftRightArgs.append_secondN)r   r   r   r   r   r   rc  r   rf  setterrl  rq  r   r   ro  r  rt  r0  r  r  r  r#   r#   r#   r$   rR    s*    





rR  c                 C   s&   ddl m} t| tr| S || ggS )Nr   r   )r   r   r   r*   )r   r   r#   r#   r$   _make_matrixc  s   
r  rb   r=   r:   r   r   rz   )r   r&  r}   r   r   )Gtypingr   r   	functoolsr   
sympy.corer   r   r   r   r	   sympy.core.assumptionsr
   sympy.core.decoratorsr   sympy.core.exprr   r   sympy.core.logicr   sympy.core.symbolr   r   r   r   sympy.core.sympifyr   r   sympy.external.gmpyr   sympy.functionsr   r   (sympy.functions.special.tensor_functionsr   sympy.matrices.commonr   r7  r   r   sympy.multipledispatchr   sympy.utilities.miscr   r)   r*   r  r
  "_constructor_postprocessor_mappingr  r  r1  rO  rX  rR  r  matmulr>   mataddr;   matpowrW   r   rj   r   r{   specialr   r&  determinantr~   r#   r#   r#   r$   <module>   sX    
   .

(
/IE 	