a
    <b/i                     @   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+ d dl,m-Z- d4ddZ.G dd deZ/e)e/edd Z0e)e/e/dd Z0dd Z1e1e	ge1e
gdej2e/< d5ddZ3d d! Z4G d"d# d#eZ5G d$d% d%e/Z6d&d' Z7G d(d) d)Z8d*d+ Z9d,d-l:m;Z; d,d.l<m=Z= d,d/l>m?Z? d,d0l@mAZA d,d1lBmCZC d,d2lDmEZEmFZF d,d3lGmHZH dS )6    )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simplify)
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 r/Users/vegardjervell/Documents/master/model/venv/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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.d/d0 Z*edee d1d2d3 Z+edee d4d5d6 Z,ed7d8 Z-ed9d: Z.ed;d< Z/d=d> Z0d}d?d@Z1dAdB Z2dCdD Z3dEdF Z4dGdH Z5dIdJ Z6dKdL Z7dMdN Z8 fdOdPZ9e:dQdR Z;dSdT Z<dUdV Z=d~dWdXZ>dYdZ Z?d[d\ Z@ed]d^ ZAd_d` ZBdadb ZCdcdd ZDededf ZEdgdh ZFdidj ZGeHd	dkdlZIdmdn ZJdodp ZKdqdr ZLdsdt ZMdudv ZNdwdx ZOePddydzZQd{d| ZR  ZSS )
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
    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    MatAddr6   r%   r%   r&   _add_handlerZ   s    zMatrixExpr._add_handlerc                 C   s   t S r    MatMulr6   r%   r%   r&   _mul_handler^   s    zMatrixExpr._mul_handlerc                 C   s   t tj|  S r    )r=   r   NegativeOnedoitr6   r%   r%   r&   __neg__b   s    zMatrixExpr.__neg__c                 C   s   t d S r    r4   r6   r%   r%   r&   __abs__e   s    zMatrixExpr.__abs__other__radd__c                 C   s   t | |dd S NT)checkr:   r@   r7   rC   r%   r%   r&   __add__h   s    zMatrixExpr.__add__rI   c                 C   s   t || dd S rE   rG   rH   r%   r%   r&   rD   m   s    zMatrixExpr.__radd____rsub__c                 C   s   t | | dd S rE   rG   rH   r%   r%   r&   __sub__r   s    zMatrixExpr.__sub__rK   c                 C   s   t ||  dd S rE   rG   rH   r%   r%   r&   rJ   w   s    zMatrixExpr.__rsub____rmul__c                 C   s   t | | S r    r=   r@   rH   r%   r%   r&   __mul__|   s    zMatrixExpr.__mul__c                 C   s   t | | S r    rM   rH   r%   r%   r&   
__matmul__   s    zMatrixExpr.__matmul__rN   c                 C   s   t ||  S r    rM   rH   r%   r%   r&   rL      s    zMatrixExpr.__rmul__c                 C   s   t ||  S r    rM   rH   r%   r%   r&   __rmatmul__   s    zMatrixExpr.__rmatmul____rpow__c                 C   s   t | | S r    )MatPowr@   rH   r%   r%   r&   __pow__   s    zMatrixExpr.__pow__rS   c                 C   s   t dd S )NzMatrix Power not definedr4   rH   r%   r%   r&   rQ      s    zMatrixExpr.__rpow____rtruediv__c                 C   s   | |t j  S r    )r   r?   rH   r%   r%   r&   __truediv__   s    zMatrixExpr.__truediv__rU   c                 C   s
   t  d S r    r4   rH   r%   r%   r&   rT      s    zMatrixExpr.__rtruediv__c                 C   s
   | j d S Nr   r8   r6   r%   r%   r&   rows   s    zMatrixExpr.rowsc                 C   s
   | j d S N   rW   r6   r%   r%   r&   cols   s    zMatrixExpr.colsc                 C   s   | j | jkS r    rX   r[   r6   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r7   r_   r%   r%   r&   _eval_conjugate   s    zMatrixExpr._eval_conjugatec                 K   s0   t j| |    }| |   dt j  }||fS N   )r   ZHalfrc   ZImaginaryUnit)r7   deephintsrealZimr%   r%   r&   as_real_imag   s    zMatrixExpr.as_real_imagc                 C   s   t | S r    Inverser6   r%   r%   r&   _eval_inverse   s    zMatrixExpr._eval_inversec                 C   s   t | S r    Determinantr6   r%   r%   r&   _eval_determinant   s    zMatrixExpr._eval_determinantc                 C   s   t | S r    ra   r6   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.
        rR   )r7   expr%   r%   r&   _eval_power   s    zMatrixExpr._eval_powerc                    s(   | j r
| S | j fdd| jD  S d S )Nc                    s   g | ]}t |fi  qS r%   r   ).0xr2   r%   r&   
<listcomp>       z-MatrixExpr._eval_simplify.<locals>.<listcomp>)Zis_Atomr#   r1   r7   r2   r%   rw   r&   _eval_simplify   s    zMatrixExpr._eval_simplifyc                 C   s   ddl m} || S r^   )r`   r_   rb   r%   r%   r&   _eval_adjoint   s    zMatrixExpr._eval_adjointc                 C   s   t | ||S r    )r   _eval_derivative_n_times)r7   rv   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
ZeroMatrixr8   r7   rv   	__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)integerZnonnegativeFz?The dimension specification {} should be a nonnegative integer.N)r
   
