
    sgdL                         d 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 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 g dZ G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Zy)a  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.
    )Optional)Add)Expr)
Derivativeexpand)MulooS
prettyForm)Dagger)QExprdispatch_method)eye)OperatorHermitianOperatorUnitaryOperatorIdentityOperatorOuterProductDifferentialOperatorc                       e Zd ZU dZdZee   ed<   dZee   ed<   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d ZeZd Zd Zy)r   a
  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 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 do not 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
    Nis_hermitian
is_unitaryc                      y)N)O selfs    Q/var/www/html/venv/lib/python3.12/site-packages/sympy/physics/quantum/operator.pydefault_argszOperator.default_argsj   s        ,c                 .    | j                   j                  S N)	__class____name__r    printerargss      r!   _print_operator_namezOperator._print_operator_namet   s    ~~&&&r#   c                 @    t        | j                  j                        S r&   )r   r'   r(   r)   s      r!   _print_operator_name_prettyz$Operator._print_operator_name_prettyy   s    $..1122r#   c                     t        | j                        dk(  r | j                  |g| S  | j                  |g| d | j                  |g| dS )N   ())lenlabel_print_labelr,   r)   s      r!   _print_contentszOperator._print_contents|   s`    tzz?a$4$$W4t44 *))'9D9!!!'1D1 r#   c                    t        | j                        dk(  r | j                  |g| S  | j                  |g| } | j                  |g| }t	        |j                  dd       }t	        |j                  |       }|S )Nr0   r1   r2   leftright)r3   r4   _print_label_prettyr.   r   parensr:   r    r*   r+   pformlabel_pforms        r!   _print_contents_prettyzOperator._print_contents_pretty   s    tzz?a+4++G;d;;4D44WDtDE2$227BTBK$##C#8K K 89ELr#   c                     t        | j                        dk(  r | j                  |g| S  | j                  |g| d | j                  |g| dS )Nr0   z\left(z\right))r3   r4   _print_label_latex_print_operator_name_latexr)   s      r!   _print_contents_latexzOperator._print_contents_latex   s`    tzz?a*4**7:T:: 0//?$?'''7$7 r#   c                     t        | d|fi |S )z:Evaluate [self, other] if known, return None if not known._eval_commutatorr   r    otheroptionss      r!   rF   zOperator._eval_commutator   s    t%7J'JJr#   c                     t        | d|fi |S )z Evaluate [self, other] if known._eval_anticommutatorrG   rH   s      r!   rL   zOperator._eval_anticommutator   s    t%;UNgNNr#   c                     t        | d|fi |S )N_apply_operatorrG   r    ketrJ   s      r!   rN   zOperator._apply_operator   s    t%6GwGGr#   c                      y r&   r   r    brarJ   s      r!   _apply_from_right_tozOperator._apply_from_right_to   s    r#   c                     t        d      )Nzmatrix_elements is not defined)NotImplementedError)r    r+   s     r!   matrix_elementzOperator.matrix_element   s    !"BCCr#   c                 "    | j                         S r&   _eval_inverser   s    r!   inversezOperator.inverse       !!##r#   c                     | dz  S Nr   r   s    r!   rZ   zOperator._eval_inverse   s    bzr#   c                 >    t        |t              r| S t        | |      S r&   )
isinstancer   r   r    rI   s     r!   __mul__zOperator.__mul__   s    e-.K4r#   )r(   
__module____qualname____doc__r   r   bool__annotations__r   classmethodr"   _label_separatorr,   rC   r.   r6   r@   rD   rF   rL   rN   rT   rW   r[   invrZ   rc   r   r#   r!   r   r   &   s    @B $(L(4.'!%J%  ' "63
KOHD$ C r#   r   c                        e Zd ZdZdZd Zd Zy)r   a  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
    Tc                 P    t        | t              r| S t        j                  |       S r&   )ra   r   r   rZ   r   s    r!   rZ   zHermitianOperator._eval_inverse   s"    dO,K))$//r#   c                     t        | t              r,|j                  rddlm} |j
                  S |j                  r| S t        j                  | |      S )Nr   r   )	ra   r   is_evensympy.core.singletonr   Oneis_oddr   _eval_power)r    expr   s      r!   rs   zHermitianOperator._eval_power   s>    dO,{{2uu##D#..r#   N)r(   rd   re   rf   r   rZ   rs   r   r#   r!   r   r      s    $ L0	/r#   r   c                       e Zd ZdZdZd Zy)r   a  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
    Tc                 "    | j                         S r&   rY   r   s    r!   _eval_adjointzUnitaryOperator._eval_adjoint   r\   r#   N)r(   rd   re   rf   r   rw   r   r#   r!   r   r      s    " J$r#   r   c                       e Zd ZdZd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d Zy)r   a  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
    Tc                     | j                   S r&   )Nr   s    r!   	dimensionzIdentityOperator.dimension  s    vvr#   c                     t         fS r&   r	   r   s    r!   r"   zIdentityOperator.default_args  s	    ur#   c                     t        |      dvrt        d|z        t        |      dk(  r|d   r|d   | _        y t        | _        y )N)r   r0   z"0 or 1 parameters expected, got %sr0   r   )r3   
ValueErrorr
   rz   )r    r+   hintss      r!   __init__zIdentityOperator.__init__  s@    4yF"ADHII Y!^Qabr#   c                 "    t         j                  S r&   )r   Zeror    rI   r   s      r!   rF   z!IdentityOperator._eval_commutator#  s    vvr#   c                     d|z  S )N   r   r   s      r!   rL   z%IdentityOperator._eval_anticommutator&  s    5yr#   c                     | S r&   r   r   s    r!   rZ   zIdentityOperator._eval_inverse)      r#   c                     | S r&   r   r   s    r!   rw   zIdentityOperator._eval_adjoint,  r   r#   c                     |S r&   r   rO   s      r!   rN   z IdentityOperator._apply_operator/      
