o
    3IhL                     @   s  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 ddlmZmZ ddlmZ ddlmZ g dZG dd deZG dd deZG dd deZ G dd deZ!G dd deZ"G dd deZ#dS )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                   @   s   e Zd ZU dZdZee ed< dZee ed< e	dd Z
eZdZdd	 ZeZd
d Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZeZdd ZdS ) 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                 C      dS )N)O selfr   r   ^/home/air/sanwanet/gpt-api/venv/lib/python3.10/site-packages/sympy/physics/quantum/operator.pydefault_argsn   s   zOperator.default_args,c                 G      | j jS N)	__class____name__r    printerargsr   r   r!   _print_operator_namez      zOperator._print_operator_namec                 G   s   t | jjS r%   )r   r&   r'   r(   r   r   r!   _print_operator_name_pretty   s   z$Operator._print_operator_name_prettyc                 G   H   t | jdkr| j|g|R  S d| j|g|R  | j|g|R  f S )N   %s(%s))lenlabel_print_labelr+   r(   r   r   r!   _print_contents      zOperator._print_contentsc                 G   sh   t | jdkr| j|g|R  S | j|g|R  }| j|g|R  }t|jddd }t|| }|S )Nr/   ()leftright)r1   r2   _print_label_prettyr-   r   parensr:   r    r)   r*   pformlabel_pformr   r   r!   _print_contents_pretty   s   zOperator._print_contents_prettyc                 G   r.   )Nr/   z%s\left(%s\right))r1   r2   _print_label_latex_print_operator_name_latexr(   r   r   r!   _print_contents_latex   r5   zOperator._print_contents_latexc                 K      t | d|fi |S )z:Evaluate [self, other] if known, return None if not known._eval_commutatorr   r    otheroptionsr   r   r!   rE         zOperator._eval_commutatorc                 K   rD   )z Evaluate [self, other] if known._eval_anticommutatorrF   rG   r   r   r!   rK      rJ   zOperator._eval_anticommutatorc                 K   rD   )N_apply_operatorrF   r    ketrI   r   r   r!   rL      s   zOperator._apply_operatorc                 K   s   d S r%   r   r    brarI   r   r   r!   _apply_from_right_to      zOperator._apply_from_right_toc                 G   s   t d)Nzmatrix_elements is not defined)NotImplementedError)r    r*   r   r   r!   matrix_element   r,   zOperator.matrix_elementc                 C      |   S r%   _eval_inverser   r   r   r!   inverse   r,   zOperator.inversec                 C   s   | d S Nr   r   r   r   r!   rW      r,   zOperator._eval_inverse)r'   
__module____qualname____doc__r   r   bool__annotations__r   classmethodr"   r   kind_label_separatorr+   rB   r-   r4   r@   rC   rE   rK   rL   rQ   rT   rX   invrW   r   r   r   r!   r   *   s,   
 A
	r   c                   @   s$   e Zd ZdZdZdd Zdd ZdS )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                 C   s   t | tr| S t| S r%   )
isinstancer   r   rW   r   r   r   r!   rW      s   

zHermitianOperator._eval_inversec                 C   s8   t | tr|jrddlm} |jS |jr| S t| |S )Nr   r
   )	rd   r   is_evensympy.core.singletonr   Oneis_oddr   _eval_power)r    expr   r   r   r!   ri      s   
zHermitianOperator._eval_powerN)r'   r[   r\   r]   r   rW   ri   r   r   r   r!   r      s
    r   c                   @   s   e Zd ZdZdZdd ZdS )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                 C   rU   r%   rV   r   r   r   r!   _eval_adjoint   r,   zUnitaryOperator._eval_adjointN)r'   r[   r\   r]   r   rk   r   r   r   r!   r      s    r   c                   @   s   e Zd ZdZdZdZedd Zedd Z	dd Z
d	d
 Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS ) 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                 C   s   | j S r%   )Nr   r   r   r!   	dimension     zIdentityOperator.dimensionc                 C   s   t fS r%   r   r   r   r   r!   r"     rn   zIdentityOperator.default_argsc                 O   sR   t dddd t|dvrtd| t|dkr$|d r$|d | _d S t| _d S )	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   r/   z"0 or 1 parameters expected, got %sr/   r   )r   r1   
ValueErrorr	   rl   )r    r*   hintsr   r   r!   __init__   s   ,zIdentityOperator.__init__c                 K   s   t jS r%   )r   Zeror    rH   rr   r   r   r!   rE   .  s   z!IdentityOperator._eval_commutatorc                 K   s   d| S )N   r   ru   r   r   r!   rK   1  r,   z%IdentityOperator._eval_anticommutatorc                 C      | S r%   r   r   r   r   r!   rW   4  rR   zIdentityOperator._eval_inversec                 C   rw   r%   r   r   r   r   r!   rk   7  rR   zIdentityOperator._eval_adjointc                 K      |S r%   r   rM   r   r   r!   rL   :  rR   z IdentityOperator._apply_operatorc                 K   rx   r%   r   rO   r   r   r!   rQ   =  rR   z%IdentityOperator._apply_from_right_toc                 C   rw   r%   r   )r    rj   r   r   r!   ri   @  rR   zIdentityOperator._eval_powerc                 G   r   NIr   r(   r   r   r!   r4   C  rR   z IdentityOperator._print_contentsc                 G   s   t dS ry   r   r(   r   r   r!   r@   F  r,   z'IdentityOperator._print_contents_prettyc                 G   r   )Nz{\mathcal{I}}r   r(   r   r   r!   rC   I  rR   z&IdentityOperator._print_contents_latexc                 K   sF   | j r| j tkrtd|dd}|dkrtdd|  t| j S )NzCCannot represent infinite dimensional identity operator as a matrixformatsympyzRepresentation in format z%s not implemented.)rl   r	   rS   getr   )r    rI   r{   r   r   r!   _represent_default_basisL  s   
z)IdentityOperator._represent_default_basisN)r'   r[   r\   r]   r   r   propertyrm   r`   r"   rs   rE   rK   rW   rk   rL   rQ   ri   r4   r@   rC   r~   r   r   r   r!   r      s(    

