o
    ohk                     @  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% d dl&m'Z' d dl(m)Z) d dl*m+Z+ d4d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-< d5d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,d0l>m?Z? d,d1l@mAZA d,d2lBmCZCmDZD d,d3lEmFZF dS )6    )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                   s,   z
t |} | |W S  ty    Y S w N)r   r   )ab)funcretval v/var/www/html/construction_image-detection-poc/venv/lib/python3.10/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                      sN  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dd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ddFdGZ.dHdI Z/ddJdKZ0dLdM Z1dNdO Z2dPdQ Z3dRdS Z4dTdU Z5dVdW Z6dXdY Z7dZd[ Z8d\d] Z9 fd^d_Z:e;d`da Z<dbdc Z=ddde Z>ddfdgZ?dhdi Z@djdk ZAedldm ZBdndo ZCdpdq ZDdrds ZEedtdu ZFdvdw ZGdxdy ZHddzd{ZId|d} ZJd~d ZKeLdfddZMdd ZNdd ZOdd ZPeQdddZRdd ZS  ZTS )
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| g|R i |S r   )mapr   r   __new__)clsargskwargsr#   r#   r$   r2   Q   s   
zMatrixExpr.__new__returntuple[Expr, Expr]c                 C     t r   NotImplementedErrorselfr#   r#   r$   shapeW      zMatrixExpr.shapec                 C     t S r   MatAddr;   r#   r#   r$   _add_handler[   r>   zMatrixExpr._add_handlerc                 C  r?   r   MatMulr;   r#   r#   r$   _mul_handler_   r>   zMatrixExpr._mul_handlerc                 C  s   t tj|  S r   )rD   r   NegativeOnedoitr;   r#   r#   r$   __neg__c      zMatrixExpr.__neg__c                 C  r8   r   r9   r;   r#   r#   r$   __abs__f      zMatrixExpr.__abs__other__radd__c                 C     t | | S r   rA   rG   r<   rL   r#   r#   r$   __add__i      zMatrixExpr.__add__rQ   c                 C     t ||  S r   rO   rP   r#   r#   r$   rM   n   rR   zMatrixExpr.__radd____rsub__c                 C  s   t | |  S r   rO   rP   r#   r#   r$   __sub__s      zMatrixExpr.__sub__rU   c                 C  s   t ||   S r   rO   rP   r#   r#   r$   rT   x   rV   zMatrixExpr.__rsub____rmul__c                 C  rN   r   rD   rG   rP   r#   r#   r$   __mul__}   rR   zMatrixExpr.__mul__c                 C  rN   r   rX   rP   r#   r#   r$   
__matmul__   rR   zMatrixExpr.__matmul__rY   c                 C  rS   r   rX   rP   r#   r#   r$   rW      rR   zMatrixExpr.__rmul__c                 C  rS   r   rX   rP   r#   r#   r$   __rmatmul__   rR   zMatrixExpr.__rmatmul____rpow__c                 C  rN   r   )MatPowrG   rP   r#   r#   r$   __pow__   rR   zMatrixExpr.__pow__r^   c                 C  s   t d)NzMatrix Power not definedr9   rP   r#   r#   r$   r\         zMatrixExpr.__rpow____rtruediv__c                 C  s   | |t j  S r   )r   rF   rP   r#   r#   r$   __truediv__   rR   zMatrixExpr.__truediv__ra   c                 C  s   t  r   r9   rP   r#   r#   r$   r`      s   zMatrixExpr.__rtruediv__c                 C  
   | j d S Nr   r=   r;   r#   r#   r$   rows      
zMatrixExpr.rowsc                 C  rb   N   rd   r;   r#   r#   r$   cols   rf   zMatrixExpr.colsbool | Nonec                 C  s6   | j \}}t|trt|tr||kS ||krdS d S NT)r=   
isinstancer   )r<   re   ri   r#   r#   r$   	is_square   s   
zMatrixExpr.is_squarec                 C  s   ddl m} |t| S Nr   )Adjoint)"sympy.matrices.expressions.adjointro   	Transposer<   ro   r#   r#   r$   _eval_conjugate   s   zMatrixExpr._eval_conjugatec                 K     |   S r   )_eval_as_real_imag)r<   deephintsr#   r#   r$   as_real_imag      zMatrixExpr.as_real_imagc                 C  s0   t j| |    }| |   dt j  }||fS N   )r   Halfrs   ImaginaryUnit)r<   realimr#   r#   r$   ru      s   zMatrixExpr._eval_as_real_imagc                 C     t | S r   Inverser;   r#   r#   r$   _eval_inverse   ry   zMatrixExpr._eval_inversec                 C  r   r   Determinantr;   r#   r#   r$   _eval_determinant   ry   zMatrixExpr._eval_determinantc                 C  r   r   rq   r;   r#   r#   r$   _eval_transpose   ry   zMatrixExpr._eval_transposec                 C  s   d S r   r#   r;   r#   r#   r$   _eval_trace   rK   zMatrixExpr._eval_tracec                 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.
        r]   )r<   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r5   r   r#   r$   
