
    sg"                     n    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mZmZmZ  G d de      Zy	)
    )permutedims)Number)S)Symbol)sympify)TensorTensExprTensAddTensMulc                       e Zd ZdZd Zed        Zed        Zed        Z	d Z
d Zd Zd	 Zd
 Zd Zed        Zed        Zd Zy)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])
    >>> 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                     t        |t              r|j                  |z   }|j                  }| j	                  t        |      |      \  }}}}t        j                  | g| }||_        ||_	        ||_
        |S N)
isinstancer   	variablesexpr _contract_indices_for_derivativer   r	   __new___indices_free_dum)clsr   r   argsindicesfreedumobjs           J/var/www/html/venv/lib/python3.12/site-packages/sympy/tensor/toperators.pyr   zPartialDerivative.__new__`   sy     d-.2I99D#&#G#GdGY$  gtS s*T*	
    c                 "    t         j                  S r   )r   Oneselfs    r   coeffzPartialDerivative.coeffq   s    uur   c                     | S r    r"   s    r   nocoeffzPartialDerivative.nocoeffu   s    r   c           
      .   g }|D ]u  }t        |t              rA|j                         }|j                  |j	                  |D ci c]  }||  c}             Tt        |t
              se|j                  |       w t        j                  |g|z   d      \  }}}	}
t        dt        |            D ]R  }||   }t        |t              s||   j                         }||   j	                  |D ci c]  }||  c}      ||<   T |||	|
fS c c}w c c}w )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   z2PartialDerivative._contract_indices_for_derivativey   s%   %'" 	5A!V$!"!3!3!5*11

>#BaArE#BCEAv&*11!4	5 $+#D#DF//$G gtS q#d)$ 	GA!WF&&) G446	q'**9+EaArE+EFQ		G WdC'' $C ,Fs   D0D
c                     | j                  | j                  | j                        \  }}}} | j                  | }||_        ||_        ||_        |S r   )r   r   r   funcr   r   r   )r#   hintsr   r   r   r   r   s          r   doitzPartialDerivative.doit   sR    #'#H#HTXTbTb#c gtSdii	
r   c           	      V   | j                  | j                  | j                        \  }}}} | j                  | }||_        ||_        ||_        |}|d   j                  st        j                  S t        |j                  t              rf |j                  j                  |j                  j                  D cg c]-  } | j                  |g|j                   j                         / c} }|S t        |j                  t              rt        |j                        dk(  rg }t!        |j                  j                        }	t#        t        |	            D ]t  }
t        t%        |	|
         t&              r  | j                  |	|
   g|j                   j                         }|j)                  t        |	d |
 |gz   |	|
dz   d  z           v t        j*                  |      }|S |j                  }|j                  D ]"  }| j                  ||      j                         }$ |S c c}w )Nr   r*   )r   r   r   r8   r   r   r   free_symbolsr   Zeror   r
   r   _expand_partial_derivativer   r0   listr/   r   r   r,   fromiter)r#   r   r   r   r   r   resultatermsmulargsinddvs                r   r>   z,PartialDerivative._expand_partial_derivative   s   #'#H#HTXTbTb#c gtSdii	Aw##66M'*"SXX]]#[[--%/ DIIa0#--0KKM%/ 0F8 3 '*3==!Q&sxx}}- W. HC%ggcl&;VD &DIIgclCS]]C^^`Wwt}230518#'1D0E &G HH !))%0   OA!YYvq1LLNFO 9%/s   92H&c                     | j                   }| j                  D ]R  }t        |t              r|j	                  |      }%|j
                  r|j                  |      }Ct        j                  }T |S r   )	r   r   r   r	   _eval_partial_derivative	_diff_wrt_eval_derivativer   r=   )r#   rA   rG   s      r   _perform_derivativez%PartialDerivative._perform_derivative   s_     	$A&(+88;;;#44Q7FVVF	$ r   c                     | j                   S r   )r   r"   s    r   get_indiceszPartialDerivative.get_indices   s    }}r   c                 b    t        | j                  d       }|D cg c]  }|d   	 c}S c c}w )Nc                     | d   S Nr*   r&   )xs    r   <lambda>z4PartialDerivative.get_free_indices.<locals>.<lambda>   s
    ! r   )keyr   )sortedr   )r#   r   r2   s      r   r+   z"PartialDerivative.get_free_indices   s*    djjn5"#!###s   ,c                    | j                   j                  |      }|j                         D ci c]
  \  }}| |  }}}| j                  D cg c]  }|j                  |       }} | j                  |g| S c c}}w c c}w r   )r   r-   itemsr   r8   )r#   replr   r4   rG   mirroredr2   r   s           r   _replace_indicesz"PartialDerivative._replace_indices   sy    yy!!$''+zz|4tq!QBF4437>>BaQZZ)B	Btyy*	** 5Bs   A<Bc                      | j                   d   S )Nr   r   r"   s    r   r   zPartialDerivative.expr   s    yy|r   c                      | j                   dd  S rQ   r\   r"   s    r   r   zPartialDerivative.variables   s    yy}r   c           
         ddl m}m} | j                  j	                  |      \  }}| j
                  D ]|  }|j	                  |      \  }}|D 	cg c]  }	|	  }}	t        |D 	cg c]  }	|	j                          c}	 \  }
}t        |j                        } |||      }t        |j                        }||z
  }t        |t        |      D 	cg c]  }	|	|z   	 c}	t        t        |            z         }|j                         }|d   }dgt        t        |            D 	cg c]  }	t        d        c}	z   }t        |
      D ]   \  }	}|	|d<   |t!        |      xx   |z  cc<   " | |v r3|j#                  |       } ||d|dz   f      }|j%                  |       l|j'                  |        ||fS c c}	w c c}	w c c}	w c c}	w )Nr*   )derive_by_arraytensorcontractionr   )arrayr_   r`   r   _extract_datar   zipas_coeff_Mulr0   shaper   r/   r?   
as_mutableslice	enumeratetupleindexpopr,   )r#   replacement_dictr_   r`   r   ra   variablevar_indices	var_arrayr2   coeff_array
dim_before	dim_afterdim_increasevarindexcoeff_indexr$   poss                     r   rb   zPartialDerivative._extract_data   s   =001AB 	)H%-%;%;<L%M"K'23!A23K3%(Y*O1>>+;*O%P"KU[[)J#E95EEKK(I$z1L%
BS'TQL(8'TW[\abn\oWp'pqE$$&E"1~H#eCL6I Jt JJK%k2 35!"AeK()U2)3 yG#mmXI.)%!SU<C x(+	), ~) 4*O
 (U !Ks   
F7$F<
G"GN)__name__
__module____qualname____doc__r   propertyr$   r'   classmethodr   r:   r>   rL   rN   r+   rZ   r   r   rb   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   