U
    -eOk                     @  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j/e,< d4ddZ0dd  Z1G d!d" d"eZ2G d#d$ d$e,Z3d%d& Z4G d'd( d(Z5d)d* Z6d+d,l7m8Z8 d+d-l9m:Z: d+d.l;m<Z< d+d/l=m>Z> d+d0l?m@Z@ d+d1lAmBZBmCZC d+d2lDmEZE dS )5    )annotations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                   s2   zt |} | |W S  tk
r,    Y S X d S N)r   r   )ab)funcretval c/var/www/html/Darija-Ai-Train/env/lib/python3.8/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                      sL  e Zd ZU dZdZded< dZdZdZded	< dZ	ded
< dZ
ded< dZdZdZdZdZdZdZdZdZe Zded< dd Zed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d0d1d2 Z&edeed0d3d4 Z'edeed5d6d7 Z(edeed8d9d: Z)edeed;d<d= Z*edeed>d?d@ Z+edAdB Z,edCdD Z-edEddFdGZ.dHdI Z/ddJdKZ0dLdM Z1dNdO Z2dPdQ Z3dRdS Z4dTdU Z5dVdW Z6dXdY Z7dZd[ Z8 fd\d]Z9e:d^d_ Z;d`da Z<dbdc Z=ddddeZ>dfdg Z?dhdi Z@edjdk ZAdldm ZBdndo ZCdpdq ZDedrds ZEdtdu ZFdvdw ZGdddxdyZHdzd{ ZId|d} ZJd~d ZKdd ZLdd ZMdd ZNeOdddZPdd ZQ  ZRS )
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#   ztuple[str, ...]	__slots__Fg      &@Tbool	is_Matrixis_MatrixExprNr   is_Identityr   kindc                 O  s   t t|}tj| f||S r   )mapr   r   __new__)clsargskwargsr#   r#   r$   r2   P   s    
zMatrixExpr.__new__ztuple[Expr, Expr])returnc                 C  s   t d S r   NotImplementedErrorselfr#   r#   r$   shapeV   s    zMatrixExpr.shapec                 C  s   t S r   MatAddr9   r#   r#   r$   _add_handlerZ   s    zMatrixExpr._add_handlerc                 C  s   t S r   MatMulr9   r#   r#   r$   _mul_handler^   s    zMatrixExpr._mul_handlerc                 C  s   t tj|  S r   )r@   r   NegativeOnedoitr9   r#   r#   r$   __neg__b   s    zMatrixExpr.__neg__c                 C  s   t d S r   r7   r9   r#   r#   r$   __abs__e   s    zMatrixExpr.__abs__other__radd__c                 C  s   t | | S r   r=   rC   r:   rF   r#   r#   r$   __add__h   s    zMatrixExpr.__add__rJ   c                 C  s   t ||  S r   rH   rI   r#   r#   r$   rG   m   s    zMatrixExpr.__radd____rsub__c                 C  s   t | |  S r   rH   rI   r#   r#   r$   __sub__r   s    zMatrixExpr.__sub__rL   c                 C  s   t ||   S r   rH   rI   r#   r#   r$   rK   w   s    zMatrixExpr.__rsub____rmul__c                 C  s   t | | S r   r@   rC   rI   r#   r#   r$   __mul__|   s    zMatrixExpr.__mul__c                 C  s   t | | S r   rN   rI   r#   r#   r$   
__matmul__   s    zMatrixExpr.__matmul__rO   c                 C  s   t ||  S r   rN   rI   r#   r#   r$   rM      s    zMatrixExpr.__rmul__c                 C  s   t ||  S r   rN   rI   r#   r#   r$   __rmatmul__   s    zMatrixExpr.__rmatmul____rpow__c                 C  s   t | | S r   )MatPowrC   rI   r#   r#   r$   __pow__   s    zMatrixExpr.__pow__rT   c                 C  s   t dd S )NzMatrix Power not definedr7   rI   r#   r#   r$   rR      s    zMatrixExpr.__rpow____rtruediv__c                 C  s   | |t j  S r   )r   rB   rI   r#   r#   r$   __truediv__   s    zMatrixExpr.__truediv__rV   c                 C  s
   t  d S r   r7   rI   r#   r#   r$   rU      s    zMatrixExpr.__rtruediv__c                 C  s
   | j d S Nr   r;   r9   r#   r#   r$   rows   s    zMatrixExpr.rowsc                 C  s
   | j d S N   rX   r9   r#   r#   r$   cols   s    zMatrixExpr.colszbool | Nonec                 C  s6   | j \}}t|tr&t|tr&||kS ||kr2dS d S NT)r;   
