
    Ed                         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dS )    )Add)Tuple)Expr)Mul)Pow)default_sort_key)sympify)Matrixc                     t          |           } t          | t                    r,| j        s#| j        s| j        s| j        s| j        r	| j        rdS dS )z Helper method used in TrTF)	r	   
isinstancer   
is_Integeris_Floatis_Rational	is_Number	is_Symbolis_commutative)es    ;lib/python3.11/site-packages/sympy/physics/quantum/trace.py
_is_scalarr      si     	

A!T L 	AJ 	M	[	[	-	 45    c                    t          |           dk    r| S t          | t                    fdt          |           D             t	          |                               |                                t          |           d         z              fdt          t                    dz
            D             }|                    t          |                    }|         |         t          |           z            }|S )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

       )keyc                 &    g | ]\  }}|k    |S  r   ).0ixmin_items      r   
<listcomp>z"_cycle_permute.<locals>.<listcomp>,   s&    ;;;TQQ(];q;;;r   r   c                 D    g | ]}|         |d z                     gS )r   r   )r   r   indicesles     r   r    z"_cycle_permute.<locals>.<listcomp>7   s>     ( ( (171:ga!en,-. ( ( (r   )	lenminr   	enumeratelistextendappendrangeindex)lsublistidx	ordered_lr"   r#   r   s       @@@r   _cycle_permuter0      s    1vv{ 1*+++H;;;;Yq\\;;;G	aBIIaLLL NN3q66GAJ&'''
( ( ( ( (S\\A%&&( ( (G
 --G
%
%C73<s1vv 556Ir   c                     t          |           dk    r| S t          | dd                   }|                    | 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_argsr4   B   sT    
 1vv{ QrssVAHHQqtW7<r   c                   V    e Zd ZdZd Zed             Zd Zed             Zd Z	d Z
dS )	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    rVt          |d         t          t          t          f          st          |d                   nt          |d          |d         }n9t          |          dk    rt                      |d         }nt          d          t          |t                    r|                                S t          |d          r(t          |j                  r|                                S t          |t                    rt          fd|j        D              S t          |t                    rq|                                \  }}t          |          dk    r	t          | S t          j        | t          |           }t          |          dk    rt          | |z  n|S t          |t                     rLt#          |j        d                   rt#          |j        d                   r|S t          j        | |          S t#          |          r|S t          j        | |          S )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]])tracec                 0    g | ]}t          |          S r   )r6   )r   argr"   s     r   r    zTr.__new__.<locals>.<listcomp>   s#    ???cC))???r   )r$   r   r'   r   tuple
ValueErrorr
   r9   hasattrcallabler   r3   r   args_cncr   __new__r   r   )clsr3   exprc_partnc_partobjr"   s         @r   rA   z
Tr.__new__n   s    IIN 	4d1geU';<< *Q..a/7DD$ii1n 	4ggG7DD 3 4 4 4 dF## 	4::<<T7## 	4(<(< 	4::<<c"" 	4????TY???@@c"" 	4"mmooOFG7||q  DF|#l3Ww@@ ,/v;;?CsF|C''Cc"" 
	449Q<(( 8ty|,,8|Cw7774   <T7333r   c                 8    | j         d         }|j        }|j        S )Nr   )r3   kindelement_kind)selfrC   	expr_kinds      r   rH   zTr.kind   s    y|I	%%r   c                     t          | j        d         d          r,| j        d                             | 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"   )r>   r3   rM   )rJ   hintss     r   doitzTr.doit   sE     49Q<// 	B9Q<++DIaL+AAAr   c                     dS )NTr   )rJ   s    r   	is_numberzTr.is_number   s	     tr   c                 h   |dk    r#|t          | j        d         j                  z  }n0t          |          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$   r3   absr'   r6   r   )rJ   posr3   s      r   permutez
Tr.permute   s    * 7 	7DIaL-...CCHHs49Q<#45556CDIaL%sdee,ty|/@C4/HHI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   r3   r   r0   r4   r<   )rJ   r3   s     r   _hashable_contentzTr._hashable_content   sa    dilC(( 	"!/$)A,2C"D"DEEDDIaL>DT{{dil---r   N)__name__
__module____qualname____doc__rA   propertyrH   rO   rQ   rU   rW   r   r   r   r6   r6   O   s         <34 34 34j & & X&
  $   X     <. . . . .r   r6   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   r0   r4   r6   r   r   r   <module>re      s         ' ' ' ' ' '                               / / / / / / & & & & & & ! ! ! ! ! !  % % %P
 
 
W. W. W. W. W. W. W. W. W. W.r   