
    g"                     v    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d	S )
    )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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])
    >>> 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        }|                     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objs           S/var/www/html/ai-engine/env/lib/python3.11/site-packages/sympy/tensor/toperators.pyr   zPartialDerivative.__new__`   s     d-.. 	2I9D#&#G#GdGGY$  $  gtS s*T***	
    c                     t           j        S r   )r   Oneselfs    r   coeffzPartialDerivative.coeffq   s	    ur   c                     | S r    r"   s    r   nocoeffzPartialDerivative.nocoeffu   s    r   c                 d   g }|D ]}t          |t                    rG|                                }|                    |                    d |D                                  ^t          |t
                    r|                    |           t          j        |g|z   d          \  }}}}	t          dt          |                    D ]a}||         }
t          |
t                    rB||                                         }||                             d |D                       ||<   b||||	fS )Nc                     i | ]}|| S r&   r&   .0ks     r   
<dictcomp>zFPartialDerivative._contract_indices_for_derivative.<locals>.<dictcomp>   s    #B#B#BaAr#B#B#Br   T)replace_indices   c                     i | ]}|| S r&   r&   r*   s     r   r-   zFPartialDerivative._contract_indices_for_derivative.<locals>.<dictcomp>   s    +E+E+EaAr+E+E+Er   )
r   r   get_free_indicesappendxreplacer   r   _tensMul_contract_indicesrangelen)r   r   r   variables_opposite_valenceii_free_indicesr   r   r   r   args_i	i_indicess               r   r   z2PartialDerivative._contract_indices_for_derivativey   s^   %'" 	5 	5A!V$$ 5!"!3!3!5!5*11

#B#B>#B#B#BCCE E E EAv&& 5*11!444#*#DF//$G $G $G gtS q#d))$$ 	G 	GA!WF&&)) G G4466	q'**+E+E9+E+E+EFFQWdC''r   c                     |                      | j        | j                  \  }}}} | j        | }||_        ||_        ||_        |S r   )r   r   r   funcr   r   r   )r#   hintsr   r   r   r   r   s          r   doitzPartialDerivative.doit   sN    #'#H#HTXTb#c#c gtSdi	
r   c           	                                 j         j                  \  }}}}  j        | |_        |_        |_        }|d         j        st          j	        S t          j        t                    r( j        j         fd|j        j        D              }nDt          j        t                    r)t          j                  dk    rg }t          j        j                  }t!          t          |                    D ]}t          t#          ||                   t$                    sa  j        ||         gj        R                                  }	|                    t          |d |         |	gz   ||dz   d          z               t          j        |          }n9j        }j        D ]*}
                     ||
                                          }+|S )Nr   c                 Z    g | ]'} j         |gj        R                                  (S r&   )r=   r   _expand_partial_derivative)r+   ar   r#   s     r   
<listcomp>z@PartialDerivative._expand_partial_derivative.<locals>.<listcomp>   sK     %/ %/ %/ DIa0#-000KKMM%/ %/ %/r   r/   )r   r   r   r=   r   r   r   free_symbolsr   Zeror   r
   r   r   r6   listr5   r   r   rB   r2   fromiter)r#   r   r   r   r   resulttermsmulargsinddvr   s   `          @r   rB   z,PartialDerivative._expand_partial_derivative   s   #'#H#HTXTb#c#c gtSdi	Aw# 	O6M'** 	O"SX] %/ %/ %/ %/ %/#[-%/ %/ %/ 0FF '** 	O3=!!Q&&sx}-- W.. H HC%ggcl&;&;VDD H &DIgclCS]CCC^^``Wwtt}230518#'1D0E &G H H H !)%00  O OA!YYvq11LLNNFF r   c                     | j         }| j        D ]V}t          |t                    r|                    |          }-|j        r|                    |          }Jt          j        }W|S r   )	r   r   r   r	   _eval_partial_derivative	_diff_wrt_eval_derivativer   rF   )r#   rI   rN   s      r   _perform_derivativez%PartialDerivative._perform_derivative   sn     	$ 	$A&(++ $88;;; $#44Q77FFVFFr   c                     | j         S r   )r   r"   s    r   get_indiceszPartialDerivative.get_indices   s
    }r   c                 H    t          | j        d           }d |D             S )Nc                     | d         S Nr/   r&   )xs    r   <lambda>z4PartialDerivative.get_free_indices.<locals>.<lambda>   s
    ! r   )keyc                     g | ]
}|d          S )r   r&   r+   r8   s     r   rD   z6PartialDerivative.get_free_indices.<locals>.<listcomp>   s    ###!###r   )sortedr   )r#   r   s     r   r1   z"PartialDerivative.get_free_indices   s,    djnn555##d####r   c                     | j                             |          }d |                                D             fd| j        D             } | j        |g|R  S )Nc                     i | ]
\  }}| | S r&   r&   )r+   r,   rN   s      r   r-   z6PartialDerivative._replace_indices.<locals>.<dictcomp>   s"    444tq!QB444r   c                 :    g | ]}|                               S r&   )r3   )r+   r8   mirroreds     r   rD   z6PartialDerivative._replace_indices.<locals>.<listcomp>   s%    BBBaQZZ))BBBr   )r   r3   itemsr   r=   )r#   replr   r   rb   s       @r   _replace_indicesz"PartialDerivative._replace_indices   sh    y!!$''44tzz||444BBBB4>BBB	ty*	****r   c                     | j         d         S )Nr   r   r"   s    r   r   zPartialDerivative.expr   s    y|r   c                      | j         dd          S rX   rg   r"   s    r   r   zPartialDerivative.variables   s    y}r   c           
         ddl m}m} | j                            |          \  }}| j        D ]}|                    |          \  }}d |D             }t          d |D              \  }	}t          |j                  }
 |||          }t          |j                  }||