isinstancer   )r:   rY   r\   r#   r#   r$   	is_square   s    
zMatrixExpr.is_squarec                 C  s   ddl m} |t| S Nr   )Adjoint)"sympy.matrices.expressions.adjointra   	Transposer:   ra   r#   r#   r$   _eval_conjugate   s    zMatrixExpr._eval_conjugatec                 K  s   |   S r   )_eval_as_real_imag)r:   deephintsr#   r#   r$   as_real_imag   s    zMatrixExpr.as_real_imagc                 C  s0   t j| |    }| |   dt j  }||fS N   )r   ZHalfre   ZImaginaryUnit)r:   realZimr#   r#   r$   rf      s    zMatrixExpr._eval_as_real_imagc                 C  s   t | S r   Inverser9   r#   r#   r$   _eval_inverse   s    zMatrixExpr._eval_inversec                 C  s   t | S r   Determinantr9   r#   r#   r$   _eval_determinant   s    zMatrixExpr._eval_determinantc                 C  s   t | S r   rc   r9   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.
        rS   )r:   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 qS r#   r#   ).0xr5   rx   r#   r$   
<listcomp>   s     z-MatrixExpr._eval_simplify.<locals>.<listcomp>)Zis_AtomZsympy.simplifyrx   r!   r4   r:   r5   r#   r{   r$   _eval_simplify   s    zMatrixExpr._eval_simplifyc                 C  s   ddl m} || S r`   )rb   ra   rd   r#   r#   r$   _eval_adjoint   s    zMatrixExpr._eval_adjointc                 C  s   t | ||S r   )r   _eval_derivative_n_times)r:   rz   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
ZeroMatrixr;   r:   rz   	__class__r#   r$   r      s    
zMatrixExpr._eval_derivativec                 C  s(   t |ddd}|dkr$td|dS )z2Helper function to check invalid matrix dimensionsT)integerZnonnegativeFz?The dimension specification {} should be a nonnegative integer.N)r
   
ValueErrorformat)r3   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)r8   r   __name__r:   ijr5   r#   r#   r$   _entry   s    
zMatrixExpr._entryc                 C  s   t | S r   )r   r9   r#   r#   r$   r      s    zMatrixExpr.adjointc                 C  s
   t j| fS )z1Efficiently extract the coefficient of a product.)r   One)r:   Zrationalr#   r#   r$   as_coeff_Mul   s    zMatrixExpr.as_coeff_Mulc                 C  s   t | S r   )r   r9   r#   r#   r$   r      s    zMatrixExpr.conjugatec                 C  s   ddl m} || S )Nr   	transpose)Z$sympy.matrices.expressions.transposer   )r:   r   r#   r#   r$   r      s    zMatrixExpr.transposec                 C  s   |   S )zMatrix transpositionr   r9   r#   r#   r$   T  s    zMatrixExpr.Tc                 C  s   | j dkrtd|  S )NFzInverse of non-square matrix)r_   r   ro   r9   r#   r#   r$   inverse	  s    
zMatrixExpr.inversec                 C  s   |   S r   r   r9   r#   r#   r$   inv  s    zMatrixExpr.invc                 C  s   ddl m} || S )Nr   )det)Z&sympy.matrices.expressions.determinantr   )r:   r   r#   r#   r$   r     s    zMatrixExpr.detc                 C  s   |   S r   r   r9   r#   r#   r$   I  s    zMatrixExpr.Ic                 C  s^   dd }||o\||o\| j d k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   )r^   intr   r   r   )idxr#   r#   r$   is_valid  s    z(MatrixExpr.valid_index.<locals>.is_validF)rY   r\   )r:   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   Nr[   rk   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   r;   r   r   r   )r:   keyr   r   r   rY   r\   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^   rY   r   r   r\   r9   r#   r#   r$   _is_shape_symbolicD  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#   ry   r   )r   r:   r#   r$   r|   e  s   z5MatrixExpr.as_explicit.<locals>.<listcomp>.<listcomp>)ranger\   )ry   r9   )r   r$   r|   e  s   z*MatrixExpr.as_explicit.<locals>.<listcomp>)r   r   sympy.matrices.immutabler   r   rY   )r:   r   r#   r9   r$   as_explicitH  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_mutabler9   r#   r#   r$   r   i  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)Zdtype)numpyr   r;   objectr   rY   r\   )r:   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   equalsrI   r#   r#   r$   r     s    	zMatrixExpr.equalsc                 C  s   | S r   r#   r9   r#   r#   r$   canonicalize  s    zMatrixExpr.canonicalizec                 C  s   t jt| fS r   )r   r   r@   r9   r#   r#   r$   as_coeff_mmul  s    zMatrixExpr.as_coeff_mmulc                 C  sT   ddl m} ddlm} g }|dk	r.|| |dk	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)Z4sympy.tensor.array.expressions.from_indexed_to_arrayr   3sympy.tensor.array.expressions.from_array_to_matrixr   append)exprZfirst_index
last_index
dimensionsr   r   r   Zarrr#   r#   r$   from_index_summation  s    *

