a
    RG5dj                     @   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                    s0   zt |} | |W S  ty*    Y S 0 d S N)r   r   )ab)funcretval ^/var/www/html/django/DPS/env/lib/python3.9/site-packages/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eeef d
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 ZIeJd
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   s   t d S r   NotImplementedErrorselfr#   r#   r$   shapeV   s    zMatrixExpr.shapec                 C   s   t S r   MatAddr4   r#   r#   r$   _add_handlerZ   s    zMatrixExpr._add_handlerc                 C   s   t S r   MatMulr4   r#   r#   r$   _mul_handler^   s    zMatrixExpr._mul_handlerc                 C   s   t tj|  S r   )r;   r   NegativeOnedoitr4   r#   r#   r$   __neg__b   s    zMatrixExpr.__neg__c                 C   s   t d S r   r2   r4   r#   r#   r$   __abs__e   s    zMatrixExpr.__abs__other__radd__c                 C   s   t | | S r   r8   r>   r5   rA   r#   r#   r$   __add__h   s    zMatrixExpr.__add__rE   c                 C   s   t ||  S r   rC   rD   r#   r#   r$   rB   m   s    zMatrixExpr.__radd____rsub__c                 C   s   t | |  S r   rC   rD   r#   r#   r$   __sub__r   s    zMatrixExpr.__sub__rG   c                 C   s   t ||   S r   rC   rD   r#   r#   r$   rF   w   s    zMatrixExpr.__rsub____rmul__c                 C   s   t | | S r   r;   r>   rD   r#   r#   r$   __mul__|   s    zMatrixExpr.__mul__c                 C   s   t | | S r   rI   rD   r#   r#   r$   
__matmul__   s    zMatrixExpr.__matmul__rJ   c                 C   s   t ||  S r   rI   rD   r#   r#   r$   rH      s    zMatrixExpr.__rmul__c                 C   s   t ||  S r   rI   rD   r#   r#   r$   __rmatmul__   s    zMatrixExpr.__rmatmul____rpow__c                 C   s   t | | S r   )MatPowr>   rD   r#   r#   r$   __pow__   s    zMatrixExpr.__pow__rO   c                 C   s   t dd S )NzMatrix Power not definedr2   rD   r#   r#   r$   rM      s    zMatrixExpr.__rpow____rtruediv__c                 C   s   | |t j  S r   )r   r=   rD   r#   r#   r$   __truediv__   s    zMatrixExpr.__truediv__rQ   c                 C   s
   t  d S r   r2   rD   r#   r#   r$   rP      s    zMatrixExpr.__rtruediv__c                 C   s
   | j d S Nr   r6   r4   r#   r#   r$   rows   s    zMatrixExpr.rowsc                 C   s
   | j d S N   rS   r4   r#   r#   r$   cols   s    zMatrixExpr.colsc                 C   s   | j | jkS r   rT   rW   r4   r#   r#   r$   	is_square   s    zMatrixExpr.is_squarec                 C   s   ddl m} |t| S Nr   )Adjoint)"sympy.matrices.expressions.adjointr[   	Transposer5   r[   r#   r#   r$   _eval_conjugate   s    zMatrixExpr._eval_conjugatec                 K   s   |   S r   )_eval_as_real_imag)r5   deephintsr#   r#   r$   as_real_imag   s    zMatrixExpr.as_real_imagc                 C   s0   t j| |    }| |   dt j  }||fS N   )r   Halfr_   ImaginaryUnit)r5   realimr#   r#   r$   r`      s    zMatrixExpr._eval_as_real_imagc                 C   s   t | S r   Inverser4   r#   r#   r$   _eval_inverse   s    zMatrixExpr._eval_inversec                 C   s   t | S r   Determinantr4   r#   r#   r$   _eval_determinant   s    zMatrixExpr._eval_determinantc                 C   s   t | S r   r]   r4   r#   r#   r$   _eval_transpose   s    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.
        rN   )r5   expr#   r#   r$   _eval_power   s    zMatrixExpr._eval_powerc                    s6   | j r
