
    \hL                     8   S r SSKJr  SSKJr  SSKJr  SSKJrJ	r	  SSK
Jr  SSKJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSKJrJr  SSKJr  SSKJr  / SQr " S S\5      r " S S\5      r " S S\5      r  " S S\5      r! " S S\5      r" " S S\5      r#g)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)OperatorKind)QExprdispatch_method)eye)sympy_deprecation_warning)OperatorHermitianOperatorUnitaryOperatorIdentityOperatorOuterProductDifferentialOperatorc                       \ rS rSr% SrSr\\   \S'   Sr	\\   \S'   \
S 5       r\rSrS r\rS	 rS
 rS rS rS rS rS rS rS rS r\rS rSrg)r   *   aJ  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                     g)N)O selfs    V/var/www/auris/envauris/lib/python3.13/site-packages/sympy/physics/quantum/operator.pydefault_argsOperator.default_argsn   s        ,c                 .    U R                   R                  $ N)	__class____name__r#   printerargss      r$   _print_operator_nameOperator._print_operator_namez   s    ~~&&&r'   c                 @    [        U R                  R                  5      $ r*   )r   r+   r,   r-   s      r$   _print_operator_name_pretty$Operator._print_operator_name_pretty   s    $..1122r'   c                     [        U R                  5      S:X  a  U R                  " U/UQ76 $ U R                  " U/UQ76 < SU R                  " U/UQ76 < S3$ )N   ())lenlabel_print_labelr0   r-   s      r$   _print_contentsOperator._print_contents   sZ    tzz?a$$W4t44 ))'9D9!!'1D1 r'   c                    [        U R                  5      S:X  a  U R                  " U/UQ76 $ U R                  " U/UQ76 nU R                  " U/UQ76 n[	        UR                  SSS96 n[	        UR                  U5      6 nU$ )Nr6   r7   r8   leftright)r9   r:   _print_label_prettyr3   r   parensrA   r#   r.   r/   pformlabel_pforms        r$   _print_contents_prettyOperator._print_contents_pretty   s    tzz?a++G;d;;44WDtDE227BTBK$##C#8K K 89ELr'   c                     [        U R                  5      S:X  a  U R                  " U/UQ76 $ U R                  " U/UQ76 < SU R                  " U/UQ76 < S3$ )Nr6   z\left(z\right))r9   r:   _print_label_latex_print_operator_name_latexr-   s      r$   _print_contents_latexOperator._print_contents_latex   sZ    tzz?a**7:T:: //?$?''7$7 r'   c                     [        U SU40 UD6$ )z:Evaluate [self, other] if known, return None if not known._eval_commutatorr   r#   otheroptionss      r$   rO   Operator._eval_commutator   s    t%7J'JJr'   c                     [        U SU40 UD6$ )z Evaluate [self, other] if known._eval_anticommutatorrP   rQ   s      r$   rV   Operator._eval_anticommutator   s    t%;UNgNNr'   c                     [        U SU40 UD6$ )N_apply_operatorrP   r#   ketrS   s      r$   rY   Operator._apply_operator   s    t%6GwGGr'   c                     g r*   r!   r#   brarS   s      r$   _apply_from_right_toOperator._apply_from_right_to   s    r'   c                     [        S5      e)Nzmatrix_elements is not defined)NotImplementedError)r#   r/   s     r$   matrix_elementOperator.matrix_element   s    !"BCCr'   c                 "    U R                  5       $ r*   _eval_inverser"   s    r$   inverseOperator.inverse       !!##r'   c                     U S-  $ Nr!   r"   s    r$   rh   Operator._eval_inverse   s    bzr'   r!   )r,   