<listcomp>       z-MatrixExpr._eval_simplify.<locals>.<listcomp>)is_Atomsympy.simplifyr   r!   r4   r<   r5   r#   r   r$   _eval_simplify   s   zMatrixExpr._eval_simplifyc                 C     ddl m} || S rn   )rp   ro   rr   r#   r#   r$   _eval_adjoint      zMatrixExpr._eval_adjointc                 C  s   t | ||S r   )r   _eval_derivative_n_times)r<   r   nr#   r#   r$   r         z#MatrixExpr._eval_derivative_n_timesc                   s    |  |rt |S t| j S r   )hassuper_eval_derivative
ZeroMatrixr=   r<   r   	__class__r#   r$   r      s   

zMatrixExpr._eval_derivativec                 C  s0   |j  o
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)is_Floatr
   
ValueErrorformat)r3   dimokr#   r#   r$   
_check_dim   s   
zMatrixExpr._check_dimc                 K  s   t d| jj )NzIndexing not implemented for %s)r:   r   __name__r<   ijr5   r#   r#   r$   _entry   s   
zMatrixExpr._entryc                 C  r   r   )r   r;   r#   r#   r$   r      ry   zMatrixExpr.adjointc                 C  s
   t j| fS )z1Efficiently extract the coefficient of a product.)r   One)r<   rationalr#   r#   r$   as_coeff_Mul   rf   zMatrixExpr.as_coeff_Mulc                 C  r   r   )r   r;   r#   r#   r$   r     ry   zMatrixExpr.conjugatec                 C  r   )Nr   	transpose)$sympy.matrices.expressions.transposer   )r<   r   r#   r#   r$   r     r   zMatrixExpr.transposec                 C  rt   )zMatrix transpositionr   r;   r#   r#   r$   T	  r_   zMatrixExpr.Tc                 C  s   | j du r	td|  S )NFzInverse of non-square matrix)rm   r   r   r;   r#   r#   r$   inverse  s   
zMatrixExpr.inversec                 C  rt   r   r   r;   r#   r#   r$   inv  ry   zMatrixExpr.invc                 C  r   )Nr   )det)&sympy.matrices.expressions.determinantr   )r<   r   r#   r#   r$   r     r   zMatrixExpr.detc                 C  rt   r   r   r;   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   )rl   intr   r   r   )idxr#   r#   r$   is_valid     z(MatrixExpr.valid_index.<locals>.is_validF)re   ri   )r<   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   Nrh   r{   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])rl   tupleslice sympy.matrices.expressions.slicer   lenr   r   r   
IndexErrorr   r   r=   r   r   r   )r<   keyr   r   r   re   ri   r#   r#   r$   __getitem__&  s2   

zMatrixExpr.__getitem__c                 C  s$   t | jttf pt | jttf S r   )rl   re   r   r   ri   r;   r#   r#   r$   _is_shape_symbolicI  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   r<   r#   r$   r   j  s    z5MatrixExpr.as_explicit.<locals>.<listcomp>.<listcomp>)rangeri   )r   r;   )r   r$   r   j  s
    