z
  t          |fdt          |
          D             t          t                              z             }|                                }|d         }dgd t          t          |                    D             z   }t          |	          D ]'\  }}||d<   |t          |          xx         |z  cc<   (| |v r>|                    |           } ||d|dz   f          }|                    |           ||                    |           ||fS )Nr/   )derive_by_arraytensorcontractionc                     g | ]}| S r&   r&   r]   s     r   rD   z3PartialDerivative._extract_data.<locals>.<listcomp>   s    333!A2333r   c                 6    g | ]}|                                 S r&   )as_coeff_Mulr]   s     r   rD   z3PartialDerivative._extract_data.<locals>.<listcomp>   s"    *O*O*O1>>+;+;*O*O*Or   c                     g | ]}|z   S r&   r&   )r+   r8   dim_increases     r   rD   z3PartialDerivative._extract_data.<locals>.<listcomp>   s    'T'T'TQL(8'T'T'Tr   r   c                 ,    g | ]}t          d           S r   )slicer]   s     r   rD   z3PartialDerivative._extract_data.<locals>.<listcomp>   s     J J Jt J J Jr   )arrayrj   rk   r   _extract_datar   zipr6   shaper   r5   rG   
as_mutable	enumeratetupleindexpopr2   )r#   replacement_dictrj   rk   r   rs   variablevar_indices	var_arraycoeff_array
dim_before	dim_aftervarindexcoeff_indexr8   r$   posrp   s                    @r   rt   zPartialDerivative._extract_data   s	   ========001ABB 	) 	)H%-%;%;<L%M%M"K33{333K%(*O*OY*O*O*O%P"KU[))J#OE955EEK((I$z1L'T'T'T'T%
BSBS'T'T'TW[\abn\o\oWpWp'pqqE$$&&E"1~H# J JeCLL6I6I J J JJK%k22 3 35!"AeK(()))U2))))yG##mmXI..))%!SU<<C    x((((~r   N)__name__
__module____qualname____doc__r   propertyr$   r'   classmethodr   r?   rB   rS   rU   r1   re   r   r   rt   r&   r   r   r   r   	   s!       T Tl  "   X   X ( ( [(,  * * *X
 
 
  $ $ $+ + +   X   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 B B B B B B B B B Bw w w w w w w w w wr   