__module____qualname____firstlineno____doc__r   r   bool__annotations__r   classmethodr%   r   kind_label_separatorr0   rK   r3   r<   rG   rL   rO   rV   rY   r`   rd   ri   invrh   __static_attributes__r!   r'   r$   r   r   *   s    @B $(L(4.'!%J%  D ' "63
KOHD$ Cr'   r   c                   (    \ rS rSrSrSrS rS rSrg)r      ad  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                 Z    [        U [        5      (       a  U $ [        R                  U 5      $ r*   )
isinstancer   r   rh   r"   s    r$   rh   HermitianOperator._eval_inverse   s%    dO,,K))$//r'   c                     [        U [        5      (       a6  UR                  (       a  SSKJn  UR
                  $ UR                  (       a  U $ [        R                  X5      $ )Nr   r   )	r~   r   is_evensympy.core.singletonr   Oneis_oddr   _eval_power)r#   expr   s      r$   r   HermitianOperator._eval_power   s?    dO,,{{2uu##D..r'   r!   N)	r,   rp   rq   rr   rs   r   rh   r   rz   r!   r'   r$   r   r      s    $ L0	/r'   r   c                   "    \ rS rSrSrSrS rSrg)r      ab  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                 "    U R                  5       $ r*   rg   r"   s    r$   _eval_adjointUnitaryOperator._eval_adjoint   rk   r'   r!   N)r,   rp   rq   rr   rs   r   r   rz   r!   r'   r$   r   r      s    " J$r'   r   c                       \ rS rSrSrSrSr\S 5       r\	S 5       r
S rS rS rS	 rS
 rS rS rS rS rS rS rS rSrg)r      a  An identity operator I that satisfies op * I == I * op == op for any
operator op.

.. deprecated:: 1.14.
    Use the scalar S.One instead as the multiplicative identity for
    operators and states.

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() # doctest: +SKIP
I
Tc                     U R                   $ r*   Nr"   s    r$   	dimensionIdentityOperator.dimension  s    vvr'   c                     [         4$ r*   r	   r"   s    r$   r%   IdentityOperator.default_args  s	    ur'   c                     [        SSSS9  [        U5      S;  a  [        SU-  5      e[        U5      S:X  a  US   (       a  US   U l        g [        U l        g )	Nz
            IdentityOperator has been deprecated. In the future, please use
            S.One as the identity for quantum operators and states.
            z1.14zdeprecated-operator-identity)deprecated_since_versionactive_deprecations_target)r   r6   z"0 or 1 parameters expected, got %sr6   r   )r   r9   
ValueErrorr
   r   )r#   r/   hintss      r$   __init__IdentityOperator.__init__   sW    ! &,'E	
 4yF"ADHII Y!^Qabr'   c                 "    [         R                  $ r*   )r   Zeror#   rR   r   s      r$   rO   !IdentityOperator._eval_commutator.  s    vvr'   c                     SU-  $ )N   r!   r   s      r$   rV   %IdentityOperator._eval_anticommutator1  s    5yr'   c                     U $ r*   r!   r"   s    r$   rh   IdentityOperator._eval_inverse4      r'   c                     U $ r*   r!   r"   s    r$   r   IdentityOperator._eval_adjoint7  r   r'   c                     U$ r*   r!   rZ   s      r$   rY    IdentityOperator._apply_operator:      
r'   c                     U$ r*   r!   r^   s      r$   r`   %IdentityOperator._apply_from_right_to=  r   r'   c                     U $ r*   r!   )r#   r   s     r$   r   IdentityOperator._eval_power@  r   r'   c                     gNIr!   r-   s      r$   r<    IdentityOperator._print_contentsC  s    r'   c                     [        S5      $ r   r   r-   s      r$   rG   'IdentityOperator._print_contents_prettyF  s    #r'   c                     g)Nz{\mathcal{I}}r!   r-   s      r$   rL   &IdentityOperator._print_contents_latexI  s    r'   c                     U R                   (       a  U R                   [        :X  a  [        S5      eUR                  SS5      nUS:w  a  [        SSU-  -   5      e[	        U R                   5      $ )NzCCannot represent infinite dimensional identity operator as a matrixformatsympyzRepresentation in format z%s not implemented.)r   r
   rc   getr   )r#   rS   r   s      r$   _represent_default_basis)IdentityOperator._represent_default_basisL  sr    vv2% 'G H H Xw/W%&A&;f&D'E F F 466{r'   r   N)r,   rp   rq   rr   rs   r   r   propertyr   rv   r%   r   rO   rV   rh   r   rY   r`   r   r<   rG   rL   r   rz   r!   r'   r$   r   r      sv    * LJ   A 