| S ddlm | j fdd| jD  S d S )Nr   )simplifyc                    s   g | ]}|fi  qS r#   r#   ).0xr0   ru   r#   r$   
<listcomp>       z-MatrixExpr._eval_simplify.<locals>.<listcomp>)is_Atomsympy.simplifyru   r!   r/   r5   r0   r#   rx   r$   _eval_simplify   s    zMatrixExpr._eval_simplifyc                 C   s   ddl m} || S rZ   )r\   r[   r^   r#   r#   r$   _eval_adjoint   s    zMatrixExpr._eval_adjointc                 C   s   t | ||S r   )r   _eval_derivative_n_times)r5   rw   nr#   r#   r$   r      s    z#MatrixExpr._eval_derivative_n_timesc                    s$   |  |rt |S t| j S d S r   )hassuper_eval_derivative
ZeroMatrixr6   r5   rw   	__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 d S )NzIndexing not implemented for %s)r3   r   __name__r5   ijr0   r#   r#   r$   _entry   s    
zMatrixExpr._entryc                 C   s   t | S r   )r   r4   r#   r#   r$   r      s    zMatrixExpr.adjointc                 C   s
   t j| fS )z2Efficiently extract the coefficient of a product. )r   One)r5   rationalr#   r#   r$   as_coeff_Mul   s    zMatrixExpr.as_coeff_Mulc                 C   s   t | S r   )r   r4   r#   r#   r$   r      s    zMatrixExpr.conjugatec                 C   s   ddl m} || S )Nr   	transpose)Z$sympy.matrices.expressions.transposer   )r5   r   r#   r#   r$   r      s    zMatrixExpr.transposec                 C   s   |   S )zMatrix transpositionr   r4   r#   r#   r$   T   s    zMatrixExpr.Tc                 C   s   | j std|  S )NzInverse of non-square matrix)rY   r   rl   r4   r#   r#   r$   inverse  s    zMatrixExpr.inversec                 C   s   |   S r   r   r4   r#   r#   r$   inv	  s    zMatrixExpr.invc                 C   s   ddl m} || S )Nr   )det)Z&sympy.matrices.expressions.determinantr   )r5   r   r#   r#   r$   r     s    zMatrixExpr.detc                 C   s   |   S r   r   r4   r#   r#   r$   I  s    zMatrixExpr.Ic                 C   s^   dd }||o\||o\| j d u s@|| 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  s    z(MatrixExpr.valid_index.<locals>.is_validFrX   )r5   r   r   r   r#   r#   r$   valid_index  s    