z*MatrixExpr.as_explicit.<locals>.<listcomp>)r   r   sympy.matrices.immutabler   r   re   )r<   r   r#   r;   r$   as_explicitM  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_mutabler;   r#   r#   r$   r   n  s   zMatrixExpr.as_mutablec                 C  sf   |d ur
|s
t dddlm} || jtd}t| jD ]}t| jD ]}| ||f |||f< q#q|S )Nz=Cannot implement copy=False when converting Matrix to ndarrayr   )empty)dtype)	TypeErrornumpyr   r=   objectr   re   ri   )r<   r   copyr   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   equalsrP   r#   r#   r$   r     s   	zMatrixExpr.equalsc                 C     | S r   r#   r;   r#   r#   r$   canonicalize  rK   zMatrixExpr.canonicalizec                 C  s   t jt| fS r   )r   r   rD   r;   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.from_indexed_to_arrayr   3sympy.tensor.array.expressions.from_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 )Nrh   )ElementwiseApplyFunction)	applyfuncr   )r<   r!   r   r#   r#   r$   r     s   
zMatrixExpr.applyfunc)r6   r7   )r6   rj   )TF)r6   r,   )NNN)Ur   
__module____qualname____doc__r+   __annotations__	_iterable_op_priorityr-   r.   r/   
is_Inverseis_Transposeis_ZeroMatrix	is_MatAdd	is_MatMulis_commutative	is_number	is_symbol	is_scalarr   r0   r2   propertyr=   rB   rE   rH   rJ   r)   NotImplementedr   rQ   rM   rU   rT   rY   rZ   rW   r[   r^   r\   ra   r`   re   ri   rm   rs   rx   ru   r   r   r   r   r   r   r   r   r   classmethodr   r   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     dS )NFr#   lhsrhsr#   r#   r$   _eval_is_eq  r>   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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)rv   )r   rD   r	   rA   r4   rl   r*   r   
_from_argsr   r   r.   rY   rG   )r   	mat_classnonmatrices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   )	rl   r    _matrix_derivative_old_algorithm3sympy.tensor.array.expressions.from_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rh   rh   rl   r*   r=   elemr#   r#   r$   
_get_shape0     
z4_matrix_derivative_old_algorithm.<locals>._get_shapec                   s   t  fdd| D S )Nc                 3  s&    | ]} |D ]}|d vV  qqdS )rh   NNr#   )r   r   r   r#  r#   r$   	<genexpr>6  s   $ zE_matrix_derivative_old_algorithm.<locals>.get_rank.<locals>.<genexpr>)sum)partsr&  r#   r$   get_rank5  s   z2_matrix_derivative_old_algorithm.<locals>.get_rankc                   r  r#   r#   r  )r*  r#   r$   r   8  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 )Nrh   r   r{    )r   r-   r   Identityr   r   fromiter)r)  p1p2pbaser#   r#   r$   contract_one_dims;  s   z;_matrix_derivative_old_algorithm.<locals>.contract_one_dimsr{   c                   r  r#   r#   r  )r1  r#   r$   r   P  r  )$sympy.tensor.array.array_derivativesr  _eval_derivative_matrix_linesr   r   r	   r-  )r   r   r  linesr)  ranksrankr#   )r#  r1  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  rb   rc   r4   r;   r#   r#   r$   <lambda>V     
 zMatrixElement.<lambda>c                 C  rb   rg   r8  r;   r#   r#   r$   r9  W  r:  c                 C  rb   rz   r8  r;   r#   r#   r$   r9  X  r:  Tc                 C  s   t t||f\}}t|trt|}n3t|tr)|jr$|jr$|||f S t|}nt|}t|jts7t	dt
|ddd ||sFtdt| |||}|S )Nz2First argument of MatrixElement should be a matrixr   c                 S  r  rk   r#   )r   mr#   r#   r$   r9  j  s    z'MatrixElement.__new__.<locals>.<lambda>zindices out of range)r1   r   rl   strr   r   
is_Integerr0   r   r   getattrr   r   r2   r3   namer   r;  objr#   r#   r$   r2   ]  s   



zMatrixElement.__new__c                 C  rb   rc   r8  r;   r#   r#   r$   symbolo  rf   zMatrixElement.symbolc                   sD     dd}|r fdd| jD }n| j}|d |d |d f S )Nrv   Tc                   s   g | ]
}|j d i  qS )r#   )rG   )r   r(   rw   r#   r$   r   v  r   z&MatrixElement.doit.<locals>.<listcomp>r   rh   r{   )getr4   )r<   rw   rv   r4   r#   rC  r$   rG   s  s
   zMatrixElement.doitc                 C  s   | j dd  S rg   r8  r;   r#   r#   r$   indices{  s   zMatrixElement.indicesc                 C  s4  t |ts| j|| j| jf S | jd }| jj\}}||jd krCt| 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   rh   r{   )Sumzz1, z2r  )rl   r7  parentdiffr   r   r4   r=   r   r   sympy.concrete.summationsrF  r   r   r   r   Zero)r<   vMr;  r   rF  r   r   i1i2Yr1r2r#   r#   r$   r     s$   




HzMatrixElement._eval_derivativeN)r   r   r   r   rG  r   r   	_diff_wrtr   r   r2   rB  rG   rE  r   r#   r#   r#   r$   r7  U  s    

r7  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   rl   r<  r   r   r2   r?  r#   r#   r$   r2     s   


zMatrixSymbol.__new__c                 C  s   | j d | j d fS )Nrh   r{   r8  r;   r#   r#   r$   r=     s   zMatrixSymbol.shapec                 C  s   | j d jS rc   )r4   r@  r;   r#   r#   r$   r@       zMatrixSymbol.namec                 K  s   t | ||S r   )r7  r   r#   r#   r$   r     s   zMatrixSymbol._entryc                 C  s   | hS r   r#   r;   r#   r#   r$   free_symbols  s   zMatrixSymbol.free_symbolsc                 K  r   r   r#   r   r#   r#   r$   r     rK   zMatrixSymbol._eval_simplifyc                 C  s   t | jd | jd S Nr   rh   )r   r=   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 rV  )r=   r   r   rJ  _LeftRightArgsr,  r   )r<   r   firstsecondr#   r#   r$   r3    s   **""z*MatrixSymbol._eval_derivative_matrix_linesN)r   r   r   r   r   r   rR  r2   r   r=   r@  r   rU  r   r   r3  r#   r#   r#   r$   rS    s     


rS  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>)rU  r   r#   r#   r$   matrix_symbols  rI   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 )rW  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 rV  )	list_lines_first_pointer_parent_first_pointer_index_first_line_index_second_pointer_parent_second_pointer_index_second_line_indexhigher)r<   r4  rf  r#   r#   r$   __init__  s   

z_LeftRightArgs.__init__c                 C     | j | j S r   r`  ra  r;   r#   r#   r$   first_pointer  rT  z_LeftRightArgs.first_pointerc                 C     || j | j< d S r   ri  r<   valuer#   r#   r$   rj       c                 C  rh  r   rc  rd  r;   r#   r#   r$   second_pointer  rT  z_LeftRightArgs.second_pointerc                 C  rk  r   ro  rl  r#   r#   r$   rp    rn  c                   s"    fdd j D }d| jf S )Nc                      g | ]}  |qS r#   _buildr  r;   r#   r$   r     r[  z+_LeftRightArgs.__repr__.<locals>.<listcomp>z#_LeftRightArgs(lines=%s, higher=%s))r_  rf  )r<   builtr#   r;   r$   __repr__  s
   z_LeftRightArgs.__repr__c                 C  s:   | j | j| _| _ | j| j| _| _| j| j| _| _| S r   )rc  r`  rd  ra  re  rb  r;   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 )Nrh   r   c                 S  s   g | ]}t |qS r#   )rW  rs  r  r#   r#   r$   r      r[  z)_LeftRightArgs._build.<locals>.<listcomp>)rl   r   r  r^  r   r\  r#   r#   r$   rs    s   

z_LeftRightArgs._buildc                   s<    fdd j D } jdkr|  jg7 }t|}|S )Nc                   rq  r#   rr  r  r;   r#   r$   r   %  r[  z(_LeftRightArgs.build.<locals>.<listcomp>rh   )r_  rf  rs  r^  )r<   datar#   r;   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 )Nrh   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)rX  rf  r   rY  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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   rh   c                 s      | ]}|d kV  qdS r%  r#   r  r#   r#   r$   r'  H      z&_LeftRightArgs.rank.<locals>.<genexpr>c                 s  rx  r%  r#   r  r#   r#   r$   r'  J  ry  r{   )rX  r(  r=   rY  rf  )r<   r6  r#   r#   r$   r6  A  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)rh   r{   )	validator)*tensor.array.expressions.array_expressionsr{  r|  r   	_validate)r<   pointerrL   r{  r|  subexprr#   r#   r$   _multiply_pointerO  s   
z _LeftRightArgs._multiply_pointerc                 C     |  j |9  _ d S r   )rj  rP   r#   r#   r$   append_firstd  r   z_LeftRightArgs.append_firstc                 C  r  r   )rp  rP   r#   r#   r$   append_secondg  r   z_LeftRightArgs.append_secondN)r   r   r   r   r   r   rg  r   rj  setterrp  ru  r   r   rs  r  rw  r6  r  r  r  r#   r#   r#   r$   rW    s*    





rW  c                 C  s&   ddl m} t| tr| S || ggS )Nr   r   )r   r   rl   r*   )r   r   r#   r#   r$   _make_matrixk  s   
r  rh   rC   r@   r   r   r   )r   r,  r   r   r   )G
__future__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.exceptionsr   sympy.matrices.kindr   sympy.matrices.matrixbaser   sympy.multipledispatchr   sympy.utilities.miscr   r)   r*   r  r  "_constructor_postprocessor_mappingr  r  r7  rS  r]  rW  r  matmulrD   mataddrA   matpowr]   r   rq   r   r   specialr   r,  determinantr   r#   r#   r#   r$   <module>   sZ    
   9

(
/EE 	