ó
¡¼™\c           @  s6  d  Z  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 d l m Z m Z d d l m Z d d	 d
 d d d g Z d e f d „  ƒ  YZ d	 e f d „  ƒ  YZ d
 e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d e f d „  ƒ  YZ d S(   s  Quantum mechanical operators.

TODO:

* Fix early 0 in apply_operators.
* Debug and test apply_operators.
* Get cse working with classes in this file.
* Doctests and documentation of special methods for InnerProduct, Commutator,
  AntiCommutator, represent, apply_operators.
iÿÿÿÿ(   t   print_functiont   division(   t
   Derivativet   Exprt   Integert   oot   Mult   expandt   Add(   t
   prettyForm(   t   Dagger(   t   QExprt   dispatch_method(   t   eyet   Operatort   HermitianOperatort   UnitaryOperatort   IdentityOperatort   OuterProductt   DifferentialOperatorc           B  s›   e  Z d  Z e d „  ƒ Z d Z d „  Z e Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z e Z d „  Z d „  Z RS(   s  Base class for non-commuting quantum operators.

    An operator maps between quantum states [1]_. In quantum mechanics,
    observables (including, but not limited to, measured physical values) are
    represented as Hermitian operators [2]_.

    Parameters
    ==========

    args : tuple
        The list of numbers or parameters that uniquely specify the
        operator. For time-dependent operators, this will include the time.

    Examples
    ========

    Create an operator and examine its attributes::

        >>> from sympy.physics.quantum import Operator
        >>> from sympy import symbols, I
        >>> A = Operator('A')
        >>> A
        A
        >>> A.hilbert_space
        H
        >>> A.label
        (A,)
        >>> A.is_commutative
        False

    Create another operator and do some arithmetic operations::

        >>> B = Operator('B')
        >>> C = 2*A*A + I*B
        >>> C
        2*A**2 + I*B

    Operators don't commute::

        >>> A.is_commutative
        False
        >>> B.is_commutative
        False
        >>> A*B == B*A
        False

    Polymonials of operators respect the commutation properties::

        >>> e = (A+B)**3
        >>> e.expand()
        A*B*A + A*B**2 + A**2*B + A**3 + B*A*B + B*A**2 + B**2*A + B**3

    Operator inverses are handle symbolically::

        >>> A.inv()
        A**(-1)
        >>> A*A.inv()
        1

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Operator_%28physics%29
    .. [2] https://en.wikipedia.org/wiki/Observable
    c         C  s   d S(   Nt   O(   R   (    (   t   self(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   default_argse   s    t   ,c         G  s   | j  |  j j | Œ S(   N(   t   _printt	   __class__t   __name__(   R   t   printert   args(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_operator_nameo   s    c         G  s   t  |  j j ƒ S(   N(   R	   R   R   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_operator_name_prettyt   s    c         G  sO   t  |  j ƒ d k r% |  j | | Œ Sd |  j | | Œ |  j | | Œ f Sd  S(   Ni   s   %s(%s)(   t   lent   labelt   _print_labelR   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_contentsw   s
    c         G  s„   t  |  j ƒ d k r% |  j | | Œ S|  j | | Œ } |  j | | Œ } t | j d d d d ƒ Œ  } t | j | ƒ Œ  } | Sd  S(   Ni   t   leftt   (t   rightt   )(   R   R    t   _print_label_prettyR   R	   t   parensR%   (   R   R   R   t   pformt   label_pform(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_contents_pretty€   s    c         G  sO   t  |  j ƒ d k r% |  j | | Œ Sd |  j | | Œ |  j | | Œ f Sd  S(   Ni   s   %s\left(%s\right)(   R   R    t   _print_label_latext   _print_operator_name_latex(   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_contents_latexŒ   s
    c         K  s   t  |  d | |  S(   s:   Evaluate [self, other] if known, return None if not known.t   _eval_commutator(   R   (   R   t   othert   options(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR/   ™   s    c         K  s   t  |  d | |  S(   s    Evaluate [self, other] if known.t   _eval_anticommutator(   R   (   R   R0   R1   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR2      s    c         K  s   t  |  d | |  S(   Nt   _apply_operator(   R   (   R   t   ketR1   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR3   ¥   s    c         G  s   t  d ƒ ‚ d  S(   Ns   matrix_elements is not defined(   t   NotImplementedError(   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   matrix_element¨   s    c         C  s
   |  j  ƒ  S(   N(   t   _eval_inverse(   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   inverse«   s    c         C  s   |  d S(   Niÿÿÿÿ(    (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR7   °   s    c         C  s    t  | t ƒ r |  St |  | ƒ S(   N(   t
   isinstanceR   R   (   R   R0   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   __mul__³   s    (   R   t
   __module__t   __doc__t   classmethodR   t   _label_separatorR   R-   R   R"   R+   R.   R/   R2   R3   R6   R8   t   invR7   R:   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   "   s"   A												c           B  s&   e  Z d  Z e Z d „  Z d „  Z RS(   s”  A Hermitian operator that satisfies H == Dagger(H).

    Parameters
    ==========

    args : tuple
        The list of numbers or parameters that uniquely specify the
        operator. For time-dependent operators, this will include the time.

    Examples
    ========

    >>> from sympy.physics.quantum import Dagger, HermitianOperator
    >>> H = HermitianOperator('H')
    >>> Dagger(H)
    H
    c         C  s$   t  |  t ƒ r |  St j |  ƒ Sd  S(   N(   R9   R   R   R7   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR7   Ð   s    c         C  sm   t  |  t ƒ rY | d k r+ t j |  | ƒ St | ƒ d d k rR |  t j |  ƒ S|  Sn t j |  | ƒ Sd  S(   Niÿÿÿÿi   i    (   R9   R   R   t   _eval_powert   absR7   (   R   t   exp(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR@   Ö   s    (   R   R;   R<   t   Truet   is_hermitianR7   R@   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   »   s   	c           B  s   e  Z d  Z d „  Z RS(   s’  A unitary operator that satisfies U*Dagger(U) == 1.

    Parameters
    ==========

    args : tuple
        The list of numbers or parameters that uniquely specify the
        operator. For time-dependent operators, this will include the time.

    Examples
    ========

    >>> from sympy.physics.quantum import Dagger, UnitaryOperator
    >>> U = UnitaryOperator('U')
    >>> U*Dagger(U)
    1
    c         C  s
   |  j  ƒ  S(   N(   R7   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _eval_adjointõ   s    (   R   R;   R<   RE   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   â   s   c           B  s˜   e  Z d  Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d	 „  Z d
 „  Z d „  Z d „  Z d „  Z d „  Z RS(   sš  An identity operator I that satisfies op * I == I * op == op for any
    operator op.

    Parameters
    ==========

    N : Integer
        Optional parameter that specifies the dimension of the Hilbert space
        of operator. This is used when generating a matrix representation.

    Examples
    ========

    >>> from sympy.physics.quantum import IdentityOperator
    >>> IdentityOperator()
    I
    c         C  s   |  j  S(   N(   t   N(   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt	   dimension  s    c         C  s   t  f S(   N(   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR     s    c         O  sX   t  | ƒ d k r% t d | ƒ ‚ n  t  | ƒ d k rK | d rK | d n t |  _ d  S(   Ni    i   s"   0 or 1 parameters expected, got %s(   i    i   (   R   t
   ValueErrorR   RF   (   R   R   t   hints(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   __init__  s    c         K  s
   t  d ƒ S(   Ni    (   R   (   R   R0   RI   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR/     s    c         K  s   d | S(   Ni   (    (   R   R0   RI   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR2     s    c         C  s   |  S(   N(    (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR7     s    c         C  s   |  S(   N(    (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRE   "  s    c         K  s   | S(   N(    (   R   R4   R1   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR3   %  s    c         C  s   |  S(   N(    (   R   RB   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR@   (  s    c         G  s   d S(   Nt   I(    (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR"   +  s    c         G  s
   t  d ƒ S(   NRK   (   R	   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR+   .  s    c         G  s   d S(   Ns   {\mathcal{I}}(    (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR.   1  s    c         C  s    t  | t ƒ r | St |  | ƒ S(   N(   R9   R   R   (   R   R0   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR:   4  s    c         K  sn   |  j  s |  j  t k r, t d d ƒ ‚ n  | j d d ƒ } | d k ra t d d | ƒ ‚ n  t |  j  ƒ S(   Ns%   Cannot represent infinite dimensionals    identity operator as a matrixt   formatt   sympys   Representation in format s   %s not implemented.(   RF   R   R5   t   getR   (   R   R1   RL   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _represent_default_basis;  s    (   R   R;   R<   t   propertyRG   R=   R   RJ   R/   R2   R7   RE   R3   R@   R"   R+   R.   R:   RO   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   ù   s   											c           B  sz   e  Z d  Z e Z d „  Z e d „  ƒ Z e d „  ƒ Z d „  Z	 d „  Z
 d „  Z d „  Z d „  Z d	 „  Z d
 „  Z RS(   sÙ  An unevaluated outer product between a ket and bra.

    This constructs an outer product between any subclass of ``KetBase`` and
    ``BraBase`` as ``|a><b|``. An ``OuterProduct`` inherits from Operator as they act as
    operators in quantum expressions.  For reference see [1]_.

    Parameters
    ==========

    ket : KetBase
        The ket on the left side of the outer product.
    bar : BraBase
        The bra on the right side of the outer product.

    Examples
    ========

    Create a simple outer product by hand and take its dagger::

        >>> from sympy.physics.quantum import Ket, Bra, OuterProduct, Dagger
        >>> from sympy.physics.quantum import Operator

        >>> k = Ket('k')
        >>> b = Bra('b')
        >>> op = OuterProduct(k, b)
        >>> op
        |k><b|
        >>> op.hilbert_space
        H
        >>> op.ket
        |k>
        >>> op.bra
        <b|
        >>> Dagger(op)
        |b><k|

    In simple products of kets and bras outer products will be automatically
    identified and created::

        >>> k*b
        |k><b|

    But in more complex expressions, outer products are not automatically
    created::

        >>> A = Operator('A')
        >>> A*k*b
        A*|k>*<b|

    A user can force the creation of an outer product in a complex expression
    by using parentheses to group the ket and bra::

        >>> A*(k*b)
        A*|k><b|

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Outer_product
    c         O  s¼  d d l  m } m } t | ƒ d k rA t d t | ƒ ƒ ‚ n  t | d ƒ } t | d ƒ } t | | t f ƒ r¶t | | t f ƒ r¶| j ƒ  \ } } | j ƒ  \ }	 }
 t | ƒ d k sÕ t | d | ƒ rî t	 d t | Œ  ƒ ‚ n  t |
 ƒ d k st |
 d | ƒ r-t	 d t |
 Œ  ƒ ‚ n  | d j
 ƒ  |
 d j k sqt	 d	 | d j |
 d j f ƒ ‚ n  t j |  | d |
 d f | Ž } | d j | _ t | |	 Œ  | Sg  } t | t ƒ rt | t ƒ rxÕ | j D]3 } x* | j D] } | j t | | |  ƒ qôWqäWn” t | t ƒ r]x‚ | j D] } | j t | | |  ƒ q7WnU t | t ƒ rœxC | j D] } | j t | | |  ƒ qvWn t	 d
 | | f ƒ ‚ t | Œ  S(   Niÿÿÿÿ(   t   KetBaset   BraBasei   s   2 parameters expected, got %di    i   s"   KetBase subclass expected, got: %rs"   BraBase subclass expected, got: %rs(   ket and bra are not dual classes: %r, %rs,   Expected ket and bra expression, got: %r, %r(   t   sympy.physics.quantum.stateRQ   RR   R   RH   R   R9   R   t   args_cnct	   TypeErrort
   dual_classR   R   t   __new__t   hilbert_spaceR   R   t   appendR   (   t   clsR   t   old_assumptionsRQ   RR   t   ket_exprt   bra_exprt   ket_ct   ketst   bra_ct   brast   objt   op_termst   ket_termt   bra_term(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRW   ‡  sP    &&!#c         C  s   |  j  d S(   s5   Return the ket on the left side of the outer product.i    (   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR4   ¿  s    c         C  s   |  j  d S(   s6   Return the bra on the right side of the outer product.i   (   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   braÄ  s    c         C  s   t  t |  j ƒ t |  j ƒ ƒ S(   N(   R   R
   Rf   R4   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRE   É  s    c         G  s   t  |  j ƒ t  |  j ƒ S(   N(   t   strR4   Rf   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt	   _sympystrÌ  s    c         G  s5   d |  j  j | j |  j | Œ | j |  j | Œ f S(   Ns	   %s(%s,%s)(   R   R   R   R4   Rf   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt
   _sympyreprÏ  s    c         G  s7   |  j  j | | Œ } t | j |  j j | | Œ ƒ Œ  S(   N(   R4   t   _prettyR	   R%   Rf   (   R   R   R   R)   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRj   Ó  s    c         G  s2   | j  |  j | Œ } | j  |  j | Œ } | | S(   N(   R   R4   Rf   (   R   R   R   t   kt   b(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _latex×  s    c         K  s,   |  j  j |   } |  j j |   } | | S(   N(   R4   t
   _representRf   (   R   R1   Rk   Rl   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRn   Ü  s    c         K  s   |  j  j |  j |  S(   N(   R4   t   _eval_traceRf   (   R   t   kwargs(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRo   á  s    (   R   R;   R<   t   Falset   is_commutativeRW   RP   R4   Rf   RE   Rh   Ri   Rj   Rm   Rn   Ro   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   H  s   <	8						c           B  sn   e  Z d  Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z e d „  ƒ Z d „  Z d „  Z	 d „  Z
 d „  Z RS(	   s+  An operator for representing the differential operator, i.e. d/dx

    It is initialized by passing two arguments. The first is an arbitrary
    expression that involves a function, such as ``Derivative(f(x), x)``. The
    second is the function (e.g. ``f(x)``) which we are to replace with the
    ``Wavefunction`` that this ``DifferentialOperator`` is applied to.

    Parameters
    ==========

    expr : Expr
           The arbitrary expression which the appropriate Wavefunction is to be
           substituted into

    func : Expr
           A function (e.g. f(x)) which is to be replaced with the appropriate
           Wavefunction when this DifferentialOperator is applied

    Examples
    ========

    You can define a completely arbitrary expression and specify where the
    Wavefunction is to be substituted

    >>> from sympy import Derivative, Function, Symbol
    >>> from sympy.physics.quantum.operator import DifferentialOperator
    >>> from sympy.physics.quantum.state import Wavefunction
    >>> from sympy.physics.quantum.qapply import qapply
    >>> f = Function('f')
    >>> x = Symbol('x')
    >>> d = DifferentialOperator(1/x*Derivative(f(x), x), f(x))
    >>> w = Wavefunction(x**2, x)
    >>> d.function
    f(x)
    >>> d.variables
    (x,)
    >>> qapply(d*w)
    Wavefunction(2, x)

    c         C  s   |  j  d j  S(   s  
        Returns the variables with which the function in the specified
        arbitrary expression is evaluated

        Examples
        ========

        >>> from sympy.physics.quantum.operator import DifferentialOperator
        >>> from sympy import Symbol, Function, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(1/x*Derivative(f(x), x), f(x))
        >>> d.variables
        (x,)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.variables
        (x, y)
        iÿÿÿÿ(   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt	   variables  s    c         C  s   |  j  d S(   sd  
        Returns the function which is to be replaced with the Wavefunction

        Examples
        ========

        >>> from sympy.physics.quantum.operator import DifferentialOperator
        >>> from sympy import Function, Symbol, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(Derivative(f(x), x), f(x))
        >>> d.function
        f(x)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.function
        f(x, y)
        iÿÿÿÿ(   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   function+  s    c         C  s   |  j  d S(   s¯  
        Returns the arbitrary expression which is to have the Wavefunction
        substituted into it

        Examples
        ========

        >>> from sympy.physics.quantum.operator import DifferentialOperator
        >>> from sympy import Function, Symbol, Derivative
        >>> x = Symbol('x')
        >>> f = Function('f')
        >>> d = DifferentialOperator(Derivative(f(x), x), f(x))
        >>> d.expr
        Derivative(f(x), x)
        >>> y = Symbol('y')
        >>> d = DifferentialOperator(Derivative(f(x, y), x) +
        ...                          Derivative(f(x, y), y), f(x, y))
        >>> d.expr
        Derivative(f(x, y), x) + Derivative(f(x, y), y)
        i    (   R   (   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   exprC  s    c         C  s
   |  j  j S(   s<   
        Return the free symbols of the expression.
        (   Ru   t   free_symbols(   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyRv   \  s    c         C  sc   d d l  m } |  j } | j d } |  j } |  j j | | | Œ  ƒ } | j ƒ  } | | | Œ S(   Niÿÿÿÿ(   t   Wavefunctioni   (   RS   Rw   Rs   R   Rt   Ru   t   subst   doit(   R   t   funcRw   t   vart   wf_varst   ft   new_expr(    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _apply_operator_Wavefunctiond  s    		c         C  s&   t  |  j | ƒ } t | |  j d ƒ S(   Niÿÿÿÿ(   R   Ru   R   R   (   R   t   symbolR~   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _eval_derivativeo  s    c         G  s&   d |  j  | | Œ |  j | | Œ f S(   Ns   %s(%s)(   R   R!   (   R   R   R   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   w  s    c         G  s[   |  j  | | Œ } |  j | | Œ } t | j d d d d ƒ Œ  } t | j | ƒ Œ  } | S(   NR#   R$   R%   R&   (   R   R'   R	   R(   R%   (   R   R   R   R)   R*   (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   _print_pretty}  s    (   R   R;   R<   RP   Rs   Rt   Ru   Rv   R   R   R   R‚   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyR   è  s   (			N(   R<   t
   __future__R    R   RM   R   R   R   R   R   R   R   t    sympy.printing.pretty.stringpictR	   t   sympy.physics.quantum.daggerR
   t   sympy.physics.quantum.qexprR   R   t   sympy.matricesR   t   __all__R   R   R   R   R   R   (    (    (    s=   lib/python2.7/site-packages/sympy/physics/quantum/operator.pyt   <module>
   s$   4	™'O 