ValueErrorformat)r0   Z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)r5   r   __name__r7   ijr2   r%   r%   r&   _entry   s    
zMatrixExpr._entryc                 C   s   t | S r    )r   r6   r%   r%   r&   r      s    zMatrixExpr.adjointc                 C   s
   t j| fS )z2Efficiently extract the coefficient of a product. )r   One)r7   Zrationalr%   r%   r&   as_coeff_Mul   s    zMatrixExpr.as_coeff_Mulc                 C   s   t | S r    )r   r6   r%   r%   r&   r      s    zMatrixExpr.conjugatec                 C   s   ddl m} || S )Nr   	transpose)Z$sympy.matrices.expressions.transposer   )r7   r   r%   r%   r&   r      s    zMatrixExpr.transposec                 C   s   |   S )zMatrix transpositionr   r6   r%   r%   r&   T   s    zMatrixExpr.Tc                 C   s   | j std|  S )NzInverse of non-square matrix)r]   r   rl   r6   r%   r%   r&   inverse   s    zMatrixExpr.inversec                 C   s   |   S r    r   r6   r%   r%   r&   inv  s    zMatrixExpr.invc                 C   s   ddl m} || S )Nr   )det)Z&sympy.matrices.expressions.determinantr   )r7   r   r%   r%   r&   r     s    zMatrixExpr.detc                 C   s   |   S r    r   r6   r%   r%   r&   I  s    zMatrixExpr.Ic                 C   sV   dd }||oT||oT| j d u s<d|kdkoT|| j k dkoTd|kdkoT|| 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_validr   Fr\   )r7   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   NrZ   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   r8   r   r   r   )r7   keyr   r   r   rX   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   rX   r   r   r[   r6   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%   ru   r   )r   r7   r%   r&   rx   \  s   z5MatrixExpr.as_explicit.<locals>.<listcomp>.<listcomp>)ranger[   )ru   r6   )r   r&   rx   \  s   z*MatrixExpr.as_explicit.<locals>.<listcomp>)r   r   sympy.matrices.immutabler   r   rX   )r7   r   r%   r6   r&   as_explicit?  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_mutabler6   r%   r%   r&   r   `  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)Znumpyr   r8   objectr   rX   r[   )r7   r   r!   r   r   r%   r%   r&   	__array__y  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   equalsrH   r%   r%   r&   r     s    	zMatrixExpr.equalsc                 C   s   | S r    r%   r6   r%   r%   r&   canonicalize  s    zMatrixExpr.canonicalizec                 C   s   dt | fS rY   r<   r6   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)Z4sympy.tensor.array.expressions.conv_indexed_to_arrayr   3sympy.tensor.array.expressions.conv_array_to_matrixr   append)exprZfirst_index
last_indexZ
dimensionsr   r   r   Zarrr%   r%   r&   from_index_summation  s    *

zMatrixExpr.from_index_summationc                 C   s   ddl m} ||| S )NrZ   )ElementwiseApplyFunction)	applyfuncr   )r7   r#   r   r%   r%   r&   r     s    zMatrixExpr.applyfunc)T)F)NNN)Tr   
__module____qualname____doc__Z	_iterableZ_op_priority	is_Matrixis_MatrixExprZis_IdentityZ
is_InverseZis_Transposeis_ZeroMatrixZ	is_MatAddZ	is_MatMulis_commutativeZ	is_number	is_symbolZ	is_scalarr   r-   __annotations__r/   propertytTupler   r8   r;   r>   rA   rB   r+   NotImplementedr   rI   rD   rK   rJ   rN   rO   rL   rP   rS   rQ   rU   rT   rX   r[   r]   rc   ri   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)r8   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)rf   )r   r=   r	   r:   r1   r   r,   r   Z
_from_argsr   r   r   rN   r@   )r   Z	mat_classZnonmatricesZmatricesZtermr   r0   r%   r&   _postprocessor  s(    



z)get_postprocessor.<locals>._postprocessorr%   )r0   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   rv   Zold_algorithmr   r   r   Z
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ru   r   r%   r%   r&   rx     ry   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&   rx     ry   z?_matrix_derivative_old_algorithm.<locals>.<listcomp>.<listcomp>r%   r   r   r%   r&   rx     ry   c                 S   s   t | tr| jS dS )NrZ   rZ   r   r,   r8   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 ))rZ   Nr%   )ru   r   r   r   r%   r&   rx   &  ry   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&   rx   (  ry   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 )NrZ   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&   rx   @  ry   )Z$sympy.tensor.array.array_derivativesr   _eval_derivative_matrix_linesr   r   r	   r   )r   rv   r   linesr   Zranksrankr%   )r   r   r   r   r&   r     s    
r   c                   @   s`   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
dd	 Zed
d Zdd ZdS )MatrixElementc                 C   s
   | j d S rV   r1   r6   r%   r%   r&   <lambda>F  ry   zMatrixElement.<lambda>c                 C   s
   | j d S rY   r   r6   r%   r%   r&   r   G  ry   c                 C   s
   | j d S rd   r   r6   r%   r%   r&   r   H  ry   Tc                 C   s   t t||f\}}ddlm} t||frB|jrB|jrB|||f S t|trVt|}nt|}t|jt	srt
