
    \h"                     n    S SK Jr  S SKJr  S SKJr  S SKJr  S SKJ	r	  S SK
JrJrJrJr   " S S\5      rg	)
    )permutedims)Number)S)Symbol)sympify)TensorTensExprTensAddTensMulc                       \ rS rSrSrS r\S 5       r\S 5       r\	S 5       r
S rS rS	 rS
 rS rS r\S 5       r\S 5       rS rSrg)PartialDerivative	   a	  
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])
>>> B = TensorHead("B", [L])
>>> i, j, k = symbols("i j k")

>>> 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]

Notice that the deriving variables have opposite valence than the
printed one: ``A(j)`` is printed as covariant, but the index of the
derivative is actually contravariant, i.e. ``-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]

The method ``.get_indices()`` always returns all indices (even the
contracted ones). If only uncontracted indices are needed, call
``.get_free_indices()``:

>>> expr.get_free_indices()
[]

Nested partial derivatives are flattened:

>>> expr = PartialDerivative(PartialDerivative(A(i), A(j)), A(k))
>>> expr
PartialDerivative(A(i), A(j), A(k))
>>> expr.get_indices()
[i, -j, -k]

Replace a derivative with array values:

>>> from sympy.abc import x, y
>>> from sympy import sin, log
>>> compA = [sin(x), log(x)*y**3]
>>> compB = [x, y]
>>> expr = PartialDerivative(A(i), B(j))
>>> expr.replace_with_arrays({A(i): compA, B(i): compB})
[[cos(x), 0], [y**3/x, 3*y**2*log(x)]]

The returned array is indexed by `(i, -j)`.

Be careful that other SymPy modules put the indices of the deriving
variables before the indices of the derivand in the derivative result.
For example:

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

>>> from sympy import Matrix, Array
>>> Matrix(compA).diff(Matrix(compB)).reshape(2, 2)
[[cos(x), y**3/x], [0, 3*y**2*log(x)]]
>>> Array(compA).diff(Array(compB))
[[cos(x), y**3/x], [0, 3*y**2*log(x)]]

These are the transpose of the result of ``PartialDerivative``,
as the matrix and the array modules put the index `-j` before `i` in the
derivative result. An array read with index order `(-j, i)` is indeed the
transpose of the same array read with index order `(i, -j)`. By specifying
the index order to ``.replace_with_arrays`` one can get a compatible
expression:

>>> expr.replace_with_arrays({A(i): compA, B(i): compB}, [-j, i])
[[cos(x), y**3/x], [0, 3*y**2*log(x)]]
c                     [        U[        5      (       a  UR                  U-   nUR                  nU R	                  [        U5      U5      u  p4pV[        R                  " U /UQ76 nXGl        XWl	        Xgl
        U$ N)
isinstancer   	variablesexpr _contract_indices_for_derivativer   r	   __new___indices_free_dum)clsr   r   argsindicesfreedumobjs           O/var/www/auris/envauris/lib/python3.13/site-packages/sympy/tensor/toperators.pyr   PartialDerivative.__new__`   sr     d-..2I99D#&#G#GdGY$  t s*T*	
    c                 "    [         R                  $ r   )r   Oneselfs    r   coeffPartialDerivative.coeffq   s    uur!   c                     U $ r    r$   s    r   nocoeffPartialDerivative.nocoeffu   s    r!   c           
      N   / nU H  n[        U[        5      (       aD  UR                  5       nUR                  UR	                  U Vs0 s H  ofU* _M     sn5      5        M\  [        U[
        5      (       d  Ms  UR                  U5        M     [        R                  " U/U-   SS9u  pxp[        S[        U5      5       HW  nXt   n[        U[        5      (       d  M  Xt   R                  5       nXt   R	                  U Vs0 s H  ofU* _M     sn5      Xt'   MY     XxX4$ s  snf s  snf )NT)replace_indices   )
r   r   get_free_indicesappendxreplacer   r   _tensMul_contract_indicesrangelen)r   r   r   variables_opposite_valenceii_free_indiceskr   r   r   r   args_i	i_indicess                r   r   2PartialDerivative._contract_indices_for_derivativey   s   %'"A!V$$!"!3!3!5*11

>#B>arE>#BCEAv&&*11!4  $+#D#DF//$G t q#d)$AWF&&)) G446	'**9+E9arE9+EF	 % d'' $C ,Fs   D?D"
c                     U R                  U R                  U R                  5      u  p#pEU R                  " U6 nX6l        XFl        XVl        U$ r   )r   r   r   funcr   r   r   )r%   hintsr   r   r   r   r   s          r   doitPartialDerivative.doit   sF    #'#H#HTXTbTb#c tii	
r!   c           	         U R                  U R                  U R                  5      u  pp4U R                  " U6 nX%l        X5l        XEl        UnUS   R                  (       d  [        R                  $ [        UR                  [        5      (       ai  UR                  R                  " UR                  R                   Vs/ s H.  nU R                  " U/UR                  Q76 R                  5       PM0     sn6 nU$ [        UR                  [        5      (       Ga   [        UR                  5      S:X  a  / n[!        UR                  R                  5      n	[#        [        U	5      5       Hx  n
[        [%        X   5      [&        5      (       a  M%  U R                  " X   /UR                  Q76 R                  5       nUR)                  [        U	S U
 U/-   XS-   S  -   6 5        Mz     [        R*                  " U5      nU$ UR                  nUR                   H"  nU R                  Xl5      R                  5       nM$     U$ s  snf )Nr   r.   )r   r   r   r=   r   r   r   free_symbolsr   Zeror   r
   r   _expand_partial_derivativer   r4   listr3   r   r   r0   fromiter)r%   r   r   r   r   r   resultatermsmulargsinddvs                r   rD   ,PartialDerivative._expand_partial_derivative   s   #'#H#HTXTbTb#c tii	Aw##66M'**XX]]#[[--%/- IIa0#--0KKM-%/ 0F8 3 '**3==!Q&sxx}}- W.C%ggl&;VDD !IIglCS]]C^^`Wwt}230518'1D0E &G H / !))%0  A!YYv1LLNF ' 9%/s   >5H;c                     U R                   nU R                   H_  n[        U[        5      (       a  UR	                  U5      nM+  UR
                  (       a  UR                  U5      nMO  [        R                  nMa     U$ r   )	r   r   r   r	   _eval_partial_derivative	_diff_wrt_eval_derivativer   rC   )r%   rG   rM   s      r   _perform_derivative%PartialDerivative._perform_derivative   s]    A&(++88;;;#44Q7FVVF   r!   c                     U R                   $ r   )r   r$   s    r   get_indicesPartialDerivative.get_indices   s    }}r!   c                 `    [        U R                  S S9nU Vs/ s H  o"S   PM	     sn$ s  snf )Nc                     U S   $ Nr.   r)   )xs    r   <lambda>4PartialDerivative.get_free_indices.<locals>.<lambda>   s    !r!   )keyr   )sortedr   )r%   r   r6   s      r   r/   "PartialDerivative.get_free_indices   s,    djjn5"#d!d###s   +c                    U R                   R                  U5      nUR                  5        VVs0 s H
  u  p4U* U* _M     nnnU R                   Vs/ s H  ofR                  U5      PM     nnU R                  " U/UQ76 $ s  snnf s  snf r   )r   r1   itemsr   r=   )r%   replr   r8   rM   mirroredr6   r   s           r   _replace_indices"PartialDerivative._replace_indices   su    yy!!$''+zz|4|tqQBF|437>>B>aZZ)>	Byy*	** 5Bs   B Bc                      U R                   S   $ )Nr   r   r$   s    r   r   PartialDerivative.expr   s    yy|r!   c                      U R                   SS  $ rZ   rh   r$   s    r   r   PartialDerivative.variables   s    yy}r!   c           
         SSK JnJn  U R                  R	                  U5      u  pEU R
                   GH  nUR	                  U5      u  pxU V	s/ s H  o* PM     nn	[        U V	s/ s H  oR                  5       PM     sn	6 u  p[        UR                  5      nU" XX5      n[        UR                  5      nX-
  n[        U[        U5       V	s/ s H  oU-   PM	     sn	[        [        U5      5      -   5      nUR                  5       nUS   nS/[        [        U5      5       V	s/ s H  n	[        S 5      PM     sn	-   n[        U
5       H   u  n	nXS'   U[!        U5      ==   U-  ss'   M"     U* U;   a4  UR#                  U* 5      nU" USUS-   45      nUR%                  U5        GMu  UR'                  U5        GM     XE4$ s  sn	f s  sn	f s  sn	f s  sn	f )Nr.   )derive_by_arraytensorcontractionr   )arrayrm   rn   r   _extract_datar   zipas_coeff_Mulr4   shaper   r3   rE   
as_mutableslice	enumeratetupleindexpopr0   )r%   replacement_dictrm   rn   r   ro   variablevar_indices	var_arrayr6   coeff_array
dim_before	dim_afterdim_increasevarindexcoeff_indexr&   poss                     r   rp   PartialDerivative._extract_data   s   =001ABH%-%;%;<L%M"K'23{!2{K3%(Y*OY>>+;Y*O%P"KU[[)J#E5EEKK(I$1L%
BS'TBSQL(8BS'TW[\abn\oWp'pqE$$&E"1~H#eCL6I J6It6I JJK%k25!"AeK()U2) 3 yG#mmXI.)%!SU<C x(+ ', ~) 4*O
 (U !Ks   G $G
G
#Gr)   N)__name__
__module____qualname____firstlineno____doc__r   propertyr&   r*   classmethodr   r?   rD   rS   rV   r/   re   r   r   rp   __static_attributes__r)   r!   r   r   r   	   s    Tl"     ( (,*X
$+    r!   r   N)sympyr   sympy.core.numbersr   sympy.core.singletonr   sympy.core.symbolr   sympy.core.sympifyr   sympy.tensor.tensorr   r	   r
   r   r   r)   r!   r   <module>r      s(     % " $ & B Bw wr!   