zMatrixExpr.from_index_summationc                 C  s   ddl m} ||| S )Nr[   )ElementwiseApplyFunction)	applyfuncr   )r:   r!   r   r#   r#   r$   r     s    zMatrixExpr.applyfunc)T)F)NNN)Sr   
__module____qualname____doc__r+   __annotations__	_iterableZ_op_priorityr-   r.   r/   Z
is_InverseZis_Transposeis_ZeroMatrixZ	is_MatAddZ	is_MatMulis_commutativeZ	is_number	is_symbolZ	is_scalarr   r0   r2   propertyr;   r>   rA   rD   rE   r)   NotImplementedr   rJ   rG   rL   rK   rO   rP   rM   rQ   rT   rR   rV   rU   rY   r\   r_   re   ri   rf   ro   rr   rt   rw   r~   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r   r   r   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)r;   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 | |f| jddS )NF)rg   )r   r@   r	   r=   r4   r^   r*   r   Z
_from_argsr   r   r.   rO   rC   )r   Z	mat_classZnonmatricesZmatricestermr   r3   r#   r$   _postprocessor  s(    



z)get_postprocessor.<locals>._postprocessorr#   )r3   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.from_matrix_to_arrayr   Z4sympy.tensor.array.expressions.arrayexpr_derivativesr   r   r   )	r   rz   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ry   r   r#   r#   r$   r|   #  s     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$   r|   '  s     z?_matrix_derivative_old_algorithm.<locals>.<listcomp>.<listcomp>r#   r   r   r#   r$   r|   '  s     c                 S  s   t | tr| jS dS )Nr[   r[   r^   r*   r;   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 kqqS ))r[   Nr#   )ry   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                   s   g | ]} |qS r#   r#   r   )r   r#   r$   r|   1  s     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 )Nr[   r   rk    )r   r-   r   Identityr   r   fromiter)r   p1p2Zpbaser#   r#   r$   contract_one_dims4  s    z;_matrix_derivative_old_algorithm.<locals>.contract_one_dimsrk   c                   s   g | ]} |qS r#   r#   r   )r   r#   r$   r|   I  s     )Z$sympy.tensor.array.array_derivativesr   _eval_derivative_matrix_linesr   r   r	   r   )r   rz   r   linesr   Z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 rW   r4   r9   r#   r#   r$   <lambda>O      zMatrixElement.<lambda>c                 C  s
   | j d S rZ   r   r9   r#   r#   r$   r   P  r   c                 C  s
   | j d S rj   r   r9   r#   r#   r$   r   Q  r   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 r]   r#   )r   mr#   r#   r$   r   d  r   z'MatrixElement.__new__.<locals>.<lambda>zindices out of range)r1   r   sympy.matrices.matricesr   r^   strr   Z
is_Integerr0   r   	TypeErrorgetattrr   r   r2   )r3   namer   r   r   objr#   r#   r$   r2   V  s    



zMatrixElement.__new__c                 C  s
   | j d S rW   r   r9   r#   r#   r$   symboli  s    zMatrixElement.symbolc                   sD     dd}|r& fdd| jD }n| j}|d |d |d f S )Nrg   Tc                   s   g | ]}|j f  qS r#   )rC   )ry   r(   rh   r#   r$   r|   p  s     z&MatrixElement.doit.<locals>.<listcomp>r   r[   rk   )getr4   )r:   rh   rg   r4   r#   r   r$   rC   m  s
    zMatrixElement.doitc                 C  s   | j dd  S rZ   r   r9   r#   r#   r$   indicesu  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   r[   rk   )Sumzz1, z2r   )r^   r   r   r   parentdiffr   r   r   Zeror4   r;   r   rn   Zsympy.concrete.summationsr  r   r   r   )r:   vr   Mr   r   r  r   r   i1i2Yr1r2r#   r#   r$   r   y  s*    



