
    \h                         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  S SKJr  S SKJr  S	 rS
 rS r " S S\5      rg)    )Add)Tuple)Expr)Mul)Pow)default_sort_key)sympify)Matrixc                    [        U 5      n [        U [        5      (       ag  U R                  (       dU  U R                  (       dD  U R
                  (       d3  U R                  (       d"  U R                  (       a  U R                  (       a  gg)zHelper method used in TrTF)	r	   
isinstancer   
is_Integeris_Floatis_Rational	is_Number	is_Symbolis_commutative)es    S/var/www/auris/envauris/lib/python3.13/site-packages/sympy/physics/quantum/trace.py
_is_scalarr      sI     	
A!TLLAJJMMQ[[[[Q--    c                    [        U 5      S:X  a  U $ [        U [        S9n[        U 5       VVs/ s H  u  p#X1:X  d  M  UPM     nnn[	        U 5      nUR                  U 5        UR                  [        U 5      US   -   5        [        [        U5      S-
  5       Vs/ s H  o%XB   XBS-       /PM     nnUR                  [        U5      5      nXTU   XG   [        U 5      -    nU$ s  snnf s  snf )a  Cyclic permutations based on canonical ordering

Explanation
===========

This method does the sort based ascii values while
a better approach would be to used lexicographic sort.

TODO: Handle condition such as symbols have subscripts/superscripts
in case of lexicographic sort

   )keyr   )	lenminr   	enumeratelistextendappendrangeindex)	lmin_itemixindiceslesublistidx	ordered_ls	            r   _cycle_permuter+      s     1v{1*+H&q\;\TQQ]q\G;	aBIIaL NN3q6GAJ&' S\A%&(& 457:g!en-.&  (
 --G
%C3<s1v 56I' <(s   C$C$C*c                     [        U 5      S:X  a  U $ [        U SS 5      nUR                  U SS 5        [        U6 R                  $ )z\this just moves the last arg to first position
to enable expansion of args
A,B,A ==> A**2,B
r   Nr   )r   r   r   r   args)r"   r%   s     r   _rearrange_argsr/   B   sC    
 1v{QrsVAHHQqW7<<r   c                   P    \ rS rSrSrS r\S 5       rS r\S 5       r	S r
S rS	rg
)TrO   a)  Generic Trace operation than can trace over:

a) SymPy matrix
b) operators
c) outer products

Parameters
==========
o : operator, matrix, expr
i : tuple/list indices (optional)

Examples
========

# TODO: Need to handle printing

a) Trace(A+B) = Tr(A) + Tr(B)
b) Trace(scalar*Operator) = scalar*Trace(Operator)

>>> from sympy.physics.quantum.trace import Tr
>>> from sympy import symbols, Matrix
>>> a, b = symbols('a b', commutative=True)
>>> A, B = symbols('A B', commutative=False)
>>> Tr(a*A,[2])
a*Tr(A)
>>> m = Matrix([[1,2],[1,1]])
>>> Tr(m)
2

c           	      X   [        U5      S:X  aC  [        US   [        [        [        45      (       d  [        US   5      nO[        US   6 nUS   nO*[        U5      S:X  a  [        5       nUS   nO[        S5      e[        U[        5      (       a  UR                  5       $ [        US5      (       a*  [        UR                  5      (       a  UR                  5       $ [        U[        5      (       a,  [        UR                   Vs/ s H  n[        XB5      PM     sn6 $ [        U[        5      (       ac  UR                  5       u  pV[        U5      S:X  a  [        U6 $ [        R                   " U [        U6 U5      n[        U5      S:  a  [        U6 U-  $ U$ [        U["        5      (       aS  [%        UR                  S   5      (       a  [%        UR                  S   5      (       a  U$ [        R                   " XU5      $ [%        U5      (       a  U$ [        R                   " XU5      $ s  snf )ztConstruct a Trace object.

Parameters
==========
args = SymPy expression
indices = tuple/list if indices, optional

   r   r   z5Arguments to Tr should be of form (expr[, [indices]])trace)r   r   r   r   tuple
ValueErrorr
   r5   hasattrcallabler   r.   r1   r   args_cncr   __new__r   r   )clsr.   r&   exprargc_partnc_partobjs           r   r;   
Tr.__new__n   s    INd1geU';<<Q.a/7D$i1ngG7D 3 4 4 dF##::<T7##(<(<::<c""TYY?YcC)Y?@@c"""mmoOF7|q F|#ll3Ww@ ,/v;?sF|C'CCc""499Q<((tyy|,,||Cw774  <<733) @s   H'c                 P    U R                   S   nUR                  nUR                  $ )Nr   )r.   kindelement_kind)selfr=   	expr_kinds      r   rD   Tr.kind   s$    yy|II	%%%r   c                     [        U R                  S   S5      (       a)  U R                  S   R                  U R                  S   S9$ U $ )aE  Perform the trace operation.

#TODO: Current version ignores the indices set for partial trace.

>>> from sympy.physics.quantum.trace import Tr
>>> from sympy.physics.quantum.operator import OuterProduct
>>> from sympy.physics.quantum.spin import JzKet, JzBra
>>> t = Tr(OuterProduct(JzKet(1,1), JzBra(1,1)))
>>> t.doit()
1

r   _eval_tracer   )r&   )r8   r.   rJ   )rF   hintss     r   doitTr.doit   sB     499Q<//99Q<++DIIaL+AAr   c                     g)NT )rF   s    r   	is_numberTr.is_number   s     r   c                 b   US:  a&  U[        U R                  S   R                  5      -  nO/[        U5      [        U R                  S   R                  5      -  * n[        U R                  S   R                  U* S U R                  S   R                  SU*  -   5      n[	        [        U6 5      $ )a[  Permute the arguments cyclically.

Parameters
==========

pos : integer, if positive, shift-right, else shift-left

Examples
========

>>> from sympy.physics.quantum.trace import Tr
>>> from sympy import symbols
>>> A, B, C, D = symbols('A B C D', commutative=False)
>>> t = Tr(A*B*C*D)
>>> t.permute(2)
Tr(C*D*A*B)
>>> t.permute(-2)
Tr(C*D*A*B)

r   N)r   r.   absr   r1   r   )rF   posr.   s      r   permute
Tr.permute   s    * 7DIIaL--..CHs499Q<#4#4556CDIIaL%%sde,tyy|/@/@C4/HHI#,r   c                     [        U R                  S   [        5      (       a,  [        [	        U R                  S   R                  5      5      nOU R                  S   /n[        U5      U R                  S   4-   $ )Nr   r   )r   r.   r   r+   r/   r6   )rF   r.   s     r   _hashable_contentTr._hashable_content   s]    diilC((!/$))A,2C2C"DEDIIaL>DT{diil---r   rO   N)__name__
__module____qualname____firstlineno____doc__r;   propertyrD   rL   rP   rU   rX   __static_attributes__rO   r   r   r1   r1   O   sD    <34j & &
$   <.r   r1   N)sympy.core.addr   sympy.core.containersr   sympy.core.exprr   sympy.core.mulr   sympy.core.powerr   sympy.core.sortingr   sympy.core.sympifyr	   sympy.matricesr
   r   r+   r/   r1   rO   r   r   <module>ri      s;     '      / & !%P
W. W.r   