a
    <b                     @   s   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 G d	d
 d
eZdd ZdS )    )Basic)ExprExprBuilder)S)default_sort_key)Dummy)sympify)
MatrixBase)NonSquareMatrixErrorc                   @   sd   e Zd ZdZdZdZdd Z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S )TraceaS  Matrix Trace

    Represents the trace of a matrix expression.

    Examples
    ========

    >>> from sympy import MatrixSymbol, Trace, eye
    >>> A = MatrixSymbol('A', 3, 3)
    >>> Trace(A)
    Trace(A)
    >>> Trace(eye(3))
    Trace(Matrix([
    [1, 0, 0],
    [0, 1, 0],
    [0, 0, 1]]))
    >>> Trace(eye(3)).simplify()
    3
    Tc                 C   s8   t |}|jstdt| |js,tdt| |S )Nz#input to Trace, %s, is not a matrixzTrace of a non-square matrix)r   Z	is_Matrix	TypeErrorstrZ	is_squarer
   r   __new__)clsmat r   p/Users/vegardjervell/Documents/master/model/venv/lib/python3.9/site-packages/sympy/matrices/expressions/trace.pyr   "   s    zTrace.__new__c                 C   s   | S Nr   selfr   r   r   _eval_transpose-   s    zTrace._eval_transposec                 C   sR   ddl m} ddlm} t||r2| ||S |  }t|trHt	|
|S )Nr   Sum   )MatrixElement)sympy.concrete.summationsr   Zmatexprr   
isinstanceZrewritediffdoitr   NotImplementedError_eval_derivative)r   vr   r   exprr   r   r   r    0   s    

zTrace._eval_derivativec                 C   s   ddl m}m} | jd |}|D ]}|jdkr`t|t||jd |jd gdg|jd|_n,t|t||jd |jd |jgddg|_t	j
t	j
g|_|j|_|j|_d|_d|_q$|S )Nr   )ArrayTensorProductArrayContractionr   )r      )Z	validator)r      )Z0sympy.tensor.array.expressions.array_expressionsr#   r$   args_eval_derivative_matrix_linesZhigherr   _lines	_validater   ZOneZ_first_pointer_parentZ_second_pointer_parentZ_first_pointer_indexZ_second_pointer_index)r   xr#   r$   rlrr   r   r   r(   ;   sD    


z#Trace._eval_derivative_matrix_linesc                 C   s
   | j d S )Nr   )r'   r   r   r   r   arge   s    z	Trace.argc              	   K   sn   | ddrJ| jjf i |}z
| W S  ttfyF   t| Y S 0 n t| jtr`t	| jS t| jS d S )NdeepT)
getr.   r   Z_eval_traceAttributeErrorr   r   r   r	   trace)r   kwargsr.   r   r   r   r   i   s    

z
Trace.doitc                 C   s   t | j  S r   )r   r.   as_explicitr   r   r   r   r   r4   w   s    zTrace.as_explicitc                    s   ddl m} ddlm  | jt|r fdd}tttj	|d}tj	|  r 
 tttj	fddd}|j	|d  j	d |  tS | S )	Nr   )MatMul)	Transposec                    s"   j |  }t| r|j}t|S r   )r'   r   r.   r   )r+   ar6   	trace_argr   r   get_arg_key   s    

z%Trace._normalize.<locals>.get_arg_key)keyc                    s   t  j|  S r   )r   r'   )r+   )r9   r   r   <lambda>       z"Trace._normalize.<locals>.<lambda>)Z!sympy.matrices.expressions.matmulr5   Z$sympy.matrices.expressions.transposer6   r.   r   minrangelenr'   r   Zfromiterr   )r   r5   r:   Zindminr   r8   r   
_normalizez   s    
"zTrace._normalizec                 K   s:   ddl m} td}|| j||f |d| jjd f S )Nr   r   ir   )r   r   r   r.   rowsr   )r   r"   r3   r   rB   r   r   r   _eval_rewrite_as_Sum   s    zTrace._eval_rewrite_as_SumN)__name__
__module____qualname____doc__Zis_TraceZis_commutativer   r   r    r(   propertyr.   r   r4   rA   rD   r   r   r   r   r      s   *
r   c                 C   s   t |  S )a  Trace of a Matrix.  Sum of the diagonal elements.

    Examples
    ========

    >>> from sympy import trace, Symbol, MatrixSymbol, eye
    >>> n = Symbol('n')
    >>> X = MatrixSymbol('X', n, n)  # A square matrix
    >>> trace(2*X)
    2*Trace(X)
    >>> trace(eye(3))
    3
    )r   r   )r"   r   r   r   r2      s    r2   N)Zsympy.core.basicr   Zsympy.core.exprr   r   Zsympy.core.singletonr   Zsympy.core.sortingr   Zsympy.core.symbolr   Zsympy.core.sympifyr   Zsympy.matrices.matricesr	   Zsympy.matrices.commonr
   r   r2   r   r   r   r   <module>   s    