r#   c                     |S r&   r   rR   s      r!   rT   z%IdentityOperator._apply_from_right_to2  r   r#   c                     | S r&   r   )r    rt   s     r!   rs   zIdentityOperator._eval_power5  r   r#   c                      yNIr   r)   s      r!   r6   z IdentityOperator._print_contents8  s    r#   c                     t        d      S r   r   r)   s      r!   r@   z'IdentityOperator._print_contents_pretty;  s    #r#   c                      y)Nz{\mathcal{I}}r   r)   s      r!   rD   z&IdentityOperator._print_contents_latex>  s    r#   c                 J    t        |t        t        f      r|S t        | |      S r&   )ra   r   r   r   rb   s     r!   rc   zIdentityOperator.__mul__A  s#    eh/0L4r#   c                     | j                   r| j                   t        k(  rt        d      |j                  dd      }|dk7  rt        dd|z  z         t	        | j                         S )NzCCannot represent infinite dimensional identity operator as a matrixformatsympyzRepresentation in format z%s not implemented.)rz   r
   rV   getr   )r    rJ   r   s      r!   _represent_default_basisz)IdentityOperator._represent_default_basisH  sr    vv2% 'G H H Xw/W%&A&;f&D'E F F 466{r#   N)r(   rd   re   rf   r   r   propertyr{   ri   r"   r   rF   rL   rZ   rw   rN   rT   rs   r6   r@   rD   rc   r   r   r#   r!   r   r     s{    " LJ   A  
r#   r   c                   d    e Zd ZdZdZd Zed        Zed        Zd Z	d Z
d Zd	 Zd
 Zd Zd Zy)r   a  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
    Fc           	         ddl m}m} t        |      dk7  rt	        dt        |      z        t        |d         }t        |d         }t        ||t        f      r,t        ||t        f      r|j                         \  }}|j                         \  }	}
t        |      dk7  st        |d   |      st        dt        | z        t        |
      dk7  st        |
d   |      st        dt        |
 z        |d   j                         |
