U
    L?h                     @   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)uniquely_named_symbol)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   s<   t |}|jstdt| |jdkr0tdt| |S )Nz#input to Trace, %s, is not a matrixFzTrace of a non-square matrix)r   Z	is_Matrix	TypeErrorstrZ	is_squarer
   r   __new__)clsZmat r   R/var/www/html/venv/lib/python3.8/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      )	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(   ;   sF    


 z#Trace._eval_derivative_matrix_linesc                 C   s
   | j d S )Nr   )r'   r   r   r   r   arge   s    z	Trace.argc                 K   s\   | ddr8| jjf |}| }|d k	r.|S t|S n t| jtrNt| jS t| jS d S )NdeepT)getr.   r   Z_eval_tracer   r   r	   trace)r   hintsr.   resultr   r   r   r   i   s    

z
Trace.doitc                 C   s   t | j  S r   )r   r.   as_explicitr   r   r   r   r   r4   x   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   
_normalize{   s    
"zTrace._normalizec                 K   sB   ddl m} td|g}|| j||f |d| jjd f}| S )Nr   r   ir   )r   r   r   r.   rowsr   )r   r!   kwargsr   rB   sr   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   rF   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   r1      s    r1   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.matrixbaser	   Zsympy.matrices.exceptionsr
   r   r1   r   r   r   r   <module>   s    