B
    [                 @   s   d Z ddlmZmZ ddlmZmZmZmZ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mZ dd
lmZmZmZmZ ddlmZ dgZdd Zdd Z dS )z}Logic for applying operators to states.

Todo:
* Sometimes the final result needs to be expanded, we should do this by hand.
    )print_functiondivision)AddMulPowsympifyS)range)AntiCommutator)
Commutator)Dagger)InnerProduct)OuterProductOperator)StateKetBaseBraBaseWavefunction)TensorProductqapplyc                s$  ddl m}  dd}| dkr&tjS | jddd} t| trB| S t| trtd}x| j	D ]}|t
|f 7 }qXW |S t| |r fdd| j	D }|| S t| trt fd	d| j	D  S t| trt
| jf | j S t| trt| f }|| kr|rttt| f S |S n| S d
S )a_  Apply operators to states in a quantum expression.

    Parameters
    ==========

    e : Expr
        The expression containing operators and states. This expression tree
        will be walked to find operators acting on states symbolically.
    options : dict
        A dict of key/value pairs that determine how the operator actions
        are carried out.

        The following options are valid:

        * ``dagger``: try to apply Dagger operators to the left
          (default: False).
        * ``ip_doit``: call ``.doit()`` in inner products when they are
          encountered (default: True).

    Returns
    =======

    e : Expr
        The original expression, but with the operators applied to states.

    Examples
    ========

        >>> from sympy.physics.quantum import qapply, Ket, Bra
        >>> b = Bra('b')
        >>> k = Ket('k')
        >>> A = k * b
        >>> A
        |k><b|
        >>> qapply(A * b.dual / (b * b.dual))
        |k>
        >>> qapply(k.dual * A / (k.dual * k), dagger=True)
        <b|
        >>> qapply(k.dual * A / (k.dual * k))
        <k|*|k><b|/<k|k>
    r   )DensitydaggerFT)Z
commutatortensorproductc                s    g | ]\}}t |f |fqS  )r   ).0stateZprob)optionsr   ;lib/python3.7/site-packages/sympy/physics/quantum/qapply.py
<listcomp>d   s    zqapply.<locals>.<listcomp>c                s   g | ]}t |f qS r   )r   )r   t)r   r   r   r   j   s    N)Zsympy.physics.quantum.densityr   getr   Zeroexpand
isinstancer   r   argsr   r   r   baseexpr   
qapply_Mulr   )er   r   r   resultargZnew_argsr   )r   r   r      s4    *






c                s   dd}t| j}t|dks,t| ts0| S | |  tjrTtt	rht jrlt t	sl| S t t
r jjr| j jd    j t tr| j  j t ttfr,  }t|trt| j||jd g  | j||jd g   fS t| j| |  fS t trtdd  jD rttrtdd jD rt jtjkrt fddtt jD  jdd	}t| j| f| S y jf}W n~ ttfk
rX   yj f}W nP ttfk
rR   t t rJtt!rJt" }|rN| }nd }Y nX Y nX |dkrjt#j$S |d krt|dkr| S t| j| g  f S n8t|t"r|t| j| f S t| j| | fS d S )
Nip_doitT   r   c             S   s&   g | ]}t |ttttfp |d kqS )r,   )r#   r   r   r   r   )r   r*   r   r   r   r      s    zqapply_Mul.<locals>.<listcomp>c             S   s&   g | ]}t |ttttfp |d kqS )r,   )r#   r   r   r   r   )r   r*   r   r   r   r      s    c                s(   g | ] }t  j| j|  fqS r   )r   r$   )r   n)lhsr   rhsr   r   r      s    )r   )%r    listr$   lenr#   r   popr   Zis_commutativer   r   r&   Z
is_Integerappendr%   r   ZketZbrar   r
   Zdoitr   r   funcr   allr	   r"   r'   Z_apply_operatorNotImplementedErrorAttributeErrorr   r   r   r   r!   )r(   r   r+   r$   Zcommr)   r   )r.   r   r/   r   r'   ~   s`    

"",



r'   N)!__doc__Z
__future__r   r   Zsympyr   r   r   r   r   Zsympy.core.compatibilityr	   Z$sympy.physics.quantum.anticommutatorr
   Z sympy.physics.quantum.commutatorr   Zsympy.physics.quantum.daggerr   Z"sympy.physics.quantum.innerproductr   Zsympy.physics.quantum.operatorr   r   Zsympy.physics.quantum.stater   r   r   r   Z#sympy.physics.quantum.tensorproductr   __all__r   r'   r   r   r   r   <module>   s   a