HzMatrixElement._eval_derivativeN)r   r   r   r   r  r   r   	_diff_wrtr   r   r2   r   rC   r  r   r#   r#   r#   r$   r   N  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   r2   )r3   r   r   r   r   r#   r#   r$   r2     s    


zMatrixSymbol.__new__c                 C  s   | j d | j d fS )Nr[   rk   r   r9   r#   r#   r$   r;     s    zMatrixSymbol.shapec                 C  s   | j d jS rW   )r4   r   r9   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#   r9   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   r[   )r   r;   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  )r;   r   r   r  _LeftRightArgsr   r   )r:   rz   firstsecondr#   r#   r$   r     s    **""z*MatrixSymbol._eval_derivative_matrix_linesN)r   r   r   r   r   r   r  r2   r   r;   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-   )ry   symr#   r#   r$   r|     s      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  s<   t || _| j| _d| _d| _| j| _d| _d| _|| _d S r  )	list_lines_first_pointer_parent_first_pointer_index_first_line_index_second_pointer_parent_second_pointer_index_second_line_indexhigher)r:   r   r   r#   r#   r$   __init__  s    
z_LeftRightArgs.__init__c                 C  s   | j | j S r   r  r  r9   r#   r#   r$   first_pointer  s    z_LeftRightArgs.first_pointerc                 C  s   || j | j< d S r   r"  r:   valuer#   r#   r$   r#    s    c                 C  s   | j | j S r   r  r  r9   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   r9   r#   r$   r|   	  s     z+_LeftRightArgs.__repr__.<locals>.<listcomp>z#_LeftRightArgs(lines=%s, higher=%s))r  r   )r:   Zbuiltr#   r9   r$   __repr__  s
    z_LeftRightArgs.__repr__c                 C  s:   | j | j | _| _ | j| j | _| _| j| j | _| _| S r   )r  r  r  r  r  r  r9   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 )Nr[   r   c                 S  s   g | ]}t |qS r#   )r  r)  r   r#   r#   r$   r|     s     z)_LeftRightArgs._build.<locals>.<listcomp>)r^   r   r   r  r   r  r#   r#   r$   r)    s    

z_LeftRightArgs._buildc                   s<    fdd j D } jdkr0|  jg7 }t|}|S )Nc                   s   g | ]}  |qS r#   r(  r   r9   r#   r$   r|   "  s     z(_LeftRightArgs.build.<locals>.<listcomp>r[   )r  r   r)  r  )r:   datar#   r9   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 )Nr[   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  r   r   r  r   )r:   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   r[   c                 S  s   g | ]}|d kqS r[   r#   r   r#   r#   r$   r|   E  s     z'_LeftRightArgs.rank.<locals>.<listcomp>c                 S  s   g | ]}|d kqS r-  r#   r   r#   r#   r$   r|   G  s     rk   )r  r   r;   r  r   )r:   r   r#   r#   r$   r   >  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)r[   rk   )	validator)Z*tensor.array.expressions.array_expressionsr/  r0  r   	_validate)r:   ZpointerrF   r/  r0  Zsubexprr#   r#   r$   _multiply_pointerL  s    
z _LeftRightArgs._multiply_pointerc                 C  s   |  j |9  _ d S r   )r#  rI   r#   r#   r$   append_firsta  s    z_LeftRightArgs.append_firstc                 C  s   |  j |9  _ d S r   )r'  rI   r#   r#   r$   append_secondd  s    z_LeftRightArgs.append_secondN)r   r   r   r   r   r   r!  r   r#  setterr'  r*  r   r   r)  r   r,  r   r3  r4  r5  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*   )rz   r   r#   r#   r$   _make_matrixh  s    
r7  r[   r?   r<   ru   rs   rm   )r   r   rp   )N)F)F
__future__r   	functoolsr   Z
sympy.corer   r   r   r   r	   Zsympy.core.assumptionsr
   Zsympy.core.decoratorsr   Zsympy.core.exprr   r   Zsympy.core.logicr   Zsympy.core.symbolr   r   r   r   Zsympy.core.sympifyr   r   Zsympy.external.gmpyr   Zsympy.functionsr   r   Z(sympy.functions.special.tensor_functionsr   Zsympy.matrices.commonr   r   r   r   Zsympy.multipledispatchr   Zsympy.utilities.miscr   r)   r*   r   r   Z"_constructor_postprocessor_mappingr   r   r   r  r  r  r7  matmulr@   Zmataddr=   ZmatpowrS   r   rc   r   rn   specialr   r   Zdeterminantrq   r#   r#   r#   r$   <module>   sV   
   3

(
/IE 	