d   j                  k(  s+t        d|d   j                  d	|
d   j                        t        j                  | g|d   |
d   fi |}|d   j                  |_        t        ||	z    |z  S g }t        |t              rVt        |t              rF|j                   D ]/  }|j                   D ]  }|j#                  t%        ||fi |         1 t        | S t        |t              r5|j                   D ]  }|j#                  t%        ||fi |         t        | S t        |t              r5|j                   D ]  }|j#                  t%        ||fi |         t        | S t        d
|d	|      )Nr   )KetBaseBraBaser   z2 parameters expected, got %dr0   z"KetBase subclass expected, got: %rz"BraBase subclass expected, got: %rz"ket and bra are not dual classes: z, z&Expected ket and bra expression, got: )sympy.physics.quantum.stater   r   r3   r~   r   ra   r   args_cnc	TypeError
dual_classr'   r   __new__hilbert_spacer   r+   appendr   )clsr+   old_assumptionsr   r   ket_exprbra_exprket_cketsbra_cbrasobjop_termsket_termbra_terms                  r!   r   zOuterProduct.__new__  s   @t9><s4yHII$q'?$q'?x'308gs^4"++-KE4"++-KE44yA~ZQ%A !,.14j!9 : : 4yA~ZQ%A !,.14j!9 : : 7%%'47+<+<<!W&&Q(9(9;  ,,sKd1gtAw%7K?KC $Q 5 5C(3..h$Hc)B$MM E ( EHOOL8 %D3B%D EEE$ H~ #&$MM AXx !@/>!@ AA H~ #&$MM AXx !@/>!@ AA H~ 8% r#   c                      | j                   d   S )z5Return the ket on the left side of the outer product.r   r+   r   s    r!   rP   zOuterProduct.ket       yy|r#   c                      | j                   d   S )z6Return the bra on the right side of the outer product.r0   r   r   s    r!   rS   zOuterProduct.bra  r   r#   c                 f    t        t        | j                        t        | j                              S r&   )r   r   rS   rP   r   s    r!   rw   zOuterProduct._eval_adjoint  s!    F488,fTXX.>??r#   c                 p    |j                  | j                        |j                  | j                        z   S r&   _printrP   rS   r)   s      r!   	_sympystrzOuterProduct._sympystr  s'    ~~dhh''..*BBBr#   c                     | j                   j                  d |j                  | j                  g| d |j                  | j                  g| dS )Nr1   r$   r2   )r'   r(   r   rP   rS   r)   s      r!   
_sympyreprzOuterProduct._sympyrepr  sH    "nn55GNN488+d+^W^^DHH-Lt-LN 	Nr#   c                      | j                   j                  |g| }t        |j                   | j                  j                  |g|        S r&   )rP   _prettyr   r:   rS   )r    r*   r+   r>   s       r!   r   zOuterProduct._pretty  sH       0405;;'7txx'7'7'G$'GHIIr#   c                      |j                   | j                  g| } |j                   | j                  g| }||z   S r&   r   )r    r*   r+   kbs        r!   _latexzOuterProduct._latex  s=    GNN488+d+GNN488+d+1ur#   c                 |     | j                   j                  di |} | j                  j                  di |}||z  S )Nr   )rP   
_representrS   )r    rJ   r   r   s       r!   r   zOuterProduct._represent  s=    DHH*'*DHH*'*s
r#   c                 P     | j                   j                  | j                  fi |S r&   )rP   _eval_tracerS   )r    kwargss     r!   r   zOuterProduct._eval_trace  s$     $txx##DHH777r#   N)r(   rd   re   rf   is_commutativer   r   rP   rS   rw   r   r   r   r   r   r   r   r#   r!   r   r   U  sd    ;x N6p    @CNJ

8r#   r   c                   h    e Zd ZdZed        Zed        Zed        Zed        Zd Z	d Z
d Zd	 Zy
)r   a+  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                 4    | j                   d   j                   S )a  
        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)
        r_   r   r   s    r!   	variableszDifferentialOperator.variables  s    . yy}!!!r#   c                      | j                   d   S )ad  
        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)
        r_   r   r   s    r!   functionzDifferentialOperator.function8  s    , yy}r#   c                      | j                   d   S )a  
        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)
        r   r   r   s    r!   exprzDifferentialOperator.exprP  s    . yy|r#   c                 .    | j                   j                  S )z<
        Return the free symbols of the expression.
        )r   free_symbolsr   s    r!   r   z!DifferentialOperator.free_symbolsi  s     yy%%%r#   c                     ddl m} | j                  }|j                  dd  }| j                  }| j
                  j                  | ||       }|j                         } ||g| S )Nr   )Wavefunctionr0   )r   r   r   r+   r   r   subsdoit)r    funcrJ   r   varwf_varsfnew_exprs           r!   _apply_operator_Wavefunctionz1DifferentialOperator._apply_operator_Wavefunctionq  sY    <nn))AB-MM99>>!T3Z0==?H/w//r#   c                 `    t        | j                  |      }t        || j                  d         S r^   )r   r   r   r+   )r    symbolr   s      r!   _eval_derivativez%DifferentialOperator._eval_derivative|  s'    dii0#Hdiim<<r#   c                 V     | j                   |g| d | j                  |g| dS )Nr1   r2   )r,   r5   r)   s      r!   r   zDifferentialOperator._print  s6    %D%%g55Dg--
 	
r#   c                      | j                   |g| } | j                  |g| }t        |j                  dd       }t        |j	                  |       }|S )Nr1   r2   r8   )r.   r;   r   r<   r:   r=   s        r!   _print_prettyz"DifferentialOperator._print_pretty  sg    000@4@.d..w>> S4
 EKK45r#   N)r(   rd   re   rf   r   r   r   r   r   r   r   r   r   r   r#   r!   r   r     sl    'R " "0  .  0 & &	0=
r#   r   N) rf   typingr   sympy.core.addr   sympy.core.exprr   sympy.core.functionr   r   sympy.core.mulr   sympy.core.numbersr
   rp   r    sympy.printing.pretty.stringpictr   sympy.physics.quantum.daggerr   sympy.physics.quantum.qexprr   r   sympy.matricesr   __all__r   r   r   r   r   r   r   r#   r!   <module>r      s   	     4  ! " 7 / > Z u Z z$/ $/N$h $.Qx Qh]88 ]8@\8 \r#   