r'   r   c                   l    \ rS rSrSrSrS r\S 5       r\S 5       r	S r
S rS	 rS
 rS rS rS rSrg)r   iY  aG  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

    >>> 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 quantum expressions, outer products will be automatically
identified and created::

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

However, the creation of inner products always has higher priority than that of
outer products:

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

References
==========

.. [1] https://en.wikipedia.org/wiki/Outer_product
Fc           	      `   SSK JnJn  [        U5      S:w  a  [	        S[        U5      -  5      e[        US   5      n[        US   5      n[        XS[        45      (       Ga=  [        Xd[        45      (       Ga&  UR                  5       u  pxUR                  5       u  p[        U5      S:w  d  [        US   U5      (       d  [        S[        U6 -  5      e[        U
5      S:w  d  [        U
S   U5      (       d  [        S[        U
6 -  5      eUS   R                  5       U
S   R                  :X  d-  [        SUS   R                  < S	U
S   R                  < 35      e[        R                  " U /US   U
S   4Q70 UD6nUS   R                  Ul        [        Xy-   6 U-  $ / n[        U[        5      (       aW  [        U[        5      (       aB  UR                    H1  nUR                    H  nUR#                  [%        X40 UD65        M      M3     O[        U[        5      (       a/  UR                    H  nUR#                  [%        X40 UD65        M      OW[        U[        5      (       a/  UR                    H  nUR#                  [%        X^40 UD65        M      O[        S
U< S	U< 35      e[        U6 $ )Nr   )KetBaseBraBaser   z2 parameters expected, got %dr6   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   r9   r   r   r~   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   OuterProduct.__new__  s   @t9><s4yHII$q'?$q'?x3008s^44"++-KE"++-KE4yA~ZQ%A%A !,.14j!9 : : 4yA~ZQ%A%A !,.14j!9 : : 7%%'47+<+<<!W&&Q(9(9;  ,,sKd1gtAw%7K?KC $Q 5 5C(3..h$$Hc)B)B$MM (HOOL %D3B%D E !. * #&&$MMX !@/>!@ A * #&&$MMX !@/>!@ A * 8% 
 H~r'   c                      U R                   S   $ )z5Return the ket on the left side of the outer product.r   r/   r"   s    r$   r[   OuterProduct.ket       yy|r'   c                      U R                   S   $ )z6Return the bra on the right side of the outer product.r6   r   r"   s    r$   r_   OuterProduct.bra  r   r'   c                 f    [        [        U R                  5      [        U R                  5      5      $ r*   )r   r   r_   r[   r"   s    r$   r   OuterProduct._eval_adjoint  s!    F488,fTXX.>??r'   c                 p    UR                  U R                  5      UR                  U R                  5      -   $ r*   _printr[   r_   r-   s      r$   	_sympystrOuterProduct._sympystr  s'    ~~dhh''..*BBBr'   c                     U R                   R                  < SUR                  " U R                  /UQ76 < SUR                  " U R                  /UQ76 < S3$ )Nr7   r(   r8   )r+   r,   r   r[   r_   r-   s      r$   
_sympyreprOuterProduct._sympyrepr  sD    "nn55NN488+d+W^^DHH-Lt-LN 	Nr'   c                     U R                   R                  " U/UQ76 n[        UR                  U R                  R                  " U/UQ76 5      6 $ r*   )r[   _prettyr   rA   r_   )r#   r.   r/   rE   s       r$   r   OuterProduct._pretty  sC      0405;;txx'7'7'G$'GHIIr'   c                 ~    UR                   " U R                  /UQ76 nUR                   " U R                  /UQ76 nX4-   $ r*   r   )r#   r.   r/   kbs        r$   _latexOuterProduct._latex  s7    NN488+d+NN488+d+ur'   c                 z    U R                   R                  " S0 UD6nU R                  R                  " S0 UD6nX#-  $ )Nr!   )r[   
_representr_   )r#   rS   r   r   s       r$   r   OuterProduct._represent  s7    HH*'*HH*'*s
r'   c                 P    U R                   R                  " U R                  40 UD6$ r*   )r[   _eval_tracer_   )r#   kwargss     r$   r   OuterProduct._eval_trace  s"     xx##DHH777r'   r!   N)r,   rp   rq   rr   rs   is_commutativer   r   r[   r_   r   r   r   r   r   r   r   rz   r!   r'   r$   r   r   Y  sd    3h N6p    @CNJ

8r'   r   c                   p    \ rS rSrSr\S 5       r\S 5       r\S 5       r\S 5       r	S r
S rS	 rS
 rSrg)r   i  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    U R                   S   R                   $ )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)
rn   r   r"   s    r$   	variablesDifferentialOperator.variables  s    . yy}!!!r'   c                      U R                   S   $ )a  
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)
rn   r   r"   s    r$   functionDifferentialOperator.function4  s    , yy}r'   c                      U R                   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$   exprDifferentialOperator.exprL  s    . yy|r'   c                 .    U R                   R                  $ )z,
Return the free symbols of the expression.
)r   free_symbolsr"   s    r$   r  !DifferentialOperator.free_symbolse  s     yy%%%r'   c                     SSK Jn  U R                  nUR                  SS  nU R                  nU R
                  R                  Xa" U6 5      nUR                  5       nU" U/UQ76 $ )Nr   )Wavefunctionr6   )r   r  r   r/   r   r   subsdoit)r#   funcrS   r  varwf_varsfnew_exprs           r$   _apply_operator_Wavefunction1DifferentialOperator._apply_operator_Wavefunctionm  sY    <nn))AB-MM99>>!T3Z0==?H/w//r'   c                 ^    [        U R                  U5      n[        X R                  S   5      $ rm   )r   r   r   r/   )r#   symbolr  s      r$   _eval_derivative%DifferentialOperator._eval_derivativex  s%    dii0#Hiim<<r'   c                 Z    U R                   " U/UQ76 < SU R                  " U/UQ76 < S3$ )Nr7   r8   )r0   r;   r-   s      r$   r   DifferentialOperator._print  s2    %%g55g--
 	
r'   c                     U R                   " U/UQ76 nU R                  " U/UQ76 n[        UR                  SSS96 n[        UR	                  U5      6 nU$ )Nr7   r8   r?   )r3   rB   r   rC   rA   rD   s        r$   _print_pretty"DifferentialOperator._print_pretty  sc    00@4@..w>> S4
 EKK45r'   r!   N)r,   rp   rq   rr   rs   r   r   r   r   r  r  r  r   r  rz   r!   r'   r$   r   r     sl    'R " "0  .  0 & &	0=
r'   r   N)$rs   typingr   sympy.core.addr   sympy.core.exprr   sympy.core.functionr   r   sympy.core.mulr   sympy.core.numbersr
   r   r    sympy.printing.pretty.stringpictr   sympy.physics.quantum.daggerr   sympy.physics.quantum.kindr   sympy.physics.quantum.qexprr   r   sympy.matricesr   sympy.utilities.exceptionsr   __all__r   r   r   r   r   r   r!   r'   r$   <module>r%     s   	     4  ! " 7 / 3 >  @Uu Up$/ $/N$h $.Vx VrU88 U8p\8 \r'   