o
    8Va                     @   sT   d dl mZmZmZ d dl mZmZ d dlmZmZm	Z	m
Z
mZ G dd deZdS )    )SymbolNumbersympify)MutableDenseNDimArrayS)TensorTensExprTensAddTensMulTensorIndexc                   @   s   e Zd ZdZdd Zedd Ze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edd Zedd Zdd ZdS )PartialDerivativea  
    Partial derivative for tensor expressions.

    Examples
    ========

    >>> from sympy.tensor.tensor import TensorIndexType, TensorHead
    >>> from sympy.tensor.toperators import PartialDerivative
    >>> from sympy import symbols
    >>> L = TensorIndexType("L")
    >>> A = TensorHead("A", [L])
    >>> i, j = symbols("i j")

    >>> expr = PartialDerivative(A(i), A(j))
    >>> expr
    PartialDerivative(A(i), A(j))

    The ``PartialDerivative`` object behaves like a tensorial expression:

    >>> expr.get_indices()
    [i, -j]

    Indices can be contracted:

    >>> expr = PartialDerivative(A(i), A(i))
    >>> expr
    PartialDerivative(A(L_0), A(L_0))
    >>> expr.get_indices()
    [L_0, -L_0]
    c                 G   sZ   t |tr|j| }|j}| t||\}}}}tj| g|R  }||_||_	||_
|S N)
isinstancer   	variablesexpr _contract_indices_for_derivativer   r   __new___indices_free_dum)clsr   r   argsindicesfreedumobj r   9/usr/lib/python3/dist-packages/sympy/tensor/toperators.pyr   '   s   

zPartialDerivative.__new__c                 C   s   t jS r   )r   ZOneselfr   r   r   coeff8   s   zPartialDerivative.coeffc                 C   s   | S r   r   r   r   r   r   nocoeff<   s   zPartialDerivative.nocoeffc                 C   s   g }|D ]#}t |tr| }||dd |D  qt |tr'|| qtj|g| dd\}}}}	tdt	|D ]}|| }
t |
tr\||  }|| dd |D ||< q=||||	fS )Nc                 S      i | ]}|| qS r   r   .0kr   r   r   
<dictcomp>H       zFPartialDerivative._contract_indices_for_derivative.<locals>.<dictcomp>T)Zreplace_indices   c                 S   r"   r   r   r#   r   r   r   r&   S   r'   )
r   r   get_free_indicesappendxreplacer   r
   Z_tensMul_contract_indicesrangelen)r   r   r   Zvariables_opposite_valenceiZi_free_indicesr   r   r   r   Zargs_iZ	i_indicesr   r   r   r   @   s(   




z2PartialDerivative._contract_indices_for_derivativec                 C   s8   |  | j| j\}}}}| j| }||_||_||_|S r   )r   r   r   funcr   r   r   )r   r   r   r   r   r   r   r   r   doitW   s   
zPartialDerivative.doitc                    sB   jj\}}}}j|  | _| _| _ }|d js$tj	S t
 jtr< jj fdd|jjD  }|S t
 jtrt jdkrg }t jj}tt|D ]/}t
t|| tsj|| g jR   }	|t|d | |	g ||d d     qWt|}|S  j} jD ]
}
||
 }q|S )Nr   c                    s$   g | ]}j |g jR   qS r   )r/   r   _expand_partial_derivative)r$   ar   r   r   r   
<listcomp>o   s    z@PartialDerivative._expand_partial_derivative.<locals>.<listcomp>r(   )r   r   r   r/   r   r   r   Zfree_symbolsr   Zeror   r	   r   r
   r-   listr,   r   r   r1   r*   Zfromiter)r   r   r   r   r   resultZtermsZmulargsZinddvr   r3   r   r1   a   s@   



z,PartialDerivative._expand_partial_derivativec                 C   sD   | j }| jD ]}t|tr||}q|jr||}qtj}q|S r   )	r   r   r   r   Z_eval_partial_derivativeZ	_diff_wrtZ_eval_derivativer   r5   )r   r7   r9   r   r   r   _perform_derivative   s   

z%PartialDerivative._perform_derivativec                 C   s   | j S r   )r   r   r   r   r   get_indices   s   zPartialDerivative.get_indicesc                 C   s    t | jdd d}dd |D S )Nc                 S   s   | d S Nr(   r   )xr   r   r   <lambda>   s    z4PartialDerivative.get_free_indices.<locals>.<lambda>)keyc                 S   s   g | ]}|d  qS )r   r   r$   r.   r   r   r   r4      r'   z6PartialDerivative.get_free_indices.<locals>.<listcomp>)sortedr   )r   r   r   r   r   r)      s   z"PartialDerivative.get_free_indicesc                    sD   | j |}dd | D   fdd| jD }| j|g|R  S )Nc                 S   s   i | ]	\}}| | qS r   r   )r$   r%   r9   r   r   r   r&      s    z6PartialDerivative._replace_indices.<locals>.<dictcomp>c                    s   g | ]}|  qS r   )r+   r@   mirroredr   r   r4      s    z6PartialDerivative._replace_indices.<locals>.<listcomp>)r   r+   itemsr   r/   )r   replr   r   r   rB   r   _replace_indices   s   z"PartialDerivative._replace_indicesc                 C   s
   | j d S )Nr   r   r   r   r   r   r      s   
zPartialDerivative.exprc                 C   s   | j dd  S r<   rG   r   r   r   r   r      s   zPartialDerivative.variablesc                 C   s  ddl m}m} | j|\}}| jD ]l}||\}}dd |D }tdd |D  \}	}|||}| }|d }
dgdd tt	|D  }t
|	D ]\}}||d< |t|  |  < qM|
 |v rz||
 }||d|d f}|| q||
 q||fS )Nr(   )derive_by_arraytensorcontractionc                 S   s   g | ]}| qS r   r   r@   r   r   r   r4      s    z3PartialDerivative._extract_data.<locals>.<listcomp>c                 S   s   g | ]}|  qS r   )Zas_coeff_Mulr@   r   r   r   r4      r'   r   c                 S   s   g | ]}t d qS r   )slicer@   r   r   r   r4      r'   )arrayrH   rI   r   _extract_datar   zipZ
as_mutabler,   r-   	enumeratetupleindexpopr*   )r   Zreplacement_dictrH   rI   r   rK   variableZvar_indicesZ	var_arrayZcoeff_arrayZvarindexZcoeff_indexr.   r    posr   r   r   rL      s&   


zPartialDerivative._extract_dataN)__name__
__module____qualname____doc__r   propertyr    r!   classmethodr   r0   r1   r:   r;   r)   rF   r   r   rL   r   r   r   r   r      s(    



,

r   N)Zsympyr   r   r   r   r   Zsympy.tensor.tensorr   r   r	   r
   r   r   r   r   r   r   <module>   s    