a
    kh                     @   s   d 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 dd	lmZ dd
lmZmZ dgZG dd deZejeedd ZdS )z"The commutator: [A,B] = A*B - B*A.    )Add)Expr)KindDispatcher)Mul)Pow)S)
prettyForm)Dagger)_OperatorKindOperatorKind
Commutatorc                   @   s   e Zd ZdZdZedddZedd Z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S )r   a?  The standard commutator, in an unevaluated state.

    Explanation
    ===========

    Evaluating a commutator is defined [1]_ as: ``[A, B] = A*B - B*A``. This
    class returns the commutator in an unevaluated form. To evaluate the
    commutator, use the ``.doit()`` method.

    Canonical ordering of a commutator is ``[A, B]`` for ``A < B``. The
    arguments of the commutator are put into canonical order using ``__cmp__``.
    If ``B < A``, then ``[B, A]`` is returned as ``-[A, B]``.

    Parameters
    ==========

    A : Expr
        The first argument of the commutator [A,B].
    B : Expr
        The second argument of the commutator [A,B].

    Examples
    ========

    >>> from sympy.physics.quantum import Commutator, Dagger, Operator
    >>> from sympy.abc import x, y
    >>> A = Operator('A')
    >>> B = Operator('B')
    >>> C = Operator('C')

    Create a commutator and use ``.doit()`` to evaluate it:

    >>> comm = Commutator(A, B)
    >>> comm
    [A,B]
    >>> comm.doit()
    A*B - B*A

    The commutator orders it arguments in canonical order:

    >>> comm = Commutator(B, A); comm
    -[A,B]

    Commutative constants are factored out:

    >>> Commutator(3*x*A, x*y*B)
    3*x**2*y*[A,B]

    Using ``.expand(commutator=True)``, the standard commutator expansion rules
    can be applied:

    >>> Commutator(A+B, C).expand(commutator=True)
    [A,C] + [B,C]
    >>> Commutator(A, B+C).expand(commutator=True)
    [A,B] + [A,C]
    >>> Commutator(A*B, C).expand(commutator=True)
    [A,C]*B + A*[B,C]
    >>> Commutator(A, B*C).expand(commutator=True)
    [A,B]*C + B*[A,C]

    Adjoint operations applied to the commutator are properly applied to the
    arguments:

    >>> Dagger(Commutator(A, B))
    -[Dagger(A),Dagger(B)]

    References
    ==========

    .. [1] https://en.wikipedia.org/wiki/Commutator
    FZCommutator_kind_dispatcherT)Zcommutativec                 C   s   dd | j D }| j| S )Nc                 s   s   | ]}|j V  qd S N)kind).0a r   N/var/www/auris/lib/python3.9/site-packages/sympy/physics/quantum/commutator.py	<genexpr>f       z"Commutator.kind.<locals>.<genexpr>)args_kind_dispatcher)selfZ	arg_kindsr   r   r   r   d   s    zCommutator.kindc                 C   s*   |  ||}|d ur|S t| ||}|S r   )evalr   __new__)clsABrobjr   r   r   r   i   s
    zCommutator.__new__c                 C   s   |r|st jS ||krt jS |js(|jr.t jS | \}}| \}}|| }|rrtt| | t|t|S ||dkrt j| || S d S )N   )r   ZZerois_commutativeZargs_cncr   Z
_from_argscompareZNegativeOne)r   r   bcaZncacbZncbZc_partr   r   r   r   p   s     zCommutator.evalc           	      C   s   |j }|jr | r t|dkr$| S |j}|jr@|jd }| }t||jdd}||d  | }td|D ]$}|||d |  | ||  7 }ql||  S )Nr   T)Z
commutator)	exp
is_integeris_constantabsbaseZis_negativer   expandrange)	r   r   r   signr&   r*   commresultir   r   r   _expand_pow   s    
"zCommutator._expand_powc                 K   s  | j d }| j d }t|tr\g }|j D ]*}t||}t|trH| }|| q(t| S t|trg }|j D ]*}t||}t|tr| }|| qpt| S t|tr(|j d }t|j dd   }|}	t||	}
t||	}t|
tr|
 }
t|tr
| }t||
}t||}t||S t|tr|}|j d }t|j dd   }	t||}
t||	}t|
tr||
 }
t|tr| }t|
|	}t||}t||S t|tr| ||dS t|tr| ||dS | S )Nr   r   r%   )	r   
isinstancer   r   _eval_expand_commutatorappendr   r   r1   )r   hintsr   r   ZsargsZtermr.   r   r"   cZcomm1Zcomm2firstsecondr   r   r   r3      sb    






















z"Commutator._eval_expand_commutatorc                 K   s   ddl m} | jd }| jd }t||rt||rz|j|fi |}W nD ty   zd|j|fi | }W n ty   d}Y n0 Y n0 |dur|jf i |S || ||  jf i |S )z Evaluate commutator r   )Operatorr   r%   N)Zsympy.physics.quantum.operatorr9   r   r2   Z_eval_commutatorNotImplementedErrordoit)r   r5   r9   r   r   r.   r   r   r   r;      s    

zCommutator.doitc                 C   s   t t| jd t| jd S )Nr   r   )r   r	   r   )r   r   r   r   _eval_adjoint   s    zCommutator._eval_adjointc                 G   s*   d| j j|| jd || jd f S )Nz	%s(%s,%s)r   r   )	__class____name___printr   r   printerr   r   r   r   
_sympyrepr   s    
zCommutator._sympyreprc                 G   s$   d| | jd | | jd f S )Nz[%s,%s]r   r   )r?   r   r@   r   r   r   	_sympystr   s    zCommutator._sympystrc                 G   sb   |j | jd g|R  }t|td }t||j | jd g|R   }t|jddd }|S )Nr   ,r   [])leftright)r?   r   r   rH   parens)r   rA   r   Zpformr   r   r   _pretty   s
    "zCommutator._prettyc                    s   dt  fdd| jD  S )Nz\left[%s,%s\right]c                    s   g | ]}j |g R  qS r   )r?   )r   argr   rA   r   r   
<listcomp>   s   z%Commutator._latex.<locals>.<listcomp>)tupler   r@   r   rL   r   _latex   s    zCommutator._latexN)r>   
__module____qualname____doc__r    r   r   propertyr   r   classmethodr   r1   r3   r;   r<   rB   rC   rJ   rO   r   r   r   r   r      s    G

<c                 C   s   t S )z8Find the kind of an anticommutator of two OperatorKinds.)r   )e1e2r   r   r   find_op_kind   s    rW   N)rR   Zsympy.core.addr   Zsympy.core.exprr   Zsympy.core.kindr   Zsympy.core.mulr   Zsympy.core.powerr   Zsympy.core.singletonr   Z sympy.printing.pretty.stringpictr   Zsympy.physics.quantum.daggerr	   Zsympy.physics.quantum.kindr
   r   __all__r   r   registerrW   r   r   r   r   <module>   s   	 f