ó
¡¼™\c           @  sŸ   d  d l  m Z m Z d  d l m Z m Z m Z m Z m Z m	 Z	 m
 Z
 d  d l m Z d  d l m Z d „  Z d „  Z d „  Z d e f d	 „  ƒ  YZ d
 S(   iÿÿÿÿ(   t   print_functiont   division(   t   Exprt   Addt   Mult   Powt   sympifyt   Matrixt   Tuple(   t   range(   t   default_sort_keyc         C  s\   t  |  ƒ }  t |  t ƒ rX |  j sQ |  j sQ |  j sQ |  j sQ |  j rX |  j rX t	 Sn  t
 S(   s    Helper method used in Tr(   R   t
   isinstanceR   t
   is_Integert   is_Floatt   is_Rationalt	   is_Numbert	   is_Symbolt   is_commutativet   Truet   False(   t   e(    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt
   _is_scalar   s    c   	      C  s  t  |  ƒ d k r |  St |  d t ƒ} g  t |  ƒ D] \ } } | | k r5 | ^ q5 } t |  ƒ } | j |  ƒ | j t  |  ƒ | d ƒ g  t t  | ƒ d ƒ D]" } | | | | | d !g ^ q¤ } | j t | ƒ ƒ } | | | | | t  |  ƒ !} | S(   s   Cyclic permutations based on canonical ordering

    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

    i   t   keyi    (	   t   lent   minR
   t	   enumeratet   listt   extendt   appendR	   t   index(	   t   lt   min_itemt   it   xt   indicest   let   sublistt   idxt	   ordered_l(    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   _cycle_permute   s    
1<c         C  sG   t  |  ƒ d k r |  St |  d ƒ } | j |  d d !ƒ t | Œ  j S(   sk    this just moves the last arg to first position
     to enable expansion of args
     A,B,A ==> A**2,B
    i   iÿÿÿÿi    (   R   R   R   R   t   args(   R   R!   (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   _rearrange_args;   s
    t   Trc           B  sA   e  Z d  Z d „  Z d „  Z e d „  ƒ Z d „  Z d „  Z RS(   sw   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.core.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         G  s   t  | ƒ d k r^ t | d t t t f ƒ sA t | d ƒ } n t | d Œ  } | d } n4 t  | ƒ d k r† t ƒ  } | d } n t d ƒ ‚ t | t ƒ r« | j ƒ  St | d ƒ rÓ t	 | j ƒ rÓ | j ƒ  St | t
 ƒ rt
 g  | j D] } t | | ƒ ^ qï Œ  St | t ƒ rŠ| j ƒ  \ } } t  | ƒ d k rHt | Œ  St j |  t | Œ  | ƒ } t  | ƒ d k rƒt | Œ  | S| Snr t | t ƒ rÙt | j d ƒ rÃt | j d ƒ rÃ| St j |  | | ƒ Sn# t | ƒ ré| St j |  | | ƒ Sd S(   s    Construct a Trace object.

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

        i   i   i    s5   Arguments to Tr should be of form (expr[, [indices]])t   traceN(   R   R   R   R   t   tuplet
   ValueErrorR   R+   t   hasattrt   callableR   R(   R*   R   t   args_cncR   t   __new__R   R   (   t   clsR(   R"   t   exprt   argt   c_partt   nc_partt   obj(    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyR1   g   s:    	

)
'c         K  s8   t  |  j d d ƒ r4 |  j d j d |  j d ƒ S|  S(   s{   Perform the trace operation.

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

        >>> from sympy.core.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

        i    t   _eval_traceR"   i   (   R.   R(   R8   (   t   selft   kwargs(    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   doitœ   s    c         C  s   t  S(   N(   R   (   R9   (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt	   is_number®   s    c         C  s‹   | d k r) | t  |  j d j ƒ } n! t | ƒ t  |  j d j ƒ } t |  j d j | |  j d j d | !ƒ } t t | Œ  ƒ S(   sÀ   Permute the arguments cyclically.

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

        Examples
        ========

        >>> from sympy.core.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)

        i    (   R   R(   t   absR   R*   R   (   R9   t   posR(   (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   permuteµ   s
    !1c         C  s]   t  |  j d t ƒ r5 t t |  j d j ƒ ƒ } n |  j d g } t | ƒ |  j d f S(   Ni    i   (   R   R(   R   R'   R)   R,   (   R9   R(   (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   _hashable_contentÒ   s    (	   t   __name__t
   __module__t   __doc__R1   R;   t   propertyR<   R?   R@   (    (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyR*   H   s   	5		N(   t
   __future__R    R   t   sympyR   R   R   R   R   R   R   t   sympy.core.compatibilityR	   t   sympy.utilitiesR
   R   R'   R)   R*   (    (    (    s/   lib/python2.7/site-packages/sympy/core/trace.pyt   <module>   s   4		$	