
    sg                         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 d dlmZ d dlmZ d	 Zd
 Zd Z G d de      Zy)    )Add)Tuple)Expr)Mul)Pow)default_sort_key)sympify)Matrixc                     t        |       } t        | t              rI| j                  s<| j                  s0| j
                  s$| j                  s| j                  r| j                  ryy)z Helper method used in TrTF)	r	   
isinstancer   
is_Integeris_Floatis_Rational	is_Number	is_Symbolis_commutative)es    N/var/www/html/venv/lib/python3.12/site-packages/sympy/physics/quantum/trace.py
_is_scalarr      sF     	
A!TLLAJJMMQ[[[[Q--    c                    t        |       dk(  r| S t        | t              }t        |       D cg c]  \  }}||k(  s| }}}t	        |       }|j                  |        |j                  t        |       |d   z          t        t        |      dz
        D cg c]  }|||   ||dz       g }}|j                  t        |            }|||   ||   t        |       z    }|S c c}}w c c}w )a5   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\;TQQ(]q;G;	aBIIaL NN3q6GAJ&' S\A%&(171:ga!en-. (G (
 --G
%C73<s1v 56I' <(s   C%C%C+c                     t        |       dk(  r| S t        | dd       }|j                  | dd        t        | j                  S )zk 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                   H    e Zd ZdZd Zed        Zd Zed        Zd Z	d Z
y)	Tra   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           	         t        |      dk(  r>t        |d   t        t        t        f      st        |d         }nt        |d    }|d   }n)t        |      dk(  rt               }|d   }nt        d      t        |t              r|j                         S t        |d      r%t        |j                        r|j                         S t        |t              r*t        |j                  D cg c]  }t        ||       c} S t        |t              ra|j                         \  }}t        |      dk(  rt        | S t        j                   | t        | |      }t        |      dkD  rt        | |z  S |S t        |t"              rIt%        |j                  d         rt%        |j                  d         r|S t        j                   | ||      S t%        |      r|S t        j                   | ||      S c c}w )z Construct 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
   r4   hasattrcallabler   r.   r1   r   args_cncr   __new__r   r   )clsr.   r&   exprargc_partnc_partobjs           r   r:   z
Tr.__new__n   s    INd1geU';<Q.a/7D$i1ngG7D 3 4 4 dF#::<T7#(<::<c"TYY?cC)?@@c""mmoOFG7|q F|#ll3Ww@ ,/v;?sF|C'CCc"499Q<(tyy|,||Cw774 <<T733) @s   *G/c                 P    | j                   d   }|j                  }|j                  S )Nr   )r.   kindelement_kind)selfr<   	expr_kinds      r   rB   zTr.kind   s$    yy|II	%%%r   c                     t        | j                  d   d      r,| j                  d   j                  | j                  d         S | S )a   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&   )r7   r.   rG   )rD   hintss     r   doitzTr.doit   s?     499Q</99Q<++DIIaL+AAr   c                      y)NT )rD   s    r   	is_numberzTr.is_number   s     r   c                 `   |dkD  r&|t        | j                  d   j                        z  }n/t        |      t        | j                  d   j                        z   }t        | j                  d   j                  | d | j                  d   j                  d|  z         }t	        t        |       S )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   )rD   posr.   s      r   permutez
Tr.permute   s    * 7DIIaL--..CHs499Q<#4#4556CDIIaL%%sde,tyy|/@/@C4/HHI#,r   c                     t        | j                  d   t              r,t        t	        | j                  d   j                              }n| j                  d   g}t        |      | j                  d   fz   S )Nr   r   )r   r.   r   r+   r/   r5   )rD   r.   s     r   _hashable_contentzTr._hashable_content   sZ    diilC(!/$))A,2C2C"DEDIIaL>DT{diil---r   N)__name__
__module____qualname____doc__r:   propertyrB   rI   rL   rP   rR   rK   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   rK   r   r   <module>r`      s;     '      / & !%P
W. W.r   