zMatrixExpr.valid_indexc                 C   sV  t |ts,t |tr,ddlm} || |dS t |trt|dkr|\}}t |ts^t |trvddlm} || ||S t|t| }}| ||dkr| ||S t	d||f nt |t
tfr*| j\}}t |tst	tdt|}|| }|| }| ||dkr| ||S t	d| nt |ttfrFt	td	t	d
|  d S )Nr   )MatrixSlice)r   NrV   re   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sliceZ sympy.matrices.expressions.slicer   lenr   r   r   
IndexErrorr   r   r6   r   r   r   )r5   keyr   r   r   rT   rW   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   rT   r   r   rW   r4   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#   rv   r   )r   r5   r#   r$   ry   `  s   z5MatrixExpr.as_explicit.<locals>.<listcomp>.<listcomp>)rangerW   )rv   r4   )r   r$   ry   `  s   z*MatrixExpr.as_explicit.<locals>.<listcomp>)r   r   sympy.matrices.immutabler   r   rT   )r5   r   r#   r4   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_mutabler4   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< q2q$|S )Nr   )empty)dtype)numpyr   r6   objectr   rT   rW   )r5   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   equalsrD   r#   r#   r$   r     s    	zMatrixExpr.equalsc                 C   s   | S r   r#   r4   r#   r#   r$   canonicalize  s    zMatrixExpr.canonicalizec                 C   s   t jt| fS r   )r   r   r;   r4   r#   r#   r$   as_coeff_mmul  s    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 )NrV   )ElementwiseApplyFunction)	applyfuncr   )r5   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_IdentityZ
is_InverseZis_Transposeis_ZeroMatrix	is_MatAdd	is_MatMulis_commutative	is_number	is_symbol	is_scalarr   r+   __annotations__r-   propertytTupler   r6   r9   r<   r?   r@   r)   NotImplementedr   rE   rB   rG   rF   rJ   rK   rH   rL   rO   rM   rQ   rP   rT   rW   rY   r_   rc   r`   rl   ro   rq   rt   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   s   dS )NFr#   lhsrhsr#   r#   r$   _eval_is_eq  s    r   c                 C   s"   | j |j krdS | | jrdS d S )NFT)r6   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r8|| q|| q|sR |S |r t krt	t
|D ].}|| jsj||  |||< g } qqjn ||| jddg S |tkr|| jddS | |g|R  jddS )NF)ra   )r   r;   r	   r8   r/   r   r*   r   
_from_argsr   r   r   rJ   r>   )r   Z	mat_classZ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_algorithmZ3sympy.tensor.array.expressions.conv_matrix_to_arrayr   Z4sympy.tensor.array.expressions.arrayexpr_derivativesr   r   r   )	r   rw   Zold_algorithmr   r   r   
array_exprZdiff_array_exprZ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rtfdd|D S || |S )Nr   )ArrayDerivativec                 S   s   g | ]}|  qS r#   )buildrv   r   r#   r#   r$   ry     rz   z4_matrix_derivative_old_algorithm.<locals>.<listcomp>r   c                    s   g | ]} fd d|D qS )c                    s   g | ]} |qS r#   r#   r   r   r#   r$   ry   "  rz   z?_matrix_derivative_old_algorithm.<locals>.<listcomp>.<listcomp>r#   r   r   r#   r$   ry   "  rz   c                 S   s   t | tr| jS dS )NrV   rV   r   r*   r6   elemr#   r#   r$   
_get_shape$  s    
z4_matrix_derivative_old_algorithm.<locals>._get_shapec                    s   t  fdd| D S )Nc                    s"   g | ]} |D ]}|d vqqS ))rV   Nr#   )rv   r   r   r   r#   r$   ry   *  rz   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                    s   g | ]} |qS r#   r#   r   )r   r#   r$   ry   ,  rz   c                 S   s   t | dkr| d S | d d \}}|jr0|j}|tdkrB|}n|tdkrT|}n|| }t | dkrl|S |jrztd|t| dd   S d S )NrV   r   re    )r   r   r   Identityr   r   fromiter)r   p1p2Zpbaser#   r#   r$   contract_one_dims/  s    z;_matrix_derivative_old_algorithm.<locals>.contract_one_dimsre   c                    s   g | ]} |qS r#   r#   r   )r  r#   r$   ry   D  rz   )$sympy.tensor.array.array_derivativesr   _eval_derivative_matrix_linesr   r   r	   r   )r   rw   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   s
   | j d S rR   r/   r4   r#   r#   r$   <lambda>J  rz   zMatrixElement.<lambda>c                 C   s
   | j d S rU   r
  r4   r#   r#   r$   r  K  rz   c                 C   s
   | j d S rd   r
  r4   r#   r#   r$   r  L  rz   Tc                 C   s   t t||f\}}ddlm} t|tr2t|}nft||r^|jrT|jrT|||f S t|}nt|}t|jt	szt
dt|ddd ||stdt| |||}|S )Nr   r   z2First argument of MatrixElement should be a matrixr   c                 S   s   dS )NTr#   )r   mr#   r#   r$   r  _  rz   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   r  r   objr#   r#   r$   r-   Q  s    



zMatrixElement.__new__c                 C   s
   | j d S rR   r
  r4   r#   r#   r$   symbold  s    zMatrixElement.symbolc                    sD     dd}|r& fdd| jD }n| j}|d |d |d f S )Nra   Tc                    s   g | ]}|j f i  qS r#   )r>   )rv   r(   rb   r#   r$   ry   k  rz   z&MatrixElement.doit.<locals>.<listcomp>r   rV   re   )getr/   )r5   rb   ra   r/   r#   r  r$   r>   h  s
    zMatrixElement.doitc                 C   s   | j dd  S rU   r
  r4   r#   r#   r$   indicesp  s    zMatrixElement.indicesc                 C   sV  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rt| j
d |j
d d|d ft| j
d |j
d d|d f S t |tr:d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 rPd S tj	S )Nr   r  rV   re   )Sumzz1, z2r   )r   r	  r  r   parentdiffr   r   r   Zeror/   r6   r   rk   sympy.concrete.summationsr  r   r   r   )r5   vr   Mr  r   r  r   r   i1i2Yr1r2r#   r#   r$   r   t  s*    



HzMatrixElement._eval_derivativeN)r   r   r   r   r  r   r   	_diff_wrtr   r   r-   r  r>   r  r   r#   r#   r#   r$   r	  I  s   

r	  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r8t|}t| |||}|S r   )r   r   r   r  r   r   r-   )r.   r  r   r  r  r#   r#   r$   r-     s    


zMatrixSymbol.__new__c                 C   s   | j d | j d fS )NrV   re   r
  r4   r#   r#   r$   r6     s    zMatrixSymbol.shapec                 C   s   | j d jS rR   )r/   r  r4   r#   r#   r$   r    s    zMatrixSymbol.namec                 K   s   t | ||S r   )r	  r   r#   r#   r$   r     s    zMatrixSymbol._entryc                 C   s   | hS r   r#   r4   r#   r#   r$   free_symbols  s    zMatrixSymbol.free_symbolsc                 K   s   | S r   r#   r}   r#   r#   r$   r~     s    zMatrixSymbol._eval_simplifyc                 C   s   t | jd | jd S Nr   rV   )r   r6   r   r#   r#   r$   r     s    zMatrixSymbol._eval_derivativec                 C   s   | |krj| j d dkr,t|j d | j d ntj}| j d dkrVt|j d | j d ntj}t||ggS | j d dkrt| j d ntj}| j d dkrt| j d ntj}t||ggS d S r(  )r6   r   r   r  _LeftRightArgsr   r   )r5   rw   firstsecondr#   r#   r$   r    s    **""z*MatrixSymbol._eval_derivative_matrix_linesN)r   r   r   r   r   r   r%  r-   r   r6   r  r   r'  r~   r   r  r#   r#   r#   r$   r&    s   


r&  c                 C   s   dd | j D S )Nc                 S   s   g | ]}|j r|qS r#   )r   )rv   symr#   r#   r$   ry     rz   z"matrix_symbols.<locals>.<listcomp>)r'  r   r#   r#   r$   matrix_symbols  s    r.  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 )r)  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   s   g | ]}|qS r#   r#   r   r#   r#   r$   ry     rz   z+_LeftRightArgs.__init__.<locals>.<listcomp>r   rV   )_lines_first_pointer_parent_first_pointer_index_first_line_index_second_pointer_parent_second_pointer_index_second_line_indexhigher)r5   r  r6  r#   r#   r$   __init__  s    z_LeftRightArgs.__init__c                 C   s   | j | j S r   r0  r1  r4   r#   r#   r$   first_pointer  s    z_LeftRightArgs.first_pointerc                 C   s   || j | j< d S r   r8  r5   valuer#   r#   r$   r9    s    c                 C   s   | j | j S r   r3  r4  r4   r#   r#   r$   second_pointer  s    z_LeftRightArgs.second_pointerc                 C   s   || j | j< d S r   r<  r:  r#   r#   r$   r=    s    c                    s"    fdd j D }d| jf S )Nc                    s   g | ]}  |qS r#   _buildr   r4   r#   r$   ry     rz   z+_LeftRightArgs.__repr__.<locals>.<listcomp>z#_LeftRightArgs(lines=%s, higher=%s))r/  r6  )r5   Zbuiltr#   r4   r$   __repr__  s
    z_LeftRightArgs.__repr__c                 C   s:   | j | j | _| _ | j| j | _| _| j| j | _| _| S r   )r3  r0  r4  r1  r5  r2  r4   r#   r#   r$   r   
  s    z_LeftRightArgs.transposec                 C   sT   t | tr|  S t | trLt| dkr0| d S | d dd | d D  S n| S d S )NrV   r   c                 S   s   g | ]}t |qS r#   )r)  r?  r   r#   r#   r$   ry     rz   z)_LeftRightArgs._build.<locals>.<listcomp>)r   r   r   listr   r-  r#   r#   r$   r?    s    

z_LeftRightArgs._buildc                    sB    fdd j D } jdkr0|  jg7 }dd |D }|S )Nc                    s   g | ]}  |qS r#   r>  r   r4   r#   r$   ry     rz   z(_LeftRightArgs.build.<locals>.<listcomp>rV   c                 S   s   g | ]}|qS r#   r#   r   r#   r#   r$   ry      rz   )r/  r6  r?  )r5   datar#   r4   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r|| jdkr^| j | jd  S || j dkr~| j d | jj S td| j dkr| j | jj S | jS d S )NrV   z.higher dimensional array cannot be representedc                 S   s   t | tr| jS dS )N)NNr   r   r#   r#   r$   r   '  s    
z._LeftRightArgs.matrix_form.<locals>._get_shaper   )r   r   zincompatible shapes)r*  r6  r   r+  r   )r5   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rL|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   rV   c                 S   s   g | ]}|d kqS rV   r#   r   r#   r#   r$   ry   @  rz   z'_LeftRightArgs.rank.<locals>.<listcomp>c                 S   s   g | ]}|d kqS rD  r#   r   r#   r#   r$   ry   B  rz   re   )r*  r   r6   r+  r6  )r5   r  r#   r#   r$   r  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)rV   re   )	validator)Z*tensor.array.expressions.array_expressionsrF  rG  r   	_validate)r5   pointerrA   rF  rG  Zsubexprr#   r#   r$   _multiply_pointerG  s    
z _LeftRightArgs._multiply_pointerc                 C   s   |  j |9  _ d S r   )r9  rD   r#   r#   r$   append_first\  s    z_LeftRightArgs.append_firstc                 C   s   |  j |9  _ d S r   )r=  rD   r#   r#   r$   append_second_  s    z_LeftRightArgs.append_secondN)r   r   r   r   r   r   r7  r   r9  setterr=  r@  r   r   r?  r   rC  r  rK  rL  rM  r#   r#   r#   r$   r)    s(   





r)  c                 C   s&   ddl m} t| tr| S || ggS )Nr   r   )r   r   r   r*   )rw   r   r#   r#   r$   _make_matrixc  s    
rO  rV   r:   r7   rr   rp   rj   )r   r   rm   )N)F)Gtypingr   r   	functoolsr   
sympy.corer   r   r   r   r	   Zsympy.core.assumptionsr
   Zsympy.core.decoratorsr   sympy.core.exprr   r   Z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   r  r   r   sympy.multipledispatchr   sympy.utilities.miscr   r)   r*   r   r   "_constructor_postprocessor_mappingr   r   r	  r&  r.  r)  rO  matmulr;   mataddr8   matpowrN   r   r]   r   rk   specialr   r   determinantrn   r#   r#   r#   r$   <module>   sV   
   .

(
/IE 	