r   c                   @   sl   e Zd ZdZdZdd Zedd Zedd Zd	d
 Z	dd Z
dd Zdd Zdd Zdd Zdd ZdS )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

        >>> 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                 O   s
  ddl m}m} t|dkrtdt| t|d }t|d }t||tfrt||tfr| \}}| \}	}
t|dksIt|d |sQt	dt|  t|
dks^t|
d |sft	dt|
  |d 
 |
d jkst	d|d j|
d jf tj| g|d |
d fR i |}|d j|_t||	  | S g }t|trt|tr|jD ]}|jD ]}|t||fi | qqt| S t|tr|jD ]}|t||fi | qt| S t|tr|jD ]}|t||fi | qt| S t	d	||f )
Nr   )KetBaseBraBaserv   z2 parameters expected, got %dr/   z"KetBase subclass expected, got: %rz"BraBase subclass expected, got: %rz(ket and bra are not dual classes: %r, %rz,Expected ket and bra expression, got: %r, %r)sympy.physics.quantum.stater   r   r1   rq   r   rd   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_termr   r   r!   r     sj   $








zOuterProduct.__new__c                 C   
   | j d S )z5Return the ket on the left side of the outer product.r   r*   r   r   r   r!   rN        
zOuterProduct.ketc                 C   r   )z6Return the bra on the right side of the outer product.r/   r   r   r   r   r!   rP     r   zOuterProduct.brac                 C   s   t t| jt| jS r%   )r   r   rP   rN   r   r   r   r!   rk     s   zOuterProduct._eval_adjointc                 G   s   | | j| | j S r%   _printrN   rP   r(   r   r   r!   	_sympystr  s   zOuterProduct._sympystrc                 G   s2   d| j j|j| jg|R  |j| jg|R  f S )Nz	%s(%s,%s))r&   r'   r   rN   rP   r(   r   r   r!   
_sympyrepr  s   $zOuterProduct._sympyreprc                 G   s2   | j j|g|R  }t|| jj|g|R   S r%   )rN   _prettyr   r:   rP   )r    r)   r*   r>   r   r   r!   r     s   zOuterProduct._prettyc                 G   s0   |j | jg|R  }|j | jg|R  }|| S r%   r   )r    r)   r*   kbr   r   r!   _latex  s   zOuterProduct._latexc                 K   s,   | j jdi |}| jjdi |}|| S )Nr   )rN   
_representrP   )r    rI   r   r   r   r   r!   r     s   zOuterProduct._representc                 K   s   | j j| jfi |S r%   )rN   _eval_tracerP   )r    kwargsr   r   r!   r     s   zOuterProduct._eval_traceN)r'   r[   r\   r]   is_commutativer   r   rN   rP   rk   r   r   r   r   r   r   r   r   r   r!   r   Y  s    48

r   c                   @   s`   e Zd ZdZedd Zedd Zedd Zedd	 Zd
d Z	dd Z
dd Zdd ZdS )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                 C   s   | 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)
        rZ   r   r   r   r   r!   	variables  s   zDifferentialOperator.variablesc                 C   r   )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)
        rZ   r   r   r   r   r!   function4  s   
zDifferentialOperator.functionc                 C   r   )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   r   r   r!   exprL  s   
zDifferentialOperator.exprc                 C   r$   )z<
        Return the free symbols of the expression.
        )r   free_symbolsr   r   r   r!   r   e  s   z!DifferentialOperator.free_symbolsc                 K   sP   ddl m} | j}|jdd  }| j}| j||| }| }||g|R  S )Nr   )Wavefunctionr/   )r   r   r   r*   r   r   subsdoit)r    funcrI   r   varwf_varsfnew_exprr   r   r!   _apply_operator_Wavefunctionm  s   z1DifferentialOperator._apply_operator_Wavefunctionc                 C   s   t | j|}t|| jd S rY   )r   r   r   r*   )r    symbolr   r   r   r!   _eval_derivativex  s   z%DifferentialOperator._eval_derivativec                 G   s(   d| j |g|R  | j|g|R  f S )Nr0   )r+   r3   r(   r   r   r!   r     s   zDifferentialOperator._printc                 G   sH   | j |g|R  }| j|g|R  }t|jddd }t|| }|S )Nr6   r7   r8   )r-   r;   r   r<   r:   r=   r   r   r!   _print_pretty  s   z"DifferentialOperator._print_prettyN)r'   r[   r\   r]   r   r   r   r   r   r   r   r   r   r   r   r   r!   r     s    )



r   N)$r]   typingr   sympy.core.addr   sympy.core.exprr   sympy.core.functionr   r   sympy.core.mulr   sympy.core.numbersr	   rf   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   r!   <module>   s.    
 'Y 