dt| |||}|S )Nr   r   z2First argument of MatrixElement should be a matrix)r.   r   sympy.matrices.matricesr   r   Z
is_Integerstrr   r-   r   	TypeErrorr   r/   )r0   namer~   mr   objr%   r%   r&   r/   M  s    

zMatrixElement.__new__c                    sD     dd}|r& fdd| jD }n| j}|d |d |d f S )Nrf   Tc                    s   g | ]}|j f i  qS r%   )r@   )ru   r*   rw   r%   r&   rx   _  ry   z&MatrixElement.doit.<locals>.<listcomp>r   rZ   re   )getr1   )r7   r2   rf   r1   r%   rw   r&   r@   \  s
    zMatrixElement.doitc                 C   s   | j dd  S rY   r   r6   r%   r%   r&   indicesd  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   rZ   re   )Sumzz1, z2r   )r   r   r   r   parentdiffr   r   r   Zeror1   r8   r   rk   Zsympy.concrete.summationsr   r   r   r   )r7   vr   Mr   r~   r   r   r   i1i2YZr1Zr2r%   r%   r&   r   h  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   E  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/   )r0   r   r~   r   r   r%   r%   r&   r/     s    


zMatrixSymbol.__new__c                 C   s   | j d | j d fS )NrZ   re   r   r6   r%   r%   r&   r8     s    zMatrixSymbol.shapec                 C   s   | j d jS rV   )r1   r   r6   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%   r6   r%   r%   r&   free_symbols  s    zMatrixSymbol.free_symbolsc                 K   s   | S r    r%   rz   r%   r%   r&   r{     s    zMatrixSymbol._eval_simplifyc                 C   s   t | jd | jd S Nr   rZ   )r   r8   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  )r8   r   r   r   _LeftRightArgsr   r   )r7   rv   firstsecondr%   r%   r&   r     s    **""z*MatrixSymbol._eval_derivative_matrix_linesN)r   r   r   r   r   r   r  r/   r   r8   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   )ru   symr%   r%   r&   rx     ry   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&   rx     ry   z+_LeftRightArgs.__init__.<locals>.<listcomp>r   rZ   )_lines_first_pointer_parent_first_pointer_index_first_line_index_second_pointer_parent_second_pointer_index_second_line_indexhigher)r7   r   r  r%   r%   r&   __init__  s    z_LeftRightArgs.__init__c                 C   s   | j | j S r    r  r  r6   r%   r%   r&   first_pointer  s    z_LeftRightArgs.first_pointerc                 C   s   || j | j< d S r    r  r7   valuer%   r%   r&   r    s    c                 C   s   | j | j S r    r  r  r6   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   r6   r%   r&   rx     ry   z+_LeftRightArgs.__repr__.<locals>.<listcomp>z#_LeftRightArgs(lines=%s, higher=%s))r  r  )r7   Zbuiltr%   r6   r&   __repr__  s
    z_LeftRightArgs.__repr__c                 C   s:   | j | j | _| _ | j| j | _| _| j| j | _| _| S r    )r  r  r  r  r  r  r6   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 )NrZ   r   c                 S   s   g | ]}t |qS r%   )r  r  r   r%   r%   r&   rx     ry   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   r6   r%   r&   rx     ry   z(_LeftRightArgs.build.<locals>.<listcomp>rZ   c                 S   s   g | ]}|qS r%   r%   r   r%   r%   r&   rx     ry   )r  r  r  )r7   datar%   r6   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 )NrZ   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   )r7   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   rZ   c                 S   s   g | ]}|d kqS rZ   r%   r   r%   r%   r&   rx   4  ry   z'_LeftRightArgs.rank.<locals>.<listcomp>c                 S   s   g | ]}|d kqS r#  r%   r   r%   r%   r&   rx   6  ry   re   )r	  r   r8   r
  r  )r7   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)rZ   re   )Z	validator)Z*tensor.array.expressions.array_expressionsr%  r&  r   	_validate)r7   pointerrC   r%  r&  Zsubexprr%   r%   r&   _multiply_pointer;  s    
z _LeftRightArgs._multiply_pointerc                 C   s   |  j |9  _ d S r    )r  rH   r%   r%   r&   append_firstP  s    z_LeftRightArgs.append_firstc                 C   s   |  j |9  _ d S r    )r  rH   r%   r%   r&   append_secondS  s    z_LeftRightArgs.append_secondN)r   r   r   r   r   r   r  r   r  setterr  r  r   r   r  r   r"  r   r)  r*  r+  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,   )rv   r   r%   r%   r&   _make_matrixW  s    
r-  rZ   r<   r9   rr   rp   rj   )r   r   rm   )N)F)Itypingr   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.simplifyr   Zsympy.utilities.miscr   r+   r,   r   r   Z"_constructor_postprocessor_mappingr   r   r   r  r  r  r-  matmulr=   Zmataddr:   ZmatpowrR   r   ra   r   rk   Zspecialr   r   Zdeterminantrn   r%   r%   r%   r&   <module>   sX   
   )

(
/AE 	